Ticket #5567: 5567.patch

File 5567.patch, 5.6 KB (added by Garry Yao, 9 years ago)
  • _source/plugins/styles/plugin.js

     
    550550                                        styleRange.insertNode( styleNode );
    551551
    552552                                        // Let's merge our new style with its neighbors, if possible.
    553                                         mergeSiblings( styleNode );
     553                                        styleNode.mergeSiblings();
    554554
    555555                                        // As the style system breaks text nodes constantly, let's normalize
    556556                                        // things for performance.
     
    624624                                                 * no difference that they're separate entities in the DOM tree. So, merge
    625625                                                 * them before removal.
    626626                                                 */
    627                                                 mergeSiblings( element );
     627                                                element.mergeSiblings();
    628628                                                removeFromElement( this, element );
    629629
    630630                                        }
     
    10571057                        if ( firstChild )
    10581058                        {
    10591059                                // Check the cached nodes for merging.
    1060                                 mergeSiblings( firstChild );
     1060                                firstChild.mergeSiblings();
    10611061
    10621062                                if ( lastChild && !firstChild.equals( lastChild ) )
    1063                                         mergeSiblings( lastChild );
     1063                                        lastChild.mergeSiblings();
    10641064                        }
    10651065                }
    10661066        }
    10671067
    1068         function mergeSiblings( element )
    1069         {
    1070                 if ( !element || element.type != CKEDITOR.NODE_ELEMENT || !CKEDITOR.dtd.$removeEmpty[ element.getName() ] )
    1071                         return;
    1072 
    1073                 mergeElements( element, element.getNext(), true );
    1074                 mergeElements( element, element.getPrevious() );
    1075         }
    1076 
    1077         function mergeElements( element, sibling, isNext )
    1078         {
    1079                 if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT )
    1080                 {
    1081                         var hasBookmark = sibling.getAttribute( '_fck_bookmark' );
    1082 
    1083                         if ( hasBookmark )
    1084                                 sibling = isNext ? sibling.getNext() : sibling.getPrevious();
    1085 
    1086                         if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT && element.isIdentical( sibling ) )
    1087                         {
    1088                                 // Save the last child to be checked too, to merge things like
    1089                                 // <b><i></i></b><b><i></i></b> => <b><i></i></b>
    1090                                 var innerSibling = isNext ? element.getLast() : element.getFirst();
    1091 
    1092                                 if ( hasBookmark )
    1093                                         ( isNext ? sibling.getPrevious() : sibling.getNext() ).move( element, !isNext );
    1094 
    1095                                 sibling.moveChildren( element, !isNext );
    1096                                 sibling.remove();
    1097 
    1098                                 // Now check the last inner child (see two comments above).
    1099                                 if ( innerSibling )
    1100                                         mergeSiblings( innerSibling );
    1101                         }
    1102                 }
    1103         }
    1104 
    11051068        function getElement( style, targetDocument )
    11061069        {
    11071070                var el;
  • _source/core/dom/element.js

     
    777777                },
    778778
    779779                /**
     780                 * Whether it's an empty inline elements which has no visual impact when removed.
     781                 */
     782                isEmptyInlineRemoveable : function()
     783                {
     784                        if ( !CKEDITOR.dtd.$removeEmpty[ this.getName() ] )
     785                                return false;
     786
     787                        var children = this.getChildren();
     788                        for ( var i = 0, count = children.count(); i < count; i++ )
     789                        {
     790                                var child = children.getItem( i );
     791
     792                                if ( child.type == CKEDITOR.NODE_ELEMENT && child.getAttribute( '_fck_bookmark' ) )
     793                                        continue;
     794
     795                                if ( child.type == CKEDITOR.NODE_ELEMENT && !child.isEmptyInlineRemoveable()
     796                                        || child.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( child.getText() ) )
     797                                {
     798                                        return false;
     799                                }
     800                        }
     801                        return true;
     802                },
     803
     804                /**
    780805                 * Indicates that the element has defined attributes.
    781806                 * @returns {Boolean} True if the element has attributes.
    782807                 * @example
  • _source/core/dom/node.js

     
    550550                        target.append( this.remove(), toStart );
    551551                },
    552552
     553                mergeSiblings : ( function()
     554                {
     555                        function mergeElements( element, sibling, isNext )
     556                        {
     557                                if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT )
     558                                {
     559                                        // Jumping over bookmark nodes and empty inline elements, e.g. <b><i></i></b>,
     560                                        // queuing them to be moved later. (#5567)
     561                                        var ignore,
     562                                                pendingNodes = [];
     563
     564                                        while ( ignore = sibling.getAttribute( '_fck_bookmark' )
     565                                                || sibling.isEmptyInlineRemoveable() )
     566                                        {
     567                                                pendingNodes.push( sibling );
     568                                                sibling = isNext ? sibling.getNext() : sibling.getPrevious();
     569                                                if ( !sibling || sibling.type != CKEDITOR.NODE_ELEMENT )
     570                                                        return;
     571                                        }
     572
     573                                        if ( element.isIdentical( sibling ) )
     574                                        {
     575                                                // Save the last child to be checked too, to merge things like
     576                                                // <b><i></i></b><b><i></i></b> => <b><i></i></b>
     577                                                var innerSibling = isNext ? element.getLast() : element.getFirst();
     578
     579                                                // Move pending nodes first into the target element.
     580                                                while( pendingNodes.length )
     581                                                        pendingNodes.shift().move( element, !isNext );
     582
     583                                                sibling.moveChildren( element, !isNext );
     584                                                sibling.remove();
     585
     586                                                // Now check the last inner child (see two comments above).
     587                                                if ( innerSibling )
     588                                                        innerSibling.mergeSiblings();
     589                                        }
     590                                }
     591                        }
     592
     593                        return function()
     594                        {
     595                                if ( this.type != CKEDITOR.NODE_ELEMENT
     596                                        || !CKEDITOR.dtd.$removeEmpty[ this.getName() ]
     597                                                // Merge links but not anchors. (#5567)
     598                                                && ( !this.is( 'a' ) || this.hasAttribute( 'name' ) ) )
     599                                        return;
     600
     601                                mergeElements( this, this.getNext(), true );
     602                                mergeElements( this, this.getPrevious() );
     603                        }
     604                } )(),
     605
    553606                /**
    554607                 * Removes this node from the document DOM.
    555608                 * @param {Boolean} [preserveChildren] Indicates that the children
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy