source: sandbox/3.0/phpgwapi/js/ckeditor/_source/plugins/list/plugin.js @ 2862

Revision 2862, 22.0 KB checked in by rodsouza, 14 years ago (diff)

Ticket #663 - Atualizando e centralizando o CKEditor (v. 3.2.1)

Line 
1/*
2Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
3For licensing, see LICENSE.html or http://ckeditor.com/license
4*/
5
6/**
7 * @file Insert and remove numbered and bulleted lists.
8 */
9
10(function()
11{
12        var listNodeNames = { ol : 1, ul : 1 },
13                emptyTextRegex = /^[\n\r\t ]*$/;
14
15        CKEDITOR.plugins.list = {
16                /*
17                 * Convert a DOM list tree into a data structure that is easier to
18                 * manipulate. This operation should be non-intrusive in the sense that it
19                 * does not change the DOM tree, with the exception that it may add some
20                 * markers to the list item nodes when database is specified.
21                 */
22                listToArray : function( listNode, database, baseArray, baseIndentLevel, grandparentNode )
23                {
24                        if ( !listNodeNames[ listNode.getName() ] )
25                                return [];
26
27                        if ( !baseIndentLevel )
28                                baseIndentLevel = 0;
29                        if ( !baseArray )
30                                baseArray = [];
31
32                        // Iterate over all list items to and look for inner lists.
33                        for ( var i = 0, count = listNode.getChildCount() ; i < count ; i++ )
34                        {
35                                var listItem = listNode.getChild( i );
36
37                                // It may be a text node or some funny stuff.
38                                if ( listItem.$.nodeName.toLowerCase() != 'li' )
39                                        continue;
40
41                                var itemObj = { 'parent' : listNode, indent : baseIndentLevel, element : listItem, contents : [] };
42                                if ( !grandparentNode )
43                                {
44                                        itemObj.grandparent = listNode.getParent();
45                                        if ( itemObj.grandparent && itemObj.grandparent.$.nodeName.toLowerCase() == 'li' )
46                                                itemObj.grandparent = itemObj.grandparent.getParent();
47                                }
48                                else
49                                        itemObj.grandparent = grandparentNode;
50
51                                if ( database )
52                                        CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length );
53                                baseArray.push( itemObj );
54
55                                for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount ; j++ )
56                                {
57                                        child = listItem.getChild( j );
58                                        if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] )
59                                                // Note the recursion here, it pushes inner list items with
60                                                // +1 indentation in the correct order.
61                                                CKEDITOR.plugins.list.listToArray( child, database, baseArray, baseIndentLevel + 1, itemObj.grandparent );
62                                        else
63                                                itemObj.contents.push( child );
64                                }
65                        }
66                        return baseArray;
67                },
68
69                // Convert our internal representation of a list back to a DOM forest.
70                arrayToList : function( listArray, database, baseIndex, paragraphMode )
71                {
72                        if ( !baseIndex )
73                                baseIndex = 0;
74                        if ( !listArray || listArray.length < baseIndex + 1 )
75                                return null;
76                        var doc = listArray[ baseIndex ].parent.getDocument(),
77                                retval = new CKEDITOR.dom.documentFragment( doc ),
78                                rootNode = null,
79                                currentIndex = baseIndex,
80                                indentLevel = Math.max( listArray[ baseIndex ].indent, 0 ),
81                                currentListItem = null,
82                                paragraphName = ( paragraphMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
83                        while ( true )
84                        {
85                                var item = listArray[ currentIndex ];
86                                if ( item.indent == indentLevel )
87                                {
88                                        if ( !rootNode || listArray[ currentIndex ].parent.getName() != rootNode.getName() )
89                                        {
90                                                rootNode = listArray[ currentIndex ].parent.clone( false, true );
91                                                retval.append( rootNode );
92                                        }
93                                        currentListItem = rootNode.append( item.element.clone( false, true ) );
94                                        for ( var i = 0 ; i < item.contents.length ; i++ )
95                                                currentListItem.append( item.contents[i].clone( true, true ) );
96                                        currentIndex++;
97                                }
98                                else if ( item.indent == Math.max( indentLevel, 0 ) + 1 )
99                                {
100                                        var listData = CKEDITOR.plugins.list.arrayToList( listArray, null, currentIndex, paragraphMode );
101                                        currentListItem.append( listData.listNode );
102                                        currentIndex = listData.nextIndex;
103                                }
104                                else if ( item.indent == -1 && !baseIndex && item.grandparent )
105                                {
106                                        currentListItem;
107                                        if ( listNodeNames[ item.grandparent.getName() ] )
108                                                currentListItem = item.element.clone( false, true );
109                                        else
110                                        {
111                                                // Create completely new blocks here, attributes are dropped.
112                                                if ( paragraphMode != CKEDITOR.ENTER_BR && item.grandparent.getName() != 'td' )
113                                                        currentListItem = doc.createElement( paragraphName );
114                                                else
115                                                        currentListItem = new CKEDITOR.dom.documentFragment( doc );
116                                        }
117
118                                        for ( i = 0 ; i < item.contents.length ; i++ )
119                                                currentListItem.append( item.contents[i].clone( true, true ) );
120
121                                        if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT
122                                                 && currentIndex != listArray.length - 1 )
123                                        {
124                                                if ( currentListItem.getLast()
125                                                                && currentListItem.getLast().type == CKEDITOR.NODE_ELEMENT
126                                                                && currentListItem.getLast().getAttribute( 'type' ) == '_moz' )
127                                                        currentListItem.getLast().remove();
128                                                currentListItem.appendBogus();
129                                        }
130
131                                        if ( currentListItem.type == CKEDITOR.NODE_ELEMENT &&
132                                                        currentListItem.getName() == paragraphName &&
133                                                        currentListItem.$.firstChild )
134                                        {
135                                                currentListItem.trim();
136                                                var firstChild = currentListItem.getFirst();
137                                                if ( firstChild.type == CKEDITOR.NODE_ELEMENT && firstChild.isBlockBoundary() )
138                                                {
139                                                        var tmp = new CKEDITOR.dom.documentFragment( doc );
140                                                        currentListItem.moveChildren( tmp );
141                                                        currentListItem = tmp;
142                                                }
143                                        }
144
145                                        var currentListItemName = currentListItem.$.nodeName.toLowerCase();
146                                        if ( !CKEDITOR.env.ie && ( currentListItemName == 'div' || currentListItemName == 'p' ) )
147                                                currentListItem.appendBogus();
148                                        retval.append( currentListItem );
149                                        rootNode = null;
150                                        currentIndex++;
151                                }
152                                else
153                                        return null;
154
155                                if ( listArray.length <= currentIndex || Math.max( listArray[ currentIndex ].indent, 0 ) < indentLevel )
156                                        break;
157                        }
158
159                        // Clear marker attributes for the new list tree made of cloned nodes, if any.
160                        if ( database )
161                        {
162                                var currentNode = retval.getFirst();
163                                while ( currentNode )
164                                {
165                                        if ( currentNode.type == CKEDITOR.NODE_ELEMENT )
166                                                CKEDITOR.dom.element.clearMarkers( database, currentNode );
167                                        currentNode = currentNode.getNextSourceNode();
168                                }
169                        }
170
171                        return { listNode : retval, nextIndex : currentIndex };
172                }
173        };
174
175        function setState( editor, state )
176        {
177                editor.getCommand( this.name ).setState( state );
178        }
179
180        function onSelectionChange( evt )
181        {
182                var path = evt.data.path,
183                        blockLimit = path.blockLimit,
184                        elements = path.elements,
185                        element;
186
187                // Grouping should only happen under blockLimit.(#3940).
188                for ( var i = 0 ; i < elements.length && ( element = elements[ i ] )
189                          && !element.equals( blockLimit ); i++ )
190                {
191                        if ( listNodeNames[ elements[i].getName() ] )
192                        {
193                                return setState.call( this, evt.editor,
194                                                this.type == elements[i].getName() ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
195                        }
196                }
197
198                return setState.call( this, evt.editor, CKEDITOR.TRISTATE_OFF );
199        }
200
201        function changeListType( editor, groupObj, database, listsCreated )
202        {
203                // This case is easy...
204                // 1. Convert the whole list into a one-dimensional array.
205                // 2. Change the list type by modifying the array.
206                // 3. Recreate the whole list by converting the array to a list.
207                // 4. Replace the original list with the recreated list.
208                var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
209                        selectedListItems = [];
210
211                for ( var i = 0 ; i < groupObj.contents.length ; i++ )
212                {
213                        var itemNode = groupObj.contents[i];
214                        itemNode = itemNode.getAscendant( 'li', true );
215                        if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
216                                continue;
217                        selectedListItems.push( itemNode );
218                        CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
219                }
220
221                var fakeParent = groupObj.root.getDocument().createElement( this.type );
222                for ( i = 0 ; i < selectedListItems.length ; i++ )
223                {
224                        var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
225                        listArray[listIndex].parent = fakeParent;
226                }
227                var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );
228                var child, length = newList.listNode.getChildCount();
229                for ( i = 0 ; i < length && ( child = newList.listNode.getChild( i ) ) ; i++ )
230                {
231                        if ( child.getName() == this.type )
232                                listsCreated.push( child );
233                }
234                newList.listNode.replace( groupObj.root );
235        }
236
237        function createList( editor, groupObj, listsCreated )
238        {
239                var contents = groupObj.contents,
240                        doc = groupObj.root.getDocument(),
241                        listContents = [];
242
243                // It is possible to have the contents returned by DomRangeIterator to be the same as the root.
244                // e.g. when we're running into table cells.
245                // In such a case, enclose the childNodes of contents[0] into a <div>.
246                if ( contents.length == 1 && contents[0].equals( groupObj.root ) )
247                {
248                        var divBlock = doc.createElement( 'div' );
249                        contents[0].moveChildren && contents[0].moveChildren( divBlock );
250                        contents[0].append( divBlock );
251                        contents[0] = divBlock;
252                }
253
254                // Calculate the common parent node of all content blocks.
255                var commonParent = groupObj.contents[0].getParent();
256                for ( var i = 0 ; i < contents.length ; i++ )
257                        commonParent = commonParent.getCommonAncestor( contents[i].getParent() );
258
259                // We want to insert things that are in the same tree level only, so calculate the contents again
260                // by expanding the selected blocks to the same tree level.
261                for ( i = 0 ; i < contents.length ; i++ )
262                {
263                        var contentNode = contents[i],
264                                parentNode;
265                        while ( ( parentNode = contentNode.getParent() ) )
266                        {
267                                if ( parentNode.equals( commonParent ) )
268                                {
269                                        listContents.push( contentNode );
270                                        break;
271                                }
272                                contentNode = parentNode;
273                        }
274                }
275
276                if ( listContents.length < 1 )
277                        return;
278
279                // Insert the list to the DOM tree.
280                var insertAnchor = listContents[ listContents.length - 1 ].getNext(),
281                        listNode = doc.createElement( this.type );
282
283                listsCreated.push( listNode );
284                while ( listContents.length )
285                {
286                        var contentBlock = listContents.shift(),
287                                listItem = doc.createElement( 'li' );
288                        contentBlock.moveChildren( listItem );
289                        contentBlock.remove();
290                        listItem.appendTo( listNode );
291
292                        // Append a bogus BR to force the LI to render at full height
293                        if ( !CKEDITOR.env.ie )
294                                listItem.appendBogus();
295                }
296                if ( insertAnchor )
297                        listNode.insertBefore( insertAnchor );
298                else
299                        listNode.appendTo( commonParent );
300        }
301
302        function removeList( editor, groupObj, database )
303        {
304                // This is very much like the change list type operation.
305                // Except that we're changing the selected items' indent to -1 in the list array.
306                var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
307                        selectedListItems = [];
308
309                for ( var i = 0 ; i < groupObj.contents.length ; i++ )
310                {
311                        var itemNode = groupObj.contents[i];
312                        itemNode = itemNode.getAscendant( 'li', true );
313                        if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
314                                continue;
315                        selectedListItems.push( itemNode );
316                        CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
317                }
318
319                var lastListIndex = null;
320                for ( i = 0 ; i < selectedListItems.length ; i++ )
321                {
322                        var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
323                        listArray[listIndex].indent = -1;
324                        lastListIndex = listIndex;
325                }
326
327                // After cutting parts of the list out with indent=-1, we still have to maintain the array list
328                // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the
329                // list cannot be converted back to a real DOM list.
330                for ( i = lastListIndex + 1 ; i < listArray.length ; i++ )
331                {
332                        if ( listArray[i].indent > listArray[i-1].indent + 1 )
333                        {
334                                var indentOffset = listArray[i-1].indent + 1 - listArray[i].indent;
335                                var oldIndent = listArray[i].indent;
336                                while ( listArray[i] && listArray[i].indent >= oldIndent )
337                                {
338                                        listArray[i].indent += indentOffset;
339                                        i++;
340                                }
341                                i--;
342                        }
343                }
344
345                var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );
346
347                // Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836)
348                var docFragment = newList.listNode, boundaryNode, siblingNode;
349                function compensateBrs( isStart )
350                {
351                        if ( ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() )
352                                 && !( boundaryNode.is && boundaryNode.isBlockBoundary() )
353                                 && ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ]
354                                      ( CKEDITOR.dom.walker.whitespaces( true ) ) )
355                                 && !( siblingNode.is && siblingNode.isBlockBoundary( { br : 1 } ) ) )
356                                editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode );
357                }
358                compensateBrs( true );
359                compensateBrs();
360
361                docFragment.replace( groupObj.root );
362        }
363
364        function listCommand( name, type )
365        {
366                this.name = name;
367                this.type = type;
368        }
369
370        listCommand.prototype = {
371                exec : function( editor )
372                {
373                        editor.focus();
374
375                        var doc = editor.document,
376                                selection = editor.getSelection(),
377                                ranges = selection && selection.getRanges();
378
379                        // There should be at least one selected range.
380                        if ( !ranges || ranges.length < 1 )
381                                return;
382
383                        // Midas lists rule #1 says we can create a list even in an empty document.
384                        // But DOM iterator wouldn't run if the document is really empty.
385                        // So create a paragraph if the document is empty and we're going to create a list.
386                        if ( this.state == CKEDITOR.TRISTATE_OFF )
387                        {
388                                var body = doc.getBody();
389                                body.trim();
390                                if ( !body.getFirst() )
391                                {
392                                        var paragraph = doc.createElement( editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' :
393                                                        ( editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'br' ) );
394                                        paragraph.appendTo( body );
395                                        ranges = [ new CKEDITOR.dom.range( doc ) ];
396                                        // IE exception on inserting anything when anchor inside <br>.
397                                        if ( paragraph.is( 'br' ) )
398                                        {
399                                                ranges[ 0 ].setStartBefore( paragraph );
400                                                ranges[ 0 ].setEndAfter( paragraph );
401                                        }
402                                        else
403                                                ranges[ 0 ].selectNodeContents( paragraph );
404                                        selection.selectRanges( ranges );
405                                }
406                                // Maybe a single range there enclosing the whole list,
407                                // turn on the list state manually(#4129).
408                                else
409                                {
410                                        var range = ranges.length == 1 && ranges[ 0 ],
411                                                enclosedNode = range && range.getEnclosedNode();
412                                        if ( enclosedNode && enclosedNode.is
413                                                && this.type == enclosedNode.getName() )
414                                        {
415                                                setState.call( this, editor, CKEDITOR.TRISTATE_ON );
416                                        }
417                                }
418                        }
419
420                        var bookmarks = selection.createBookmarks( true );
421
422                        // Group the blocks up because there are many cases where multiple lists have to be created,
423                        // or multiple lists have to be cancelled.
424                        var listGroups = [],
425                                database = {};
426
427                        while ( ranges.length > 0 )
428                        {
429                                range = ranges.shift();
430
431                                var boundaryNodes = range.getBoundaryNodes(),
432                                        startNode = boundaryNodes.startNode,
433                                        endNode = boundaryNodes.endNode;
434
435                                if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' )
436                                        range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START );
437
438                                if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' )
439                                        range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END );
440
441                                var iterator = range.createIterator(),
442                                        block;
443
444                                iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF );
445
446                                while ( ( block = iterator.getNextParagraph() ) )
447                                {
448                                        var path = new CKEDITOR.dom.elementPath( block ),
449                                                pathElements = path.elements,
450                                                pathElementsCount = pathElements.length,
451                                                listNode = null,
452                                                processedFlag = false,
453                                                blockLimit = path.blockLimit,
454                                                element;
455
456                                        // First, try to group by a list ancestor.
457                                        for ( var i = pathElementsCount - 1; i >= 0 && ( element = pathElements[ i ] ); i-- )
458                                        {
459                                                if ( listNodeNames[ element.getName() ]
460                                                         && blockLimit.contains( element ) )     // Don't leak outside block limit (#3940).
461                                                {
462                                                        // If we've encountered a list inside a block limit
463                                                        // The last group object of the block limit element should
464                                                        // no longer be valid. Since paragraphs after the list
465                                                        // should belong to a different group of paragraphs before
466                                                        // the list. (Bug #1309)
467                                                        blockLimit.removeCustomData( 'list_group_object' );
468
469                                                        var groupObj = element.getCustomData( 'list_group_object' );
470                                                        if ( groupObj )
471                                                                groupObj.contents.push( block );
472                                                        else
473                                                        {
474                                                                groupObj = { root : element, contents : [ block ] };
475                                                                listGroups.push( groupObj );
476                                                                CKEDITOR.dom.element.setMarker( database, element, 'list_group_object', groupObj );
477                                                        }
478                                                        processedFlag = true;
479                                                        break;
480                                                }
481                                        }
482
483                                        if ( processedFlag )
484                                                continue;
485
486                                        // No list ancestor? Group by block limit.
487                                        var root = blockLimit;
488                                        if ( root.getCustomData( 'list_group_object' ) )
489                                                root.getCustomData( 'list_group_object' ).contents.push( block );
490                                        else
491                                        {
492                                                groupObj = { root : root, contents : [ block ] };
493                                                CKEDITOR.dom.element.setMarker( database, root, 'list_group_object', groupObj );
494                                                listGroups.push( groupObj );
495                                        }
496                                }
497                        }
498
499                        // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.
500                        // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking
501                        // at the group that's not rooted at lists. So we have three cases to handle.
502                        var listsCreated = [];
503                        while ( listGroups.length > 0 )
504                        {
505                                groupObj = listGroups.shift();
506                                if ( this.state == CKEDITOR.TRISTATE_OFF )
507                                {
508                                        if ( listNodeNames[ groupObj.root.getName() ] )
509                                                changeListType.call( this, editor, groupObj, database, listsCreated );
510                                        else
511                                                createList.call( this, editor, groupObj, listsCreated );
512                                }
513                                else if ( this.state == CKEDITOR.TRISTATE_ON && listNodeNames[ groupObj.root.getName() ] )
514                                        removeList.call( this, editor, groupObj, database );
515                        }
516
517                        // For all new lists created, merge adjacent, same type lists.
518                        for ( i = 0 ; i < listsCreated.length ; i++ )
519                        {
520                                listNode = listsCreated[i];
521                                var mergeSibling, listCommand = this;
522                                ( mergeSibling = function( rtl ){
523
524                                        var sibling = listNode[ rtl ?
525                                                'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.whitespaces( true ) );
526                                        if ( sibling && sibling.getName &&
527                                             sibling.getName() == listCommand.type )
528                                        {
529                                                sibling.remove();
530                                                // Move children order by merge direction.(#3820)
531                                                sibling.moveChildren( listNode, rtl ? true : false );
532                                        }
533                                } )();
534                                mergeSibling( true );
535                        }
536
537                        // Clean up, restore selection and update toolbar button states.
538                        CKEDITOR.dom.element.clearAllMarkers( database );
539                        selection.selectBookmarks( bookmarks );
540                        editor.focus();
541                }
542        };
543
544        var dtd = CKEDITOR.dtd;
545        var tailNbspRegex = /[\t\r\n ]*(?:&nbsp;|\xa0)$/;
546
547        function indexOfFirstChildElement( element, tagNameList )
548        {
549                var child,
550                        children = element.children,
551                        length = children.length;
552
553                for ( var i = 0 ; i < length ; i++ )
554                {
555                        child = children[ i ];
556                        if ( child.name && ( child.name in tagNameList ) )
557                                return i;
558                }
559
560                return length;
561        }
562
563        function getExtendNestedListFilter( isHtmlFilter )
564        {
565                // An element filter function that corrects nested list start in an empty
566                // list item for better displaying/outputting. (#3165)
567                return function( listItem )
568                {
569                        var children = listItem.children,
570                                firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ),
571                                firstNestedList = children[ firstNestedListIndex ],
572                                nodeBefore = firstNestedList && firstNestedList.previous,
573                                tailNbspmatch;
574
575                        if ( nodeBefore
576                                && ( nodeBefore.name && nodeBefore.name == 'br'
577                                        || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) )
578                        {
579                                var fillerNode = nodeBefore;
580
581                                // Always use 'nbsp' as filler node if we found a nested list appear
582                                // in front of a list item.
583                                if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] )
584                                        children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ?
585                                                         new CKEDITOR.htmlParser.text( '\xa0' ) :
586                                                                         new CKEDITOR.htmlParser.element( 'br', {} );
587
588                                // Otherwise the filler is not needed anymore.
589                                else if ( fillerNode.name == 'br' )
590                                        children.splice( firstNestedListIndex - 1, 1 );
591                                else
592                                        fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' );
593                        }
594
595                };
596        }
597
598        var defaultListDataFilterRules = { elements : {} };
599        for ( var i in dtd.$listItem )
600                if ( ! ( i in Object.prototype ) )
601                        defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter();
602
603        var defaultListHtmlFilterRules = { elements : {} };
604        for ( i in dtd.$listItem )
605                defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true );
606
607        CKEDITOR.plugins.add( 'list',
608        {
609                init : function( editor )
610                {
611                        // Register commands.
612                        var numberedListCommand = new listCommand( 'numberedlist', 'ol' ),
613                                bulletedListCommand = new listCommand( 'bulletedlist', 'ul' );
614                        editor.addCommand( 'numberedlist', numberedListCommand );
615                        editor.addCommand( 'bulletedlist', bulletedListCommand );
616
617                        // Register the toolbar button.
618                        editor.ui.addButton( 'NumberedList',
619                                {
620                                        label : editor.lang.numberedlist,
621                                        command : 'numberedlist'
622                                } );
623                        editor.ui.addButton( 'BulletedList',
624                                {
625                                        label : editor.lang.bulletedlist,
626                                        command : 'bulletedlist'
627                                } );
628
629                        // Register the state changing handlers.
630                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, numberedListCommand ) );
631                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) );
632                },
633
634                afterInit : function ( editor )
635                {
636                        var dataProcessor = editor.dataProcessor;
637                        if ( dataProcessor )
638                        {
639                                dataProcessor.dataFilter.addRules( defaultListDataFilterRules );
640                                dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );
641                        }
642                },
643
644                requires : [ 'domiterator' ]
645        } );
646})();
Note: See TracBrowser for help on using the repository browser.