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 * Moves the selection focus to this element. 176 * @example 177 * var element = CKEDITOR.document.getById( 'myTextarea' ); 178 * <b>element.focus()</b>; 179 */ 180 focus : function() 181 { 182 this.$.focus(); 183 }, 184 185 /** 186 * Gets the inner HTML of this element. 187 * @returns {String} The inner HTML of this element. 188 * @example 189 * var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' ); 190 * alert( <b>p.getHtml()</b> ); // "<b>Example</b>" 191 */ 192 getHtml : function() 193 { 194 return this.$.innerHTML; 195 }, 196 197 /** 198 * Sets the inner HTML of this element. 199 * @param {String} html The HTML to be set for this element. 200 * @returns {String} The inserted HTML. 201 * @example 202 * var p = new CKEDITOR.dom.element( 'p' ); 203 * <b>p.setHtml( '<b>Inner</b> HTML' );</b> 204 * 205 * // result: "<p><b>Inner</b> HTML</p>" 206 */ 207 setHtml : function( html ) 208 { 209 return ( this.$.innerHTML = html ); 210 }, 211 212 /** 213 * Sets the element contents as plain text. 214 * @param {String} text The text to be set. 215 * @returns {String} The inserted text. 216 * @example 217 * var element = new CKEDITOR.dom.element( 'div' ); 218 * element.setText( 'A > B & C < D' ); 219 * alert( element.innerHTML ); // "A > B & C < D" 220 */ 221 setText : function( text ) 222 { 223 CKEDITOR.dom.element.prototype.setText = ( this.$.innerText != undefined ) ? 224 function ( text ) 225 { 226 return this.$.innerText = text; 227 } : 228 function ( text ) 229 { 230 return this.$.textContent = text; 231 }; 232 233 return this.setText( text ); 234 }, 235 236 /** 237 * Gets the document containing this element. 238 * @returns {CKEDITOR.dom.document} The document. 239 * @example 240 * var element = CKEDITOR.document.getById( 'example' ); 241 * alert( <b>element.getDocument().equals( CKEDITOR.document )</b> ); // "true" 242 */ 243 getDocument : function() 244 { 245 var document = new CKEDITOR.dom.document( this.$.ownerDocument ); 246 247 return ( 248 /** @ignore */ 249 this.getDocument = function() 250 { 251 return document; 252 })(); 253 }, 254 255 /** 256 * Gets the window object that contains this element. 257 * @returns {CKEDITOR.dom.window} The window object. 258 * @example 259 */ 260 getWindow : function() 261 { 262 return this.getDocument().getWindow(); 263 }, 264 265 /** 266 * Gets the value of the "id" attribute of this element. 267 * @returns {String} The element id, or null if not available. 268 * @example 269 * var element = CKEDITOR.dom.element.createFromHtml( '<p id="myId"></p>' ); 270 * alert( <b>element.getId()</b> ); // "myId" 271 */ 272 getId : function() 273 { 274 return this.$.id || null; 275 }, 276 277 /** 278 * Gets the value of the "name" attribute of this element. 279 * @returns {String} The element name, or null if not available. 280 * @example 281 * var element = CKEDITOR.dom.element.createFromHtml( '<input name="myName"></input>' ); 282 * alert( <b>element.getNameAtt()</b> ); // "myName" 283 */ 284 getNameAtt : function() 285 { 286 return this.$.name || null; 287 }, 288 289 /** 290 * Gets the element name (tag name). The returned name is guaranteed to 291 * be always full lowercased. 292 * @returns {String} The element name. 293 * @example 294 * var element = new CKEDITOR.dom.element( 'span' ); 295 * alert( <b>element.getName()</b> ); // "span" 296 */ 297 getName : function() 298 { 299 // Cache the lowercased name inside a closure. 300 var nodeName = this.$.nodeName.toLowerCase(); 301 302 return ( 303 /** @ignore */ 304 this.getName = function() 305 { 306 return nodeName; 307 })(); 308 }, 309 310 /** 311 * Gets the value set to this element. This value is usually available 312 * for form field elements. 313 * @returns {String} The element value. 314 */ 315 getValue : function() 316 { 317 return this.$.value; 318 }, 319 320 /** 321 * Gets the first child node of this element. 322 * @returns {CKEDITOR.dom.node} The first child node or null if not 323 * available. 324 * @example 325 * var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' ); 326 * var first = <b>element.getFirst()</b>; 327 * alert( first.getName() ); // "b" 328 */ 329 getFirst : function() 330 { 331 var $ = this.$.firstChild; 332 return $ ? new CKEDITOR.dom.node( $ ) : null; 333 }, 334 335 /** 336 * Hides this element (display:none). 337 * @example 338 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 339 * <b>element.hide()</b>; 340 */ 341 hide : function() 342 { 343 this.setStyle( 'display', 'none' ); 344 }, 345 346 /** 347 * Shows this element (display it). 348 * @example 349 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 350 * <b>element.show()</b>; 351 */ 352 show : function() 353 { 354 this.setStyle( 'display', '' ); 355 }, 356 357 /** 358 * Sets the value of an element attribute. 359 * @param {String} name The name of the attribute. 360 * @param {String} value The value to be set to the attribute. 361 * @function 362 * @returns {CKEDITOR.dom.element} This element instance. 363 * @example 364 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 365 * <b>element.setAttribute( 'class', 'myClass' )</b>; 366 * <b>element.setAttribute( 'title', 'This is an example' )</b>; 367 */ 368 setAttribute : (function() 369 { 370 var standard = function( name, value ) 371 { 372 this.$.setAttribute( name, value ); 373 return this; 374 }; 375 376 if ( CKEDITOR.env.ie ) 377 { 378 return function( name, value ) 379 { 380 if ( name == 'class' ) 381 this.$.className = value; 382 if ( name == 'style' ) 383 this.$.style.cssText = value; 384 else 385 standard.apply( this, arguments ); 386 return this; 387 }; 388 } 389 else 390 return standard; 391 })(), 392 393 /** 394 * Sets the value of several element attributes. 395 * @param {Object} attributesPairs An object containing the names and 396 * values of the attributes. 397 * @returns {CKEDITOR.dom.element} This element instance. 398 * @example 399 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 400 * <b>element.setAttributes({ 401 * 'class' : 'myClass', 402 * 'title' : 'This is an example' })</b>; 403 */ 404 setAttributes : function( attributesPairs ) 405 { 406 for ( var name in attributesPairs ) 407 this.setAttribute( name, attributesPairs[ name ] ); 408 return this; 409 }, 410 411 /** 412 * Sets the element value. This function is usually used with form 413 * field element. 414 * @param {String} value The element value. 415 * @returns {CKEDITOR.dom.element} This element instance. 416 */ 417 setValue : function( value ) 418 { 419 this.$.value = value; 420 return this; 421 }, 422 423 /** 424 * Removes the element from the document DOM. 425 * @example 426 * var element = CKEDITOR.dom.element.getById( 'MyElement' ); 427 * <b>element.remove()</b>; 428 */ 429 remove : function() 430 { 431 this.$.parentNode.removeChild( this.$ ); 432 }, 433 434 /** 435 * Removes an attribute from the element. 436 * @param {String} name The attribute name. 437 * @function 438 * @example 439 * var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' ); 440 * element.removeAttribute( 'class' ); 441 */ 442 removeAttribute : (function() 443 { 444 var standard = function( name ) 445 { 446 this.$.removeAttribute( name ); 447 }; 448 449 if ( CKEDITOR.env.ie ) 450 { 451 return function( name ) 452 { 453 if ( name == 'class' ) 454 name = 'className'; 455 standard.call( this, name ); 456 }; 457 } 458 else 459 return standard; 460 })(), 461 462 /** 463 * Sets the value of an element style. 464 * @param {String} name The name of the style. The CSS naming notation 465 * must be used (e.g. "background-color"). 466 * @param {String} value The value to be set to the style. 467 * @returns {CKEDITOR.dom.element} This element instance. 468 * @example 469 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 470 * <b>element.setStyle( 'background-color', '#ff0000' )</b>; 471 * <b>element.setStyle( 'margin-top', '10px' )</b>; 472 * <b>element.setStyle( 'float', 'right' )</b>; 473 */ 474 setStyle : function( name, value ) 475 { 476 this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ] = value; 477 return this; 478 }, 479 480 /** 481 * Sets the value of several element styles. 482 * @param {Object} stylesPairs An object containing the names and 483 * values of the styles. 484 * @returns {CKEDITOR.dom.element} This element instance. 485 * @example 486 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 487 * <b>element.setStyles({ 488 * 'position' : 'absolute', 489 * 'float' : 'right' })</b>; 490 */ 491 setStyles : function( stylesPairs ) 492 { 493 for ( var name in stylesPairs ) 494 this.setStyle( name, stylesPairs[ name ] ); 495 return this; 496 }, 497 498 /** 499 * Makes the element unselectable. 500 * @function 501 * @example 502 * var element = CKEDITOR.dom.element.getById( 'myElement' ); 503 * element.unselectable(); 504 */ 505 unselectable : 506 CKEDITOR.env.gecko ? 507 function() 508 { 509 this.$.style.MozUserSelect = 'none'; 510 } 511 : CKEDITOR.env.webkit ? 512 function() 513 { 514 this.$.style.KhtmlUserSelect = 'none'; 515 } 516 : 517 function() 518 { 519 if ( CKEDITOR.env.ie || CKEDITOR.env.opera ) 520 { 521 var element = this.$, 522 e, 523 i = 0; 524 525 element.unselectable = 'on'; 526 527 while ( ( e = element.all[ i++ ] ) ) 528 { 529 switch ( e.tagName.toLowerCase() ) 530 { 531 case 'iframe' : 532 case 'textarea' : 533 case 'input' : 534 case 'select' : 535 /* Ignore the above tags */ 536 break; 537 default : 538 e.unselectable = 'on'; 539 } 540 } 541 } 542 } 543 }); 544