]>
git.immae.eu Git - perso/Immae/Projets/packagist/connexionswing-ckeditor-component.git/blob - sources/plugins/dialogui/plugin.js
03fe75388d5216bd4ebe0e7e1657ac758524df45
2 * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
7 * @fileOverview The Dialog User Interface plugin.
10 CKEDITOR
.plugins
.add( 'dialogui', {
13 var initPrivateObject = function( elementDefinition
) {
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
] );
21 CKEDITOR
.tools
.extend
.apply( CKEDITOR
.tools
, args
);
25 build: function( dialog
, elementDefinition
, output
) {
26 return new CKEDITOR
.ui
.dialog
.textInput( dialog
, elementDefinition
, output
);
30 build: function( dialog
, elementDefinition
, output
) {
31 return new CKEDITOR
.ui
.dialog
[ elementDefinition
.type
]( dialog
, elementDefinition
, output
);
35 build: function( dialog
, elementDefinition
, output
) {
36 var children
= elementDefinition
.children
,
41 ( i
< children
.length
&& ( child
= children
[ i
] ) ); i
++ ) {
43 childHtmlList
.push( childHtml
);
44 childObjList
.push( CKEDITOR
.dialog
._
.uiElementBuilders
[ child
.type
].build( dialog
, child
, childHtml
) );
46 return new CKEDITOR
.ui
.dialog
[ elementDefinition
.type
]( dialog
, childObjList
, childHtmlList
, output
, elementDefinition
);
50 isChanged: function() {
51 return this.getValue() != this.getInitValue();
54 reset: function( noChangeEvent
) {
55 this.setValue( this.getInitValue(), noChangeEvent
);
58 setInitValue: function() {
59 this._
.initValue
= this.getValue();
62 resetInitValue: function() {
63 this._
.initValue
= this._
[ 'default' ];
66 getInitValue: function() {
67 return this._
.initValue
;
70 commonEventProcessors
= CKEDITOR
.tools
.extend( {}, CKEDITOR
.ui
.dialog
.uiElement
.prototype.eventProcessors
, {
71 onChange: function( dialog
, func
) {
72 if ( !this._
.domOnChangeRegistered
) {
73 dialog
.on( 'load', function() {
74 this.getInputElement().on( 'change', function() {
75 // Make sure 'onchange' doesn't get fired after dialog closed. (#5719)
76 if ( !dialog
.parts
.dialog
.isVisible() )
79 this.fire( 'change', { value: this.getValue() } );
82 this._
.domOnChangeRegistered
= true;
85 this.on( 'change', func
);
88 eventRegex
= /^on([A-Z]\w+)/,
89 cleanInnerDefinition = function( def
) {
90 // An inner UI element should not have the parent's type, title or events.
91 for ( var i
in def
) {
92 if ( eventRegex
.test( i
) || i
== 'title' || i
== 'type' )
97 // @context {CKEDITOR.dialog.uiElement} UI element (textarea or textInput)
98 // @param {CKEDITOR.dom.event} evt
99 toggleBidiKeyUpHandler = function( evt
) {
100 var keystroke
= evt
.data
.getKeystroke();
102 // ALT + SHIFT + Home for LTR direction.
103 if ( keystroke
== CKEDITOR
.SHIFT
+ CKEDITOR
.ALT
+ 36 )
104 this.setDirectionMarker( 'ltr' );
106 // ALT + SHIFT + End for RTL direction.
107 else if ( keystroke
== CKEDITOR
.SHIFT
+ CKEDITOR
.ALT
+ 35 )
108 this.setDirectionMarker( 'rtl' );
111 CKEDITOR
.tools
.extend( CKEDITOR
.ui
.dialog
, {
113 * Base class for all dialog window elements with a textual label on the left.
115 * @class CKEDITOR.ui.dialog.labeledElement
116 * @extends CKEDITOR.ui.dialog.uiElement
117 * @constructor Creates a labeledElement class instance.
118 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
119 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
120 * The element definition. Accepted fields:
122 * * `label` (Required) The label string.
123 * * `labelLayout` (Optional) Put 'horizontal' here if the
124 * label element is to be laid out horizontally. Otherwise a vertical
125 * layout will be used.
126 * * `widths` (Optional) This applies only to horizontal
127 * layouts — a two-element array of lengths to specify the widths of the
128 * label and the content element.
129 * * `role` (Optional) Value for the `role` attribute.
130 * * `includeLabel` (Optional) If set to `true`, the `aria-labelledby` attribute
133 * @param {Array} htmlList The list of HTML code to output to.
134 * @param {Function} contentHtml
135 * A function returning the HTML code string to be added inside the content
138 labeledElement: function( dialog
, elementDefinition
, htmlList
, contentHtml
) {
139 if ( arguments
.length
< 4 )
142 var _
= initPrivateObject
.call( this, elementDefinition
);
143 _
.labelId
= CKEDITOR
.tools
.getNextId() + '_label';
144 this._
.children
= [];
146 var innerHTML = function() {
148 requiredClass
= elementDefinition
.required
? ' cke_required' : '';
149 if ( elementDefinition
.labelLayout
!= 'horizontal' ) {
151 '<label class="cke_dialog_ui_labeled_label' + requiredClass
+ '" ', ' id="' + _
.labelId
+ '"',
152 ( _
.inputId
? ' for="' + _
.inputId
+ '"' : '' ),
153 ( elementDefinition
.labelStyle
? ' style="' + elementDefinition
.labelStyle
+ '"' : '' ) + '>',
154 elementDefinition
.label
,
156 '<div class="cke_dialog_ui_labeled_content"',
157 ( elementDefinition
.controlStyle
? ' style="' + elementDefinition
.controlStyle
+ '"' : '' ),
158 ' role="presentation">',
159 contentHtml
.call( this, dialog
, elementDefinition
),
162 var hboxDefinition
= {
164 widths: elementDefinition
.widths
,
168 html: '<label class="cke_dialog_ui_labeled_label' + requiredClass
+ '"' +
169 ' id="' + _
.labelId
+ '"' +
170 ' for="' + _
.inputId
+ '"' +
171 ( elementDefinition
.labelStyle
? ' style="' + elementDefinition
.labelStyle
+ '"' : '' ) + '>' +
172 CKEDITOR
.tools
.htmlEncode( elementDefinition
.label
) +
177 html: '<span class="cke_dialog_ui_labeled_content"' + ( elementDefinition
.controlStyle
? ' style="' + elementDefinition
.controlStyle
+ '"' : '' ) + '>' +
178 contentHtml
.call( this, dialog
, elementDefinition
) +
182 CKEDITOR
.dialog
._
.uiElementBuilders
.hbox
.build( dialog
, hboxDefinition
, html
);
184 return html
.join( '' );
186 var attributes
= { role: elementDefinition
.role
|| 'presentation' };
188 if ( elementDefinition
.includeLabel
)
189 attributes
[ 'aria-labelledby' ] = _
.labelId
;
191 CKEDITOR
.ui
.dialog
.uiElement
.call( this, dialog
, elementDefinition
, htmlList
, 'div', null, attributes
, innerHTML
);
195 * A text input with a label. This UI element class represents both the
196 * single-line text inputs and password inputs in dialog boxes.
198 * @class CKEDITOR.ui.dialog.textInput
199 * @extends CKEDITOR.ui.dialog.labeledElement
200 * @constructor Creates a textInput class instance.
201 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
202 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
203 * The element definition. Accepted fields:
205 * * `default` (Optional) The default value.
206 * * `validate` (Optional) The validation function.
207 * * `maxLength` (Optional) The maximum length of text box contents.
208 * * `size` (Optional) The size of the text box. This is
209 * usually overridden by the size defined by the skin, though.
211 * @param {Array} htmlList List of HTML code to output to.
213 textInput: function( dialog
, elementDefinition
, htmlList
) {
214 if ( arguments
.length
< 3 )
217 initPrivateObject
.call( this, elementDefinition
);
218 var domId
= this._
.inputId
= CKEDITOR
.tools
.getNextId() + '_textInput',
219 attributes
= { 'class': 'cke_dialog_ui_input_' + elementDefinition
.type
, id: domId
, type: elementDefinition
.type
};
221 // Set the validator, if any.
222 if ( elementDefinition
.validate
)
223 this.validate
= elementDefinition
.validate
;
225 // Set the max length and size.
226 if ( elementDefinition
.maxLength
)
227 attributes
.maxlength
= elementDefinition
.maxLength
;
228 if ( elementDefinition
.size
)
229 attributes
.size
= elementDefinition
.size
;
231 if ( elementDefinition
.inputStyle
)
232 attributes
.style
= elementDefinition
.inputStyle
;
234 // If user presses Enter in a text box, it implies clicking OK for the dialog.
236 keyPressedOnMe
= false;
237 dialog
.on( 'load', function() {
238 me
.getInputElement().on( 'keydown', function( evt
) {
239 if ( evt
.data
.getKeystroke() == 13 )
240 keyPressedOnMe
= true;
243 // Lower the priority this 'keyup' since 'ok' will close the dialog.(#3749)
244 me
.getInputElement().on( 'keyup', function( evt
) {
245 if ( evt
.data
.getKeystroke() == 13 && keyPressedOnMe
) {
246 dialog
.getButton( 'ok' ) && setTimeout( function() {
247 dialog
.getButton( 'ok' ).click();
249 keyPressedOnMe
= false;
253 toggleBidiKeyUpHandler
.call( me
, evt
);
254 }, null, null, 1000 );
257 var innerHTML = function() {
258 // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline
259 // container's width, so need to wrap it inside a <div>.
260 var html
= [ '<div class="cke_dialog_ui_input_', elementDefinition
.type
, '" role="presentation"' ];
262 if ( elementDefinition
.width
)
263 html
.push( 'style="width:' + elementDefinition
.width
+ '" ' );
265 html
.push( '><input ' );
267 attributes
[ 'aria-labelledby' ] = this._
.labelId
;
268 this._
.required
&& ( attributes
[ 'aria-required' ] = this._
.required
);
269 for ( var i
in attributes
)
270 html
.push( i
+ '="' + attributes
[ i
] + '" ' );
271 html
.push( ' /></div>' );
272 return html
.join( '' );
274 CKEDITOR
.ui
.dialog
.labeledElement
.call( this, dialog
, elementDefinition
, htmlList
, innerHTML
);
278 * A text area with a label at the top or on the left.
280 * @class CKEDITOR.ui.dialog.textarea
281 * @extends CKEDITOR.ui.dialog.labeledElement
282 * @constructor Creates a textarea class instance.
283 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
284 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
286 * The element definition. Accepted fields:
288 * * `rows` (Optional) The number of rows displayed.
289 * Defaults to 5 if not defined.
290 * * `cols` (Optional) The number of cols displayed.
291 * Defaults to 20 if not defined. Usually overridden by skins.
292 * * `default` (Optional) The default value.
293 * * `validate` (Optional) The validation function.
295 * @param {Array} htmlList List of HTML code to output to.
297 textarea: function( dialog
, elementDefinition
, htmlList
) {
298 if ( arguments
.length
< 3 )
301 initPrivateObject
.call( this, elementDefinition
);
303 domId
= this._
.inputId
= CKEDITOR
.tools
.getNextId() + '_textarea',
306 if ( elementDefinition
.validate
)
307 this.validate
= elementDefinition
.validate
;
309 // Generates the essential attributes for the textarea tag.
310 attributes
.rows
= elementDefinition
.rows
|| 5;
311 attributes
.cols
= elementDefinition
.cols
|| 20;
313 attributes
[ 'class' ] = 'cke_dialog_ui_input_textarea ' + ( elementDefinition
[ 'class' ] || '' );
315 if ( typeof elementDefinition
.inputStyle
!= 'undefined' )
316 attributes
.style
= elementDefinition
.inputStyle
;
318 if ( elementDefinition
.dir
)
319 attributes
.dir
= elementDefinition
.dir
;
322 dialog
.on( 'load', function() {
323 me
.getInputElement().on( 'keyup', toggleBidiKeyUpHandler
);
327 var innerHTML = function() {
328 attributes
[ 'aria-labelledby' ] = this._
.labelId
;
329 this._
.required
&& ( attributes
[ 'aria-required' ] = this._
.required
);
330 var html
= [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea id="', domId
, '" ' ];
331 for ( var i
in attributes
)
332 html
.push( i
+ '="' + CKEDITOR
.tools
.htmlEncode( attributes
[ i
] ) + '" ' );
333 html
.push( '>', CKEDITOR
.tools
.htmlEncode( me
._
[ 'default' ] ), '</textarea></div>' );
334 return html
.join( '' );
336 CKEDITOR
.ui
.dialog
.labeledElement
.call( this, dialog
, elementDefinition
, htmlList
, innerHTML
);
340 * A single checkbox with a label on the right.
342 * @class CKEDITOR.ui.dialog.checkbox
343 * @extends CKEDITOR.ui.dialog.uiElement
344 * @constructor Creates a checkbox class instance.
345 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
346 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
347 * The element definition. Accepted fields:
349 * * `checked` (Optional) Whether the checkbox is checked
350 * on instantiation. Defaults to `false`.
351 * * `validate` (Optional) The validation function.
352 * * `label` (Optional) The checkbox label.
354 * @param {Array} htmlList List of HTML code to output to.
356 checkbox: function( dialog
, elementDefinition
, htmlList
) {
357 if ( arguments
.length
< 3 )
360 var _
= initPrivateObject
.call( this, elementDefinition
, { 'default': !!elementDefinition
[ 'default' ] } );
362 if ( elementDefinition
.validate
)
363 this.validate
= elementDefinition
.validate
;
365 var innerHTML = function() {
366 var myDefinition
= CKEDITOR
.tools
.extend(
370 id: elementDefinition
.id
? elementDefinition
.id
+ '_checkbox' : CKEDITOR
.tools
.getNextId() + '_checkbox'
376 var labelId
= CKEDITOR
.tools
.getNextId() + '_label';
377 var attributes
= { 'class': 'cke_dialog_ui_checkbox_input', type: 'checkbox', 'aria-labelledby': labelId
};
378 cleanInnerDefinition( myDefinition
);
379 if ( elementDefinition
[ 'default' ] )
380 attributes
.checked
= 'checked';
382 if ( typeof myDefinition
.inputStyle
!= 'undefined' )
383 myDefinition
.style
= myDefinition
.inputStyle
;
385 _
.checkbox
= new CKEDITOR
.ui
.dialog
.uiElement( dialog
, myDefinition
, html
, 'input', null, attributes
);
391 '"' + ( elementDefinition
.labelStyle
? ' style="' + elementDefinition
.labelStyle
+ '"' : '' ) + '>',
392 CKEDITOR
.tools
.htmlEncode( elementDefinition
.label
),
395 return html
.join( '' );
398 CKEDITOR
.ui
.dialog
.uiElement
.call( this, dialog
, elementDefinition
, htmlList
, 'span', null, null, innerHTML
);
402 * A group of radio buttons.
404 * @class CKEDITOR.ui.dialog.radio
405 * @extends CKEDITOR.ui.dialog.labeledElement
406 * @constructor Creates a radio class instance.
407 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
408 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
409 * The element definition. Accepted fields:
411 * * `default` (Required) The default value.
412 * * `validate` (Optional) The validation function.
413 * * `items` (Required) An array of options. Each option
414 * is a one- or two-item array of format `[ 'Description', 'Value' ]`. If `'Value'`
415 * is missing, then the value would be assumed to be the same as the description.
417 * @param {Array} htmlList List of HTML code to output to.
419 radio: function( dialog
, elementDefinition
, htmlList
) {
420 if ( arguments
.length
< 3 )
423 initPrivateObject
.call( this, elementDefinition
);
425 if ( !this._
[ 'default' ] )
426 this._
[ 'default' ] = this._
.initValue
= elementDefinition
.items
[ 0 ][ 1 ];
428 if ( elementDefinition
.validate
)
429 this.validate
= elementDefinition
.validate
;
434 var innerHTML = function() {
435 var inputHtmlList
= [],
437 commonName
= ( elementDefinition
.id
? elementDefinition
.id : CKEDITOR
.tools
.getNextId() ) + '_radio';
439 for ( var i
= 0; i
< elementDefinition
.items
.length
; i
++ ) {
440 var item
= elementDefinition
.items
[ i
],
441 title
= item
[ 2 ] !== undefined ? item
[ 2 ] : item
[ 0 ],
442 value
= item
[ 1 ] !== undefined ? item
[ 1 ] : item
[ 0 ],
443 inputId
= CKEDITOR
.tools
.getNextId() + '_radio_input',
444 labelId
= inputId
+ '_label',
446 inputDefinition
= CKEDITOR
.tools
.extend( {}, elementDefinition
, {
452 labelDefinition
= CKEDITOR
.tools
.extend( {}, inputDefinition
, {
458 'class': 'cke_dialog_ui_radio_input',
461 'aria-labelledby': labelId
466 if ( me
._
[ 'default' ] == value
)
467 inputAttributes
.checked
= 'checked';
469 cleanInnerDefinition( inputDefinition
);
470 cleanInnerDefinition( labelDefinition
);
472 if ( typeof inputDefinition
.inputStyle
!= 'undefined' )
473 inputDefinition
.style
= inputDefinition
.inputStyle
;
475 // Make inputs of radio type focusable (#10866).
476 inputDefinition
.keyboardFocusable
= true;
478 children
.push( new CKEDITOR
.ui
.dialog
.uiElement( dialog
, inputDefinition
, inputHtml
, 'input', null, inputAttributes
) );
480 inputHtml
.push( ' ' );
482 new CKEDITOR
.ui
.dialog
.uiElement( dialog
, labelDefinition
, inputHtml
, 'label', null, {
484 'for': inputAttributes
.id
487 inputHtmlList
.push( inputHtml
.join( '' ) );
490 new CKEDITOR
.ui
.dialog
.hbox( dialog
, children
, inputHtmlList
, html
);
492 return html
.join( '' );
495 // Adding a role="radiogroup" to definition used for wrapper.
496 elementDefinition
.role
= 'radiogroup';
497 elementDefinition
.includeLabel
= true;
499 CKEDITOR
.ui
.dialog
.labeledElement
.call( this, dialog
, elementDefinition
, htmlList
, innerHTML
);
500 this._
.children
= children
;
504 * A button with a label inside.
506 * @class CKEDITOR.ui.dialog.button
507 * @extends CKEDITOR.ui.dialog.uiElement
508 * @constructor Creates a button class instance.
509 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
510 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
511 * The element definition. Accepted fields:
513 * * `label` (Required) The button label.
514 * * `disabled` (Optional) Set to `true` if you want the
515 * button to appear in the disabled state.
517 * @param {Array} htmlList List of HTML code to output to.
519 button: function( dialog
, elementDefinition
, htmlList
) {
520 if ( !arguments
.length
)
523 if ( typeof elementDefinition
== 'function' )
524 elementDefinition
= elementDefinition( dialog
.getParentEditor() );
526 initPrivateObject
.call( this, elementDefinition
, { disabled: elementDefinition
.disabled
|| false } );
528 // Add OnClick event to this input.
529 CKEDITOR
.event
.implementOn( this );
533 // Register an event handler for processing button clicks.
534 dialog
.on( 'load', function() {
535 var element
= this.getElement();
538 element
.on( 'click', function( evt
) {
541 evt
.data
.preventDefault();
544 element
.on( 'keydown', function( evt
) {
545 if ( evt
.data
.getKeystroke() in { 32: 1 } ) {
547 evt
.data
.preventDefault();
552 element
.unselectable();
555 var outerDefinition
= CKEDITOR
.tools
.extend( {}, elementDefinition
);
556 delete outerDefinition
.style
;
558 var labelId
= CKEDITOR
.tools
.getNextId() + '_label';
559 CKEDITOR
.ui
.dialog
.uiElement
.call( this, dialog
, outerDefinition
, htmlList
, 'a', null, {
560 style: elementDefinition
.style
,
561 href: 'javascript:void(0)', // jshint ignore:line
562 title: elementDefinition
.label
,
564 'class': elementDefinition
[ 'class' ],
566 'aria-labelledby': labelId
567 }, '<span id="' + labelId
+ '" class="cke_dialog_ui_button">' +
568 CKEDITOR
.tools
.htmlEncode( elementDefinition
.label
) +
575 * @class CKEDITOR.ui.dialog.select
576 * @extends CKEDITOR.ui.dialog.uiElement
577 * @constructor Creates a button class instance.
578 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
579 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
580 * The element definition. Accepted fields:
582 * * `default` (Required) The default value.
583 * * `validate` (Optional) The validation function.
584 * * `items` (Required) An array of options. Each option
585 * is a one- or two-item array of format `[ 'Description', 'Value' ]`. If `'Value'`
586 * is missing, then the value would be assumed to be the same as the
588 * * `multiple` (Optional) Set this to `true` if you would like
589 * to have a multiple-choice select box.
590 * * `size` (Optional) The number of items to display in
593 * @param {Array} htmlList List of HTML code to output to.
595 select: function( dialog
, elementDefinition
, htmlList
) {
596 if ( arguments
.length
< 3 )
599 var _
= initPrivateObject
.call( this, elementDefinition
);
601 if ( elementDefinition
.validate
)
602 this.validate
= elementDefinition
.validate
;
604 _
.inputId
= CKEDITOR
.tools
.getNextId() + '_select';
606 var innerHTML = function() {
607 var myDefinition
= CKEDITOR
.tools
.extend(
611 id: ( elementDefinition
.id
? elementDefinition
.id
+ '_select' : CKEDITOR
.tools
.getNextId() + '_select' )
617 attributes
= { 'id': _
.inputId
, 'class': 'cke_dialog_ui_input_select', 'aria-labelledby': this._
.labelId
};
619 html
.push( '<div class="cke_dialog_ui_input_', elementDefinition
.type
, '" role="presentation"' );
620 if ( elementDefinition
.width
)
621 html
.push( 'style="width:' + elementDefinition
.width
+ '" ' );
624 // Add multiple and size attributes from element definition.
625 if ( elementDefinition
.size
!== undefined )
626 attributes
.size
= elementDefinition
.size
;
627 if ( elementDefinition
.multiple
!== undefined )
628 attributes
.multiple
= elementDefinition
.multiple
;
630 cleanInnerDefinition( myDefinition
);
631 for ( var i
= 0, item
; i
< elementDefinition
.items
.length
&& ( item
= elementDefinition
.items
[ i
] ); i
++ ) {
632 innerHTML
.push( '<option value="', CKEDITOR
.tools
.htmlEncode( item
[ 1 ] !== undefined ? item
[ 1 ] : item
[ 0 ] ).replace( /"/g, '"' ), '" /> ', CKEDITOR.tools.htmlEncode( item[ 0 ] ) );
635 if ( typeof myDefinition.inputStyle != 'undefined' )
636 myDefinition.style = myDefinition.inputStyle;
638 _.select = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'select
', null, attributes, innerHTML.join( '' ) );
640 html.push( '</div
>' );
642 return html.join( '' );
645 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
649 * A file upload input.
651 * @class CKEDITOR.ui.dialog.file
652 * @extends CKEDITOR.ui.dialog.labeledElement
653 * @constructor Creates a file class instance.
654 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
655 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
656 * The element definition. Accepted fields:
658 * * `validate` (Optional) The validation function.
660 * @param {Array} htmlList List of HTML code to output to.
662 file: function( dialog, elementDefinition, htmlList ) {
663 if ( arguments.length < 3 )
666 if ( elementDefinition[ 'default' ] === undefined )
667 elementDefinition[ 'default' ] = '';
669 var _ = CKEDITOR.tools.extend( initPrivateObject.call( this, elementDefinition ), { definition: elementDefinition, buttons: [] } );
671 if ( elementDefinition.validate )
672 this.validate = elementDefinition.validate;
675 var innerHTML = function() {
676 _.frameId = CKEDITOR.tools.getNextId() + '_fileInput
';
681 ' allowtransparency
="0"' +
682 ' class="cke_dialog_ui_input_file"' +
683 ' role
="presentation"' +
684 ' id
="', _.frameId, '"' +
685 ' title
="', elementDefinition.label, '"' +
686 ' src
="javascript:void('
689 // Support for custom document.domain on IE. (#10165)
690 html.push( CKEDITOR.env.ie ?
691 '(function(){' + encodeURIComponent(
693 '(' + CKEDITOR.tools.fixDomain + ')();' +
700 html.push( ')"></iframe
>' );
702 return html.join( '' );
705 // IE BUG: Parent container does not resize to contain the iframe automatically.
706 dialog.on( 'load
', function() {
707 var iframe = CKEDITOR.document.getById( _.frameId ),
708 contentDiv = iframe.getParent();
709 contentDiv.addClass( 'cke_dialog_ui_input_file
' );
712 CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
716 * A button for submitting the file in a file upload input.
718 * @class CKEDITOR.ui.dialog.fileButton
719 * @extends CKEDITOR.ui.dialog.button
720 * @constructor Creates a fileButton class instance.
721 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
722 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
723 * The element definition. Accepted fields:
725 * * `for` (Required) The file input's page and element ID
726 * to associate
with, in a two
-item array
format: `[ 'page_id', 'element_id' ]`.
727 * * `validate` (Optional
) The validation
function.
729 * @param
{Array
} htmlList List
of HTML code to output to
.
731 fileButton: function( dialog
, elementDefinition
, htmlList
) {
733 if ( arguments
.length
< 3 )
736 initPrivateObject
.call( this, elementDefinition
);
738 if ( elementDefinition
.validate
)
739 this.validate
= elementDefinition
.validate
;
741 var myDefinition
= CKEDITOR
.tools
.extend( {}, elementDefinition
);
742 var onClick
= myDefinition
.onClick
;
743 myDefinition
.className
= ( myDefinition
.className
? myDefinition
.className
+ ' ' : '' ) + 'cke_dialog_ui_button';
744 myDefinition
.onClick = function( evt
) {
745 var target
= elementDefinition
[ 'for' ]; // [ pageId, elementId ]
746 if ( !onClick
|| onClick
.call( this, evt
) !== false ) {
747 dialog
.getContentElement( target
[ 0 ], target
[ 1 ] ).submit();
752 dialog
.on( 'load', function() {
753 dialog
.getContentElement( elementDefinition
[ 'for' ][ 0 ], elementDefinition
[ 'for' ][ 1 ] )._
.buttons
.push( me
);
756 CKEDITOR
.ui
.dialog
.button
.call( this, dialog
, myDefinition
, htmlList
);
760 var myHtmlRe
= /^\s*<[\w:]+\s+([^>]*)?>/,
761 theirHtmlRe
= /^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/,
764 * A dialog window element made from raw HTML code.
766 * @class CKEDITOR.ui.dialog.html
767 * @extends CKEDITOR.ui.dialog.uiElement
768 * @constructor Creates a html class instance.
769 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
770 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition Element definition.
773 * * `html` (Required) HTML code of this element.
775 * @param {Array} htmlList List of HTML code to be added to the dialog's content area.
777 return function( dialog
, elementDefinition
, htmlList
) {
778 if ( arguments
.length
< 3 )
783 theirHtml
= elementDefinition
.html
,
786 // If the HTML input doesn't contain any tags at the beginning, add a <span> tag around it.
787 if ( theirHtml
.charAt( 0 ) != '<' )
788 theirHtml
= '<span>' + theirHtml
+ '</span>';
790 // Look for focus function in definition.
791 var focus
= elementDefinition
.focus
;
793 var oldFocus
= this.focus
;
794 this.focus = function() {
795 ( typeof focus
== 'function' ? focus : oldFocus
).call( this );
796 this.fire( 'focus' );
798 if ( elementDefinition
.isFocusable
) {
799 var oldIsFocusable
= this.isFocusable
;
800 this.isFocusable
= oldIsFocusable
;
802 this.keyboardFocusable
= true;
805 CKEDITOR
.ui
.dialog
.uiElement
.call( this, dialog
, elementDefinition
, myHtmlList
, 'span', null, null, '' );
807 // Append the attributes created by the uiElement call to the real HTML.
808 myHtml
= myHtmlList
.join( '' );
809 myMatch
= myHtml
.match( myHtmlRe
);
810 theirMatch
= theirHtml
.match( theirHtmlRe
) || [ '', '', '' ];
812 if ( emptyTagRe
.test( theirMatch
[ 1 ] ) ) {
813 theirMatch
[ 1 ] = theirMatch
[ 1 ].slice( 0, -1 );
814 theirMatch
[ 2 ] = '/' + theirMatch
[ 2 ];
817 htmlList
.push( [ theirMatch
[ 1 ], ' ', myMatch
[ 1 ] || '', theirMatch
[ 2 ] ].join( '' ) );
822 * Form fieldset for grouping dialog UI elements.
824 * @class CKEDITOR.ui.dialog.fieldset
825 * @extends CKEDITOR.ui.dialog.uiElement
826 * @constructor Creates a fieldset class instance.
827 * @param {CKEDITOR.dialog} dialog Parent dialog window object.
828 * @param {Array} childObjList
829 * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.
830 * @param {Array} childHtmlList Array of HTML code that corresponds to the HTML output of all the
831 * objects in childObjList.
832 * @param {Array} htmlList Array of HTML code that this element will output to.
833 * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
834 * The element definition. Accepted fields:
836 * * `label` (Optional) The legend of the this fieldset.
837 * * `children` (Required) An array of dialog window field definitions which will be grouped inside this fieldset.
840 fieldset: function( dialog
, childObjList
, childHtmlList
, htmlList
, elementDefinition
) {
841 var legendLabel
= elementDefinition
.label
;
843 var innerHTML = function() {
845 legendLabel
&& html
.push( '<legend' +
846 ( elementDefinition
.labelStyle
? ' style="' + elementDefinition
.labelStyle
+ '"' : '' ) +
847 '>' + legendLabel
+ '</legend>' );
848 for ( var i
= 0; i
< childHtmlList
.length
; i
++ )
849 html
.push( childHtmlList
[ i
] );
850 return html
.join( '' );
853 this._
= { children: childObjList
};
854 CKEDITOR
.ui
.dialog
.uiElement
.call( this, dialog
, elementDefinition
, htmlList
, 'fieldset', null, null, innerHTML
);
859 CKEDITOR
.ui
.dialog
.html
.prototype = new CKEDITOR
.ui
.dialog
.uiElement();
861 /** @class CKEDITOR.ui.dialog.labeledElement */
862 CKEDITOR
.ui
.dialog
.labeledElement
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.uiElement(), {
864 * Sets the label text of the element.
866 * @param {String} label The new label text.
867 * @returns {CKEDITOR.ui.dialog.labeledElement} The current labeled element.
869 setLabel: function( label
) {
870 var node
= CKEDITOR
.document
.getById( this._
.labelId
);
871 if ( node
.getChildCount() < 1 )
872 ( new CKEDITOR
.dom
.text( label
, CKEDITOR
.document
) ).appendTo( node
);
874 node
.getChild( 0 ).$.nodeValue
= label
;
879 * Retrieves the current label text of the elment.
881 * @returns {String} The current label text.
883 getLabel: function() {
884 var node
= CKEDITOR
.document
.getById( this._
.labelId
);
885 if ( !node
|| node
.getChildCount() < 1 )
888 return node
.getChild( 0 ).getText();
892 * Defines the `onChange` event for UI element definitions.
895 eventProcessors: commonEventProcessors
898 /** @class CKEDITOR.ui.dialog.button */
899 CKEDITOR
.ui
.dialog
.button
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.uiElement(), {
901 * Simulates a click to the button.
903 * @returns {Object} Return value of the `click` event.
906 if ( !this._
.disabled
)
907 return this.fire( 'click', { dialog: this._
.dialog
} );
912 * Enables the button.
915 this._
.disabled
= false;
916 var element
= this.getElement();
917 element
&& element
.removeClass( 'cke_disabled' );
921 * Disables the button.
923 disable: function() {
924 this._
.disabled
= true;
925 this.getElement().addClass( 'cke_disabled' );
929 * Checks whether a field is visible.
933 isVisible: function() {
934 return this.getElement().getFirst().isVisible();
938 * Checks whether a field is enabled. Fields can be disabled by using the
939 * {@link #disable} method and enabled by using the {@link #enable} method.
943 isEnabled: function() {
944 return !this._
.disabled
;
948 * Defines the `onChange` event and `onClick` for button element definitions.
952 eventProcessors: CKEDITOR
.tools
.extend( {}, CKEDITOR
.ui
.dialog
.uiElement
.prototype.eventProcessors
, {
953 onClick: function( dialog
, func
) {
954 this.on( 'click', function() {
955 func
.apply( this, arguments
);
961 * Handler for the element's access key up event. Simulates a click to
964 accessKeyUp: function() {
969 * Handler for the element's access key down event. Simulates a mouse
970 * down to the button.
972 accessKeyDown: function() {
976 keyboardFocusable: true
979 /** @class CKEDITOR.ui.dialog.textInput */
980 CKEDITOR
.ui
.dialog
.textInput
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.labeledElement(), {
982 * Gets the text input DOM element under this UI object.
984 * @returns {CKEDITOR.dom.element} The DOM element of the text input.
986 getInputElement: function() {
987 return CKEDITOR
.document
.getById( this._
.inputId
);
991 * Puts focus into the text input.
994 var me
= this.selectParentTab();
996 // GECKO BUG: setTimeout() is needed to workaround invisible selections.
997 setTimeout( function() {
998 var element
= me
.getInputElement();
999 element
&& element
.$.focus();
1004 * Selects all the text in the text input.
1006 select: function() {
1007 var me
= this.selectParentTab();
1009 // GECKO BUG: setTimeout() is needed to workaround invisible selections.
1010 setTimeout( function() {
1011 var e
= me
.getInputElement();
1020 * Handler for the text input's access key up event. Makes a `select()`
1021 * call to the text input.
1023 accessKeyUp: function() {
1028 * Sets the value of this text input object.
1030 * uiElement.setValue( 'Blamo' );
1032 * @param {Object} value The new value.
1033 * @returns {CKEDITOR.ui.dialog.textInput} The current UI element.
1035 setValue: function( value
) {
1037 var marker
= value
&& value
.charAt( 0 ),
1038 dir
= ( marker
== '\u202A' ? 'ltr' : marker
== '\u202B' ? 'rtl' : null );
1041 value
= value
.slice( 1 );
1044 // Set the marker or reset it (if dir==null).
1045 this.setDirectionMarker( dir
);
1052 return CKEDITOR
.ui
.dialog
.uiElement
.prototype.setValue
.apply( this, arguments
);
1056 * Gets the value of this text input object.
1058 * @returns {String} The value.
1060 getValue: function() {
1061 var value
= CKEDITOR
.ui
.dialog
.uiElement
.prototype.getValue
.call( this );
1063 if ( this.bidi
&& value
) {
1064 var dir
= this.getDirectionMarker();
1066 value
= ( dir
== 'ltr' ? '\u202A' : '\u202B' ) + value
;
1074 * Sets the text direction marker and the `dir` attribute of the input element.
1077 * @param {String} dir The text direction. Pass `null` to reset.
1079 setDirectionMarker: function( dir
) {
1080 var inputElement
= this.getInputElement();
1083 inputElement
.setAttributes( {
1085 'data-cke-dir-marker': dir
1087 // Don't remove the dir attribute if this field hasn't got the marker,
1088 // because the dir attribute could be set independently.
1089 } else if ( this.getDirectionMarker() ) {
1090 inputElement
.removeAttributes( [ 'dir', 'data-cke-dir-marker' ] );
1095 * Gets the value of the text direction marker.
1098 * @returns {String} `'ltr'`, `'rtl'` or `null` if the marker is not set.
1100 getDirectionMarker: function() {
1101 return this.getInputElement().data( 'cke-dir-marker' );
1104 keyboardFocusable: true
1105 }, commonPrototype
, true );
1107 CKEDITOR
.ui
.dialog
.textarea
.prototype = new CKEDITOR
.ui
.dialog
.textInput();
1109 /** @class CKEDITOR.ui.dialog.select */
1110 CKEDITOR
.ui
.dialog
.select
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.labeledElement(), {
1112 * Gets the DOM element of the select box.
1114 * @returns {CKEDITOR.dom.element} The `<select>` element of this UI element.
1116 getInputElement: function() {
1117 return this._
.select
.getElement();
1121 * Adds an option to the select box.
1123 * @param {String} label Option label.
1124 * @param {String} value (Optional) Option value, if not defined it will be
1125 * assumed to be the same as the label.
1126 * @param {Number} index (Optional) Position of the option to be inserted
1127 * to. If not defined, the new option will be inserted to the end of list.
1128 * @returns {CKEDITOR.ui.dialog.select} The current select UI element.
1130 add: function( label
, value
, index
) {
1131 var option
= new CKEDITOR
.dom
.element( 'option', this.getDialog().getParentEditor().document
),
1132 selectElement
= this.getInputElement().$;
1133 option
.$.text
= label
;
1134 option
.$.value
= ( value
=== undefined || value
=== null ) ? label : value
;
1135 if ( index
=== undefined || index
=== null ) {
1136 if ( CKEDITOR
.env
.ie
) {
1137 selectElement
.add( option
.$ );
1139 selectElement
.add( option
.$, null );
1142 selectElement
.add( option
.$, index
);
1148 * Removes an option from the selection list.
1150 * @param {Number} index Index of the option to be removed.
1151 * @returns {CKEDITOR.ui.dialog.select} The current select UI element.
1153 remove: function( index
) {
1154 var selectElement
= this.getInputElement().$;
1155 selectElement
.remove( index
);
1160 * Clears all options out of the selection list.
1162 * @returns {CKEDITOR.ui.dialog.select} The current select UI element.
1165 var selectElement
= this.getInputElement().$;
1166 while ( selectElement
.length
> 0 )
1167 selectElement
.remove( 0 );
1171 keyboardFocusable: true
1172 }, commonPrototype
, true );
1174 /** @class CKEDITOR.ui.dialog.checkbox */
1175 CKEDITOR
.ui
.dialog
.checkbox
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.uiElement(), {
1177 * Gets the checkbox DOM element.
1179 * @returns {CKEDITOR.dom.element} The DOM element of the checkbox.
1181 getInputElement: function() {
1182 return this._
.checkbox
.getElement();
1186 * Sets the state of the checkbox.
1188 * @param {Boolean} checked `true` to tick the checkbox, `false` to untick it.
1189 * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element.
1191 setValue: function( checked
, noChangeEvent
) {
1192 this.getInputElement().$.checked
= checked
;
1193 !noChangeEvent
&& this.fire( 'change', { value: checked
} );
1197 * Gets the state of the checkbox.
1199 * @returns {Boolean} `true` means that the checkbox is ticked, `false` means it is not ticked.
1201 getValue: function() {
1202 return this.getInputElement().$.checked
;
1206 * Handler for the access key up event. Toggles the checkbox.
1208 accessKeyUp: function() {
1209 this.setValue( !this.getValue() );
1213 * Defines the `onChange` event for UI element definitions.
1215 * @property {Object}
1218 onChange: function( dialog
, func
) {
1219 if ( !CKEDITOR
.env
.ie
|| ( CKEDITOR
.env
.version
> 8 ) )
1220 return commonEventProcessors
.onChange
.apply( this, arguments
);
1222 dialog
.on( 'load', function() {
1223 var element
= this._
.checkbox
.getElement();
1224 element
.on( 'propertychange', function( evt
) {
1226 if ( evt
.propertyName
== 'checked' )
1227 this.fire( 'change', { value: element
.$.checked
} );
1230 this.on( 'change', func
);
1236 keyboardFocusable: true
1237 }, commonPrototype
, true );
1239 /** @class CKEDITOR.ui.dialog.radio */
1240 CKEDITOR
.ui
.dialog
.radio
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.uiElement(), {
1242 * Selects one of the radio buttons in this button group.
1244 * @param {String} value The value of the button to be chcked.
1245 * @param {Boolean} noChangeEvent Internal commit, to supress the `change` event on this element.
1247 setValue: function( value
, noChangeEvent
) {
1248 var children
= this._
.children
,
1251 ( i
< children
.length
) && ( item
= children
[ i
] ); i
++ )
1252 item
.getElement().$.checked
= ( item
.getValue() == value
);
1253 !noChangeEvent
&& this.fire( 'change', { value: value
} );
1257 * Gets the value of the currently selected radio button.
1259 * @returns {String} The currently selected button's value.
1261 getValue: function() {
1262 var children
= this._
.children
;
1263 for ( var i
= 0; i
< children
.length
; i
++ ) {
1264 if ( children
[ i
].getElement().$.checked
)
1265 return children
[ i
].getValue();
1271 * Handler for the access key up event. Focuses the currently
1272 * selected radio button, or the first radio button if none is selected.
1274 accessKeyUp: function() {
1275 var children
= this._
.children
,
1277 for ( i
= 0; i
< children
.length
; i
++ ) {
1278 if ( children
[ i
].getElement().$.checked
) {
1279 children
[ i
].getElement().focus();
1283 children
[ 0 ].getElement().focus();
1287 * Defines the `onChange` event for UI element definitions.
1289 * @property {Object}
1292 onChange: function( dialog
, func
) {
1293 if ( !CKEDITOR
.env
.ie
|| ( CKEDITOR
.env
.version
> 8 ) )
1294 return commonEventProcessors
.onChange
.apply( this, arguments
);
1296 dialog
.on( 'load', function() {
1297 var children
= this._
.children
,
1299 for ( var i
= 0; i
< children
.length
; i
++ ) {
1300 var element
= children
[ i
].getElement();
1301 element
.on( 'propertychange', function( evt
) {
1303 if ( evt
.propertyName
== 'checked' && this.$.checked
)
1304 me
.fire( 'change', { value: this.getAttribute( 'value' ) } );
1308 this.on( 'change', func
);
1313 }, commonPrototype
, true );
1315 /** @class CKEDITOR.ui.dialog.file */
1316 CKEDITOR
.ui
.dialog
.file
.prototype = CKEDITOR
.tools
.extend( new CKEDITOR
.ui
.dialog
.labeledElement(), commonPrototype
, {
1318 * Gets the `<input>` element of this file input.
1320 * @returns {CKEDITOR.dom.element} The file input element.
1322 getInputElement: function() {
1323 var frameDocument
= CKEDITOR
.document
.getById( this._
.frameId
).getFrameDocument();
1324 return frameDocument
.$.forms
.length
> 0 ? new CKEDITOR
.dom
.element( frameDocument
.$.forms
[ 0 ].elements
[ 0 ] ) : this.getElement();
1328 * Uploads the file in the file input.
1330 * @returns {CKEDITOR.ui.dialog.file} This object.
1332 submit: function() {
1333 this.getInputElement().getParent().$.submit();
1338 * Gets the action assigned to the form.
1340 * @returns {String} The value of the action.
1342 getAction: function() {
1343 return this.getInputElement().getParent().$.action
;
1347 * The events must be applied to the inner input element, and
1348 * this must be done when the iframe and form have been loaded.
1350 registerEvents: function( definition
) {
1351 var regex
= /^on([A-Z]\w+)/,
1354 var registerDomEvent = function( uiElement
, dialog
, eventName
, func
) {
1355 uiElement
.on( 'formLoaded', function() {
1356 uiElement
.getInputElement().on( eventName
, func
, uiElement
);
1360 for ( var i
in definition
) {
1361 if ( !( match
= i
.match( regex
) ) )
1364 if ( this.eventProcessors
[ i
] )
1365 this.eventProcessors
[ i
].call( this, this._
.dialog
, definition
[ i
] );
1367 registerDomEvent( this, this._
.dialog
, match
[ 1 ].toLowerCase(), definition
[ i
] );
1374 * Redraws the file input and resets the file path in the file input.
1375 * The redrawing logic is necessary because non-IE browsers tend to clear
1376 * the `<iframe>` containing the file input after closing the dialog window.
1380 frameElement
= CKEDITOR
.document
.getById( _
.frameId
),
1381 frameDocument
= frameElement
.getFrameDocument(),
1382 elementDefinition
= _
.definition
,
1383 buttons
= _
.buttons
,
1384 callNumber
= this.formLoadedNumber
,
1385 unloadNumber
= this.formUnloadNumber
,
1386 langDir
= _
.dialog
._
.editor
.lang
.dir
,
1387 langCode
= _
.dialog
._
.editor
.langCode
;
1389 // The callback function for the iframe, but we must call tools.addFunction only once
1390 // so we store the function number in this.formLoadedNumber
1391 if ( !callNumber
) {
1392 callNumber
= this.formLoadedNumber
= CKEDITOR
.tools
.addFunction( function() {
1393 // Now we can apply the events to the input type=file
1394 this.fire( 'formLoaded' );
1397 // Remove listeners attached to the content of the iframe (the file input)
1398 unloadNumber
= this.formUnloadNumber
= CKEDITOR
.tools
.addFunction( function() {
1399 this.getInputElement().clearCustomData();
1402 this.getDialog()._
.editor
.on( 'destroy', function() {
1403 CKEDITOR
.tools
.removeFunction( callNumber
);
1404 CKEDITOR
.tools
.removeFunction( unloadNumber
);
1408 function generateFormField() {
1409 frameDocument
.$.open();
1412 if ( elementDefinition
.size
)
1413 size
= elementDefinition
.size
- ( CKEDITOR
.env
.ie
? 7 : 0 ); // "Browse" button is bigger in IE.
1415 var inputId
= _
.frameId
+ '_input';
1417 frameDocument
.$.write( [
1418 '<html dir="' + langDir
+ '" lang="' + langCode
+ '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
1419 '<form enctype="multipart/form-data" method="POST" dir="' + langDir
+ '" lang="' + langCode
+ '" action="',
1420 CKEDITOR
.tools
.htmlEncode( elementDefinition
.action
),
1422 // Replicate the field label inside of iframe.
1423 '<label id="', _
.labelId
, '" for="', inputId
, '" style="display:none">',
1424 CKEDITOR
.tools
.htmlEncode( elementDefinition
.label
),
1426 // Set width to make sure that input is not clipped by the iframe (#11253).
1427 '<input style="width:100%" id="', inputId
, '" aria-labelledby="', _
.labelId
, '" type="file" name="',
1428 CKEDITOR
.tools
.htmlEncode( elementDefinition
.id
|| 'cke_upload' ),
1430 CKEDITOR
.tools
.htmlEncode( size
> 0 ? size : '' ),
1435 // Support for custom document.domain in IE.
1436 CKEDITOR
.env
.ie
? '(' + CKEDITOR
.tools
.fixDomain
+ ')();' : '',
1438 'window.parent.CKEDITOR.tools.callFunction(' + callNumber
+ ');',
1439 'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber
+ ')}',
1443 frameDocument
.$.close();
1445 for ( var i
= 0; i
< buttons
.length
; i
++ )
1446 buttons
[ i
].enable();
1449 // #3465: Wait for the browser to finish rendering the dialog first.
1450 if ( CKEDITOR
.env
.gecko
)
1451 setTimeout( generateFormField
, 500 );
1453 generateFormField();
1456 getValue: function() {
1457 return this.getInputElement().$.value
|| '';
1461 * The default value of input `type="file"` is an empty string, but during the initialization
1462 * of this UI element, the iframe still is not ready so it cannot be read from that object.
1463 * Setting it manually prevents later issues with the current value (`''`) being different
1464 * than the initial value (undefined as it asked for `.value` of a div).
1466 setInitValue: function() {
1467 this._
.initValue
= '';
1471 * Defines the `onChange` event for UI element definitions.
1473 * @property {Object}
1476 onChange: function( dialog
, func
) {
1477 // If this method is called several times (I'm not sure about how this can happen but the default
1478 // onChange processor includes this protection)
1479 // In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method
1480 if ( !this._
.domOnChangeRegistered
) {
1481 // By listening for the formLoaded event, this handler will get reapplied when a new
1483 this.on( 'formLoaded', function() {
1484 this.getInputElement().on( 'change', function() {
1485 this.fire( 'change', { value: this.getValue() } );
1488 this._
.domOnChangeRegistered
= true;
1491 this.on( 'change', func
);
1495 keyboardFocusable: true
1498 CKEDITOR
.ui
.dialog
.fileButton
.prototype = new CKEDITOR
.ui
.dialog
.button();
1500 CKEDITOR
.ui
.dialog
.fieldset
.prototype = CKEDITOR
.tools
.clone( CKEDITOR
.ui
.dialog
.hbox
.prototype );
1502 CKEDITOR
.dialog
.addUIElement( 'text', textBuilder
);
1503 CKEDITOR
.dialog
.addUIElement( 'password', textBuilder
);
1504 CKEDITOR
.dialog
.addUIElement( 'textarea', commonBuilder
);
1505 CKEDITOR
.dialog
.addUIElement( 'checkbox', commonBuilder
);
1506 CKEDITOR
.dialog
.addUIElement( 'radio', commonBuilder
);
1507 CKEDITOR
.dialog
.addUIElement( 'button', commonBuilder
);
1508 CKEDITOR
.dialog
.addUIElement( 'select', commonBuilder
);
1509 CKEDITOR
.dialog
.addUIElement( 'file', commonBuilder
);
1510 CKEDITOR
.dialog
.addUIElement( 'fileButton', commonBuilder
);
1511 CKEDITOR
.dialog
.addUIElement( 'html', commonBuilder
);
1512 CKEDITOR
.dialog
.addUIElement( 'fieldset', containerBuilder
);
1517 * Fired when the value of the uiElement is changed.
1520 * @member CKEDITOR.ui.dialog.uiElement
1524 * Fired when the inner frame created by the element is ready.
1525 * Each time the button is used or the dialog window is loaded, a new
1526 * form might be created.
1529 * @member CKEDITOR.ui.dialog.fileButton