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 * Adds a CSS class to the element. It appends the class to the 82 * already existing names. 83 * @param {String} className The name of the class to be added. 84 * @example 85 * var element = new CKEDITOR.dom.element( 'div' ); 86 * element.addClass( 'classA' ); // <div class="classA"> 87 * element.addClass( 'classB' ); // <div class="classA classB"> 88 * element.addClass( 'classA' ); // <div class="classA classB"> 89 */ 90 addClass : function( className ) 91 { 92 var c = this.$.className; 93 if ( c ) 94 { 95 var regex = new RegExp( '(?:^|\\s)' + className + '(?:\\s|$)', '' ); 96 if ( !regex.test( c ) ) 97 c += ' ' + className; 98 } 99 this.$.className = c || className; 100 }, 101 102 /** 103 * Removes a CSS class name from the elements classes. Other classes 104 * remain untouched. 105 * @param {String} className The name of the class to remove. 106 * @example 107 * var element = new CKEDITOR.dom.element( 'div' ); 108 * element.addClass( 'classA' ); // <div class="classA"> 109 * element.addClass( 'classB' ); // <div class="classA classB"> 110 * element.removeClass( 'classA' ); // <div class="classB"> 111 * element.removeClass( 'classB' ); // <div> 112 */ 113 removeClass : function( className ) 114 { 115 var c = this.$.className; 116 if ( c ) 117 { 118 var regex = new RegExp( '(?:^|\\s+)' + className + '(?=\\s|$)', '' ); 119 if ( regex.test( c ) ) 120 { 121 c = c.replace( regex, '' ).replace( /^\s+/, '' ); 122 123 if ( c ) 124 this.$.className = c; 125 else 126 this.removeAttribute( 'class' ); 127 } 128 } 129 }, 130 131 /** 132 * Append a node as a child of this element. 133 * @param {CKEDITOR.dom.node|String} node The node or element name to be 134 * appended. 135 * @returns {CKEDITOR.dom.node} The appended node. 136 * @example 137 * var p = new CKEDITOR.dom.element( 'p' ); 138 * 139 * var strong = new CKEDITOR.dom.element( 'strong' ); 140 * <b>p.append( strong );</b> 141 * 142 * var em = <b>p.append( 'em' );</b> 143 * 144 * // result: "<p><strong></strong><em></em></p>" 145 */ 146 append : function( node ) 147 { 148 if ( typeof node == 'string' ) 149 node = new CKEDITOR.dom.element( node ); 150 151 this.$.appendChild( node.$ ); 152 return node; 153 }, 154 155 /** 156 * Append text to this element. 157 * @param {String} text The text to be appended. 158 * @returns {CKEDITOR.dom.node} The appended node. 159 * @example 160 * var p = new CKEDITOR.dom.element( 'p' ); 161 * p.appendText( 'This is' ); 162 * p.appendText( ' some text' ); 163 * 164 * // result: "<p>This is some text</p>" 165 */ 166 appendText : function( text ) 167 { 168 if ( this.$.text != undefined ) 169 this.$.text += text; 170 else 171 this.append( new CKEDITOR.dom.text( text ) ); 172 }, 173 174 /** 175 * Gets the inner HTML of this element. 176 * @returns {String} The inner HTML of this element. 177 * @example 178 * var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' ); 179 * alert( <b>p.getHtml()</b> ); // "<b>Example</b>" 180 */ 181 getHtml : function() 182 { 183 return this.$.innerHTML; 184 }, 185 186 /** 187 * Sets the inner HTML of this element. 188 * @param {String} html The HTML to be set for this element. 189 * @returns {String} The inserted HTML. 190 * @example 191 * var p = new CKEDITOR.dom.element( 'p' ); 192 * <b>p.setHtml( '<b>Inner</b> HTML' );</b> 193 * 194 * // result: "<p><b>Inner</b> HTML</p>" 195 */ 196 setHtml : function( html ) 197 { 198 return ( this.$.innerHTML = html ); 199 }, 200 201 /** 202 * Sets the element contents as plain text. 203 * @param {String} text The text to be set. 204 * @returns {String} The inserted text. 205 * @example 206 * var element = new CKEDITOR.dom.element( 'div' ); 207 * element.setText( 'A > B & C < D' ); 208 * alert( element.innerHTML ); // "A > B & C < D" 209 */ 210 setText : function( text ) 211 { 212 CKEDITOR.dom.element.prototype.setText = ( this.$.innerText != undefined ) ? 213 function ( text ) 214 { 215 return this.$.innerText = text; 216 } : 217 function ( text ) 218 { 219 return this.$.textContent = text; 220 }; 221 222 return this.setText( text ); 223 }, 224 225 /** 226 * Gets the document containing this element. 227 * @returns {CKEDITOR.dom.document} The document. 228 * @example 229 * var element = CKEDITOR.document.getById( 'example' ); 230 * alert( <b>element.getDocument().equals( CKEDITOR.document )</b> ); // "true" 231 */ 232 getDocument : function() 233 { 234 var document = new CKEDITOR.dom.document( this.$.ownerDocument ); 235 236 return ( 237 /** @ignore */ 238 this.getDocument = function() 239 { 240 return document; 241 })(); 242 }, 243 244 /** 245 * Gets the value of the "id" attribute of this element. 246 * @returns {String} The element id, or null if not available. 247 * @example 248 * var element = CKEDITOR.dom.element.createFromHtml( '<p id="myId"></p>' ); 249 * alert( <b>element.getId()</b> ); // "myId" 250 */ 251 getId : function() 252 { 253 return this.$.id || null; 254 }, 255 256 /** 257 * Gets the value of the "name" attribute of this element. 258 * @returns {String} The element name, or null if not available. 259 * @example 260 * var element = CKEDITOR.dom.element.createFromHtml( '<input name="myName"></input>' ); 261 * alert( <b>element.getNameAtt()</b> ); // "myName" 262 */ 263 getNameAtt : function() 264 { 265 return this.$.name || null; 266 }, 267 268 /** 269 * Gets the element name (tag name). The returned name is guaranteed to 270 * be always full lowercased. 271 * @returns {String} The element name. 272 * @example 273 * var element = new CKEDITOR.dom.element( 'span' ); 274 * alert( <b>element.getName()</b> ); // "span" 275 */ 276 getName : function() 277 { 278 // Cache the lowercased name inside a closure. 279 var nodeName = this.$.nodeName.toLowerCase(); 280 281 return ( 282 /** @ignore */ 283 this.getName = function() 284 { 285 return nodeName; 286 })(); 287 }, 288 289 /** 290 * Gets the first child node of this element. 291 * @returns {CKEDITOR.dom.node} The first child node or null if not 292 * available. 293 * @example 294 * var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' ); 295 * var first = <b>element.getFirst()</b>; 296 * alert( first.getName() ); // "b" 297 */ 298 getFirst : function() 299 { 300 var $ = this.$.firstChild; 301 return $ ? new CKEDITOR.dom.node( $ ) : null; 302 }, 303 304 /** 305 * Hides this element (display:none). 306 * @example 307 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 308 * <b>element.hide()</b>; 309 */ 310 hide : function() 311 { 312 this.setStyle( 'display', 'none' ); 313 }, 314 315 /** 316 * Shows this element (display it). 317 * @example 318 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 319 * <b>element.show()</b>; 320 */ 321 show : function() 322 { 323 this.setStyle( 'display', '' ); 324 }, 325 326 /** 327 * Sets the value of an element attribute. 328 * @param {String} name The name of the attribute. 329 * @param {String} value The value to be set to the attribute. 330 * @function 331 * @example 332 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 333 * <b>element.setAttribute( 'class', 'myClass' )</b>; 334 * <b>element.setAttribute( 'title', 'This is an example' )</b>; 335 */ 336 setAttribute : (function() 337 { 338 var standard = function( name, value ) 339 { 340 this.$.setAttribute( name, value ); 341 }; 342 343 if ( CKEDITOR.env.ie ) 344 { 345 return function( name, value ) 346 { 347 if ( name == 'class' ) 348 this.$.className = value; 349 if ( name == 'style' ) 350 this.$.style.cssText = value; 351 else 352 standard.apply( this, arguments ); 353 }; 354 } 355 else 356 return standard; 357 })(), 358 359 /** 360 * Sets the value of several element attributes. 361 * @param {Object} attributesPairs An object containing the names and 362 * values of the attributes. 363 * @example 364 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 365 * <b>element.setAttributes({ 366 * 'class' : 'myClass', 367 * 'title' : 'This is an example' })</b>; 368 */ 369 setAttributes : function( attributesPairs ) 370 { 371 for ( var name in attributesPairs ) 372 this.setAttribute( name, attributesPairs[ name ] ); 373 }, 374 375 /** 376 * Removes the element from the document DOM. 377 * @example 378 * var element = CKEDITOR.dom.element.getById( 'MyElement' ); 379 * <b>element.remove()</b>; 380 */ 381 remove : function() 382 { 383 this.$.parentNode.removeChild( this.$ ); 384 }, 385 386 /** 387 * Removes an attribute from the element. 388 * @param {String} name The attribute name. 389 * @function 390 * @example 391 * var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' ); 392 * element.removeAttribute( 'class' ); 393 */ 394 removeAttribute : (function() 395 { 396 var standard = function( name ) 397 { 398 this.$.removeAttribute( name ); 399 }; 400 401 if ( CKEDITOR.env.ie ) 402 { 403 return function( name ) 404 { 405 if ( name == 'class' ) 406 name = 'className'; 407 standard.call( this, name ); 408 }; 409 } 410 else 411 return standard; 412 })(), 413 414 /** 415 * Sets the value of an element style. 416 * @param {String} name The name of the style. The CSS naming notation 417 * must be used (e.g. "background-color"). 418 * @param {String} value The value to be set to the style. 419 * @example 420 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 421 * <b>element.setStyle( 'background-color', '#ff0000' )</b>; 422 * <b>element.setStyle( 'margin-top', '10px' )</b>; 423 * <b>element.setStyle( 'float', 'right' )</b>; 424 */ 425 setStyle : function( name, value ) 426 { 427 this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ] = value; 428 }, 429 430 /** 431 * Sets the value of several element styles. 432 * @param {Object} stylesPairs An object containing the names and 433 * values of the styles. 434 * @example 435 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 436 * <b>element.setStyles({ 437 * 'position' : 'absolute', 438 * 'float' : 'right' })</b>; 439 */ 440 setStyles : function( stylesPairs ) 441 { 442 for ( var name in stylesPairs ) 443 this.setStyle( name, stylesPairs[ name ] ); 444 } 445 }); 446