4 /* globals gettext, interpolate */
7 var getBoundriesForAList = function(fragment) {
10 if(fragment instanceof fragment.RangeFragment && fragment.hasSiblingBoundries()) {
11 return fragment.startNode.hasSameContextRoot(fragment.endNode) && fragment.boundriesSiblingParents();
13 if(fragment instanceof fragment.NodeFragment) {
14 node = fragment.node.getNearestElementNode();
15 if(node.isContextRoot()) {
26 var countItems = function(boundries) {
27 var ptr = boundries.node1,
29 while(ptr && !ptr.sameNode(boundries.node2)) {
36 var toggleListAction = function(type) {
39 add: function(callback, params) {
40 var boundries = getBoundriesForAList(params.fragment),
41 listParams = {klass: type === 'Bullet' ? 'list' : 'list.enum'},
44 if(boundries && boundries.node1) {
45 listParams.node1 = boundries.node1;
46 listParams.node2 = boundries.node2;
47 boundries.node1.document.transaction(function() {
48 var list = boundries.node1.document.createList(listParams),
49 item1 = list.object.getItem(0),
50 text = item1 ? item1.contents()[0] : undefined, //
51 doc = boundries.node1.document;
53 return doc.createFragment(doc.CaretFragment, {node: text, offset:0});
57 description: action.getState().description,
58 fragment: params.fragment
63 throw new Error('Invalid boundries');
66 remove: function(callback, params) {
68 var current = params.fragment.node,
71 var toSearch = current.nodeType === Node.ELEMENT_NODE ? [current] : [];
72 toSearch = toSearch.concat(current.parents());
73 toSearch.some(function(node) {
75 node.document.transaction(function() {
76 var firstItem = node.object.extractListItems(),
78 if(params.fragment.isValid()) {
79 toret = params.fragment;
81 toret = node.document.createFragment(node.document.NodeFragment, {node: firstItem});
86 description: action.getState().description,
87 fragment: params.fragment
96 changeType: function(callback, params) {
97 var node = params.fragment.node,
99 node.document.transaction(function() {
100 var list = node.getParent('list');
101 list.setClass(type === 'Bullet' ? 'list' : 'list.enum');
102 if(params.fragment.isValid()) {
103 return params.fragment;
105 return node.document.createFragment(node.document.NodeFragment, {node: list.contents()[0]});
109 description: action.getState().description,
110 fragment: params.fragment
117 var isToggled = function(params) {
118 if(params.fragment && params.fragment.node && params.fragment.node.isInside('list')) {
119 var list = params.fragment.node.getParent('list');
120 return list.getClass() === (type === 'Bullet' ? 'list' : 'list.enum');
125 var label = type === 'Bullet' ? gettext('bull. list') : gettext('num. list');
128 name: 'toggle' + type + 'List',
129 context: ['fragment'],
131 fragment: {type: 'context', name: 'fragment'}
136 getState: function(params) {
137 if(!params.fragment || !params.fragment.isValid()) {
141 if(params.fragment instanceof params.fragment.CaretFragment && params.fragment.node.isInside('list')) {
142 var list = params.fragment.node.getParent('list');
143 if((list.getClass() === 'list' && type === 'Enum') || (list.getClass() === 'list.enum' && type === 'Bullet')) {
146 description: interpolate(gettext('Change list type to %s'), [label]),
147 execute: execute.changeType
152 toggled: isToggled(params),
153 description: gettext('Remove list'),
154 execute: execute.remove
158 var boundries = getBoundriesForAList(params.fragment);
159 if(boundries && boundries.node1.hasSameContextRoot(boundries.node2)) {
162 description: interpolate(gettext('Make %s fragment(s) into list'), [countItems(getBoundriesForAList(params.fragment))]),
172 actions: [toggleListAction('Bullet'), toggleListAction('Enum')]