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