| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 /* 2 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** @fileoverview The "dialogui" plugin. */ 7 8 CKEDITOR.plugins.add( 'dialogui' ); 9 10 (function() 11 { 12 var initPrivateObject = function( elementDefinition ) 13 { 14 this._ || ( this._ = {} ); 15 this._['default'] = this._.initValue = elementDefinition['default'] || ''; 16 this._.required = elementDefinition[ 'required' ] || false; 17 var args = [ this._ ]; 18 for ( var i = 1 ; i < arguments.length ; i++ ) 19 args.push( arguments[i] ); 20 args.push( true ); 21 CKEDITOR.tools.extend.apply( CKEDITOR.tools, args ); 22 return this._; 23 }, 24 textBuilder = 25 { 26 build : function( dialog, elementDefinition, output ) 27 { 28 return new CKEDITOR.ui.dialog.textInput( dialog, elementDefinition, output ); 29 } 30 }, 31 commonBuilder = 32 { 33 build : function( dialog, elementDefinition, output ) 34 { 35 return new CKEDITOR.ui.dialog[elementDefinition.type]( dialog, elementDefinition, output ); 36 } 37 }, 38 containerBuilder = 39 { 40 build : function( dialog, elementDefinition, output ) 41 { 42 var children = elementDefinition.children, 43 child, 44 childHtmlList = [], 45 childObjList = []; 46 for ( var i = 0 ; ( i < children.length && ( child = children[i] ) ) ; i++ ) 47 { 48 var childHtml = []; 49 childHtmlList.push( childHtml ); 50 childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) ); 51 } 52 return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition ); 53 } 54 }, 55 commonPrototype = 56 { 57 isChanged : function() 58 { 59 return this.getValue() != this.getInitValue(); 60 }, 61 62 reset : function( noChangeEvent ) 63 { 64 this.setValue( this.getInitValue(), noChangeEvent ); 65 }, 66 67 setInitValue : function() 68 { 69 this._.initValue = this.getValue(); 70 }, 71 72 resetInitValue : function() 73 { 74 this._.initValue = this._['default']; 75 }, 76 77 getInitValue : function() 78 { 79 return this._.initValue; 80 } 81 }, 82 commonEventProcessors = CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, 83 { 84 onChange : function( dialog, func ) 85 { 86 if ( !this._.domOnChangeRegistered ) 87 { 88 dialog.on( 'load', function() 89 { 90 this.getInputElement().on( 'change', function() 91 { 92 // Make sure 'onchange' doesn't get fired after dialog closed. (#5719) 93 if ( !dialog.parts.dialog.isVisible() ) 94 return; 95 96 this.fire( 'change', { value : this.getValue() } ); 97 }, this ); 98 }, this ); 99 this._.domOnChangeRegistered = true; 100 } 101 102 this.on( 'change', func ); 103 } 104 }, true ), 105 eventRegex = /^on([A-Z]\w+)/, 106 cleanInnerDefinition = function( def ) 107 { 108 // An inner UI element should not have the parent's type, title or events. 109 for ( var i in def ) 110 { 111 if ( eventRegex.test( i ) || i == 'title' || i == 'type' ) 112 delete def[i]; 113 } 114 return def; 115 }; 116 117 CKEDITOR.tools.extend( CKEDITOR.ui.dialog, 118 /** @lends CKEDITOR.ui.dialog */ 119 { 120 /** 121 * Base class for all dialog elements with a textual label on the left. 122 * @constructor 123 * @example 124 * @extends CKEDITOR.ui.dialog.uiElement 125 * @param {CKEDITOR.dialog} dialog 126 * Parent dialog object. 127 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 128 * The element definition. Accepted fields: 129 * <ul> 130 * <li><strong>label</strong> (Required) The label string.</li> 131 * <li><strong>labelLayout</strong> (Optional) Put 'horizontal' here if the 132 * label element is to be layed out horizontally. Otherwise a vertical 133 * layout will be used.</li> 134 * <li><strong>widths</strong> (Optional) This applies only for horizontal 135 * layouts - an 2-element array of lengths to specify the widths of the 136 * label and the content element.</li> 137 * </ul> 138 * @param {Array} htmlList 139 * List of HTML code to output to. 140 * @param {Function} contentHtml 141 * A function returning the HTML code string to be added inside the content 142 * cell. 143 */ 144 labeledElement : function( dialog, elementDefinition, htmlList, contentHtml ) 145 { 146 if ( arguments.length < 4 ) 147 return; 148 149 var _ = initPrivateObject.call( this, elementDefinition ); 150 _.labelId = CKEDITOR.tools.getNextId() + '_label'; 151 var children = this._.children = []; 152 /** @ignore */ 153 var innerHTML = function() 154 { 155 var html = [], 156 requiredClass = elementDefinition.required ? ' cke_required' : '' ; 157 if ( elementDefinition.labelLayout != 'horizontal' ) 158 html.push( '<label class="cke_dialog_ui_labeled_label' + requiredClass + '" ', 159 ' id="'+ _.labelId + '"', 160 ' for="' + _.inputId + '"', 161 ' style="' + elementDefinition.labelStyle + '">', 162 elementDefinition.label, 163 '</label>', 164 '<div class="cke_dialog_ui_labeled_content" role="presentation">', 165 contentHtml.call( this, dialog, elementDefinition ), 166 '</div>' ); 167 else 168 { 169 var hboxDefinition = { 170 type : 'hbox', 171 widths : elementDefinition.widths, 172 padding : 0, 173 children : 174 [ 175 { 176 type : 'html', 177 html : '<label class="cke_dialog_ui_labeled_label' + requiredClass + '"' + 178 ' id="' + _.labelId + '"' + 179 ' for="' + _.inputId + '"' + 180 ' style="' + elementDefinition.labelStyle + '">' + 181 CKEDITOR.tools.htmlEncode( elementDefinition.label ) + 182 '</span>' 183 }, 184 { 185 type : 'html', 186 html : '<span class="cke_dialog_ui_labeled_content">' + 187 contentHtml.call( this, dialog, elementDefinition ) + 188 '</span>' 189 } 190 ] 191 }; 192 CKEDITOR.dialog._.uiElementBuilders.hbox.build( dialog, hboxDefinition, html ); 193 } 194 return html.join( '' ); 195 }; 196 CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, { role : 'presentation' }, innerHTML ); 197 }, 198 199 /** 200 * A text input with a label. This UI element class represents both the 201 * single-line text inputs and password inputs in dialog boxes. 202 * @constructor 203 * @example 204 * @extends CKEDITOR.ui.dialog.labeledElement 205 * @param {CKEDITOR.dialog} dialog 206 * Parent dialog object. 207 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 208 * The element definition. Accepted fields: 209 * <ul> 210 * <li><strong>default</strong> (Optional) The default value.</li> 211 * <li><strong>validate</strong> (Optional) The validation function. </li> 212 * <li><strong>maxLength</strong> (Optional) The maximum length of text box 213 * contents.</li> 214 * <li><strong>size</strong> (Optional) The size of the text box. This is 215 * usually overridden by the size defined by the skin, however.</li> 216 * </ul> 217 * @param {Array} htmlList 218 * List of HTML code to output to. 219 */ 220 textInput : function( dialog, elementDefinition, htmlList ) 221 { 222 if ( arguments.length < 3 ) 223 return; 224 225 initPrivateObject.call( this, elementDefinition ); 226 var domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textInput', 227 attributes = { 'class' : 'cke_dialog_ui_input_' + elementDefinition.type, id : domId, type : 'text' }, 228 i; 229 230 // Set the validator, if any. 231 if ( elementDefinition.validate ) 232 this.validate = elementDefinition.validate; 233 234 // Set the max length and size. 235 if ( elementDefinition.maxLength ) 236 attributes.maxlength = elementDefinition.maxLength; 237 if ( elementDefinition.size ) 238 attributes.size = elementDefinition.size; 239 240 if ( elementDefinition.controlStyle ) 241 attributes.style = elementDefinition.controlStyle; 242 243 // If user presses Enter in a text box, it implies clicking OK for the dialog. 244 var me = this, keyPressedOnMe = false; 245 dialog.on( 'load', function() 246 { 247 me.getInputElement().on( 'keydown', function( evt ) 248 { 249 if ( evt.data.getKeystroke() == 13 ) 250 keyPressedOnMe = true; 251 } ); 252 253 // Lower the priority this 'keyup' since 'ok' will close the dialog.(#3749) 254 me.getInputElement().on( 'keyup', function( evt ) 255 { 256 if ( evt.data.getKeystroke() == 13 && keyPressedOnMe ) 257 { 258 dialog.getButton( 'ok' ) && setTimeout( function () 259 { 260 dialog.getButton( 'ok' ).click(); 261 }, 0 ); 262 keyPressedOnMe = false; 263 } 264 }, null, null, 1000 ); 265 } ); 266 267 /** @ignore */ 268 var innerHTML = function() 269 { 270 // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline 271 // container's width, so need to wrap it inside a <div>. 272 var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ]; 273 274 if ( elementDefinition.width ) 275 html.push( 'style="width:'+ elementDefinition.width +'" ' ); 276 277 html.push( '><input ' ); 278 279 attributes[ 'aria-labelledby' ] = this._.labelId; 280 this._.required && ( attributes[ 'aria-required' ] = this._.required ); 281 for ( var i in attributes ) 282 html.push( i + '="' + attributes[i] + '" ' ); 283 html.push( ' /></div>' ); 284 return html.join( '' ); 285 }; 286 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); 287 }, 288 289 /** 290 * A text area with a label on the top or left. 291 * @constructor 292 * @extends CKEDITOR.ui.dialog.labeledElement 293 * @example 294 * @param {CKEDITOR.dialog} dialog 295 * Parent dialog object. 296 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 297 * The element definition. Accepted fields: 298 * <ul> 299 * <li><strong>rows</strong> (Optional) The number of rows displayed. 300 * Defaults to 5 if not defined.</li> 301 * <li><strong>cols</strong> (Optional) The number of cols displayed. 302 * Defaults to 20 if not defined. Usually overridden by skins.</li> 303 * <li><strong>default</strong> (Optional) The default value.</li> 304 * <li><strong>validate</strong> (Optional) The validation function. </li> 305 * </ul> 306 * @param {Array} htmlList 307 * List of HTML code to output to. 308 */ 309 textarea : function( dialog, elementDefinition, htmlList ) 310 { 311 if ( arguments.length < 3 ) 312 return; 313 314 initPrivateObject.call( this, elementDefinition ); 315 var me = this, 316 domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textarea', 317 attributes = {}; 318 319 if ( elementDefinition.validate ) 320 this.validate = elementDefinition.validate; 321 322 // Generates the essential attributes for the textarea tag. 323 attributes.rows = elementDefinition.rows || 5; 324 attributes.cols = elementDefinition.cols || 20; 325 326 /** @ignore */ 327 var innerHTML = function() 328 { 329 attributes[ 'aria-labelledby' ] = this._.labelId; 330 this._.required && ( attributes[ 'aria-required' ] = this._.required ); 331 var html = [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea class="cke_dialog_ui_input_textarea" id="', domId, '" ' ]; 332 for ( var i in attributes ) 333 html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '" ' ); 334 html.push( '>', CKEDITOR.tools.htmlEncode( me._['default'] ), '</textarea></div>' ); 335 return html.join( '' ); 336 }; 337 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); 338 }, 339 340 /** 341 * A single checkbox with a label on the right. 342 * @constructor 343 * @extends CKEDITOR.ui.dialog.uiElement 344 * @example 345 * @param {CKEDITOR.dialog} dialog 346 * Parent dialog object. 347 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 348 * The element definition. Accepted fields: 349 * <ul> 350 * <li><strong>checked</strong> (Optional) Whether the checkbox is checked 351 * on instantiation. Defaults to false.</li> 352 * <li><strong>validate</strong> (Optional) The validation function.</li> 353 * <li><strong>label</strong> (Optional) The checkbox label.</li> 354 * </ul> 355 * @param {Array} htmlList 356 * List of HTML code to output to. 357 */ 358 checkbox : function( dialog, elementDefinition, htmlList ) 359 { 360 if ( arguments.length < 3 ) 361 return; 362 363 var _ = initPrivateObject.call( this, elementDefinition, { 'default' : !!elementDefinition[ 'default' ] } ); 364 365 if ( elementDefinition.validate ) 366 this.validate = elementDefinition.validate; 367 368 /** @ignore */ 369 var innerHTML = function() 370 { 371 var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition, 372 { 373 id : elementDefinition.id ? elementDefinition.id + '_checkbox' : CKEDITOR.tools.getNextId() + '_checkbox' 374 }, true ), 375 html = []; 376 377 var labelId = CKEDITOR.tools.getNextId() + '_label'; 378 var attributes = { 'class' : 'cke_dialog_ui_checkbox_input', type : 'checkbox', 'aria-labelledby' : labelId }; 379 cleanInnerDefinition( myDefinition ); 380 if ( elementDefinition[ 'default' ] ) 381 attributes.checked = 'checked'; 382 383 if (typeof myDefinition.controlStyle != 'undefined') 384 myDefinition.style = myDefinition.controlStyle; 385 386 _.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes ); 387 html.push( ' <label id="', labelId, '" for="', attributes.id, '">', 388 CKEDITOR.tools.htmlEncode( elementDefinition.label ), 389 '</label>' ); 390 return html.join( '' ); 391 }; 392 393 CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'span', null, null, innerHTML ); 394 }, 395 396 /** 397 * A group of radio buttons. 398 * @constructor 399 * @example 400 * @extends CKEDITOR.ui.dialog.labeledElement 401 * @param {CKEDITOR.dialog} dialog 402 * Parent dialog object. 403 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 404 * The element definition. Accepted fields: 405 * <ul> 406 * <li><strong>default</strong> (Required) The default value.</li> 407 * <li><strong>validate</strong> (Optional) The validation function.</li> 408 * <li><strong>items</strong> (Required) An array of options. Each option 409 * is a 1- or 2-item array of format [ 'Description', 'Value' ]. If 'Value' 410 * is missing, then the value would be assumed to be the same as the 411 * description.</li> 412 * </ul> 413 * @param {Array} htmlList 414 * List of HTML code to output to. 415 */ 416 radio : function( dialog, elementDefinition, htmlList ) 417 { 418 if ( arguments.length < 3) 419 return; 420 421 initPrivateObject.call( this, elementDefinition ); 422 if ( !this._['default'] ) 423 this._['default'] = this._.initValue = elementDefinition.items[0][1]; 424 if ( elementDefinition.validate ) 425 this.validate = elementDefinition.valdiate; 426 var children = [], me = this; 427 428 /** @ignore */ 429 var innerHTML = function() 430 { 431 var inputHtmlList = [], html = [], 432 commonAttributes = { 'class' : 'cke_dialog_ui_radio_item', 'aria-labelledby' : this._.labelId }, 433 commonName = elementDefinition.id ? elementDefinition.id + '_radio' : CKEDITOR.tools.getNextId() + '_radio'; 434 for ( var i = 0 ; i < elementDefinition.items.length ; i++ ) 435 { 436 var item = elementDefinition.items[i], 437 title = item[2] !== undefined ? item[2] : item[0], 438 value = item[1] !== undefined ? item[1] : item[0], 439 inputId = CKEDITOR.tools.getNextId() + '_radio_input', 440 labelId = inputId + '_label', 441 inputDefinition = CKEDITOR.tools.extend( {}, elementDefinition, 442 { 443 id : inputId, 444 title : null, 445 type : null 446 }, true ), 447 labelDefinition = CKEDITOR.tools.extend( {}, inputDefinition, 448 { 449 title : title 450 }, true ), 451 inputAttributes = 452 { 453 type : 'radio', 454 'class' : 'cke_dialog_ui_radio_input', 455 name : commonName, 456 value : value, 457 'aria-labelledby' : labelId 458 }, 459 inputHtml = []; 460 if ( me._['default'] == value ) 461 inputAttributes.checked = 'checked'; 462 cleanInnerDefinition( inputDefinition ); 463 cleanInnerDefinition( labelDefinition ); 464 465 if (typeof inputDefinition.controlStyle != 'undefined') 466 inputDefinition.style = inputDefinition.controlStyle; 467 468 children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) ); 469 inputHtml.push( ' ' ); 470 new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { id : labelId, 'for' : inputAttributes.id }, 471 item[0] ); 472 inputHtmlList.push( inputHtml.join( '' ) ); 473 } 474 new CKEDITOR.ui.dialog.hbox( dialog, [], inputHtmlList, html ); 475 return html.join( '' ); 476 }; 477 478 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); 479 this._.children = children; 480 }, 481 482 /** 483 * A button with a label inside. 484 * @constructor 485 * @example 486 * @extends CKEDITOR.ui.dialog.uiElement 487 * @param {CKEDITOR.dialog} dialog 488 * Parent dialog object. 489 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 490 * The element definition. Accepted fields: 491 * <ul> 492 * <li><strong>label</strong> (Required) The button label.</li> 493 * <li><strong>disabled</strong> (Optional) Set to true if you want the 494 * button to appear in disabled state.</li> 495 * </ul> 496 * @param {Array} htmlList 497 * List of HTML code to output to. 498 */ 499 button : function( dialog, elementDefinition, htmlList ) 500 { 501 if ( !arguments.length ) 502 return; 503 504 if ( typeof elementDefinition == 'function' ) 505 elementDefinition = elementDefinition( dialog.getParentEditor() ); 506 507 initPrivateObject.call( this, elementDefinition, { disabled : elementDefinition.disabled || false } ); 508 509 // Add OnClick event to this input. 510 CKEDITOR.event.implementOn( this ); 511 512 var me = this; 513 514 // Register an event handler for processing button clicks. 515 dialog.on( 'load', function( eventInfo ) 516 { 517 var element = this.getElement(); 518 519 (function() 520 { 521 element.on( 'click', function( evt ) 522 { 523 me.fire( 'click', { dialog : me.getDialog() } ); 524 evt.data.preventDefault(); 525 } ); 526 527 element.on( 'keydown', function( evt ) 528 { 529 if ( evt.data.getKeystroke() in { 32:1 } ) 530 { 531 me.click(); 532 evt.data.preventDefault(); 533 } 534 } ); 535 })(); 536 537 element.unselectable(); 538 }, this ); 539 540 var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition ); 541 delete outerDefinition.style; 542 543 var labelId = CKEDITOR.tools.getNextId() + '_label'; 544 CKEDITOR.ui.dialog.uiElement.call( 545 this, 546 dialog, 547 outerDefinition, 548 htmlList, 549 'a', 550 null, 551 { 552 style : elementDefinition.style, 553 href : 'javascript:void(0)', 554 title : elementDefinition.label, 555 hidefocus : 'true', 556 'class' : elementDefinition['class'], 557 role : 'button', 558 'aria-labelledby' : labelId 559 }, 560 '<span id="' + labelId + '" class="cke_dialog_ui_button">' + 561 CKEDITOR.tools.htmlEncode( elementDefinition.label ) + 562 '</span>' ); 563 }, 564 565 /** 566 * A select box. 567 * @extends CKEDITOR.ui.dialog.uiElement 568 * @example 569 * @constructor 570 * @param {CKEDITOR.dialog} dialog 571 * Parent dialog object. 572 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 573 * The element definition. Accepted fields: 574 * <ul> 575 * <li><strong>default</strong> (Required) The default value.</li> 576 * <li><strong>validate</strong> (Optional) The validation function.</li> 577 * <li><strong>items</strong> (Required) An array of options. Each option 578 * is a 1- or 2-item array of format [ 'Description', 'Value' ]. If 'Value' 579 * is missing, then the value would be assumed to be the same as the 580 * description.</li> 581 * <li><strong>multiple</strong> (Optional) Set this to true if you'd like 582 * to have a multiple-choice select box.</li> 583 * <li><strong>size</strong> (Optional) The number of items to display in 584 * the select box.</li> 585 * </ul> 586 * @param {Array} htmlList 587 * List of HTML code to output to. 588 */ 589 select : function( dialog, elementDefinition, htmlList ) 590 { 591 if ( arguments.length < 3 ) 592 return; 593 594 var _ = initPrivateObject.call( this, elementDefinition ); 595 596 if ( elementDefinition.validate ) 597 this.validate = elementDefinition.validate; 598 599 _.inputId = CKEDITOR.tools.getNextId() + '_select'; 600 /** @ignore */ 601 var innerHTML = function() 602 { 603 var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition, 604 { 605 id : elementDefinition.id ? elementDefinition.id + '_select' : CKEDITOR.tools.getNextId() + '_select' 606 }, true ), 607 html = [], 608 innerHTML = [], 609 attributes = { 'id' : _.inputId, 'class' : 'cke_dialog_ui_input_select', 'aria-labelledby' : this._.labelId }; 610 611 // Add multiple and size attributes from element definition. 612 if ( elementDefinition.size != undefined ) 613 attributes.size = elementDefinition.size; 614 if ( elementDefinition.multiple != undefined ) 615 attributes.multiple = elementDefinition.multiple; 616 617 cleanInnerDefinition( myDefinition ); 618 for ( var i = 0, item ; i < elementDefinition.items.length && ( item = elementDefinition.items[i] ) ; i++ ) 619 { 620 innerHTML.push( '<option value="', 621 CKEDITOR.tools.htmlEncode( item[1] !== undefined ? item[1] : item[0] ), '" /> ', 622 CKEDITOR.tools.htmlEncode( item[0] ) ); 623 } 624 625 if (typeof myDefinition.controlStyle != 'undefined') 626 myDefinition.style = myDefinition.controlStyle; 627 628 _.select = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'select', null, attributes, innerHTML.join( '' ) ); 629 return html.join( '' ); 630 }; 631 632 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); 633 }, 634 635 /** 636 * A file upload input. 637 * @extends CKEDITOR.ui.dialog.labeledElement 638 * @example 639 * @constructor 640 * @param {CKEDITOR.dialog} dialog 641 * Parent dialog object. 642 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 643 * The element definition. Accepted fields: 644 * <ul> 645 * <li><strong>validate</strong> (Optional) The validation function.</li> 646 * </ul> 647 * @param {Array} htmlList 648 * List of HTML code to output to. 649 */ 650 file : function( dialog, elementDefinition, htmlList ) 651 { 652 if ( arguments.length < 3 ) 653 return; 654 655 if ( elementDefinition['default'] === undefined ) 656 elementDefinition['default'] = ''; 657 658 var _ = CKEDITOR.tools.extend( initPrivateObject.call( this, elementDefinition ), { definition : elementDefinition, buttons : [] } ); 659 660 if ( elementDefinition.validate ) 661 this.validate = elementDefinition.validate; 662 663 /** @ignore */ 664 var innerHTML = function() 665 { 666 _.frameId = CKEDITOR.tools.getNextId() + '_fileInput'; 667 668 // Support for custom document.domain in IE. 669 var isCustomDomain = CKEDITOR.env.isCustomDomain(); 670 671 var html = [ 672 '<iframe' + 673 ' frameborder="0"' + 674 ' allowtransparency="0"' + 675 ' class="cke_dialog_ui_input_file"' + 676 ' id="', _.frameId, '"' + 677 ' title="', elementDefinition.label, '"' + 678 ' src="javascript:void(' ]; 679 680 html.push( 681 isCustomDomain ? 682 '(function(){' + 683 'document.open();' + 684 'document.domain=\'' + document.domain + '\';' + 685 'document.close();' + 686 '})()' 687 : 688 '0' ); 689 690 html.push( 691 ')">' + 692 '</iframe>' ); 693 694 return html.join( '' ); 695 }; 696 697 // IE BUG: Parent container does not resize to contain the iframe automatically. 698 dialog.on( 'load', function() 699 { 700 var iframe = CKEDITOR.document.getById( _.frameId ), 701 contentDiv = iframe.getParent(); 702 contentDiv.addClass( 'cke_dialog_ui_input_file' ); 703 } ); 704 705 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML ); 706 }, 707 708 /** 709 * A button for submitting the file in a file upload input. 710 * @extends CKEDITOR.ui.dialog.button 711 * @example 712 * @constructor 713 * @param {CKEDITOR.dialog} dialog 714 * Parent dialog object. 715 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 716 * The element definition. Accepted fields: 717 * <ul> 718 * <li><strong>for</strong> (Required) The file input's page and element Id 719 * to associate to, in a 2-item array format: [ 'page_id', 'element_id' ]. 720 * </li> 721 * <li><strong>validate</strong> (Optional) The validation function.</li> 722 * </ul> 723 * @param {Array} htmlList 724 * List of HTML code to output to. 725 */ 726 fileButton : function( dialog, elementDefinition, htmlList ) 727 { 728 if ( arguments.length < 3 ) 729 return; 730 731 var _ = initPrivateObject.call( this, elementDefinition ), 732 me = this; 733 734 if ( elementDefinition.validate ) 735 this.validate = elementDefinition.validate; 736 737 var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition ); 738 var onClick = myDefinition.onClick; 739 myDefinition.className = ( myDefinition.className ? myDefinition.className + ' ' : '' ) + 'cke_dialog_ui_button'; 740 myDefinition.onClick = function( evt ) 741 { 742 var target = elementDefinition[ 'for' ]; // [ pageId, elementId ] 743 if ( !onClick || onClick.call( this, evt ) !== false ) 744 { 745 dialog.getContentElement( target[0], target[1] ).submit(); 746 this.disable(); 747 } 748 }; 749 750 dialog.on( 'load', function() 751 { 752 dialog.getContentElement( elementDefinition[ 'for' ][0], elementDefinition[ 'for' ][1] )._.buttons.push( me ); 753 } ); 754 755 CKEDITOR.ui.dialog.button.call( this, dialog, myDefinition, htmlList ); 756 }, 757 758 html : (function() 759 { 760 var myHtmlRe = /^\s*<[\w:]+\s+([^>]*)?>/, 761 theirHtmlRe = /^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/, 762 emptyTagRe = /\/$/; 763 /** 764 * A dialog element made from raw HTML code. 765 * @extends CKEDITOR.ui.dialog.uiElement 766 * @name CKEDITOR.ui.dialog.html 767 * @param {CKEDITOR.dialog} dialog Parent dialog object. 768 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition Element definition. 769 * Accepted fields: 770 * <ul> 771 * <li><strong>html</strong> (Required) HTML code of this element.</li> 772 * </ul> 773 * @param {Array} htmlList List of HTML code to be added to the dialog's content area. 774 * @example 775 * @constructor 776 */ 777 return function( dialog, elementDefinition, htmlList ) 778 { 779 if ( arguments.length < 3 ) 780 return; 781 782 var myHtmlList = [], 783 myHtml, 784 theirHtml = elementDefinition.html, 785 myMatch, theirMatch; 786 787 // If the HTML input doesn't contain any tags at the beginning, add a <span> tag around it. 788 if ( theirHtml.charAt( 0 ) != '<' ) 789 theirHtml = '<span>' + theirHtml + '</span>'; 790 791 // Look for focus function in definition. 792 var focus = elementDefinition.focus; 793 if ( focus ) 794 { 795 var oldFocus = this.focus; 796 this.focus = function() 797 { 798 oldFocus.call( this ); 799 typeof focus == 'function' && focus.call( this ); 800 this.fire( 'focus' ); 801 }; 802 if ( elementDefinition.isFocusable ) 803 { 804 var oldIsFocusable = this.isFocusable; 805 this.isFocusable = oldIsFocusable; 806 } 807 this.keyboardFocusable = true; 808 } 809 810 CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, myHtmlList, 'span', null, null, '' ); 811 812 // Append the attributes created by the uiElement call to the real HTML. 813 myHtml = myHtmlList.join( '' ); 814 myMatch = myHtml.match( myHtmlRe ); 815 theirMatch = theirHtml.match( theirHtmlRe ) || [ '', '', '' ]; 816 817 if ( emptyTagRe.test( theirMatch[1] ) ) 818 { 819 theirMatch[1] = theirMatch[1].slice( 0, -1 ); 820 theirMatch[2] = '/' + theirMatch[2]; 821 } 822 823 htmlList.push( [ theirMatch[1], ' ', myMatch[1] || '', theirMatch[2] ].join( '' ) ); 824 }; 825 })(), 826 827 /** 828 * Form fieldset for grouping dialog UI elements. 829 * @constructor 830 * @extends CKEDITOR.ui.dialog.uiElement 831 * @param {CKEDITOR.dialog} dialog Parent dialog object. 832 * @param {Array} childObjList 833 * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this 834 * container. 835 * @param {Array} childHtmlList 836 * Array of HTML code that correspond to the HTML output of all the 837 * objects in childObjList. 838 * @param {Array} htmlList 839 * Array of HTML code that this element will output to. 840 * @param {CKEDITOR.dialog.uiElementDefinition} elementDefinition 841 * The element definition. Accepted fields: 842 * <ul> 843 * <li><strong>label</strong> (Optional) The legend of the this fieldset.</li> 844 * <li><strong>children</strong> (Required) An array of dialog field definitions which will be grouped inside this fieldset. </li> 845 * </ul> 846 */ 847 fieldset : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) 848 { 849 var legendLabel = elementDefinition.label; 850 /** @ignore */ 851 var innerHTML = function() 852 { 853 var html = []; 854 legendLabel && html.push( '<legend>' + legendLabel + '</legend>' ); 855 for ( var i = 0; i < childHtmlList.length; i++ ) 856 html.push( childHtmlList[ i ] ); 857 return html.join( '' ); 858 }; 859 860 this._ = { children : childObjList }; 861 CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'fieldset', null, null, innerHTML ); 862 } 863 864 }, true ); 865 866 CKEDITOR.ui.dialog.html.prototype = new CKEDITOR.ui.dialog.uiElement; 867 868 CKEDITOR.ui.dialog.labeledElement.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, 869 /** @lends CKEDITOR.ui.dialog.labeledElement.prototype */ 870 { 871 /** 872 * Sets the label text of the element. 873 * @param {String} label The new label text. 874 * @returns {CKEDITOR.ui.dialog.labeledElement} The current labeled element. 875 * @example 876 */ 877 setLabel : function( label ) 878 { 879 var node = CKEDITOR.document.getById( this._.labelId ); 880 if ( node.getChildCount() < 1 ) 881 ( new CKEDITOR.dom.text( label, CKEDITOR.document ) ).appendTo( node ); 882 else 883 node.getChild( 0 ).$.nodeValue = label; 884 return this; 885 }, 886 887 /** 888 * Retrieves the current label text of the elment. 889 * @returns {String} The current label text. 890 * @example 891 */ 892 getLabel : function() 893 { 894 var node = CKEDITOR.document.getById( this._.labelId ); 895 if ( !node || node.getChildCount() < 1 ) 896 return ''; 897 else 898 return node.getChild( 0 ).getText(); 899 }, 900 901 /** 902 * Defines the onChange event for UI element definitions. 903 * @field 904 * @type Object 905 * @example 906 */ 907 eventProcessors : commonEventProcessors 908 }, true ); 909 910 CKEDITOR.ui.dialog.button.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, 911 /** @lends CKEDITOR.ui.dialog.button.prototype */ 912 { 913 /** 914 * Simulates a click to the button. 915 * @example 916 * @returns {Object} Return value of the 'click' event. 917 */ 918 click : function() 919 { 920 if ( !this._.disabled ) 921 return this.fire( 'click', { dialog : this._.dialog } ); 922 this.getElement().$.blur(); 923 return false; 924 }, 925 926 /** 927 * Enables the button. 928 * @example 929 */ 930 enable : function() 931 { 932 this._.disabled = false; 933 var element = this.getElement(); 934 element && element.removeClass( 'disabled' ); 935 }, 936 937 /** 938 * Disables the button. 939 * @example 940 */ 941 disable : function() 942 { 943 this._.disabled = true; 944 this.getElement().addClass( 'disabled' ); 945 }, 946 947 isVisible : function() 948 { 949 return this.getElement().getFirst().isVisible(); 950 }, 951 952 isEnabled : function() 953 { 954 return !this._.disabled; 955 }, 956 957 /** 958 * Defines the onChange event and onClick for button element definitions. 959 * @field 960 * @type Object 961 * @example 962 */ 963 eventProcessors : CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, 964 { 965 /** @ignore */ 966 onClick : function( dialog, func ) 967 { 968 this.on( 'click', func ); 969 } 970 }, true ), 971 972 /** 973 * Handler for the element's access key up event. Simulates a click to 974 * the button. 975 * @example 976 */ 977 accessKeyUp : function() 978 { 979 this.click(); 980 }, 981 982 /** 983 * Handler for the element's access key down event. Simulates a mouse 984 * down to the button. 985 * @example 986 */ 987 accessKeyDown : function() 988 { 989 this.focus(); 990 }, 991 992 keyboardFocusable : true 993 }, true ); 994 995 CKEDITOR.ui.dialog.textInput.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, 996 /** @lends CKEDITOR.ui.dialog.textInput.prototype */ 997 { 998 /** 999 * Gets the text input DOM element under this UI object. 1000 * @example 1001 * @returns {CKEDITOR.dom.element} The DOM element of the text input. 1002 */ 1003 getInputElement : function() 1004 { 1005 return CKEDITOR.document.getById( this._.inputId ); 1006 }, 1007 1008 /** 1009 * Puts focus into the text input. 1010 * @example 1011 */ 1012 focus : function() 1013 { 1014 var me = this.selectParentTab(); 1015 1016 // GECKO BUG: setTimeout() is needed to workaround invisible selections. 1017 setTimeout( function() 1018 { 1019 var element = me.getInputElement(); 1020 element && element.$.focus(); 1021 }, 0 ); 1022 }, 1023 1024 /** 1025 * Selects all the text in the text input. 1026 * @example 1027 */ 1028 select : function() 1029 { 1030 var me = this.selectParentTab(); 1031 1032 // GECKO BUG: setTimeout() is needed to workaround invisible selections. 1033 setTimeout( function() 1034 { 1035 var e = me.getInputElement(); 1036 if ( e ) 1037 { 1038 e.$.focus(); 1039 e.$.select(); 1040 } 1041 }, 0 ); 1042 }, 1043 1044 /** 1045 * Handler for the text input's access key up event. Makes a select() 1046 * call to the text input. 1047 * @example 1048 */ 1049 accessKeyUp : function() 1050 { 1051 this.select(); 1052 }, 1053 1054 /** 1055 * Sets the value of this text input object. 1056 * @param {Object} value The new value. 1057 * @returns {CKEDITOR.ui.dialog.textInput} The current UI element. 1058 * @example 1059 * uiElement.setValue( 'Blamo' ); 1060 */ 1061 setValue : function( value ) 1062 { 1063 !value && ( value = '' ); 1064 return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments ); 1065 }, 1066 1067 keyboardFocusable : true 1068 }, commonPrototype, true ); 1069 1070 CKEDITOR.ui.dialog.textarea.prototype = new CKEDITOR.ui.dialog.textInput(); 1071 1072 CKEDITOR.ui.dialog.select.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, 1073 /** @lends CKEDITOR.ui.dialog.select.prototype */ 1074 { 1075 /** 1076 * Gets the DOM element of the select box. 1077 * @returns {CKEDITOR.dom.element} The <select> element of this UI 1078 * element. 1079 * @example 1080 */ 1081 getInputElement : function() 1082 { 1083 return this._.select.getElement(); 1084 }, 1085 1086 /** 1087 * Adds an option to the select box. 1088 * @param {String} label Option label. 1089 * @param {String} value (Optional) Option value, if not defined it'll be 1090 * assumed to be the same as the label. 1091 * @param {Number} index (Optional) Position of the option to be inserted 1092 * to. If not defined the new option will be inserted to the end of list. 1093 * @example 1094 * @returns {CKEDITOR.ui.dialog.select} The current select UI element. 1095 */ 1096 add : function( label, value, index ) 1097 { 1098 var option = new CKEDITOR.dom.element( 'option', this.getDialog().getParentEditor().document ), 1099 selectElement = this.getInputElement().$; 1100 option.$.text = label; 1101 option.$.value = ( value === undefined || value === null ) ? label : value; 1102 if ( index === undefined || index === null ) 1103 { 1104 if ( CKEDITOR.env.ie ) 1105 selectElement.add( option.$ ); 1106 else 1107 selectElement.add( option.$, null ); 1108 } 1109 else 1110 selectElement.add( option.$, index ); 1111 return this; 1112 }, 1113 1114 /** 1115 * Removes an option from the selection list. 1116 * @param {Number} index Index of the option to be removed. 1117 * @example 1118 * @returns {CKEDITOR.ui.dialog.select} The current select UI element. 1119 */ 1120 remove : function( index ) 1121 { 1122 var selectElement = this.getInputElement().$; 1123 selectElement.remove( index ); 1124 return this; 1125 }, 1126 1127 /** 1128 * Clears all options out of the selection list. 1129 * @returns {CKEDITOR.ui.dialog.select} The current select UI element. 1130 */ 1131 clear : function() 1132 { 1133 var selectElement = this.getInputElement().$; 1134 while ( selectElement.length > 0 ) 1135 selectElement.remove( 0 ); 1136 return this; 1137 }, 1138 1139 keyboardFocusable : true 1140 }, commonPrototype, true ); 1141 1142 CKEDITOR.ui.dialog.checkbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, 1143 /** @lends CKEDITOR.ui.dialog.checkbox.prototype */ 1144 { 1145 /** 1146 * Gets the checkbox DOM element. 1147 * @example 1148 * @returns {CKEDITOR.dom.element} The DOM element of the checkbox. 1149 */ 1150 getInputElement : function() 1151 { 1152 return this._.checkbox.getElement(); 1153 }, 1154 1155 /** 1156 * Sets the state of the checkbox. 1157 * @example 1158 * @param {Boolean} true to tick the checkbox, false to untick it. 1159 * @param {Boolean} noChangeEvent Internal commit, to supress 'change' event on this element. 1160 */ 1161 setValue : function( checked, noChangeEvent ) 1162 { 1163 this.getInputElement().$.checked = checked; 1164 !noChangeEvent && this.fire( 'change', { value : checked } ); 1165 }, 1166 1167 /** 1168 * Gets the state of the checkbox. 1169 * @example 1170 * @returns {Boolean} true means the checkbox is ticked, false means it's not ticked. 1171 */ 1172 getValue : function() 1173 { 1174 return this.getInputElement().$.checked; 1175 }, 1176 1177 /** 1178 * Handler for the access key up event. Toggles the checkbox. 1179 * @example 1180 */ 1181 accessKeyUp : function() 1182 { 1183 this.setValue( !this.getValue() ); 1184 }, 1185 1186 /** 1187 * Defines the onChange event for UI element definitions. 1188 * @field 1189 * @type Object 1190 * @example 1191 */ 1192 eventProcessors : 1193 { 1194 onChange : function( dialog, func ) 1195 { 1196 if ( !CKEDITOR.env.ie ) 1197 return commonEventProcessors.onChange.apply( this, arguments ); 1198 else 1199 { 1200 dialog.on( 'load', function() 1201 { 1202 var element = this._.checkbox.getElement(); 1203 element.on( 'propertychange', function( evt ) 1204 { 1205 evt = evt.data.$; 1206 if ( evt.propertyName == 'checked' ) 1207 this.fire( 'change', { value : element.$.checked } ); 1208 }, this ); 1209 }, this ); 1210 this.on( 'change', func ); 1211 } 1212 return null; 1213 } 1214 }, 1215 1216 keyboardFocusable : true 1217 }, commonPrototype, true ); 1218 1219 CKEDITOR.ui.dialog.radio.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement, 1220 /** @lends CKEDITOR.ui.dialog.radio.prototype */ 1221 { 1222 /** 1223 * Checks one of the radio buttons in this button group. 1224 * @example 1225 * @param {String} value The value of the button to be chcked. 1226 * @param {Boolean} noChangeEvent Internal commit, to supress 'change' event on this element. 1227 */ 1228 setValue : function( value, noChangeEvent ) 1229 { 1230 var children = this._.children, 1231 item; 1232 for ( var i = 0 ; ( i < children.length ) && ( item = children[i] ) ; i++ ) 1233 item.getElement().$.checked = ( item.getValue() == value ); 1234 !noChangeEvent && this.fire( 'change', { value : value } ); 1235 }, 1236 1237 /** 1238 * Gets the value of the currently checked radio button. 1239 * @example 1240 * @returns {String} The currently checked button's value. 1241 */ 1242 getValue : function() 1243 { 1244 var children = this._.children; 1245 for ( var i = 0 ; i < children.length ; i++ ) 1246 { 1247 if ( children[i].getElement().$.checked ) 1248 return children[i].getValue(); 1249 } 1250 return null; 1251 }, 1252 1253 /** 1254 * Handler for the access key up event. Focuses the currently 1255 * selected radio button, or the first radio button if none is 1256 * selected. 1257 * @example 1258 */ 1259 accessKeyUp : function() 1260 { 1261 var children = this._.children, i; 1262 for ( i = 0 ; i < children.length ; i++ ) 1263 { 1264 if ( children[i].getElement().$.checked ) 1265 { 1266 children[i].getElement().focus(); 1267 return; 1268 } 1269 } 1270 children[0].getElement().focus(); 1271 }, 1272 1273 /** 1274 * Defines the onChange event for UI element definitions. 1275 * @field 1276 * @type Object 1277 * @example 1278 */ 1279 eventProcessors : 1280 { 1281 onChange : function( dialog, func ) 1282 { 1283 if ( !CKEDITOR.env.ie ) 1284 return commonEventProcessors.onChange.apply( this, arguments ); 1285 else 1286 { 1287 dialog.on( 'load', function() 1288 { 1289 var children = this._.children, me = this; 1290 for ( var i = 0 ; i < children.length ; i++ ) 1291 { 1292 var element = children[i].getElement(); 1293 element.on( 'propertychange', function( evt ) 1294 { 1295 evt = evt.data.$; 1296 if ( evt.propertyName == 'checked' && this.$.checked ) 1297 me.fire( 'change', { value : this.getAttribute( 'value' ) } ); 1298 } ); 1299 } 1300 }, this ); 1301 this.on( 'change', func ); 1302 } 1303 return null; 1304 } 1305 }, 1306 1307 keyboardFocusable : true 1308 }, commonPrototype, true ); 1309 1310 CKEDITOR.ui.dialog.file.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement, 1311 commonPrototype, 1312 /** @lends CKEDITOR.ui.dialog.file.prototype */ 1313 { 1314 /** 1315 * Gets the <input> element of this file input. 1316 * @returns {CKEDITOR.dom.element} The file input element. 1317 * @example 1318 */ 1319 getInputElement : function() 1320 { 1321 var frameDocument = CKEDITOR.document.getById( this._.frameId ).getFrameDocument(); 1322 return frameDocument.$.forms.length > 0 ? 1323 new CKEDITOR.dom.element( frameDocument.$.forms[0].elements[0] ) : 1324 this.getElement(); 1325 }, 1326 1327 /** 1328 * Uploads the file in the file input. 1329 * @returns {CKEDITOR.ui.dialog.file} This object. 1330 * @example 1331 */ 1332 submit : function() 1333 { 1334 this.getInputElement().getParent().$.submit(); 1335 return this; 1336 }, 1337 1338 /** 1339 * Get the action assigned to the form. 1340 * @returns {String} The value of the action. 1341 * @example 1342 */ 1343 getAction : function() 1344 { 1345 return this.getInputElement().getParent().$.action; 1346 }, 1347 1348 /** 1349 * The events must be applied on the inner input element, and 1350 * that must be done when the iframe & form has been loaded 1351 */ 1352 registerEvents : function( definition ) 1353 { 1354 var regex = /^on([A-Z]\w+)/, 1355 match; 1356 1357 var registerDomEvent = function( uiElement, dialog, eventName, func ) 1358 { 1359 uiElement.on( 'formLoaded', function() 1360 { 1361 uiElement.getInputElement().on( eventName, func, uiElement ); 1362 }); 1363 }; 1364 1365 for ( var i in definition ) 1366 { 1367 if ( !( match = i.match( regex ) ) ) 1368 continue; 1369 1370 if ( this.eventProcessors[i] ) 1371 this.eventProcessors[i].call( this, this._.dialog, definition[i] ); 1372 else 1373 registerDomEvent( this, this._.dialog, match[1].toLowerCase(), definition[i] ); 1374 } 1375 1376 return this; 1377 }, 1378 1379 /** 1380 * Redraws the file input and resets the file path in the file input. 1381 * The redraw logic is necessary because non-IE browsers tend to clear 1382 * the <iframe> containing the file input after closing the dialog. 1383 * @example 1384 */ 1385 reset : function() 1386 { 1387 var frameElement = CKEDITOR.document.getById( this._.frameId ), 1388 frameDocument = frameElement.getFrameDocument(), 1389 elementDefinition = this._.definition, 1390 buttons = this._.buttons, 1391 callNumber = this.formLoadedNumber, 1392 unloadNumber = this.formUnloadNumber, 1393 langDir = this._.dialog._.editor.lang.dir, 1394 langCode = this._.dialog._.editor.langCode; 1395 1396 // The callback function for the iframe, but we must call tools.addFunction only once 1397 // so we store the function number in this.formLoadedNumber 1398 if (!callNumber) 1399 { 1400 callNumber = this.formLoadedNumber = CKEDITOR.tools.addFunction( 1401 function() 1402 { 1403 // Now we can apply the events to the input type=file 1404 this.fire( 'formLoaded' ) ; 1405 }, this ) ; 1406 1407 // Remove listeners attached to the content of the iframe (the file input) 1408 unloadNumber = this.formUnloadNumber = CKEDITOR.tools.addFunction( 1409 function() 1410 { 1411 this.getInputElement().clearCustomData(); 1412 }, this ) ; 1413 1414 this.getDialog()._.editor.on( 'destroy', function() 1415 { 1416 CKEDITOR.tools.removeFunction( callNumber ); 1417 CKEDITOR.tools.removeFunction( unloadNumber ); 1418 } ); 1419 } 1420 1421 function generateFormField() 1422 { 1423 frameDocument.$.open(); 1424 1425 // Support for custom document.domain in IE. 1426 if ( CKEDITOR.env.isCustomDomain() ) 1427 frameDocument.$.domain = document.domain; 1428 1429 var size = ''; 1430 if ( elementDefinition.size ) 1431 size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE. 1432 1433 frameDocument.$.write( [ '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">', 1434 '<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="', 1435 CKEDITOR.tools.htmlEncode( elementDefinition.action ), 1436 '">', 1437 '<input type="file" name="', 1438 CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ), 1439 '" size="', 1440 CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ), 1441 '" />', 1442 '</form>', 1443 '</body></html>', 1444 '<script>window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');', 1445 'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}</script>' ].join( '' ) ); 1446 1447 frameDocument.$.close(); 1448 1449 for ( var i = 0 ; i < buttons.length ; i++ ) 1450 buttons[i].enable(); 1451 } 1452 1453 // #3465: Wait for the browser to finish rendering the dialog first. 1454 if ( CKEDITOR.env.gecko ) 1455 setTimeout( generateFormField, 500 ); 1456 else 1457 generateFormField(); 1458 }, 1459 1460 getValue : function() 1461 { 1462 return this.getInputElement().$.value; 1463 }, 1464 1465 /*** 1466 * The default value of input type="file" is an empty string, but during initialization 1467 * of this UI element, the iframe still isn't ready so it can't be read from that object 1468 * Setting it manually prevents later issues about the current value ("") being different 1469 * of the initial value (undefined as it asked for .value of a div) 1470 */ 1471 setInitValue : function() 1472 { 1473 this._.initValue = ''; 1474 }, 1475 1476 /** 1477 * Defines the onChange event for UI element definitions. 1478 * @field 1479 * @type Object 1480 * @example 1481 */ 1482 eventProcessors : 1483 { 1484 onChange : function( dialog, func ) 1485 { 1486 // If this method is called several times (I'm not sure about how this can happen but the default 1487 // onChange processor includes this protection) 1488 // In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method 1489 if ( !this._.domOnChangeRegistered ) 1490 { 1491 // By listening for the formLoaded event, this handler will get reapplied when a new 1492 // form is created 1493 this.on( 'formLoaded', function() 1494 { 1495 this.getInputElement().on( 'change', function(){ this.fire( 'change', { value : this.getValue() } ); }, this ); 1496 }, this ); 1497 this._.domOnChangeRegistered = true; 1498 } 1499 1500 this.on( 'change', func ); 1501 } 1502 }, 1503 1504 keyboardFocusable : true 1505 }, true ); 1506 1507 CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button; 1508 1509 CKEDITOR.ui.dialog.fieldset.prototype = CKEDITOR.tools.clone( CKEDITOR.ui.dialog.hbox.prototype ); 1510 1511 CKEDITOR.dialog.addUIElement( 'text', textBuilder ); 1512 CKEDITOR.dialog.addUIElement( 'password', textBuilder ); 1513 CKEDITOR.dialog.addUIElement( 'textarea', commonBuilder ); 1514 CKEDITOR.dialog.addUIElement( 'checkbox', commonBuilder ); 1515 CKEDITOR.dialog.addUIElement( 'radio', commonBuilder ); 1516 CKEDITOR.dialog.addUIElement( 'button', commonBuilder ); 1517 CKEDITOR.dialog.addUIElement( 'select', commonBuilder ); 1518 CKEDITOR.dialog.addUIElement( 'file', commonBuilder ); 1519 CKEDITOR.dialog.addUIElement( 'fileButton', commonBuilder ); 1520 CKEDITOR.dialog.addUIElement( 'html', commonBuilder ); 1521 CKEDITOR.dialog.addUIElement( 'fieldset', containerBuilder ); 1522 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |