Ticket #5567: 5567.patch
File 5567.patch, 5.6 KB (added by , 14 years ago) |
---|
-
_source/plugins/styles/plugin.js
550 550 styleRange.insertNode( styleNode ); 551 551 552 552 // Let's merge our new style with its neighbors, if possible. 553 mergeSiblings( styleNode);553 styleNode.mergeSiblings(); 554 554 555 555 // As the style system breaks text nodes constantly, let's normalize 556 556 // things for performance. … … 624 624 * no difference that they're separate entities in the DOM tree. So, merge 625 625 * them before removal. 626 626 */ 627 mergeSiblings( element);627 element.mergeSiblings(); 628 628 removeFromElement( this, element ); 629 629 630 630 } … … 1057 1057 if ( firstChild ) 1058 1058 { 1059 1059 // Check the cached nodes for merging. 1060 mergeSiblings( firstChild);1060 firstChild.mergeSiblings(); 1061 1061 1062 1062 if ( lastChild && !firstChild.equals( lastChild ) ) 1063 mergeSiblings( lastChild);1063 lastChild.mergeSiblings(); 1064 1064 } 1065 1065 } 1066 1066 } 1067 1067 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 like1089 // <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 1105 1068 function getElement( style, targetDocument ) 1106 1069 { 1107 1070 var el; -
_source/core/dom/element.js
777 777 }, 778 778 779 779 /** 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 /** 780 805 * Indicates that the element has defined attributes. 781 806 * @returns {Boolean} True if the element has attributes. 782 807 * @example -
_source/core/dom/node.js
550 550 target.append( this.remove(), toStart ); 551 551 }, 552 552 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 553 606 /** 554 607 * Removes this node from the document DOM. 555 608 * @param {Boolean} [preserveChildren] Indicates that the children