X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Findent%2Fplugin.js;h=c49ce882832188b5b1c876898cd5a5d9d2762a6b;hb=614511639979907ceb0da3614122a4d8eb963ad4;hp=e60a29ebb3846d4f6ecc71c49e105aced5265542;hpb=e371ddf8abcb89013e20e6d0dd746adec344d0e5;p=ckeditor.git diff --git a/_source/plugins/indent/plugin.js b/_source/plugins/indent/plugin.js index e60a29e..c49ce88 100644 --- a/_source/plugins/indent/plugin.js +++ b/_source/plugins/indent/plugin.js @@ -78,9 +78,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } // Returns the CSS property to be used for identing a given element. - function getIndentCssProperty( element ) + function getIndentCssProperty( element, dir ) { - return element.getComputedStyle( 'direction' ) == 'ltr' ? 'margin-left' : 'margin-right'; + return ( dir || element.getComputedStyle( 'direction' ) ) == 'ltr' ? 'margin-left' : 'margin-right'; } function isListItem( node ) @@ -157,7 +157,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // 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 ); + var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, listNode.getDirection() ); // Avoid nested
  • after outdent even they're visually same, // recording them for later refactoring.(#3982) @@ -219,7 +219,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license indentElement( block ); } - function indentElement( element ) + function indentElement( element, dir ) { if ( element.getCustomData( 'indent_processed' ) ) return false; @@ -247,81 +247,95 @@ For licensing, see LICENSE.html or http://ckeditor.com/license indentStep = Math.min( indentStep, editor.config.indentClasses.length ); indentStep = Math.max( indentStep, 0 ); - var className = CKEDITOR.tools.ltrim( element.$.className.replace( self.classNameRegex, '' ) ); - if ( indentStep < 1 ) - element.$.className = className; - else + element.$.className = CKEDITOR.tools.ltrim( element.$.className.replace( self.classNameRegex, '' ) ); + if ( indentStep > 0 ) element.addClass( editor.config.indentClasses[ indentStep - 1 ] ); } else { - var indentCssProperty = getIndentCssProperty( element ); - var currentOffset = parseInt( element.getStyle( indentCssProperty ), 10 ); + var indentCssProperty = getIndentCssProperty( element, dir ), + currentOffset = parseInt( element.getStyle( indentCssProperty ), 10 ); if ( isNaN( currentOffset ) ) currentOffset = 0; - currentOffset += ( self.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset; + var indentOffset = editor.config.indentOffset || 40; + currentOffset += ( self.name == 'indent' ? 1 : -1 ) * indentOffset; if ( currentOffset < 0 ) return false; currentOffset = Math.max( currentOffset, 0 ); - currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset; - element.setStyle( indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' ); + currentOffset = Math.ceil( currentOffset / indentOffset ) * indentOffset; + element.setStyle( indentCssProperty, currentOffset ? currentOffset + ( editor.config.indentUnit || 'px' ) : '' ); if ( element.getAttribute( 'style' ) === '' ) element.removeAttribute( 'style' ); } - CKEDITOR.dom.element.setMarker( database, element, 'indent_processed', true ); + CKEDITOR.dom.element.setMarker( database, element, 'indent_processed', 1 ); return true; } var selection = editor.getSelection(), - bookmarks = selection.createBookmarks( true ), - ranges = selection && selection.getRanges( true ), + bookmarks = selection.createBookmarks( 1 ), + ranges = selection && selection.getRanges( 1 ), range; + var iterator = ranges.createIterator(); while ( ( range = iterator.getNextRange() ) ) { - var startContainer = range.startContainer, - endContainer = range.endContainer, - rangeRoot = range.getCommonAncestor(), + var rangeRoot = range.getCommonAncestor(), nearestListBlock = rangeRoot; while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ nearestListBlock.getName() ] ) ) nearestListBlock = nearestListBlock.getParent(); + // Avoid having selection enclose the entire list. (#6138) + // [] => + if ( !nearestListBlock ) + { + var selectedNode = range.getEnclosedNode(); + if ( selectedNode + && selectedNode.type == CKEDITOR.NODE_ELEMENT + && selectedNode.getName() in listNodeNames) + { + range.setStartAt( selectedNode, CKEDITOR.POSITION_AFTER_START ); + range.setEndAt( selectedNode, CKEDITOR.POSITION_BEFORE_END ); + nearestListBlock = selectedNode; + } + } + // Avoid selection anchors under list root. // => - if ( nearestListBlock && startContainer.type == CKEDITOR.NODE_ELEMENT - && startContainer.getName() in listNodeNames ) + if ( nearestListBlock && range.startContainer.type == CKEDITOR.NODE_ELEMENT + && range.startContainer.getName() in listNodeNames ) { var walker = new CKEDITOR.dom.walker( range ); walker.evaluator = isListItem; range.startContainer = walker.next(); } - if ( nearestListBlock && endContainer.type == CKEDITOR.NODE_ELEMENT - && endContainer.getName() in listNodeNames ) + if ( nearestListBlock && range.endContainer.type == CKEDITOR.NODE_ELEMENT + && range.endContainer.getName() in listNodeNames ) { walker = new CKEDITOR.dom.walker( range ); walker.evaluator = isListItem; range.endContainer = walker.previous(); } - if ( nearestListBlock ) + if ( nearestListBlock ) { - var firstListItem = nearestListBlock.getFirst( function( node ) - { - return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' ); - }), + var firstListItem = nearestListBlock.getFirst( isListItem ), + hasMultipleItems = !!firstListItem.getNext( isListItem ), rangeStart = range.startContainer, indentWholeList = firstListItem.equals( rangeStart ) || firstListItem.contains( rangeStart ); - // Indent the entire list if cursor is inside the first list item. (#3893) - if ( !( indentWholeList && indentElement( nearestListBlock ) ) ) - indentList( nearestListBlock ); + // Indent the entire list if cursor is inside the first list item. (#3893) + // Only do that for indenting or when using indent classes or when there is something to outdent. (#6141) + if ( !( indentWholeList && + ( self.name == 'indent' || self.useIndentClasses || parseInt( nearestListBlock.getStyle( getIndentCssProperty( nearestListBlock ) ), 10 ) ) && + indentElement( nearestListBlock, !hasMultipleItems && firstListItem.getDirection() ) ) ) + indentList( nearestListBlock ); } else indentBlock(); @@ -371,46 +385,62 @@ For licensing, see LICENSE.html or http://ckeditor.com/license " padding-left: 40px;" + "}" ); } - }, - requires : [ 'domiterator', 'list' ] - } ); -})(); + // Register dirChanged listener. + editor.on( 'dirChanged', function( e ) + { + var range = new CKEDITOR.dom.range( editor.document ); + range.setStartBefore( e.data.node ); + range.setEndAfter( e.data.node ); -CKEDITOR.tools.extend( CKEDITOR.config, - { - indentOffset : 40, - indentUnit : 'px', - indentClasses : null - }); + var walker = new CKEDITOR.dom.walker( range ), + node; -/** - * Size of each indentation step - * @type Number - * @example - * config.indentOffset = 40; - */ + while ( ( node = walker.next() ) ) + { + if ( node.type == CKEDITOR.NODE_ELEMENT ) + { + // A child with the defined dir is to be ignored. + if ( !node.equals( e.data.node ) && node.getDirection() ) + { + range.setStartAfter( node ); + walker = new CKEDITOR.dom.walker( range ); + continue; + } - /** - * Unit for the indentation style - * @type String - * @example - * config.indentUnit = 'px'; - */ + // Switch alignment classes. + var classes = editor.config.indentClasses; + if ( classes ) + { + var suffix = ( e.data.dir == 'ltr' ) ? [ '_rtl', '' ] : [ '', '_rtl' ]; + for ( var i = 0; i < classes.length; i++ ) + { + if ( node.hasClass( classes[ i ] + suffix[ 0 ] ) ) + { + node.removeClass( classes[ i ] + suffix[ 0 ] ); + node.addClass( classes[ i ] + suffix[ 1 ] ); + } + } + } - /** - * List of classes to use for indenting the contents. - * @type Array - * @example - * // Don't use classes for indenting. (this is the default value) - * config.indentClasses = null; - * @example - * // Use the classes 'Indent1', 'Indent2', 'Indent3' - * config.indentClasses = ['Indent1', 'Indent2', 'Indent3']; - */ + // Switch the margins. + var marginLeft = node.getStyle( 'margin-right' ), + marginRight = node.getStyle( 'margin-left' ); + + marginLeft ? node.setStyle( 'margin-left', marginLeft ) : node.removeStyle( 'margin-left' ); + marginRight ? node.setStyle( 'margin-right', marginRight ) : node.removeStyle( 'margin-right' ); + } + } + }); + }, + + requires : [ 'domiterator', 'list' ] + } ); +})(); /** * Size of each indentation step + * @name CKEDITOR.config.indentOffset * @type Number * @default 40 * @example @@ -419,6 +449,7 @@ CKEDITOR.tools.extend( CKEDITOR.config, /** * Unit for the indentation style + * @name CKEDITOR.config.indentUnit * @type String * @default 'px' * @example @@ -428,6 +459,7 @@ CKEDITOR.tools.extend( CKEDITOR.config, /** * List of classes to use for indenting the contents. If it's null, no classes will be used * and instead the {@link #indentUnit} and {@link #indentOffset} properties will be used. + * @name CKEDITOR.config.indentClasses * @type Array * default null * @example