diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-02-19 23:38:52 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-02-19 23:38:52 +0100 |
commit | 3332bebe4da6dfa0fe3e4b2abddc84b1cc62f8f5 (patch) | |
tree | a4f77655fe55b79606e7d3416504686a1ab8b058 /sources/plugins/richcombo | |
download | piedsjaloux-ckeditor-component-3332bebe4da6dfa0fe3e4b2abddc84b1cc62f8f5.tar.gz piedsjaloux-ckeditor-component-3332bebe4da6dfa0fe3e4b2abddc84b1cc62f8f5.tar.zst piedsjaloux-ckeditor-component-3332bebe4da6dfa0fe3e4b2abddc84b1cc62f8f5.zip |
Initial commit4.5.7
Diffstat (limited to 'sources/plugins/richcombo')
-rw-r--r-- | sources/plugins/richcombo/plugin.js | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/sources/plugins/richcombo/plugin.js b/sources/plugins/richcombo/plugin.js new file mode 100644 index 0000000..67ccc8e --- /dev/null +++ b/sources/plugins/richcombo/plugin.js | |||
@@ -0,0 +1,434 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | CKEDITOR.plugins.add( 'richcombo', { | ||
7 | requires: 'floatpanel,listblock,button', | ||
8 | |||
9 | beforeInit: function( editor ) { | ||
10 | editor.ui.addHandler( CKEDITOR.UI_RICHCOMBO, CKEDITOR.ui.richCombo.handler ); | ||
11 | } | ||
12 | } ); | ||
13 | |||
14 | ( function() { | ||
15 | var template = '<span id="{id}"' + | ||
16 | ' class="cke_combo cke_combo__{name} {cls}"' + | ||
17 | ' role="presentation">' + | ||
18 | '<span id="{id}_label" class="cke_combo_label">{label}</span>' + | ||
19 | '<a class="cke_combo_button" title="{title}" tabindex="-1"' + | ||
20 | ( CKEDITOR.env.gecko && !CKEDITOR.env.hc ? '' : ' href="javascript:void(\'{titleJs}\')"' ) + | ||
21 | ' hidefocus="true"' + | ||
22 | ' role="button"' + | ||
23 | ' aria-labelledby="{id}_label"' + | ||
24 | ' aria-haspopup="true"'; | ||
25 | |||
26 | // Some browsers don't cancel key events in the keydown but in the | ||
27 | // keypress. | ||
28 | // TODO: Check if really needed. | ||
29 | if ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) | ||
30 | template += ' onkeypress="return false;"'; | ||
31 | |||
32 | // With Firefox, we need to force the button to redraw, otherwise it | ||
33 | // will remain in the focus state. | ||
34 | if ( CKEDITOR.env.gecko ) | ||
35 | template += ' onblur="this.style.cssText = this.style.cssText;"'; | ||
36 | |||
37 | template += | ||
38 | ' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event,this);"' + | ||
39 | ' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' + | ||
40 | ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // #188 | ||
41 | '="CKEDITOR.tools.callFunction({clickFn},this);return false;">' + | ||
42 | '<span id="{id}_text" class="cke_combo_text cke_combo_inlinelabel">{label}</span>' + | ||
43 | '<span class="cke_combo_open">' + | ||
44 | '<span class="cke_combo_arrow">' + | ||
45 | // BLACK DOWN-POINTING TRIANGLE | ||
46 | ( CKEDITOR.env.hc ? '▼' : CKEDITOR.env.air ? ' ' : '' ) + | ||
47 | '</span>' + | ||
48 | '</span>' + | ||
49 | '</a>' + | ||
50 | '</span>'; | ||
51 | |||
52 | var rcomboTpl = CKEDITOR.addTemplate( 'combo', template ); | ||
53 | |||
54 | /** | ||
55 | * Button UI element. | ||
56 | * | ||
57 | * @readonly | ||
58 | * @property {String} [='richcombo'] | ||
59 | * @member CKEDITOR | ||
60 | */ | ||
61 | CKEDITOR.UI_RICHCOMBO = 'richcombo'; | ||
62 | |||
63 | /** | ||
64 | * @class | ||
65 | * @todo | ||
66 | */ | ||
67 | CKEDITOR.ui.richCombo = CKEDITOR.tools.createClass( { | ||
68 | $: function( definition ) { | ||
69 | // Copy all definition properties to this object. | ||
70 | CKEDITOR.tools.extend( this, definition, | ||
71 | // Set defaults. | ||
72 | { | ||
73 | // The combo won't participate in toolbar grouping. | ||
74 | canGroup: false, | ||
75 | title: definition.label, | ||
76 | modes: { wysiwyg: 1 }, | ||
77 | editorFocus: 1 | ||
78 | } ); | ||
79 | |||
80 | // We don't want the panel definition in this object. | ||
81 | var panelDefinition = this.panel || {}; | ||
82 | delete this.panel; | ||
83 | |||
84 | this.id = CKEDITOR.tools.getNextNumber(); | ||
85 | |||
86 | this.document = ( panelDefinition.parent && panelDefinition.parent.getDocument() ) || CKEDITOR.document; | ||
87 | |||
88 | panelDefinition.className = 'cke_combopanel'; | ||
89 | panelDefinition.block = { | ||
90 | multiSelect: panelDefinition.multiSelect, | ||
91 | attributes: panelDefinition.attributes | ||
92 | }; | ||
93 | panelDefinition.toolbarRelated = true; | ||
94 | |||
95 | this._ = { | ||
96 | panelDefinition: panelDefinition, | ||
97 | items: {} | ||
98 | }; | ||
99 | }, | ||
100 | |||
101 | proto: { | ||
102 | renderHtml: function( editor ) { | ||
103 | var output = []; | ||
104 | this.render( editor, output ); | ||
105 | return output.join( '' ); | ||
106 | }, | ||
107 | |||
108 | /** | ||
109 | * Renders the combo. | ||
110 | * | ||
111 | * @param {CKEDITOR.editor} editor The editor instance which this button is | ||
112 | * to be used by. | ||
113 | * @param {Array} output The output array to which append the HTML relative | ||
114 | * to this button. | ||
115 | */ | ||
116 | render: function( editor, output ) { | ||
117 | var env = CKEDITOR.env; | ||
118 | |||
119 | var id = 'cke_' + this.id; | ||
120 | var clickFn = CKEDITOR.tools.addFunction( function( el ) { | ||
121 | // Restore locked selection in Opera. | ||
122 | if ( selLocked ) { | ||
123 | editor.unlockSelection( 1 ); | ||
124 | selLocked = 0; | ||
125 | } | ||
126 | instance.execute( el ); | ||
127 | }, this ); | ||
128 | |||
129 | var combo = this; | ||
130 | var instance = { | ||
131 | id: id, | ||
132 | combo: this, | ||
133 | focus: function() { | ||
134 | var element = CKEDITOR.document.getById( id ).getChild( 1 ); | ||
135 | element.focus(); | ||
136 | }, | ||
137 | execute: function( el ) { | ||
138 | var _ = combo._; | ||
139 | |||
140 | if ( _.state == CKEDITOR.TRISTATE_DISABLED ) | ||
141 | return; | ||
142 | |||
143 | combo.createPanel( editor ); | ||
144 | |||
145 | if ( _.on ) { | ||
146 | _.panel.hide(); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | combo.commit(); | ||
151 | var value = combo.getValue(); | ||
152 | if ( value ) | ||
153 | _.list.mark( value ); | ||
154 | else | ||
155 | _.list.unmarkAll(); | ||
156 | |||
157 | _.panel.showBlock( combo.id, new CKEDITOR.dom.element( el ), 4 ); | ||
158 | }, | ||
159 | clickFn: clickFn | ||
160 | }; | ||
161 | |||
162 | function updateState() { | ||
163 | // Don't change state while richcombo is active (#11793). | ||
164 | if ( this.getState() == CKEDITOR.TRISTATE_ON ) | ||
165 | return; | ||
166 | |||
167 | var state = this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED; | ||
168 | |||
169 | if ( editor.readOnly && !this.readOnly ) | ||
170 | state = CKEDITOR.TRISTATE_DISABLED; | ||
171 | |||
172 | this.setState( state ); | ||
173 | this.setValue( '' ); | ||
174 | |||
175 | // Let plugin to disable button. | ||
176 | if ( state != CKEDITOR.TRISTATE_DISABLED && this.refresh ) | ||
177 | this.refresh(); | ||
178 | } | ||
179 | |||
180 | // Update status when activeFilter, mode, selection or readOnly changes. | ||
181 | editor.on( 'activeFilterChange', updateState, this ); | ||
182 | editor.on( 'mode', updateState, this ); | ||
183 | editor.on( 'selectionChange', updateState, this ); | ||
184 | // If this combo is sensitive to readOnly state, update it accordingly. | ||
185 | !this.readOnly && editor.on( 'readOnly', updateState, this ); | ||
186 | |||
187 | var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ) { | ||
188 | ev = new CKEDITOR.dom.event( ev ); | ||
189 | |||
190 | var keystroke = ev.getKeystroke(); | ||
191 | |||
192 | // ARROW-DOWN | ||
193 | // This call is duplicated in plugins/toolbar/plugin.js in itemKeystroke(). | ||
194 | // Move focus to the first element after drop down was opened by the arrow down key. | ||
195 | if ( keystroke == 40 ) { | ||
196 | editor.once( 'panelShow', function( evt ) { | ||
197 | evt.data._.panel._.currentBlock.onKeyDown( 40 ); | ||
198 | } ); | ||
199 | } | ||
200 | |||
201 | switch ( keystroke ) { | ||
202 | case 13: // ENTER | ||
203 | case 32: // SPACE | ||
204 | case 40: // ARROW-DOWN | ||
205 | // Show panel | ||
206 | CKEDITOR.tools.callFunction( clickFn, element ); | ||
207 | break; | ||
208 | default: | ||
209 | // Delegate the default behavior to toolbar button key handling. | ||
210 | instance.onkey( instance, keystroke ); | ||
211 | } | ||
212 | |||
213 | // Avoid subsequent focus grab on editor document. | ||
214 | ev.preventDefault(); | ||
215 | } ); | ||
216 | |||
217 | var focusFn = CKEDITOR.tools.addFunction( function() { | ||
218 | instance.onfocus && instance.onfocus(); | ||
219 | } ); | ||
220 | |||
221 | var selLocked = 0; | ||
222 | |||
223 | // For clean up | ||
224 | instance.keyDownFn = keyDownFn; | ||
225 | |||
226 | var params = { | ||
227 | id: id, | ||
228 | name: this.name || this.command, | ||
229 | label: this.label, | ||
230 | title: this.title, | ||
231 | cls: this.className || '', | ||
232 | titleJs: env.gecko && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ), | ||
233 | keydownFn: keyDownFn, | ||
234 | focusFn: focusFn, | ||
235 | clickFn: clickFn | ||
236 | }; | ||
237 | |||
238 | rcomboTpl.output( params, output ); | ||
239 | |||
240 | if ( this.onRender ) | ||
241 | this.onRender(); | ||
242 | |||
243 | return instance; | ||
244 | }, | ||
245 | |||
246 | createPanel: function( editor ) { | ||
247 | if ( this._.panel ) | ||
248 | return; | ||
249 | |||
250 | var panelDefinition = this._.panelDefinition, | ||
251 | panelBlockDefinition = this._.panelDefinition.block, | ||
252 | panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(), | ||
253 | namedPanelCls = 'cke_combopanel__' + this.name, | ||
254 | panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ), | ||
255 | list = panel.addListBlock( this.id, panelBlockDefinition ), | ||
256 | me = this; | ||
257 | |||
258 | panel.onShow = function() { | ||
259 | this.element.addClass( namedPanelCls ); | ||
260 | |||
261 | me.setState( CKEDITOR.TRISTATE_ON ); | ||
262 | |||
263 | me._.on = 1; | ||
264 | |||
265 | me.editorFocus && !editor.focusManager.hasFocus && editor.focus(); | ||
266 | |||
267 | if ( me.onOpen ) | ||
268 | me.onOpen(); | ||
269 | |||
270 | // The "panelShow" event is fired assinchronously, after the | ||
271 | // onShow method call. | ||
272 | editor.once( 'panelShow', function() { | ||
273 | list.focus( !list.multiSelect && me.getValue() ); | ||
274 | } ); | ||
275 | }; | ||
276 | |||
277 | panel.onHide = function( preventOnClose ) { | ||
278 | this.element.removeClass( namedPanelCls ); | ||
279 | |||
280 | me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); | ||
281 | |||
282 | me._.on = 0; | ||
283 | |||
284 | if ( !preventOnClose && me.onClose ) | ||
285 | me.onClose(); | ||
286 | }; | ||
287 | |||
288 | panel.onEscape = function() { | ||
289 | // Hide drop-down with focus returned. | ||
290 | panel.hide( 1 ); | ||
291 | }; | ||
292 | |||
293 | list.onClick = function( value, marked ) { | ||
294 | |||
295 | if ( me.onClick ) | ||
296 | me.onClick.call( me, value, marked ); | ||
297 | |||
298 | panel.hide(); | ||
299 | }; | ||
300 | |||
301 | this._.panel = panel; | ||
302 | this._.list = list; | ||
303 | |||
304 | panel.getBlock( this.id ).onHide = function() { | ||
305 | me._.on = 0; | ||
306 | me.setState( CKEDITOR.TRISTATE_OFF ); | ||
307 | }; | ||
308 | |||
309 | if ( this.init ) | ||
310 | this.init(); | ||
311 | }, | ||
312 | |||
313 | setValue: function( value, text ) { | ||
314 | this._.value = value; | ||
315 | |||
316 | var textElement = this.document.getById( 'cke_' + this.id + '_text' ); | ||
317 | if ( textElement ) { | ||
318 | if ( !( value || text ) ) { | ||
319 | text = this.label; | ||
320 | textElement.addClass( 'cke_combo_inlinelabel' ); | ||
321 | } else { | ||
322 | textElement.removeClass( 'cke_combo_inlinelabel' ); | ||
323 | } | ||
324 | |||
325 | textElement.setText( typeof text != 'undefined' ? text : value ); | ||
326 | } | ||
327 | }, | ||
328 | |||
329 | getValue: function() { | ||
330 | return this._.value || ''; | ||
331 | }, | ||
332 | |||
333 | unmarkAll: function() { | ||
334 | this._.list.unmarkAll(); | ||
335 | }, | ||
336 | |||
337 | mark: function( value ) { | ||
338 | this._.list.mark( value ); | ||
339 | }, | ||
340 | |||
341 | hideItem: function( value ) { | ||
342 | this._.list.hideItem( value ); | ||
343 | }, | ||
344 | |||
345 | hideGroup: function( groupTitle ) { | ||
346 | this._.list.hideGroup( groupTitle ); | ||
347 | }, | ||
348 | |||
349 | showAll: function() { | ||
350 | this._.list.showAll(); | ||
351 | }, | ||
352 | |||
353 | add: function( value, html, text ) { | ||
354 | this._.items[ value ] = text || value; | ||
355 | this._.list.add( value, html, text ); | ||
356 | }, | ||
357 | |||
358 | startGroup: function( title ) { | ||
359 | this._.list.startGroup( title ); | ||
360 | }, | ||
361 | |||
362 | commit: function() { | ||
363 | if ( !this._.committed ) { | ||
364 | this._.list.commit(); | ||
365 | this._.committed = 1; | ||
366 | CKEDITOR.ui.fire( 'ready', this ); | ||
367 | } | ||
368 | this._.committed = 1; | ||
369 | }, | ||
370 | |||
371 | setState: function( state ) { | ||
372 | if ( this._.state == state ) | ||
373 | return; | ||
374 | |||
375 | var el = this.document.getById( 'cke_' + this.id ); | ||
376 | el.setState( state, 'cke_combo' ); | ||
377 | |||
378 | state == CKEDITOR.TRISTATE_DISABLED ? | ||
379 | el.setAttribute( 'aria-disabled', true ) : | ||
380 | el.removeAttribute( 'aria-disabled' ); | ||
381 | |||
382 | this._.state = state; | ||
383 | }, | ||
384 | |||
385 | getState: function() { | ||
386 | return this._.state; | ||
387 | }, | ||
388 | |||
389 | enable: function() { | ||
390 | if ( this._.state == CKEDITOR.TRISTATE_DISABLED ) | ||
391 | this.setState( this._.lastState ); | ||
392 | }, | ||
393 | |||
394 | disable: function() { | ||
395 | if ( this._.state != CKEDITOR.TRISTATE_DISABLED ) { | ||
396 | this._.lastState = this._.state; | ||
397 | this.setState( CKEDITOR.TRISTATE_DISABLED ); | ||
398 | } | ||
399 | } | ||
400 | }, | ||
401 | |||
402 | /** | ||
403 | * Represents richCombo handler object. | ||
404 | * | ||
405 | * @class CKEDITOR.ui.richCombo.handler | ||
406 | * @singleton | ||
407 | * @extends CKEDITOR.ui.handlerDefinition | ||
408 | */ | ||
409 | statics: { | ||
410 | handler: { | ||
411 | /** | ||
412 | * Transforms a richCombo definition in a {@link CKEDITOR.ui.richCombo} instance. | ||
413 | * | ||
414 | * @param {Object} definition | ||
415 | * @returns {CKEDITOR.ui.richCombo} | ||
416 | */ | ||
417 | create: function( definition ) { | ||
418 | return new CKEDITOR.ui.richCombo( definition ); | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | } ); | ||
423 | |||
424 | /** | ||
425 | * @param {String} name | ||
426 | * @param {Object} definition | ||
427 | * @member CKEDITOR.ui | ||
428 | * @todo | ||
429 | */ | ||
430 | CKEDITOR.ui.prototype.addRichCombo = function( name, definition ) { | ||
431 | this.add( name, CKEDITOR.UI_RICHCOMBO, definition ); | ||
432 | }; | ||
433 | |||
434 | } )(); | ||