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