Ticket #3893: 3893_8.patch

File 3893_8.patch, 8.3 KB (added by Garry Yao, 14 years ago)
  • _source/core/dom/elementpath.js

     
    100100                }
    101101
    102102                return true;
    103         }
     103        },
     104
     105        contains : function( tagNames )
     106        {
     107                var elements = this.elements;
     108                for ( var i = 0 ; i < elements.length ; i++ )
     109                {
     110                        if ( elements[ i ].getName() in tagNames )
     111                                return elements[ i ];
     112                }
     113        }
    104114};
  • _source/plugins/indent/plugin.js

     
    1818
    1919        function onSelectionChange( evt )
    2020        {
    21                 var elements = evt.data.path.elements,
    22                         listNode, listItem,
    23                         editor = evt.editor;
     21                var editor = evt.editor;
    2422
    25                 for ( var i = 0 ; i < elements.length ; i++ )
    26                 {
    27                         if ( elements[i].getName() == 'li' )
    28                         {
    29                                 listItem = elements[i];
    30                                 continue;
    31                         }
    32                         if ( listNodeNames[ elements[i].getName() ] )
    33                         {
    34                                 listNode = elements[i];
    35                                 break;
    36                         }
    37                 }
     23                var elementPath = evt.data.path,
     24                                list = elementPath && elementPath.contains( listNodeNames );
    3825
    39                 if ( listNode )
    40                 {
    41                         if ( this.name == 'outdent' )
    42                                 return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
    43                         else
    44                         {
    45                                 while ( listItem && ( listItem = listItem.getPrevious( CKEDITOR.dom.walker.whitespaces( true ) ) ) )
    46                                 {
    47                                         if ( listItem.getName && listItem.getName() == 'li' )
    48                                                 return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
    49                                 }
    50                                 return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
    51                         }
    52                 }
     26                if ( list )
     27                        return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
    5328
    5429                if ( !this.useIndentClasses && this.name == 'indent' )
    5530                        return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
     
    200175                iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
    201176                var block;
    202177                while ( ( block = iterator.getNextParagraph() ) )
    203                 {
     178                        indentElement.call( this, editor, block );
     179        }
    204180
    205                         if ( this.useIndentClasses )
    206                         {
    207                                 // Transform current class name to indent step index.
    208                                 var indentClass = block.$.className.match( this.classNameRegex ),
    209                                         indentStep = 0;
    210                                 if ( indentClass )
    211                                 {
    212                                         indentClass = indentClass[1];
    213                                         indentStep = this.indentClassMap[ indentClass ];
    214                                 }
     181        function indentElement( editor, element )
     182        {
     183                if ( this.useIndentClasses )
     184                {
     185                        // Transform current class name to indent step index.
     186                        var indentClass = element.$.className.match( this.classNameRegex ),
     187                                indentStep = 0;
     188                        if ( indentClass )
     189                        {
     190                                indentClass = indentClass[1];
     191                                indentStep = this.indentClassMap[ indentClass ];
     192                        }
    215193
    216                                 // Operate on indent step index, transform indent step index back to class
    217                                 // name.
    218                                 if ( this.name == 'outdent' )
    219                                         indentStep--;
    220                                 else
    221                                         indentStep++;
    222                                 indentStep = Math.min( indentStep, editor.config.indentClasses.length );
    223                                 indentStep = Math.max( indentStep, 0 );
    224                                 var className = CKEDITOR.tools.ltrim( block.$.className.replace( this.classNameRegex, '' ) );
    225                                 if ( indentStep < 1 )
    226                                         block.$.className = className;
    227                                 else
    228                                         block.$.className = CKEDITOR.tools.ltrim( className + ' ' + editor.config.indentClasses[ indentStep - 1 ] );
    229                         }
    230                         else
    231                         {
    232                                 var currentOffset = parseInt( block.getStyle( this.indentCssProperty ), 10 );
    233                                 if ( isNaN( currentOffset ) )
    234                                         currentOffset = 0;
    235                                 currentOffset += ( this.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset;
    236                                 currentOffset = Math.max( currentOffset, 0 );
    237                                 currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset;
    238                                 block.setStyle( this.indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' );
    239                                 if ( block.getAttribute( 'style' ) === '' )
    240                                         block.removeAttribute( 'style' );
    241                         }
    242                 }
    243         }
     194                        // Operate on indent step index, transform indent step index back to class
     195                        // name.
     196                        if ( this.name == 'outdent' )
     197                                indentStep--;
     198                        else
     199                                indentStep++;
     200
     201                        if ( indentStep < 0 )
     202                                return false;
     203
     204                        indentStep = Math.min( indentStep, editor.config.indentClasses.length );
     205                        indentStep = Math.max( indentStep, 0 );
     206                        var className = CKEDITOR.tools.ltrim( element.$.className.replace( this.classNameRegex, '' ) );
     207                        if ( indentStep < 1 )
     208                                element.$.className = className;
     209                        else
     210                                element.addClass( editor.config.indentClasses[ indentStep - 1 ] );
     211                }
     212                else
     213                {
     214                        var currentOffset = parseInt( element.getStyle( this.indentCssProperty ), 10 );
     215                        if ( isNaN( currentOffset ) )
     216                                currentOffset = 0;
     217                        currentOffset += ( this.name == 'indent' ? 1 : -1 ) * editor.config.indentOffset;
     218
     219                        if ( currentOffset < 0 )
     220                                return false;
     221
     222                        currentOffset = Math.max( currentOffset, 0 );
     223                        currentOffset = Math.ceil( currentOffset / editor.config.indentOffset ) * editor.config.indentOffset;
     224                        element.setStyle( this.indentCssProperty, currentOffset ? currentOffset + editor.config.indentUnit : '' );
     225                        if ( element.getAttribute( 'style' ) === '' )
     226                                element.removeAttribute( 'style' );
     227                }
     228
     229                return true;
     230        }
    244231
    245232        function indentCommand( editor, name )
    246233        {
     
    258245                this.startDisabled = name == 'outdent';
    259246        }
    260247
     248        function isListItem( node ){ return node.type = CKEDITOR.NODE_ELEMENT && node.is( 'li' ) };
     249
    261250        indentCommand.prototype = {
    262251                exec : function( editor )
    263252                {
    264253                        var selection = editor.getSelection(),
    265254                                range = selection && selection.getRanges()[0];
    266255
    267                         if ( !selection || !range )
    268                                 return;
     256                        var startContainer = range.startContainer,
     257                                endContainer = range.endContainer,
     258                                rangeRoot = range.getCommonAncestor(),
     259                                nearestListBlock = rangeRoot;
    269260
    270                         var bookmarks = selection.createBookmarks( true ),
    271                                 nearestListBlock = range.getCommonAncestor();
    272 
    273261                        while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT &&
    274262                                listNodeNames[ nearestListBlock.getName() ] ) )
    275263                                nearestListBlock = nearestListBlock.getParent();
    276264
    277                         if ( nearestListBlock )
    278                                 indentList.call( this, editor, range, nearestListBlock );
     265                        // Avoid selection anchors under list root.
     266                        // <ul>[<li>...</li>]</ul> =>   <ul><li>[...]</li></ul>
     267                        if ( nearestListBlock && startContainer.type == CKEDITOR.NODE_ELEMENT
     268                                && startContainer.getName() in listNodeNames )
     269                        {
     270                                var walker = new CKEDITOR.dom.walker( range );
     271                                walker.evaluator = isListItem;
     272                                range.startContainer = walker.next();
     273                        }
     274
     275                        if ( nearestListBlock && endContainer.type == CKEDITOR.NODE_ELEMENT
     276                                && endContainer.getName() in listNodeNames )
     277                        {
     278                                var walker = new CKEDITOR.dom.walker( range );
     279                                walker.evaluator = isListItem;
     280                                range.endContainer = walker.previous();
     281                        }
     282                       
     283                        var bookmarks = selection.createBookmarks( true );
     284
     285                        if ( nearestListBlock  )
     286                        {
     287                                var firstListItem = nearestListBlock.getFirst( function( node )
     288                                        {
     289                                                return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' );
     290                                        }),
     291                                        rangeStart = range.startContainer,
     292                                        indentWholeList = firstListItem.equals( rangeStart ) || firstListItem.contains( rangeStart );
     293
     294                                // Indent the entire list if  cursor is inside the first list item. (#3893)
     295                                if ( !( indentWholeList && indentElement.call( this, editor, nearestListBlock ) ) )
     296                                        indentList.call( this, editor, range, nearestListBlock );
     297                        }
    279298                        else
    280299                                indentBlock.call( this, editor, range );
    281300
     
    310329                        // Register the state changing handlers.
    311330                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, indent ) );
    312331                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, outdent ) );
     332
     333                        // [IE6/7] Raw lists are using margin instead of padding for visual indentation in wysiwyg mode. (#3893)
     334                        if( CKEDITOR.env.ie6Compat || CKEDITOR.env.ie7Compat )
     335                        {
     336                                var listStyleText =
     337                                "ul,ol" +
     338                                "{" +
     339                                "       margin-left: 0px;" +
     340                                "       padding-left: 40px;" +
     341                                "}";
     342                                editor  .addCss( listStyleText );
     343                        }
    313344                },
    314345
    315346                requires : [ 'domiterator', 'list' ]
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy