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 )
 99 		{
100 			// Open element tag.
101 			writer.openTag( this.name, this.attributes );
102
103 			// Copy all attributes to an array.
104 			var attribsArray = [];
105 			for ( var a in this.attributes )
106 				attribsArray.push( [ a, this.attributes[ a ] ] );
107
108 			// Sort the attributes by name.
109 			attribsArray.sort( sortAttribs );
110
111 			// Send the attributes.
112 			for ( var i = 0, len = attribsArray.length ; i < len ; i++ )
113 			{
114 				var attrib = attribsArray[ i ];
115 				// IE's treated expand fields as dom attributes, skip it
116 				if ( CKEDITOR.env.ie && attrib === '_cke_expando' )
117 					continue;
118 				writer.attribute( attrib[0], attrib[1] );
119 			}
120
121 			// Close the tag.
122 			writer.openTagClose( this.name, this.isEmpty );
123
124 			if ( !this.isEmpty )
125 			{
126 				// Send children.
127 				CKEDITOR.htmlParser.fragment.prototype.writeHtml.apply( this, arguments );
128
129 				// Close the element.
130 				writer.closeTag( this.name );
131 			}
132 		}
133 	};
134 })();
135