4 /* globals gettext, interpolate */
 
   7 var getBoundriesForAList = function(fragment) {
 
  10     if(fragment instanceof fragment.RangeFragment && fragment.hasSiblingBoundries()) {
 
  11         return fragment.boundriesSiblingParents();
 
  13     if(fragment instanceof fragment.NodeFragment) {
 
  14         node = fragment.node.getNearestElementNode();
 
  22 var countItems = function(boundries) {
 
  23     var ptr = boundries.node1,
 
  25     while(ptr && !ptr.sameNode(boundries.node2)) {
 
  32 var toggleListAction = function(type) {
 
  35         add: function(callback, params) {
 
  36             var boundries = getBoundriesForAList(params.fragment),
 
  37                 listParams = {klass: type === 'Bullet' ? 'list' : 'list.enum'},
 
  40             if(boundries && boundries.node1) {
 
  41                 listParams.node1 = boundries.node1;
 
  42                 listParams.node2 = boundries.node2;
 
  43                 boundries.node1.document.transaction(function() {
 
  44                     var list = boundries.node1.document.createList(listParams),
 
  45                         item1 = list.object.getItem(0),
 
  46                         text = item1 ? item1.contents()[0] : undefined, //
 
  47                         doc = boundries.node1.document;
 
  49                    return doc.createFragment(doc.CaretFragment, {node: text, offset:0});
 
  52                         description: action.getState().description
 
  57                 throw new Error('Invalid boundries');
 
  60         remove: function(callback, params) {
 
  62             var current = params.fragment.node,
 
  65             var toSearch = current.nodeType === Node.ELEMENT_NODE ? [current] : [];
 
  66             toSearch = toSearch.concat(current.parents());
 
  67             toSearch.some(function(node) {
 
  69                     node.document.transaction(function() {
 
  70                         node.object.extractListItems();
 
  73                             description: action.getState().description
 
  82         changeType: function(callback, params) {
 
  83             var node = params.fragment.node,
 
  85             node.document.transaction(function() {
 
  86                 node.getParent('list').setClass(type === 'Bullet' ? 'list' : 'list.enum');
 
  89                     description: action.getState().description
 
  96     var isToggled = function(params) {
 
  97         if(params.fragment && params.fragment.node && params.fragment.node.isInside('list')) {
 
  98             var list = params.fragment.node.getParent('list');
 
  99             return list.getClass() === (type === 'Bullet' ? 'list' : 'list.enum');
 
 104     var label = type === 'Bullet' ? gettext('bull. list') : gettext('num. list');
 
 107         name: 'toggle' + type + 'List',
 
 108         context: ['fragment'],
 
 110             fragment: {type: 'context', name: 'fragment'}
 
 115         getState: function(params) {
 
 116             if(!params.fragment || !params.fragment.isValid()) {
 
 120             if(params.fragment instanceof params.fragment.CaretFragment && params.fragment.node.isInside('list')) {
 
 121                 var list = params.fragment.node.getParent('list');
 
 122                 if((list.getClass() === 'list' && type === 'Enum') || (list.getClass() === 'list.enum' && type === 'Bullet')) {
 
 125                         description: interpolate(gettext('Change list type to %s'), [label]),
 
 126                         execute: execute.changeType
 
 131                     toggled: isToggled(params),
 
 132                     description: gettext('Remove list'),
 
 133                     execute: execute.remove
 
 137             var boundries = getBoundriesForAList(params.fragment);
 
 141                     description: interpolate(gettext('Make %s fragment(s) into list'), [countItems(getBoundriesForAList(params.fragment))]),
 
 151     actions: [toggleListAction('Bullet'), toggleListAction('Enum')]