X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fcore%2Fhtmlparser%2Felement.js;h=9643e0d7ca56ab705c81bf9d31072e6254e8585b;hb=3fe9cac293e090ea459a3ee10d78cbe9e1dd0e03;hp=2e9a9c3f95282f7ef7904458eeb085e8556f4ccc;hpb=941b0a9ba4e673e292510d80a5a86806994b8ea6;p=ckeditor.git diff --git a/_source/core/htmlparser/element.js b/_source/core/htmlparser/element.js index 2e9a9c3..9643e0d 100644 --- a/_source/core/htmlparser/element.js +++ b/_source/core/htmlparser/element.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -25,7 +25,7 @@ CKEDITOR.htmlParser.element = function( name, attributes ) * @type Object * @example */ - this.attributes = attributes || ( attributes = {} ); + this.attributes = attributes || {}; /** * The nodes that are direct children of this element. @@ -34,20 +34,82 @@ CKEDITOR.htmlParser.element = function( name, attributes ) */ this.children = []; - var tagName = attributes._cke_real_element_type || name; + // Reveal the real semantic of our internal custom tag name (#6639), + // when resolving whether it's block like. + var realName = name || '', + prefixed = realName.match( /^cke:(.*)/ ); + prefixed && ( realName = prefixed[ 1 ] ); - var dtd = CKEDITOR.dtd, - isBlockLike = !!( dtd.$nonBodyContent[ tagName ] || dtd.$block[ tagName ] || dtd.$listItem[ tagName ] || dtd.$tableContent[ tagName ] || dtd.$nonEditable[ tagName ] || tagName == 'br' ), - isEmpty = !!dtd.$empty[ name ]; + var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] + || CKEDITOR.dtd.$block[ realName ] + || CKEDITOR.dtd.$listItem[ realName ] + || CKEDITOR.dtd.$tableContent[ realName ] + || CKEDITOR.dtd.$nonEditable[ realName ] + || realName == 'br' ); - this.isEmpty = isEmpty; - this.isUnknown = !dtd[ name ]; + this.isEmpty = !!CKEDITOR.dtd.$empty[ name ]; + this.isUnknown = !CKEDITOR.dtd[ name ]; /** @private */ this._ = { isBlockLike : isBlockLike, - hasInlineStarted : isEmpty || !isBlockLike + hasInlineStarted : this.isEmpty || !isBlockLike + }; +}; + +/** + * Object presentation of CSS style declaration text. + * @param {CKEDITOR.htmlParser.element|String} elementOrStyleText A html parser element or the inline style text. + */ +CKEDITOR.htmlParser.cssStyle = function() +{ + var styleText, + arg = arguments[ 0 ], + rules = {}; + + styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg; + + // html-encoded quote might be introduced by 'font-family' + // from MS-Word which confused the following regexp. e.g. + //'font-family: "Lucida, Console"' + ( styleText || '' ) + .replace( /"/g, '"' ) + .replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, + function( match, name, value ) + { + name == 'font-family' && ( value = value.replace( /["']/g, '' ) ); + rules[ name.toLowerCase() ] = value; + }); + + return { + + rules : rules, + + /** + * Apply the styles onto the specified element or object. + * @param {CKEDITOR.htmlParser.element|CKEDITOR.dom.element|Object} obj + */ + populate : function( obj ) + { + var style = this.toString(); + if ( style ) + { + obj instanceof CKEDITOR.dom.element ? + obj.setAttribute( 'style', style ) : + obj instanceof CKEDITOR.htmlParser.element ? + obj.attributes.style = style : + obj.style = style; + } + }, + + toString : function() + { + var output = []; + for ( var i in rules ) + rules[ i ] && output.push( i, ':', rules[ i ], ';' ); + return output.join( '' ); + } }; }; @@ -114,11 +176,11 @@ CKEDITOR.htmlParser.element = function( name, attributes ) */ element.filterChildren = function() { - if( !isChildrenFiltered ) + if ( !isChildrenFiltered ) { var writer = new CKEDITOR.htmlParser.basicWriter(); CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.call( element, writer, filter ); - element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml() ).children; + element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml(), 0, element.clone() ).children; isChildrenFiltered = 1; } }; @@ -154,6 +216,10 @@ CKEDITOR.htmlParser.element = function( name, attributes ) // filter but not the children. if ( !writeName ) { + // Fix broken parent refs. + for ( var c = 0, length = this.children.length ; c < length ; c++ ) + this.children[ c ].parent = element.parent; + this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter ); return; } @@ -171,13 +237,13 @@ CKEDITOR.htmlParser.element = function( name, attributes ) var attribsArray = []; // Iterate over the attributes twice since filters may alter // other attributes. - for( var i = 0 ; i < 2; i++ ) + for ( var i = 0 ; i < 2; i++ ) { for ( a in attributes ) { newAttrName = a; value = attributes[ a ]; - if( i == 1 ) + if ( i == 1 ) attribsArray.push( [ a, value ] ); else if ( filter ) { @@ -188,7 +254,7 @@ CKEDITOR.htmlParser.element = function( name, attributes ) delete attributes[ a ]; break; } - else if( newAttrName != a ) + else if ( newAttrName != a ) { delete attributes[ a ]; a = newAttrName; @@ -197,9 +263,9 @@ CKEDITOR.htmlParser.element = function( name, attributes ) else break; } - if( newAttrName ) + if ( newAttrName ) { - if( ( value = filter.onAttribute( element, newAttrName, value ) ) === false ) + if ( ( value = filter.onAttribute( element, newAttrName, value ) ) === false ) delete attributes[ newAttrName ]; else attributes [ newAttrName ] = value;