X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=_source%2Fcore%2Fdom%2Felement.js;h=bd425201afd599fe5cc18c100f8c5203a13610b9;hb=8665a7c6c60586526e32e8941fe2896739b6ebfb;hp=ead6581d86bea25dcb831057de1781b9d5b6fdd2;hpb=e7789c1ad838194d45eeee6ac2eb6e55f5cf35a1;p=ckeditor.git diff --git a/_source/core/dom/element.js b/_source/core/dom/element.js index ead6581..bd42520 100644 --- a/_source/core/dom/element.js +++ b/_source/core/dom/element.js @@ -777,6 +777,31 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, }, /** + * Whether it's an empty inline elements which has no visual impact when removed. + */ + isEmptyInlineRemoveable : function() + { + if ( !CKEDITOR.dtd.$removeEmpty[ this.getName() ] ) + return false; + + var children = this.getChildren(); + for ( var i = 0, count = children.count(); i < count; i++ ) + { + var child = children.getItem( i ); + + if ( child.type == CKEDITOR.NODE_ELEMENT && child.getAttribute( '_fck_bookmark' ) ) + continue; + + if ( child.type == CKEDITOR.NODE_ELEMENT && !child.isEmptyInlineRemoveable() + || child.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( child.getText() ) ) + { + return false; + } + } + return true; + }, + + /** * Indicates that the element has defined attributes. * @returns {Boolean} True if the element has attributes. * @example @@ -874,6 +899,56 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, } }, + mergeSiblings : ( function() + { + function mergeElements( element, sibling, isNext ) + { + if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT ) + { + // Jumping over bookmark nodes and empty inline elements, e.g. , + // queuing them to be moved later. (#5567) + var pendingNodes = []; + + while ( sibling.getAttribute( '_fck_bookmark' ) + || sibling.isEmptyInlineRemoveable() ) + { + pendingNodes.push( sibling ); + sibling = isNext ? sibling.getNext() : sibling.getPrevious(); + if ( !sibling || sibling.type != CKEDITOR.NODE_ELEMENT ) + return; + } + + if ( element.isIdentical( sibling ) ) + { + // Save the last child to be checked too, to merge things like + // => + var innerSibling = isNext ? element.getLast() : element.getFirst(); + + // Move pending nodes first into the target element. + while( pendingNodes.length ) + pendingNodes.shift().move( element, !isNext ); + + sibling.moveChildren( element, !isNext ); + sibling.remove(); + + // Now check the last inner child (see two comments above). + if ( innerSibling && innerSibling.type == CKEDITOR.NODE_ELEMENT ) + innerSibling.mergeSiblings(); + } + } + } + + return function() + { + // Merge empty links and anchors also. (#5567) + if ( !( CKEDITOR.dtd.$removeEmpty[ this.getName() ] || this.is( 'a' ) ) ) + return; + + mergeElements( this, this.getNext(), true ); + mergeElements( this, this.getPrevious() ); + }; + } )(), + /** * Shows this element (display it). * @example @@ -1397,7 +1472,7 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, this.moveChildren( newNode ); // Replace the node. - this.$.parentNode.replaceChild( newNode.$, this.$ ); + this.getParent() && this.$.parentNode.replaceChild( newNode.$, this.$ ); newNode.$._cke_expando = this.$._cke_expando; this.$ = newNode.$; },