1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * A lightweight representation of an HTML element. 8 * @param {String} name The element name. 9 * @param {Object} attributes And object holding all attributes defined for 10 * this element. 11 * @constructor 12 * @example 13 */ 14 CKEDITOR.htmlParser.element = function( name, attributes ) 15 { 16 /** 17 * The element name. 18 * @type String 19 * @example 20 */ 21 this.name = name; 22 23 /** 24 * Holds the attributes defined for this element. 25 * @type Object 26 * @example 27 */ 28 this.attributes = attributes; 29 30 /** 31 * The nodes that are direct children of this element. 32 * @type Array 33 * @example 34 */ 35 this.children = []; 36 37 var dtd = CKEDITOR.dtd, 38 isBlockLike = !!( dtd.$block[ name ] || dtd.$listItem[ name ] || dtd.$tableContent[ name ] ), 39 isEmpty = !!dtd.$empty[ name ]; 40 41 this.isEmpty = isEmpty; 42 this.isUnknown = !dtd[ name ]; 43 44 /** @private */ 45 this._ = 46 { 47 isBlockLike : isBlockLike, 48 hasInlineStarted : isEmpty || !isBlockLike 49 }; 50 }; 51 52 (function() 53 { 54 // Used to sort attribute entries in an array, where the first element of 55 // each object is the attribute name. 56 var sortAttribs = function( a, b ) 57 { 58 a = a[0]; 59 b = b[0]; 60 return a < b ? -1 : a > b ? 1 : 0; 61 }; 62 63 CKEDITOR.htmlParser.element.prototype = 64 { 65 /** 66 * The node type. This is a constant value set to {@link CKEDITOR.NODE_ELEMENT}. 67 * @type Number 68 * @example 69 */ 70 type : CKEDITOR.NODE_ELEMENT, 71 72 /** 73 * Adds a node to the element children list. 74 * @param {Object} node The node to be added. It can be any of of the 75 * following types: {@link CKEDITOR.htmlParser.element}, 76 * {@link CKEDITOR.htmlParser.text} and 77 * {@link CKEDITOR.htmlParser.comment}. 78 * @function 79 * @example 80 */ 81 add : CKEDITOR.htmlParser.fragment.prototype.add, 82 83 /** 84 * Clone this element. 85 * @returns {CKEDITOR.htmlParser.element} The element clone. 86 * @example 87 */ 88 clone : function() 89 { 90 return new CKEDITOR.htmlParser.element( this.name, this.attributes ); 91 }, 92 93 /** 94 * Writes the element HTML to a CKEDITOR.htmlWriter. 95 * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML. 96 * @example 97 */ 98 writeHtml : function( writer, filter ) 99 { 100 var attributes = this.attributes; 101 102 // The "_cke_replacedata" indicates that this element is replacing 103 // a data snippet, which should be outputted as is. 104 if ( attributes._cke_replacedata ) 105 { 106 writer.write( attributes._cke_replacedata ); 107 return; 108 } 109 110 // Ignore cke: prefixes when writing HTML. 111 var element = this, 112 writeName = element.name, 113 a, value; 114 115 if ( filter ) 116 { 117 while ( true ) 118 { 119 if ( !( writeName = filter.onElementName( writeName ) ) ) 120 return; 121 122 element.name = writeName; 123 124 if ( !( element = filter.onElement( element ) ) ) 125 return; 126 127 if ( element.name == writeName ) 128 break; 129 130 writeName = element.name; 131 } 132 133 // The element may have been changed, so update the local 134 // references. 135 attributes = element.attributes; 136 } 137 138 // Open element tag. 139 writer.openTag( writeName, attributes ); 140 141 if ( writer.sortAttributes ) 142 { 143 // Copy all attributes to an array. 144 var attribsArray = []; 145 for ( a in attributes ) 146 { 147 value = attributes[ a ]; 148 149 if ( filter && ( !( a = filter.onAttributeName( a ) ) || ( value = filter.onAttribute( element, a, value ) ) === false ) ) 150 continue; 151 152 attribsArray.push( [ a, value ] ); 153 } 154 155 // Sort the attributes by name. 156 attribsArray.sort( sortAttribs ); 157 158 // Send the attributes. 159 for ( var i = 0, len = attribsArray.length ; i < len ; i++ ) 160 { 161 var attrib = attribsArray[ i ]; 162 writer.attribute( attrib[0], attrib[1] ); 163 } 164 } 165 else 166 { 167 for ( a in attributes ) 168 { 169 writer.attribute( a, attributes[ a ] ); 170 } 171 } 172 173 // Close the tag. 174 writer.openTagClose( writeName, element.isEmpty ); 175 176 if ( !element.isEmpty ) 177 { 178 // Send children. 179 CKEDITOR.htmlParser.fragment.prototype.writeHtml.apply( element, arguments ); 180 181 // Close the element. 182 writer.closeTag( writeName ); 183 } 184 } 185 }; 186 })(); 187