1 /*
  2  * CKEditor - The text editor for Internet - http://ckeditor.com
  3  * Copyright (C) 2003-2008 Frederico Caldeira Knabben
  4  *
  5  * == BEGIN LICENSE ==
  6  *
  7  * Licensed under the terms of any of the following licenses at your
  8  * choice:
  9  *
 10  *  - GNU General Public License Version 2 or later (the "GPL")
 11  *    http://www.gnu.org/licenses/gpl.html
 12  *
 13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14  *    http://www.gnu.org/licenses/lgpl.html
 15  *
 16  *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17  *    http://www.mozilla.org/MPL/MPL-1.1.html
 18  *
 19  * == END LICENSE ==
 20  */
 21
 22 /**
 23  * @fileOverview Defines the {@link CKEDITOR.dom.element} class, which
 24  *		represents a DOM element.
 25  */
 26
 27 /**
 28  * Represents a DOM element.
 29  * @constructor
 30  * @augments CKEDITOR.dom.node
 31  * @param {Object|String} element A native DOM element or the element name for
 32  *		new elements.
 33  * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
 34  *		the element in case of element creation.
 35  * @example
 36  * // Create a new <span> element.
 37  * var element = new CKEDITOR.dom.element( 'span' );
 38  * @example
 39  * // Create an element based on a native DOM element.
 40  * var element = new CKEDITOR.dom.element( document.getElementById( 'myId' ) );
 41  */
 42 CKEDITOR.dom.element = function( element, ownerDocument )
 43 {
 44 	if ( typeof element == 'string' )
 45 		element = ( ownerDocument ? ownerDocument.$ : document ).createElement( element );
 46
 47 	/**
 48 	 * The native DOM element represented by this class instance.
 49 	 * @type Object
 50 	 * @example
 51 	 * var element = new CKEDITOR.dom.element( 'span' );
 52 	 * alert( element.$.nodeType );  // "1"
 53 	 */
 54 	this.$ = element;
 55 };
 56
 57 CKEDITOR.dom.element.prototype = new CKEDITOR.dom.node();
 58
 59 /**
 60  * Creates an instance of the {@link CKEDITOR.dom.element} class based on the
 61  * HTML representation of an element.
 62  * @param {String} html The element HTML. It should define only one element in
 63  *		the "root" level. The "root" element can have child nodes, but not
 64  *		siblings.
 65  * @returns {CKEDITOR.dom.element} The element instance.
 66  * @example
 67  * var element = <b>CKEDITOR.dom.element.createFromHtml( '<strong class="anyclass">My element</strong>' )</b>;
 68  * alert( element.getName() );  // "strong"
 69  */
 70 CKEDITOR.dom.element.createFromHtml = function( html, ownerDocument )
 71 {
 72 	var temp = new CKEDITOR.dom.element( 'div', ownerDocument );
 73 	temp.setHtml( html );
 74 	return temp.getFirst();
 75 };
 76
 77 CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
 78 	/** @lends CKEDITOR.dom.element.prototype */
 79 	{
 80 		/**
 81 		 * Append a node as a child of this element.
 82 		 * @param {CKEDITOR.dom.node|String} node The node or element name to be
 83 		 *		appended.
 84 		 * @returns {CKEDITOR.dom.node} The appended node.
 85 		 * @example
 86 		 * var p = new CKEDITOR.dom.element( 'p' );
 87 		 *
 88 		 * var strong = new CKEDITOR.dom.element( 'strong' );
 89 		 * <b>p.append( strong );</b>
 90 		 *
 91 		 * var em = <b>p.append( 'em' );</b>
 92 		 *
 93 		 * // result: "<p><strong></strong><em></em></p>"
 94 		 */
 95 		append : function( node )
 96 		{
 97 			if ( typeof node == 'string' )
 98 				node = new CKEDITOR.dom.element( node );
 99
100 			this.$.appendChild( node.$ );
101 			return node;
102 		},
103
104 		/**
105 		 * Append text to this element.
106 		 * @param {String} text The text to be appended.
107 		 * @returns {CKEDITOR.dom.node} The appended node.
108 		 * @example
109 		 * var p = new CKEDITOR.dom.element( 'p' );
110 		 * p.appendText( 'This is' );
111 		 * p.appendText( ' some text' );
112 		 *
113 		 * // result: "<p>This is some text</p>"
114 		 */
115 		appendText : function( text )
116 		{
117 			if ( this.$.text != undefined )
118 				this.$.text += text;
119 			else
120 				this.append( new CKEDITOR.dom.text( text ) );
121 		},
122
123 		/**
124 		 * Sets the inner HTML of this element.
125 		 * @param {String} html The HTML to be set for this element.
126 		 * @returns {String} The inserted HTML.
127 		 * @example
128 		 * var p = new CKEDITOR.dom.element( 'p' );
129 		 * <b>p.setHtml( '<b>Inner</b> HTML' );</b>
130 		 *
131 		 * // result: "<p><b>Inner</b> HTML</p>"
132 		 */
133 		setHtml : function( html )
134 		{
135 			return ( this.$.innerHTML = html );
136 		},
137
138 		/**
139 		 * Gets the document containing this element.
140 		 * @returns {CKEDITOR.dom.document} The document.
141 		 * @example
142 		 * var element = CKEDITOR.document.getById( 'example' );
143 		 * alert( <b>element.getDocument().equals( CKEDITOR.document )</b> );  // "true"
144 		 */
145 		getDocument : function()
146 		{
147 			var document = new CKEDITOR.dom.document( this.$.ownerDocument );
148
149 			return (
150 			/** @ignore */
151 			this.getDocument = function()
152 				{
153 					return document;
154 				})();
155 		},
156
157 		/**
158 		 * Gets the value of the "id" attribute of this element.
159 		 * @returns {String} The element id, or null if not available.
160 		 * @example
161 		 * var element = CKEDITOR.dom.element.createFromHtml( '<p id="myId"></p>' );
162 		 * alert( <b>element.getId()</b> );  // "myId"
163 		 */
164 		getId : function()
165 		{
166 			return this.$.id || null;
167 		},
168
169 		/**
170 		 * Gets the value of the "name" attribute of this element.
171 		 * @returns {String} The element name, or null if not available.
172 		 * @example
173 		 * var element = CKEDITOR.dom.element.createFromHtml( '<input name="myName"></input>' );
174 		 * alert( <b>element.getNameAtt()</b> );  // "myName"
175 		 */
176 		getNameAtt : function()
177 		{
178 			return this.$.name || null;
179 		},
180
181 		/**
182 		 * Gets the element name (tag name). The returned name is guaranteed to
183 		 * be always full lowercased.
184 		 * @returns {String} The element name.
185 		 * @example
186 		 * var element = new CKEDITOR.dom.element( 'span' );
187 		 * alert( <b>element.getName()</b> );  // "span"
188 		 */
189 		getName : function()
190 		{
191 			// Cache the lowercased name inside a closure.
192 			var nodeName = this.$.nodeName.toLowerCase();
193
194 			return (
195 			/** @ignore */
196 			this.getName = function()
197 				{
198 					return nodeName;
199 				})();
200 		},
201
202 		/**
203 		 * Gets the first child node of this element.
204 		 * @returns {CKEDITOR.dom.node} The first child node or null if not
205 		 *		available.
206 		 * @example
207 		 * var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' );
208 		 * var first = <b>element.getFirst()</b>;
209 		 * alert( first.getName() );  // "b"
210 		 */
211 		getFirst : function()
212 		{
213 			var $ = this.$.firstChild;
214 			return $ ? new CKEDITOR.dom.node( $ ) : null;
215 		},
216
217 		/**
218 		 * Hides this element (display:none).
219 		 * @type {undefined}
220 		 * @example
221 		 * var element = CKEDITOR.dom.element.getById( 'myElement' );
222 		 * <b>element.hide()</b>;
223 		 */
224 		hide : function()
225 		{
226 			this.setStyle( 'display', 'none' );
227 		},
228
229 		/**
230 		 * Shows this element (display it).
231 		 * @type {undefined}
232 		 * @example
233 		 * var element = CKEDITOR.dom.element.getById( 'myElement' );
234 		 * <b>element.show()</b>;
235 		 */
236 		show : function()
237 		{
238 			this.setStyle( 'display', '' );
239 		},
240
241 		/**
242 		 * Sets the value of an element attribute.
243 		 * @param {String} name The name of the attribute.
244 		 * @param {String} value The value to be set to the attribute.
245 		 * @type {undefined}
246 		 * @example
247 		 * var element = CKEDITOR.dom.element.getById( 'myElement' );
248 		 * <b>element.setAttribute( 'class', 'myClass' )</b>;
249 		 * <b>element.setAttribute( 'title', 'This is an example' )</b>;
250 		 */
251 		setAttribute : (function()
252 		{
253 			var standard = function( name, value )
254 			{
255 				this.$.setAttribute( name, value );
256 			};
257
258 			if ( CKEDITOR.env.ie )
259 			{
260 				return function( name, value )
261 				{
262 					if ( name == 'class' )
263 						this.$.className = value;
264 					if ( name == 'style' )
265 						this.$.style.cssText = value;
266 					else
267 						standard.apply( this, arguments );
268 				};
269 			}
270 			else
271 				return standard;
272 		})(),
273
274 		/**
275 		 * Sets the value of several element attributes.
276 		 * @param {Object} attributesPairs An object containing the names and
277 		 *		values of the attributes.
278 		 * @type {undefined}
279 		 * @example
280 		 * var element = CKEDITOR.dom.element.getById( 'myElement' );
281 		 * <b>element.setAttributes({
282 		 *     'class' : 'myClass',
283 		 *     'title' : 'This is an example' })</b>;
284 		 */
285 		setAttributes : function( attributesPairs )
286 		{
287 			for ( var name in attributesPairs )
288 				this.setAttribute( name, attributesPairs[ name ] );
289 		},
290
291 		/**
292 		 * Sets the value of an element style.
293 		 * @param {String} name The name of the style. The CSS naming notation
294 		 *		must be used (e.g. "background-color").
295 		 * @param {String} value The value to be set to the style.
296 		 * @type {undefined}
297 		 * @example
298 		 * var element = CKEDITOR.dom.element.getById( 'myElement' );
299 		 * <b>element.setStyle( 'background-color', '#ff0000' )</b>;
300 		 * <b>element.setStyle( 'margin-top', '10px' )</b>;
301 		 * <b>element.setStyle( 'float', 'right' )</b>;
302 		 */
303 		setStyle : function( name, value )
304 		{
305 			this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ] = value;
306 		}
307 	});
308