Ticket #5567: 5567_2.patch

File 5567_2.patch, 5.4 KB (added by Garry Yao, 10 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.type == CKEDITOR.NODE_ELEMENT && firstChild.mergeSiblings();
    10611061
    1062                                 if ( lastChild && !firstChild.equals( lastChild ) )
    1063                                         mergeSiblings( lastChild );
     1062                                if ( lastChild && !firstChild.equals( lastChild )
     1063                                        && lastChild.type == CKEDITOR.NODE_ELEMENT  )
     1064                                        lastChild.mergeSiblings();
    10641065                        }
    10651066                }
    10661067        }
    10671068
    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 
    11051069        function getElement( style, targetDocument )
    11061070        {
    11071071                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
     
    874899                        }
    875900                },
    876901
     902                mergeSiblings : ( function()
     903                {
     904                        function mergeElements( element, sibling, isNext )
     905                        {
     906                                if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT )
     907                                {
     908                                        // Jumping over bookmark nodes and empty inline elements, e.g. <b><i></i></b>,
     909                                        // queuing them to be moved later. (#5567)
     910                                        var ignore,
     911                                                pendingNodes = [];
     912
     913                                        while ( ignore = sibling.getAttribute( '_fck_bookmark' )
     914                                                || sibling.isEmptyInlineRemoveable() )
     915                                        {
     916                                                pendingNodes.push( sibling );
     917                                                sibling = isNext ? sibling.getNext() : sibling.getPrevious();
     918                                                if ( !sibling || sibling.type != CKEDITOR.NODE_ELEMENT )
     919                                                        return;
     920                                        }
     921
     922                                        if ( element.isIdentical( sibling ) )
     923                                        {
     924                                                // Save the last child to be checked too, to merge things like
     925                                                // <b><i></i></b><b><i></i></b> => <b><i></i></b>
     926                                                var innerSibling = isNext ? element.getLast() : element.getFirst();
     927
     928                                                // Move pending nodes first into the target element.
     929                                                while( pendingNodes.length )
     930                                                        pendingNodes.shift().move( element, !isNext );
     931
     932                                                sibling.moveChildren( element, !isNext );
     933                                                sibling.remove();
     934
     935                                                // Now check the last inner child (see two comments above).
     936                                                if ( innerSibling && innerSibling.type == CKEDITOR.NODE_ELEMENT )
     937                                                        innerSibling.mergeSiblings();
     938                                        }
     939                                }
     940                        }
     941
     942                        return function()
     943                        {
     944                                if ( !CKEDITOR.dtd.$removeEmpty[ this.getName() ]
     945                                                // Merge empty links but not anchors. (#5567)
     946                                                && ( !this.is( 'a' ) || this.hasAttribute( 'name' ) ) )
     947                                        return;
     948
     949                                mergeElements( this, this.getNext(), true );
     950                                mergeElements( this, this.getPrevious() );
     951                        }
     952                } )(),
     953
    877954                /**
    878955                 * Shows this element (display it).
    879956                 * @example
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy