Nation Notes module contributed by Z&H Healthcare.
[openemr.git] / library / custom_template / ckeditor / _source / core / htmlparser / element.js
blobba2cdf7d25954b43aaae05f9ea8d6edb2eb1e222
1 /*
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
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 )
16         /**
17          * The element name.
18          * @type String
19          * @example
20          */
21         this.name = name;
23         /**
24          * Holds the attributes defined for this element.
25          * @type Object
26          * @example
27          */
28         this.attributes = attributes || ( attributes = {} );
30         /**
31          * The nodes that are direct children of this element.
32          * @type Array
33          * @example
34          */
35         this.children = [];
37         var tagName = attributes[ 'data-cke-real-element-type' ] || name;
39         // Reveal the real semantic of our internal custom tag name (#6639).
40         var internalTag = tagName.match( /^cke:(.*)/ );
41         internalTag && ( tagName = internalTag[ 1 ] );
43         var dtd                 = CKEDITOR.dtd,
44                 isBlockLike     = !!( dtd.$nonBodyContent[ tagName ]
45                                 || dtd.$block[ tagName ]
46                                 || dtd.$listItem[ tagName ]
47                                 || dtd.$tableContent[ tagName ]
48                                 || dtd.$nonEditable[ tagName ]
49                                 || tagName == 'br' ),
50                 isEmpty = !!dtd.$empty[ name ];
52         this.isEmpty    = isEmpty;
53         this.isUnknown  = !dtd[ name ];
55         /** @private */
56         this._ =
57         {
58                 isBlockLike : isBlockLike,
59                 hasInlineStarted : isEmpty || !isBlockLike
60         };
63 (function()
65         // Used to sort attribute entries in an array, where the first element of
66         // each object is the attribute name.
67         var sortAttribs = function( a, b )
68         {
69                 a = a[0];
70                 b = b[0];
71                 return a < b ? -1 : a > b ? 1 : 0;
72         };
74         CKEDITOR.htmlParser.element.prototype =
75         {
76                 /**
77                  * The node type. This is a constant value set to {@link CKEDITOR.NODE_ELEMENT}.
78                  * @type Number
79                  * @example
80                  */
81                 type : CKEDITOR.NODE_ELEMENT,
83                 /**
84                  * Adds a node to the element children list.
85                  * @param {Object} node The node to be added. It can be any of of the
86                  *              following types: {@link CKEDITOR.htmlParser.element},
87                  *              {@link CKEDITOR.htmlParser.text} and
88                  *              {@link CKEDITOR.htmlParser.comment}.
89                  * @function
90                  * @example
91                  */
92                 add : CKEDITOR.htmlParser.fragment.prototype.add,
94                 /**
95                  * Clone this element.
96                  * @returns {CKEDITOR.htmlParser.element} The element clone.
97                  * @example
98                  */
99                 clone : function()
100                 {
101                         return new CKEDITOR.htmlParser.element( this.name, this.attributes );
102                 },
104                 /**
105                  * Writes the element HTML to a CKEDITOR.htmlWriter.
106                  * @param {CKEDITOR.htmlWriter} writer The writer to which write the HTML.
107                  * @example
108                  */
109                 writeHtml : function( writer, filter )
110                 {
111                         var attributes = this.attributes;
113                         // Ignore cke: prefixes when writing HTML.
114                         var element = this,
115                                 writeName = element.name,
116                                 a, newAttrName, value;
118                         var isChildrenFiltered;
120                         /**
121                          * Providing an option for bottom-up filtering order ( element
122                          * children to be pre-filtered before the element itself ).
123                          */
124                         element.filterChildren = function()
125                         {
126                                 if ( !isChildrenFiltered )
127                                 {
128                                         var writer = new CKEDITOR.htmlParser.basicWriter();
129                                         CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.call( element, writer, filter );
130                                         element.children = new CKEDITOR.htmlParser.fragment.fromHtml( writer.getHtml() ).children;
131                                         isChildrenFiltered = 1;
132                                 }
133                         };
135                         if ( filter )
136                         {
137                                 while ( true )
138                                 {
139                                         if ( !( writeName = filter.onElementName( writeName ) ) )
140                                                 return;
142                                         element.name = writeName;
144                                         if ( !( element = filter.onElement( element ) ) )
145                                                 return;
147                                         element.parent = this.parent;
149                                         if ( element.name == writeName )
150                                                 break;
152                                         // If the element has been replaced with something of a
153                                         // different type, then make the replacement write itself.
154                                         if ( element.type != CKEDITOR.NODE_ELEMENT )
155                                         {
156                                                 element.writeHtml( writer, filter );
157                                                 return;
158                                         }
160                                         writeName = element.name;
162                                         // This indicate that the element has been dropped by
163                                         // filter but not the children.
164                                         if ( !writeName )
165                                         {
166                                                 this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );
167                                                 return;
168                                         }
169                                 }
171                                 // The element may have been changed, so update the local
172                                 // references.
173                                 attributes = element.attributes;
174                         }
176                         // Open element tag.
177                         writer.openTag( writeName, attributes );
179                         // Copy all attributes to an array.
180                         var attribsArray = [];
181                         // Iterate over the attributes twice since filters may alter
182                         // other attributes.
183                         for ( var i = 0 ; i < 2; i++ )
184                         {
185                                 for ( a in attributes )
186                                 {
187                                         newAttrName = a;
188                                         value = attributes[ a ];
189                                         if ( i == 1 )
190                                                 attribsArray.push( [ a, value ] );
191                                         else if ( filter )
192                                         {
193                                                 while ( true )
194                                                 {
195                                                         if ( !( newAttrName = filter.onAttributeName( a ) ) )
196                                                         {
197                                                                 delete attributes[ a ];
198                                                                 break;
199                                                         }
200                                                         else if ( newAttrName != a )
201                                                         {
202                                                                 delete attributes[ a ];
203                                                                 a = newAttrName;
204                                                                 continue;
205                                                         }
206                                                         else
207                                                                 break;
208                                                 }
209                                                 if ( newAttrName )
210                                                 {
211                                                         if ( ( value = filter.onAttribute( element, newAttrName, value ) ) === false )
212                                                                 delete attributes[ newAttrName ];
213                                                         else
214                                                                 attributes [ newAttrName ] = value;
215                                                 }
216                                         }
217                                 }
218                         }
219                         // Sort the attributes by name.
220                         if ( writer.sortAttributes )
221                                 attribsArray.sort( sortAttribs );
223                         // Send the attributes.
224                         var len = attribsArray.length;
225                         for ( i = 0 ; i < len ; i++ )
226                         {
227                                 var attrib = attribsArray[ i ];
228                                 writer.attribute( attrib[0], attrib[1] );
229                         }
231                         // Close the tag.
232                         writer.openTagClose( writeName, element.isEmpty );
234                         if ( !element.isEmpty )
235                         {
236                                 this.writeChildrenHtml.call( element, writer, isChildrenFiltered ? null : filter );
237                                 // Close the element.
238                                 writer.closeTag( writeName );
239                         }
240                 },
242                 writeChildrenHtml : function( writer, filter )
243                 {
244                         // Send children.
245                         CKEDITOR.htmlParser.fragment.prototype.writeChildrenHtml.apply( this, arguments );
247                 }
248         };
249 })();