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