X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Findent%2Fplugin.js;h=c49ce882832188b5b1c876898cd5a5d9d2762a6b;hb=614511639979907ceb0da3614122a4d8eb963ad4;hp=c6888219cbdaea7f1257636689c3933f7e1a84f3;hpb=ea7e3453c7b0f023b050aca6d9f83ab372860d91;p=ckeditor.git diff --git a/_source/plugins/indent/plugin.js b/_source/plugins/indent/plugin.js index c688821..c49ce88 100644 --- a/_source/plugins/indent/plugin.js +++ b/_source/plugins/indent/plugin.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -11,6 +11,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { var listNodeNames = { ol : 1, ul : 1 }; + var isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ), + isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true ); + function setState( editor, state ) { editor.getCommand( this.name ).setState( state ); @@ -18,38 +21,13 @@ For licensing, see LICENSE.html or http://ckeditor.com/license function onSelectionChange( evt ) { - var elements = evt.data.path.elements, - listNode, listItem, - editor = evt.editor; + var editor = evt.editor; - for ( var i = 0 ; i < elements.length ; i++ ) - { - if ( elements[i].getName() == 'li' ) - { - listItem = elements[i]; - continue; - } - if ( listNodeNames[ elements[i].getName() ] ) - { - listNode = elements[i]; - break; - } - } + var elementPath = evt.data.path, + list = elementPath && elementPath.contains( listNodeNames ); - if ( listNode ) - { - if ( this.name == 'outdent' ) + if ( list ) return setState.call( this, editor, CKEDITOR.TRISTATE_OFF ); - else - { - while ( listItem && ( listItem = listItem.getPrevious( CKEDITOR.dom.walker.whitespaces( true ) ) ) ) - { - if ( listItem.getName && listItem.getName() == 'li' ) - return setState.call( this, editor, CKEDITOR.TRISTATE_OFF ); - } - return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED ); - } - } if ( !this.useIndentClasses && this.name == 'indent' ) return setState.call( this, editor, CKEDITOR.TRISTATE_OFF ); @@ -75,7 +53,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } else { - var indent = parseInt( firstBlock.getStyle( this.indentCssProperty ), 10 ); + var indent = parseInt( firstBlock.getStyle( getIndentCssProperty( firstBlock ) ), 10 ); if ( isNaN( indent ) ) indent = 0; if ( indent <= 0 ) @@ -84,201 +62,288 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } } - function indentList( editor, range, listNode ) + function indentCommand( editor, name ) { - // Our starting and ending points of the range might be inside some blocks under a list item... - // So before playing with the iterator, we need to expand the block to include the list items. - var startContainer = range.startContainer, - endContainer = range.endContainer; - while ( startContainer && !startContainer.getParent().equals( listNode ) ) - startContainer = startContainer.getParent(); - while ( endContainer && !endContainer.getParent().equals( listNode ) ) - endContainer = endContainer.getParent(); - - if ( !startContainer || !endContainer ) - return; - - // Now we can iterate over the individual items on the same tree depth. - var block = startContainer, - itemsToMove = [], - stopFlag = false; - while ( !stopFlag ) - { - if ( block.equals( endContainer ) ) - stopFlag = true; - itemsToMove.push( block ); - block = block.getNext(); - } - if ( itemsToMove.length < 1 ) - return; - - // Do indent or outdent operations on the array model of the list, not the - // list's DOM tree itself. The array model demands that it knows as much as - // possible about the surrounding lists, we need to feed it the further - // ancestor node that is still a list. - var listParents = listNode.getParents( true ); - for ( var i = 0 ; i < listParents.length ; i++ ) + this.name = name; + this.useIndentClasses = editor.config.indentClasses && editor.config.indentClasses.length > 0; + if ( this.useIndentClasses ) { - if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] ) - { - listNode = listParents[i]; - break; - } + this.classNameRegex = new RegExp( '(?:^|\\s+)(' + editor.config.indentClasses.join( '|' ) + ')(?=$|\\s)' ); + this.indentClassMap = {}; + for ( var i = 0 ; i < editor.config.indentClasses.length ; i++ ) + this.indentClassMap[ editor.config.indentClasses[i] ] = i + 1; } - var indentOffset = this.name == 'indent' ? 1 : -1, - startItem = itemsToMove[0], - lastItem = itemsToMove[ itemsToMove.length - 1 ], - database = {}; - - // Convert the list DOM tree into a one dimensional array. - var listArray = CKEDITOR.plugins.list.listToArray( listNode, database ); - - // Apply indenting or outdenting on the array. - var baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent; - for ( i = startItem.getCustomData( 'listarray_index' ) ; i <= lastItem.getCustomData( 'listarray_index' ) ; i++ ) - listArray[i].indent += indentOffset; - for ( i = lastItem.getCustomData( 'listarray_index' ) + 1 ; - i < listArray.length && listArray[i].indent > baseIndent ; i++ ) - listArray[i].indent += indentOffset; - - // Convert the array back to a DOM forest (yes we might have a few subtrees now). - // And replace the old list with the new forest. - var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, 0 ); - - // Avoid nested
  • after outdent even they're visually same, - // recording them for later refactoring.(#3982) - if ( this.name == 'outdent' ) + + this.startDisabled = name == 'outdent'; + } + + // Returns the CSS property to be used for identing a given element. + function getIndentCssProperty( element, dir ) + { + return ( dir || element.getComputedStyle( 'direction' ) ) == 'ltr' ? 'margin-left' : 'margin-right'; + } + + function isListItem( node ) + { + return node.type = CKEDITOR.NODE_ELEMENT && node.is( 'li' ); + } + + indentCommand.prototype = { + exec : function( editor ) { - var parentLiElement; - if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) ) + var self = this, database = {}; + + function indentList( listNode ) { - var children = newList.listNode.getChildren(), - pendingLis = [], - count = children.count(), - child; + // Our starting and ending points of the range might be inside some blocks under a list item... + // So before playing with the iterator, we need to expand the block to include the list items. + var startContainer = range.startContainer, + endContainer = range.endContainer; + while ( startContainer && !startContainer.getParent().equals( listNode ) ) + startContainer = startContainer.getParent(); + while ( endContainer && !endContainer.getParent().equals( listNode ) ) + endContainer = endContainer.getParent(); + + if ( !startContainer || !endContainer ) + return; + + // Now we can iterate over the individual items on the same tree depth. + var block = startContainer, + itemsToMove = [], + stopFlag = false; + while ( !stopFlag ) + { + if ( block.equals( endContainer ) ) + stopFlag = true; + itemsToMove.push( block ); + block = block.getNext(); + } + if ( itemsToMove.length < 1 ) + return; + + // Do indent or outdent operations on the array model of the list, not the + // list's DOM tree itself. The array model demands that it knows as much as + // possible about the surrounding lists, we need to feed it the further + // ancestor node that is still a list. + var listParents = listNode.getParents( true ); + for ( var i = 0 ; i < listParents.length ; i++ ) + { + if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] ) + { + listNode = listParents[i]; + break; + } + } + var indentOffset = self.name == 'indent' ? 1 : -1, + startItem = itemsToMove[0], + lastItem = itemsToMove[ itemsToMove.length - 1 ]; + + // Convert the list DOM tree into a one dimensional array. + var listArray = CKEDITOR.plugins.list.listToArray( listNode, database ); - for ( i = count - 1 ; i >= 0 ; i-- ) + // Apply indenting or outdenting on the array. + var baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent; + for ( i = startItem.getCustomData( 'listarray_index' ); i <= lastItem.getCustomData( 'listarray_index' ); i++ ) { - if( ( child = children.getItem( i ) ) && child.is && child.is( 'li' ) ) - pendingLis.push( child ); + listArray[ i ].indent += indentOffset; + // Make sure the newly created sublist get a brand-new element of the same type. (#5372) + var listRoot = listArray[ i ].parent; + listArray[ i ].parent = new CKEDITOR.dom.element( listRoot.getName(), listRoot.getDocument() ); } - } - } - if ( newList ) - newList.listNode.replace( listNode ); + for ( i = lastItem.getCustomData( 'listarray_index' ) + 1 ; + i < listArray.length && listArray[i].indent > baseIndent ; i++ ) + listArray[i].indent += indentOffset; - // Move the nested
  • to be appeared after the parent. - if ( pendingLis && pendingLis.length ) - { - for ( i = 0; i < pendingLis.length ; i++ ) - { - var li = pendingLis[ i ], - followingList = li; + // Convert the array back to a DOM forest (yes we might have a few subtrees now). + // And replace the old list with the new forest. + var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, listNode.getDirection() ); - // Nest preceding