--- /dev/null
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * A lightweight representation of an HTML element.\r
+ * @param {String} name The element name.\r
+ * @param {Object} attributes And object holding all attributes defined for\r
+ * this element.\r
+ * @constructor\r
+ * @example\r
+ */\r
+CKEDITOR.htmlParser.element = function( name, attributes )\r
+{\r
+ /**\r
+ * The element name.\r
+ * @type String\r
+ * @example\r
+ */\r
+ this.name = name;\r
+\r
+ /**\r
+ * Holds the attributes defined for this element.\r
+ * @type Object\r
+ * @example\r
+ */\r
+ this.attributes = attributes;\r
+\r
+ /**\r
+ * The nodes that are direct children of this element.\r
+ * @type Array\r
+ * @example\r
+ */\r
+ this.children = [];\r
+\r
+ var dtd = CKEDITOR.dtd,\r
+ isBlockLike = !!( dtd.$block[ name ] || dtd.$listItem[ name ] || dtd.$tableContent[ name ] ),\r
+ isEmpty = !!dtd.$empty[ name ];\r
+\r
+ this.isEmpty = isEmpty;\r
+ this.isUnknown = !dtd[ name ];\r
+\r
+ /** @private */\r
+ this._ =\r
+ {\r
+ isBlockLike : isBlockLike,\r
+ hasInlineStarted : isEmpty || !isBlockLike\r
+ };\r
+};\r
+\r
+(function()\r
+{\r
+ // Used to sort attribute entries in an array, where the first element of\r
+ // each object is the attribute name.\r
+ var sortAttribs = function( a, b )\r
+ {\r
+ a = a[0];\r
+ b = b[0];\r
+ return a < b ? -1 : a > b ? 1 : 0;\r
+ };\r
+\r
+ CKEDITOR.htmlParser.element.prototype =\r
+ {\r
+ /**\r
+ * The node type. This is a constant value set to {@link CKEDITOR.NODE_ELEMENT}.\r
+ * @type Number\r
+ * @example\r
+ */\r
+ type : CKEDITOR.NODE_ELEMENT,\r
+\r
+ /**\r
+ * Adds a node to the element children list.\r
+ * @param {Object} node The node to be added. It can be any of of the\r
+ * following types: {@link CKEDITOR.htmlParser.element},\r
+ * {@link CKEDITOR.htmlParser.text} and\r
+ * {@link CKEDITOR.htmlParser.comment}.\r
+ * @function\r
+ * @example\r
+ */\r
+ add : CKEDITOR.htmlParser.fragment.prototype.add,\r
+\r
+ /**\r
+ * Clone this element.\r
+ * @returns {CKEDITOR.htmlParser.element} The element clone.\r
+ * @example\r
+ */\r
+ clone : function()\r
+ {\r
+ return new CKEDITOR.htmlParser.element( this.name, this.attributes );\r
+ },\r
+\r
+ /**\r
+ * Writes the element HTML to a CKEDITOR.htmlWriter.\r
+ * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.\r
+ * @example\r
+ */\r
+ writeHtml : function( writer, filter )\r
+ {\r
+ var attributes = this.attributes;\r
+\r
+ // The "_cke_replacedata" indicates that this element is replacing\r
+ // a data snippet, which should be outputted as is.\r
+ if ( attributes._cke_replacedata )\r
+ {\r
+ writer.write( attributes._cke_replacedata );\r
+ return;\r
+ }\r
+\r
+ // Ignore cke: prefixes when writing HTML.\r
+ var element = this,\r
+ writeName = element.name,\r
+ a, value;\r
+\r
+ if ( filter )\r
+ {\r
+ while ( true )\r
+ {\r
+ if ( !( writeName = filter.onElementName( writeName ) ) )\r
+ return;\r
+\r
+ element.name = writeName;\r
+\r
+ if ( !( element = filter.onElement( element ) ) )\r
+ return;\r
+\r
+ if ( element.name == writeName )\r
+ break;\r
+\r
+ writeName = element.name;\r
+ if ( !writeName ) // Send children.\r
+ {\r
+ CKEDITOR.htmlParser.fragment.prototype.writeHtml.apply( element, arguments );\r
+ return;\r
+ }\r
+ }\r
+\r
+ // The element may have been changed, so update the local\r
+ // references.\r
+ attributes = element.attributes;\r
+ }\r
+\r
+ // Open element tag.\r
+ writer.openTag( writeName, attributes );\r
+\r
+ if ( writer.sortAttributes )\r
+ {\r
+ // Copy all attributes to an array.\r
+ var attribsArray = [];\r
+ for ( a in attributes )\r
+ {\r
+ value = attributes[ a ];\r
+\r
+ if ( filter && ( !( a = filter.onAttributeName( a ) ) || ( value = filter.onAttribute( element, a, value ) ) === false ) )\r
+ continue;\r
+\r
+ attribsArray.push( [ a, value ] );\r
+ }\r
+\r
+ // Sort the attributes by name.\r
+ attribsArray.sort( sortAttribs );\r
+\r
+ // Send the attributes.\r
+ for ( var i = 0, len = attribsArray.length ; i < len ; i++ )\r
+ {\r
+ var attrib = attribsArray[ i ];\r
+ writer.attribute( attrib[0], attrib[1] );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ for ( a in attributes )\r
+ {\r
+ value = attributes[ a ];\r
+\r
+ if ( filter && ( !( a = filter.onAttributeName( a ) ) || ( value = filter.onAttribute( element, a, value ) ) === false ) )\r
+ continue;\r
+\r
+ writer.attribute( a, value );\r
+ }\r
+ }\r
+\r
+ // Close the tag.\r
+ writer.openTagClose( writeName, element.isEmpty );\r
+\r
+ if ( !element.isEmpty )\r
+ {\r
+ // Send children.\r
+ CKEDITOR.htmlParser.fragment.prototype.writeHtml.apply( element, arguments );\r
+\r
+ // Close the element.\r
+ writer.closeTag( writeName );\r
+ }\r
+ }\r
+ };\r
+})();\r