+++ /dev/null
-/*\r
-Copyright (c) 2003-2013, 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
- // Reveal the real semantic of our internal custom tag name (#6639),\r
- // when resolving whether it's block like.\r
- var realName = name || '',\r
- prefixed = realName.match( /^cke:(.*)/ );\r
- prefixed && ( realName = prefixed[ 1 ] );\r
-\r
- var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ]\r
- || CKEDITOR.dtd.$block[ realName ]\r
- || CKEDITOR.dtd.$listItem[ realName ]\r
- || CKEDITOR.dtd.$tableContent[ realName ]\r
- || CKEDITOR.dtd.$nonEditable[ realName ]\r
- || realName == 'br' );\r
-\r
- this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];\r
- this.isUnknown = !CKEDITOR.dtd[ name ];\r
-\r
- /** @private */\r
- this._ =\r
- {\r
- isBlockLike : isBlockLike,\r
- hasInlineStarted : this.isEmpty || !isBlockLike\r
- };\r
-};\r
-\r
-/**\r
- * Object presentation of CSS style declaration text.\r
- * @param {CKEDITOR.htmlParser.element|String} elementOrStyleText A html parser element or the inline style text.\r
- */\r
-CKEDITOR.htmlParser.cssStyle = function()\r
-{\r
- var styleText,\r
- arg = arguments[ 0 ],\r
- rules = {};\r
-\r
- styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;\r
-\r
- // html-encoded quote might be introduced by 'font-family'\r
- // from MS-Word which confused the following regexp. e.g.\r
- //'font-family: "Lucida, Console"'\r
- ( styleText || '' )\r
- .replace( /"/g, '"' )\r
- .replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g,\r
- function( match, name, value )\r
- {\r
- name == 'font-family' && ( value = value.replace( /["']/g, '' ) );\r
- rules[ name.toLowerCase() ] = value;\r
- });\r
-\r
- return {\r
-\r
- rules : rules,\r
-\r
- /**\r
- * Apply the styles onto the specified element or object.\r
- * @param {CKEDITOR.htmlParser.element|CKEDITOR.dom.element|Object} obj\r
- */\r
- populate : function( obj )\r
- {\r
- var style = this.toString();\r
- if ( style )\r
- {\r
- obj instanceof CKEDITOR.dom.element ?\r
- obj.setAttribute( 'style', style ) :\r
- obj instanceof CKEDITOR.htmlParser.element ?\r
- obj.attributes.style = style :\r
- obj.style = style;\r
- }\r
- },\r
-\r
- toString : function()\r
- {\r
- var output = [];\r
- for ( var i in rules )\r
- rules[ i ] && output.push( i, ':', rules[ i ], ';' );\r
- return output.join( '' );\r
- }\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
- // Ignore cke: prefixes when writing HTML.\r
- var element = this,\r
- writeName = element.name,\r
- a, newAttrName, value;\r
-\r
- var isChildrenFiltered;\r
-\r
- /**\r
- * Providing an option for bottom-up filtering order ( element\r
- * children to be pre-filtered before the element itself ).\r
- */\r
- element.filterChildren = function()\r
- {\r
- if ( !isChildrenFiltered )\r
- {\r
- var writer = new CKEDITOR.htmlParser.basicWriter();\r
- CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.call( element, writer, filter );\r
- element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml(), 0, element.clone() ).children;\r
- isChildrenFiltered = 1;\r
- }\r
- };\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
- element.parent = this.parent;\r
-\r
- if ( element.name == writeName )\r
- break;\r
-\r
- // If the element has been replaced with something of a\r
- // different type, then make the replacement write itself.\r
- if ( element.type != CKEDITOR.NODE_ELEMENT )\r
- {\r
- element.writeHtml( writer, filter );\r
- return;\r
- }\r
-\r
- writeName = element.name;\r
-\r
- // This indicate that the element has been dropped by\r
- // filter but not the children.\r
- if ( !writeName )\r
- {\r
- // Fix broken parent refs.\r
- for ( var c = 0, length = this.children.length ; c < length ; c++ )\r
- this.children[ c ].parent = element.parent;\r
-\r
- this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );\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
- // Copy all attributes to an array.\r
- var attribsArray = [];\r
- // Iterate over the attributes twice since filters may alter\r
- // other attributes.\r
- for ( var i = 0 ; i < 2; i++ )\r
- {\r
- for ( a in attributes )\r
- {\r
- newAttrName = a;\r
- value = attributes[ a ];\r
- if ( i == 1 )\r
- attribsArray.push( [ a, value ] );\r
- else if ( filter )\r
- {\r
- while ( true )\r
- {\r
- if ( !( newAttrName = filter.onAttributeName( a ) ) )\r
- {\r
- delete attributes[ a ];\r
- break;\r
- }\r
- else if ( newAttrName != a )\r
- {\r
- delete attributes[ a ];\r
- a = newAttrName;\r
- continue;\r
- }\r
- else\r
- break;\r
- }\r
- if ( newAttrName )\r
- {\r
- if ( ( value = filter.onAttribute( element, newAttrName, value ) ) === false )\r
- delete attributes[ newAttrName ];\r
- else\r
- attributes [ newAttrName ] = value;\r
- }\r
- }\r
- }\r
- }\r
- // Sort the attributes by name.\r
- if ( writer.sortAttributes )\r
- attribsArray.sort( sortAttribs );\r
-\r
- // Send the attributes.\r
- var len = attribsArray.length;\r
- for ( i = 0 ; i < len ; i++ )\r
- {\r
- var attrib = attribsArray[ i ];\r
- writer.attribute( attrib[0], attrib[1] );\r
- }\r
-\r
- // Close the tag.\r
- writer.openTagClose( writeName, element.isEmpty );\r
-\r
- if ( !element.isEmpty )\r
- {\r
- this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );\r
- // Close the element.\r
- writer.closeTag( writeName );\r
- }\r
- },\r
-\r
- writeChildrenHtml : function( writer, filter )\r
- {\r
- // Send children.\r
- CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.apply( this, arguments );\r
-\r
- }\r
- };\r
-})();\r