X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fcore%2Fdom%2Felement.js;h=bd425201afd599fe5cc18c100f8c5203a13610b9;hb=8665a7c6c60586526e32e8941fe2896739b6ebfb;hp=3b33e476328cbaa82809777fd53c03142c7249b7;hpb=941b0a9ba4e673e292510d80a5a86806994b8ea6;p=ckeditor.git diff --git a/_source/core/dom/element.js b/_source/core/dom/element.js index 3b33e47..bd42520 100644 --- a/_source/core/dom/element.js +++ b/_source/core/dom/element.js @@ -243,10 +243,13 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, lastChild = lastChild.getPrevious(); if ( !lastChild || !lastChild.is || !lastChild.is( 'br' ) ) { - this.append( - CKEDITOR.env.opera ? + var bogus = CKEDITOR.env.opera ? this.getDocument().createText('') : - this.getDocument().createElement( 'br' ) ); + this.getDocument().createElement( 'br' ); + + CKEDITOR.env.gecko && bogus.setAttribute( 'type', '_moz' ); + + this.append( bogus ); } }, @@ -618,7 +621,6 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, } return ( - /** @ignore */ this.getName = function() { return nodeName; @@ -775,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 @@ -872,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 @@ -989,8 +1066,16 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, removeAttributes : function ( attributes ) { - for ( var i = 0 ; i < attributes.length ; i++ ) - this.removeAttribute( attributes[ i ] ); + if ( CKEDITOR.tools.isArray( attributes ) ) + { + for ( var i = 0 ; i < attributes.length ; i++ ) + this.removeAttribute( attributes[ i ] ); + } + else + { + for ( var attr in attributes ) + attributes.hasOwnProperty( attr ) && this.removeAttribute( attr ); + } }, /** @@ -1346,7 +1431,7 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, if ( attrName in skipAttributes ) continue; - if( attrName == 'checked' && ( attrValue = this.getAttribute( attrName ) ) ) + if ( attrName == 'checked' && ( attrValue = this.getAttribute( attrName ) ) ) dest.setAttribute( attrName, attrValue ); // IE BUG: value attribute is never specified even if it exists. else if ( attribute.specified || @@ -1387,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.$; },