diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-01-25 17:45:33 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-01-25 18:00:33 +0100 |
commit | 7adcb81e4f83f98c468889aaa5a85558ba88c770 (patch) | |
tree | 0d6ede733777b29060b48df4afaa2c64bfbae276 /sources/plugins/toolbar/plugin.js | |
download | connexionswing-ckeditor-component-4.5.6.tar.gz connexionswing-ckeditor-component-4.5.6.tar.zst connexionswing-ckeditor-component-4.5.6.zip |
Initial commit4.5.6
Diffstat (limited to 'sources/plugins/toolbar/plugin.js')
-rw-r--r-- | sources/plugins/toolbar/plugin.js | 803 |
1 files changed, 803 insertions, 0 deletions
diff --git a/sources/plugins/toolbar/plugin.js b/sources/plugins/toolbar/plugin.js new file mode 100644 index 00000000..2867e2b6 --- /dev/null +++ b/sources/plugins/toolbar/plugin.js | |||
@@ -0,0 +1,803 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | /** | ||
7 | * @fileOverview The "toolbar" plugin. Renders the default toolbar interface in | ||
8 | * the editor. | ||
9 | */ | ||
10 | |||
11 | ( function() { | ||
12 | var toolbox = function() { | ||
13 | this.toolbars = []; | ||
14 | this.focusCommandExecuted = false; | ||
15 | }; | ||
16 | |||
17 | toolbox.prototype.focus = function() { | ||
18 | for ( var t = 0, toolbar; toolbar = this.toolbars[ t++ ]; ) { | ||
19 | for ( var i = 0, item; item = toolbar.items[ i++ ]; ) { | ||
20 | if ( item.focus ) { | ||
21 | item.focus(); | ||
22 | return; | ||
23 | } | ||
24 | } | ||
25 | } | ||
26 | }; | ||
27 | |||
28 | var commands = { | ||
29 | toolbarFocus: { | ||
30 | modes: { wysiwyg: 1, source: 1 }, | ||
31 | readOnly: 1, | ||
32 | |||
33 | exec: function( editor ) { | ||
34 | if ( editor.toolbox ) { | ||
35 | editor.toolbox.focusCommandExecuted = true; | ||
36 | |||
37 | // Make the first button focus accessible for IE. (#3417) | ||
38 | // Adobe AIR instead need while of delay. | ||
39 | if ( CKEDITOR.env.ie || CKEDITOR.env.air ) { | ||
40 | setTimeout( function() { | ||
41 | editor.toolbox.focus(); | ||
42 | }, 100 ); | ||
43 | } else { | ||
44 | editor.toolbox.focus(); | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | CKEDITOR.plugins.add( 'toolbar', { | ||
52 | requires: 'button', | ||
53 | // jscs:disable maximumLineLength | ||
54 | lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% | ||
55 | // jscs:enable maximumLineLength | ||
56 | |||
57 | init: function( editor ) { | ||
58 | var endFlag; | ||
59 | |||
60 | var itemKeystroke = function( item, keystroke ) { | ||
61 | var next, toolbar; | ||
62 | var rtl = editor.lang.dir == 'rtl', | ||
63 | toolbarGroupCycling = editor.config.toolbarGroupCycling, | ||
64 | // Picking right/left key codes. | ||
65 | rightKeyCode = rtl ? 37 : 39, | ||
66 | leftKeyCode = rtl ? 39 : 37; | ||
67 | |||
68 | toolbarGroupCycling = toolbarGroupCycling === undefined || toolbarGroupCycling; | ||
69 | |||
70 | switch ( keystroke ) { | ||
71 | case 9: // TAB | ||
72 | case CKEDITOR.SHIFT + 9: // SHIFT + TAB | ||
73 | // Cycle through the toolbars, starting from the one | ||
74 | // closest to the current item. | ||
75 | while ( !toolbar || !toolbar.items.length ) { | ||
76 | if ( keystroke == 9 ) { | ||
77 | toolbar = ( ( toolbar ? toolbar.next : item.toolbar.next ) || editor.toolbox.toolbars[ 0 ] ); | ||
78 | } else { | ||
79 | toolbar = ( ( toolbar ? toolbar.previous : item.toolbar.previous ) || editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ] ); | ||
80 | } | ||
81 | |||
82 | // Look for the first item that accepts focus. | ||
83 | if ( toolbar.items.length ) { | ||
84 | item = toolbar.items[ endFlag ? ( toolbar.items.length - 1 ) : 0 ]; | ||
85 | while ( item && !item.focus ) { | ||
86 | item = endFlag ? item.previous : item.next; | ||
87 | |||
88 | if ( !item ) | ||
89 | toolbar = 0; | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
94 | if ( item ) | ||
95 | item.focus(); | ||
96 | |||
97 | return false; | ||
98 | |||
99 | case rightKeyCode: | ||
100 | next = item; | ||
101 | do { | ||
102 | // Look for the next item in the toolbar. | ||
103 | next = next.next; | ||
104 | |||
105 | // If it's the last item, cycle to the first one. | ||
106 | if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ 0 ]; | ||
107 | } | ||
108 | while ( next && !next.focus ); | ||
109 | |||
110 | // If available, just focus it, otherwise focus the | ||
111 | // first one. | ||
112 | if ( next ) | ||
113 | next.focus(); | ||
114 | else | ||
115 | // Send a TAB. | ||
116 | itemKeystroke( item, 9 ); | ||
117 | |||
118 | return false; | ||
119 | case 40: // DOWN-ARROW | ||
120 | if ( item.button && item.button.hasArrow ) { | ||
121 | // Note: code is duplicated in plugins\richcombo\plugin.js in keyDownFn(). | ||
122 | editor.once( 'panelShow', function( evt ) { | ||
123 | evt.data._.panel._.currentBlock.onKeyDown( 40 ); | ||
124 | } ); | ||
125 | item.execute(); | ||
126 | } else { | ||
127 | // Send left arrow key. | ||
128 | itemKeystroke( item, keystroke == 40 ? rightKeyCode : leftKeyCode ); | ||
129 | } | ||
130 | return false; | ||
131 | case leftKeyCode: | ||
132 | case 38: // UP-ARROW | ||
133 | next = item; | ||
134 | do { | ||
135 | // Look for the previous item in the toolbar. | ||
136 | next = next.previous; | ||
137 | |||
138 | // If it's the first item, cycle to the last one. | ||
139 | if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ item.toolbar.items.length - 1 ]; | ||
140 | } | ||
141 | while ( next && !next.focus ); | ||
142 | |||
143 | // If available, just focus it, otherwise focus the | ||
144 | // last one. | ||
145 | if ( next ) | ||
146 | next.focus(); | ||
147 | else { | ||
148 | endFlag = 1; | ||
149 | // Send a SHIFT + TAB. | ||
150 | itemKeystroke( item, CKEDITOR.SHIFT + 9 ); | ||
151 | endFlag = 0; | ||
152 | } | ||
153 | |||
154 | return false; | ||
155 | |||
156 | case 27: // ESC | ||
157 | editor.focus(); | ||
158 | return false; | ||
159 | |||
160 | case 13: // ENTER | ||
161 | case 32: // SPACE | ||
162 | item.execute(); | ||
163 | return false; | ||
164 | } | ||
165 | return true; | ||
166 | }; | ||
167 | |||
168 | editor.on( 'uiSpace', function( event ) { | ||
169 | if ( event.data.space != editor.config.toolbarLocation ) | ||
170 | return; | ||
171 | |||
172 | // Create toolbar only once. | ||
173 | event.removeListener(); | ||
174 | |||
175 | editor.toolbox = new toolbox(); | ||
176 | |||
177 | var labelId = CKEDITOR.tools.getNextId(); | ||
178 | |||
179 | var output = [ | ||
180 | '<span id="', labelId, '" class="cke_voice_label">', editor.lang.toolbar.toolbars, '</span>', | ||
181 | '<span id="' + editor.ui.spaceId( 'toolbox' ) + '" class="cke_toolbox" role="group" aria-labelledby="', labelId, '" onmousedown="return false;">' | ||
182 | ]; | ||
183 | |||
184 | var expanded = editor.config.toolbarStartupExpanded !== false, | ||
185 | groupStarted, pendingSeparator; | ||
186 | |||
187 | // If the toolbar collapser will be available, we'll have | ||
188 | // an additional container for all toolbars. | ||
189 | if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE ) | ||
190 | output.push( '<span class="cke_toolbox_main"' + ( expanded ? '>' : ' style="display:none">' ) ); | ||
191 | |||
192 | var toolbars = editor.toolbox.toolbars, | ||
193 | toolbar = getToolbarConfig( editor ); | ||
194 | |||
195 | for ( var r = 0; r < toolbar.length; r++ ) { | ||
196 | var toolbarId, | ||
197 | toolbarObj = 0, | ||
198 | toolbarName, | ||
199 | row = toolbar[ r ], | ||
200 | items; | ||
201 | |||
202 | // It's better to check if the row object is really | ||
203 | // available because it's a common mistake to leave | ||
204 | // an extra comma in the toolbar definition | ||
205 | // settings, which leads on the editor not loading | ||
206 | // at all in IE. (#3983) | ||
207 | if ( !row ) | ||
208 | continue; | ||
209 | |||
210 | if ( groupStarted ) { | ||
211 | output.push( '</span>' ); | ||
212 | groupStarted = 0; | ||
213 | pendingSeparator = 0; | ||
214 | } | ||
215 | |||
216 | if ( row === '/' ) { | ||
217 | output.push( '<span class="cke_toolbar_break"></span>' ); | ||
218 | continue; | ||
219 | } | ||
220 | |||
221 | items = row.items || row; | ||
222 | |||
223 | // Create all items defined for this toolbar. | ||
224 | for ( var i = 0; i < items.length; i++ ) { | ||
225 | var item = items[ i ], | ||
226 | canGroup; | ||
227 | |||
228 | if ( item ) { | ||
229 | if ( item.type == CKEDITOR.UI_SEPARATOR ) { | ||
230 | // Do not add the separator immediately. Just save | ||
231 | // it be included if we already have something in | ||
232 | // the toolbar and if a new item is to be added (later). | ||
233 | pendingSeparator = groupStarted && item; | ||
234 | continue; | ||
235 | } | ||
236 | |||
237 | canGroup = item.canGroup !== false; | ||
238 | |||
239 | // Initialize the toolbar first, if needed. | ||
240 | if ( !toolbarObj ) { | ||
241 | // Create the basic toolbar object. | ||
242 | toolbarId = CKEDITOR.tools.getNextId(); | ||
243 | toolbarObj = { id: toolbarId, items: [] }; | ||
244 | toolbarName = row.name && ( editor.lang.toolbar.toolbarGroups[ row.name ] || row.name ); | ||
245 | |||
246 | // Output the toolbar opener. | ||
247 | output.push( '<span id="', toolbarId, '" class="cke_toolbar"', ( toolbarName ? ' aria-labelledby="' + toolbarId + '_label"' : '' ), ' role="toolbar">' ); | ||
248 | |||
249 | // If a toolbar name is available, send the voice label. | ||
250 | toolbarName && output.push( '<span id="', toolbarId, '_label" class="cke_voice_label">', toolbarName, '</span>' ); | ||
251 | |||
252 | output.push( '<span class="cke_toolbar_start"></span>' ); | ||
253 | |||
254 | // Add the toolbar to the "editor.toolbox.toolbars" | ||
255 | // array. | ||
256 | var index = toolbars.push( toolbarObj ) - 1; | ||
257 | |||
258 | // Create the next/previous reference. | ||
259 | if ( index > 0 ) { | ||
260 | toolbarObj.previous = toolbars[ index - 1 ]; | ||
261 | toolbarObj.previous.next = toolbarObj; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | if ( canGroup ) { | ||
266 | if ( !groupStarted ) { | ||
267 | output.push( '<span class="cke_toolgroup" role="presentation">' ); | ||
268 | groupStarted = 1; | ||
269 | } | ||
270 | } else if ( groupStarted ) { | ||
271 | output.push( '</span>' ); | ||
272 | groupStarted = 0; | ||
273 | } | ||
274 | |||
275 | function addItem( item ) { // jshint ignore:line | ||
276 | var itemObj = item.render( editor, output ); | ||
277 | index = toolbarObj.items.push( itemObj ) - 1; | ||
278 | |||
279 | if ( index > 0 ) { | ||
280 | itemObj.previous = toolbarObj.items[ index - 1 ]; | ||
281 | itemObj.previous.next = itemObj; | ||
282 | } | ||
283 | |||
284 | itemObj.toolbar = toolbarObj; | ||
285 | itemObj.onkey = itemKeystroke; | ||
286 | |||
287 | // Fix for #3052: | ||
288 | // Prevent JAWS from focusing the toolbar after document load. | ||
289 | itemObj.onfocus = function() { | ||
290 | if ( !editor.toolbox.focusCommandExecuted ) | ||
291 | editor.focus(); | ||
292 | }; | ||
293 | } | ||
294 | |||
295 | if ( pendingSeparator ) { | ||
296 | addItem( pendingSeparator ); | ||
297 | pendingSeparator = 0; | ||
298 | } | ||
299 | |||
300 | addItem( item ); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | if ( groupStarted ) { | ||
305 | output.push( '</span>' ); | ||
306 | groupStarted = 0; | ||
307 | pendingSeparator = 0; | ||
308 | } | ||
309 | |||
310 | if ( toolbarObj ) | ||
311 | output.push( '<span class="cke_toolbar_end"></span></span>' ); | ||
312 | } | ||
313 | |||
314 | if ( editor.config.toolbarCanCollapse ) | ||
315 | output.push( '</span>' ); | ||
316 | |||
317 | // Not toolbar collapser for inline mode. | ||
318 | if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE ) { | ||
319 | var collapserFn = CKEDITOR.tools.addFunction( function() { | ||
320 | editor.execCommand( 'toolbarCollapse' ); | ||
321 | } ); | ||
322 | |||
323 | editor.on( 'destroy', function() { | ||
324 | CKEDITOR.tools.removeFunction( collapserFn ); | ||
325 | } ); | ||
326 | |||
327 | editor.addCommand( 'toolbarCollapse', { | ||
328 | readOnly: 1, | ||
329 | exec: function( editor ) { | ||
330 | var collapser = editor.ui.space( 'toolbar_collapser' ), | ||
331 | toolbox = collapser.getPrevious(), | ||
332 | contents = editor.ui.space( 'contents' ), | ||
333 | toolboxContainer = toolbox.getParent(), | ||
334 | contentHeight = parseInt( contents.$.style.height, 10 ), | ||
335 | previousHeight = toolboxContainer.$.offsetHeight, | ||
336 | minClass = 'cke_toolbox_collapser_min', | ||
337 | collapsed = collapser.hasClass( minClass ); | ||
338 | |||
339 | if ( !collapsed ) { | ||
340 | toolbox.hide(); | ||
341 | collapser.addClass( minClass ); | ||
342 | collapser.setAttribute( 'title', editor.lang.toolbar.toolbarExpand ); | ||
343 | } else { | ||
344 | toolbox.show(); | ||
345 | collapser.removeClass( minClass ); | ||
346 | collapser.setAttribute( 'title', editor.lang.toolbar.toolbarCollapse ); | ||
347 | } | ||
348 | |||
349 | // Update collapser symbol. | ||
350 | collapser.getFirst().setText( collapsed ? '\u25B2' : // BLACK UP-POINTING TRIANGLE | ||
351 | '\u25C0' ); // BLACK LEFT-POINTING TRIANGLE | ||
352 | |||
353 | var dy = toolboxContainer.$.offsetHeight - previousHeight; | ||
354 | contents.setStyle( 'height', ( contentHeight - dy ) + 'px' ); | ||
355 | |||
356 | editor.fire( 'resize', { | ||
357 | outerHeight: editor.container.$.offsetHeight, | ||
358 | contentsHeight: contents.$.offsetHeight, | ||
359 | outerWidth: editor.container.$.offsetWidth | ||
360 | } ); | ||
361 | }, | ||
362 | |||
363 | modes: { wysiwyg: 1, source: 1 } | ||
364 | } ); | ||
365 | |||
366 | editor.setKeystroke( CKEDITOR.ALT + ( CKEDITOR.env.ie || CKEDITOR.env.webkit ? 189 : 109 ) /*-*/, 'toolbarCollapse' ); | ||
367 | |||
368 | output.push( '<a title="' + ( expanded ? editor.lang.toolbar.toolbarCollapse : editor.lang.toolbar.toolbarExpand ) + | ||
369 | '" id="' + editor.ui.spaceId( 'toolbar_collapser' ) + | ||
370 | '" tabIndex="-1" class="cke_toolbox_collapser' ); | ||
371 | |||
372 | if ( !expanded ) | ||
373 | output.push( ' cke_toolbox_collapser_min' ); | ||
374 | |||
375 | output.push( '" onclick="CKEDITOR.tools.callFunction(' + collapserFn + ')">', '<span class="cke_arrow">▲</span>', // BLACK UP-POINTING TRIANGLE | ||
376 | '</a>' ); | ||
377 | } | ||
378 | |||
379 | output.push( '</span>' ); | ||
380 | event.data.html += output.join( '' ); | ||
381 | } ); | ||
382 | |||
383 | editor.on( 'destroy', function() { | ||
384 | if ( this.toolbox ) { | ||
385 | var toolbars, | ||
386 | index = 0, | ||
387 | i, items, instance; | ||
388 | toolbars = this.toolbox.toolbars; | ||
389 | for ( ; index < toolbars.length; index++ ) { | ||
390 | items = toolbars[ index ].items; | ||
391 | for ( i = 0; i < items.length; i++ ) { | ||
392 | instance = items[ i ]; | ||
393 | if ( instance.clickFn ) | ||
394 | CKEDITOR.tools.removeFunction( instance.clickFn ); | ||
395 | if ( instance.keyDownFn ) | ||
396 | CKEDITOR.tools.removeFunction( instance.keyDownFn ); | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | } ); | ||
401 | |||
402 | // Manage editor focus when navigating the toolbar. | ||
403 | editor.on( 'uiReady', function() { | ||
404 | var toolbox = editor.ui.space( 'toolbox' ); | ||
405 | toolbox && editor.focusManager.add( toolbox, 1 ); | ||
406 | } ); | ||
407 | |||
408 | editor.addCommand( 'toolbarFocus', commands.toolbarFocus ); | ||
409 | editor.setKeystroke( CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ); | ||
410 | |||
411 | editor.ui.add( '-', CKEDITOR.UI_SEPARATOR, {} ); | ||
412 | editor.ui.addHandler( CKEDITOR.UI_SEPARATOR, { | ||
413 | create: function() { | ||
414 | return { | ||
415 | render: function( editor, output ) { | ||
416 | output.push( '<span class="cke_toolbar_separator" role="separator"></span>' ); | ||
417 | return {}; | ||
418 | } | ||
419 | }; | ||
420 | } | ||
421 | } ); | ||
422 | } | ||
423 | } ); | ||
424 | |||
425 | function getToolbarConfig( editor ) { | ||
426 | var removeButtons = editor.config.removeButtons; | ||
427 | |||
428 | removeButtons = removeButtons && removeButtons.split( ',' ); | ||
429 | |||
430 | function buildToolbarConfig() { | ||
431 | |||
432 | // Object containing all toolbar groups used by ui items. | ||
433 | var lookup = getItemDefinedGroups(); | ||
434 | |||
435 | // Take the base for the new toolbar, which is basically a toolbar | ||
436 | // definition without items. | ||
437 | var toolbar = CKEDITOR.tools.clone( editor.config.toolbarGroups ) || getPrivateToolbarGroups( editor ); | ||
438 | |||
439 | // Fill the toolbar groups with the available ui items. | ||
440 | for ( var i = 0; i < toolbar.length; i++ ) { | ||
441 | var toolbarGroup = toolbar[ i ]; | ||
442 | |||
443 | // Skip toolbar break. | ||
444 | if ( toolbarGroup == '/' ) | ||
445 | continue; | ||
446 | // Handle simply group name item. | ||
447 | else if ( typeof toolbarGroup == 'string' ) | ||
448 | toolbarGroup = toolbar[ i ] = { name: toolbarGroup }; | ||
449 | |||
450 | var items, subGroups = toolbarGroup.groups; | ||
451 | |||
452 | // Look for items that match sub groups. | ||
453 | if ( subGroups ) { | ||
454 | for ( var j = 0, sub; j < subGroups.length; j++ ) { | ||
455 | sub = subGroups[ j ]; | ||
456 | |||
457 | // If any ui item is registered for this subgroup. | ||
458 | items = lookup[ sub ]; | ||
459 | items && fillGroup( toolbarGroup, items ); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | // Add the main group items as well. | ||
464 | items = lookup[ toolbarGroup.name ]; | ||
465 | items && fillGroup( toolbarGroup, items ); | ||
466 | } | ||
467 | |||
468 | return toolbar; | ||
469 | } | ||
470 | |||
471 | // Returns an object containing all toolbar groups used by ui items. | ||
472 | function getItemDefinedGroups() { | ||
473 | var groups = {}, | ||
474 | itemName, item, itemToolbar, group, order; | ||
475 | |||
476 | for ( itemName in editor.ui.items ) { | ||
477 | item = editor.ui.items[ itemName ]; | ||
478 | itemToolbar = item.toolbar || 'others'; | ||
479 | if ( itemToolbar ) { | ||
480 | // Break the toolbar property into its parts: "group_name[,order]". | ||
481 | itemToolbar = itemToolbar.split( ',' ); | ||
482 | group = itemToolbar[ 0 ]; | ||
483 | order = parseInt( itemToolbar[ 1 ] || -1, 10 ); | ||
484 | |||
485 | // Initialize the group, if necessary. | ||
486 | groups[ group ] || ( groups[ group ] = [] ); | ||
487 | |||
488 | // Push the data used to build the toolbar later. | ||
489 | groups[ group ].push( { name: itemName, order: order } ); | ||
490 | } | ||
491 | } | ||
492 | |||
493 | // Put the items in the right order. | ||
494 | for ( group in groups ) { | ||
495 | groups[ group ] = groups[ group ].sort( function( a, b ) { | ||
496 | return a.order == b.order ? 0 : | ||
497 | b.order < 0 ? -1 : | ||
498 | a.order < 0 ? 1 : | ||
499 | a.order < b.order ? -1 : | ||
500 | 1; | ||
501 | } ); | ||
502 | } | ||
503 | |||
504 | return groups; | ||
505 | } | ||
506 | |||
507 | function fillGroup( toolbarGroup, uiItems ) { | ||
508 | if ( uiItems.length ) { | ||
509 | if ( toolbarGroup.items ) | ||
510 | toolbarGroup.items.push( editor.ui.create( '-' ) ); | ||
511 | else | ||
512 | toolbarGroup.items = []; | ||
513 | |||
514 | var item, name; | ||
515 | while ( ( item = uiItems.shift() ) ) { | ||
516 | name = typeof item == 'string' ? item : item.name; | ||
517 | |||
518 | // Ignore items that are configured to be removed. | ||
519 | if ( !removeButtons || CKEDITOR.tools.indexOf( removeButtons, name ) == -1 ) { | ||
520 | item = editor.ui.create( name ); | ||
521 | |||
522 | if ( !item ) | ||
523 | continue; | ||
524 | |||
525 | if ( !editor.addFeature( item ) ) | ||
526 | continue; | ||
527 | |||
528 | toolbarGroup.items.push( item ); | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | } | ||
533 | |||
534 | function populateToolbarConfig( config ) { | ||
535 | var toolbar = [], | ||
536 | i, group, newGroup; | ||
537 | |||
538 | for ( i = 0; i < config.length; ++i ) { | ||
539 | group = config[ i ]; | ||
540 | newGroup = {}; | ||
541 | |||
542 | if ( group == '/' ) | ||
543 | toolbar.push( group ); | ||
544 | else if ( CKEDITOR.tools.isArray( group ) ) { | ||
545 | fillGroup( newGroup, CKEDITOR.tools.clone( group ) ); | ||
546 | toolbar.push( newGroup ); | ||
547 | } | ||
548 | else if ( group.items ) { | ||
549 | fillGroup( newGroup, CKEDITOR.tools.clone( group.items ) ); | ||
550 | newGroup.name = group.name; | ||
551 | toolbar.push( newGroup ); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | return toolbar; | ||
556 | } | ||
557 | |||
558 | var toolbar = editor.config.toolbar; | ||
559 | |||
560 | // If it is a string, return the relative "toolbar_name" config. | ||
561 | if ( typeof toolbar == 'string' ) | ||
562 | toolbar = editor.config[ 'toolbar_' + toolbar ]; | ||
563 | |||
564 | return ( editor.toolbar = toolbar ? populateToolbarConfig( toolbar ) : buildToolbarConfig() ); | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * Adds a toolbar group. See {@link CKEDITOR.config#toolbarGroups} for more details. | ||
569 | * | ||
570 | * **Note:** This method will not modify toolbar groups set explicitly by | ||
571 | * {@link CKEDITOR.config#toolbarGroups}. It will only extend the default setting. | ||
572 | * | ||
573 | * @param {String} name Toolbar group name. | ||
574 | * @param {Number/String} previous The name of the toolbar group after which this one | ||
575 | * should be added or `0` if this group should be the first one. | ||
576 | * @param {String} [subgroupOf] The name of the parent group. | ||
577 | * @member CKEDITOR.ui | ||
578 | */ | ||
579 | CKEDITOR.ui.prototype.addToolbarGroup = function( name, previous, subgroupOf ) { | ||
580 | // The toolbarGroups from the privates is the one we gonna use for automatic toolbar creation. | ||
581 | var toolbarGroups = getPrivateToolbarGroups( this.editor ), | ||
582 | atStart = previous === 0, | ||
583 | newGroup = { name: name }; | ||
584 | |||
585 | if ( subgroupOf ) { | ||
586 | // Transform the subgroupOf name in the real subgroup object. | ||
587 | subgroupOf = CKEDITOR.tools.search( toolbarGroups, function( group ) { | ||
588 | return group.name == subgroupOf; | ||
589 | } ); | ||
590 | |||
591 | if ( subgroupOf ) { | ||
592 | !subgroupOf.groups && ( subgroupOf.groups = [] ) ; | ||
593 | |||
594 | if ( previous ) { | ||
595 | // Search the "previous" item and add the new one after it. | ||
596 | previous = CKEDITOR.tools.indexOf( subgroupOf.groups, previous ); | ||
597 | if ( previous >= 0 ) { | ||
598 | subgroupOf.groups.splice( previous + 1, 0, name ); | ||
599 | return; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | // If no previous found. | ||
604 | |||
605 | if ( atStart ) | ||
606 | subgroupOf.groups.splice( 0, 0, name ); | ||
607 | else | ||
608 | subgroupOf.groups.push( name ); | ||
609 | return; | ||
610 | } else { | ||
611 | // Ignore "previous" if subgroupOf has not been found. | ||
612 | previous = null; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | if ( previous ) { | ||
617 | // Transform the "previous" name into its index. | ||
618 | previous = CKEDITOR.tools.indexOf( toolbarGroups, function( group ) { | ||
619 | return group.name == previous; | ||
620 | } ); | ||
621 | } | ||
622 | |||
623 | if ( atStart ) | ||
624 | toolbarGroups.splice( 0, 0, name ); | ||
625 | else if ( typeof previous == 'number' ) | ||
626 | toolbarGroups.splice( previous + 1, 0, newGroup ); | ||
627 | else | ||
628 | toolbarGroups.push( name ); | ||
629 | }; | ||
630 | |||
631 | function getPrivateToolbarGroups( editor ) { | ||
632 | return editor._.toolbarGroups || ( editor._.toolbarGroups = [ | ||
633 | { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, | ||
634 | { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, | ||
635 | { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, | ||
636 | { name: 'forms' }, | ||
637 | '/', | ||
638 | { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, | ||
639 | { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] }, | ||
640 | { name: 'links' }, | ||
641 | { name: 'insert' }, | ||
642 | '/', | ||
643 | { name: 'styles' }, | ||
644 | { name: 'colors' }, | ||
645 | { name: 'tools' }, | ||
646 | { name: 'others' }, | ||
647 | { name: 'about' } | ||
648 | ] ); | ||
649 | } | ||
650 | } )(); | ||
651 | |||
652 | /** | ||
653 | * Separator UI element. | ||
654 | * | ||
655 | * @readonly | ||
656 | * @property {String} [='separator'] | ||
657 | * @member CKEDITOR | ||
658 | */ | ||
659 | CKEDITOR.UI_SEPARATOR = 'separator'; | ||
660 | |||
661 | /** | ||
662 | * The part of the user interface where the toolbar will be rendered. For the default | ||
663 | * editor implementation, the recommended options are `'top'` and `'bottom'`. | ||
664 | * | ||
665 | * Please note that this option is only applicable to [classic](#!/guide/dev_framed) | ||
666 | * (`iframe`-based) editor. In case of [inline](#!/guide/dev_inline) editor the toolbar | ||
667 | * position is set dynamically depending on the position of the editable element on the screen. | ||
668 | * | ||
669 | * Read more in the [documentation](#!/guide/dev_toolbarlocation) | ||
670 | * and see the [SDK sample](http://sdk.ckeditor.com/samples/toolbarlocation.html). | ||
671 | * | ||
672 | * config.toolbarLocation = 'bottom'; | ||
673 | * | ||
674 | * @cfg | ||
675 | * @member CKEDITOR.config | ||
676 | */ | ||
677 | CKEDITOR.config.toolbarLocation = 'top'; | ||
678 | |||
679 | /** | ||
680 | * The toolbox (alias toolbar) definition. It is a toolbar name or an array of | ||
681 | * toolbars (strips), each one being also an array, containing a list of UI items. | ||
682 | * | ||
683 | * If set to `null`, the toolbar will be generated automatically using all available buttons | ||
684 | * and {@link #toolbarGroups} as a toolbar groups layout. | ||
685 | * | ||
686 | * In CKEditor 4.5+ you can generate your toolbar customization code by using the [visual | ||
687 | * toolbar configurator](http://docs.ckeditor.com/#!/guide/dev_toolbar). | ||
688 | * | ||
689 | * // Defines a toolbar with only one strip containing the "Source" button, a | ||
690 | * // separator, and the "Bold" and "Italic" buttons. | ||
691 | * config.toolbar = [ | ||
692 | * [ 'Source', '-', 'Bold', 'Italic' ] | ||
693 | * ]; | ||
694 | * | ||
695 | * // Similar to the example above, defines a "Basic" toolbar with only one strip containing three buttons. | ||
696 | * // Note that this setting is composed by "toolbar_" added to the toolbar name, which in this case is called "Basic". | ||
697 | * // This second part of the setting name can be anything. You must use this name in the CKEDITOR.config.toolbar setting | ||
698 | * // in order to instruct the editor which `toolbar_(name)` setting should be used. | ||
699 | * config.toolbar_Basic = [ | ||
700 | * [ 'Source', '-', 'Bold', 'Italic' ] | ||
701 | * ]; | ||
702 | * // Load toolbar_Name where Name = Basic. | ||
703 | * config.toolbar = 'Basic'; | ||
704 | * | ||
705 | * @cfg {Array/String} [toolbar=null] | ||
706 | * @member CKEDITOR.config | ||
707 | */ | ||
708 | |||
709 | /** | ||
710 | * The toolbar groups definition. | ||
711 | * | ||
712 | * If the toolbar layout is not explicitly defined by the {@link #toolbar} setting, then | ||
713 | * this setting is used to group all defined buttons (see {@link CKEDITOR.ui#addButton}). | ||
714 | * Buttons are associated with toolbar groups by the `toolbar` property in their definition objects. | ||
715 | * | ||
716 | * New groups may be dynamically added during the editor and plugin initialization by | ||
717 | * {@link CKEDITOR.ui#addToolbarGroup}. This is only possible if the default setting was used. | ||
718 | * | ||
719 | * // Default setting. | ||
720 | * config.toolbarGroups = [ | ||
721 | * { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, | ||
722 | * { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, | ||
723 | * { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] }, | ||
724 | * { name: 'forms' }, | ||
725 | * '/', | ||
726 | * { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, | ||
727 | * { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] }, | ||
728 | * { name: 'links' }, | ||
729 | * { name: 'insert' }, | ||
730 | * '/', | ||
731 | * { name: 'styles' }, | ||
732 | * { name: 'colors' }, | ||
733 | * { name: 'tools' }, | ||
734 | * { name: 'others' }, | ||
735 | * { name: 'about' } | ||
736 | * ]; | ||
737 | * | ||
738 | * @cfg {Array} [toolbarGroups=see example] | ||
739 | * @member CKEDITOR.config | ||
740 | */ | ||
741 | |||
742 | /** | ||
743 | * Whether the toolbar can be collapsed by the user. If disabled, the Collapse Toolbar | ||
744 | * button will not be displayed. | ||
745 | * | ||
746 | * config.toolbarCanCollapse = true; | ||
747 | * | ||
748 | * @cfg {Boolean} [toolbarCanCollapse=false] | ||
749 | * @member CKEDITOR.config | ||
750 | */ | ||
751 | |||
752 | /** | ||
753 | * Whether the toolbar must start expanded when the editor is loaded. | ||
754 | * | ||
755 | * Setting this option to `false` will affect the toolbar only when | ||
756 | * {@link #toolbarCanCollapse} is set to `true`: | ||
757 | * | ||
758 | * config.toolbarCanCollapse = true; | ||
759 | * config.toolbarStartupExpanded = false; | ||
760 | * | ||
761 | * @cfg {Boolean} [toolbarStartupExpanded=true] | ||
762 | * @member CKEDITOR.config | ||
763 | */ | ||
764 | |||
765 | /** | ||
766 | * When enabled, causes the *Arrow* keys navigation to cycle within the current | ||
767 | * toolbar group. Otherwise the *Arrow* keys will move through all items available in | ||
768 | * the toolbar. The *Tab* key will still be used to quickly jump among the | ||
769 | * toolbar groups. | ||
770 | * | ||
771 | * config.toolbarGroupCycling = false; | ||
772 | * | ||
773 | * @since 3.6 | ||
774 | * @cfg {Boolean} [toolbarGroupCycling=true] | ||
775 | * @member CKEDITOR.config | ||
776 | */ | ||
777 | |||
778 | /** | ||
779 | * List of toolbar button names that must not be rendered. This will also work | ||
780 | * for non-button toolbar items, like the Font drop-down list. | ||
781 | * | ||
782 | * config.removeButtons = 'Underline,JustifyCenter'; | ||
783 | * | ||
784 | * This configuration option should not be overused. The recommended way is to use the | ||
785 | * {@link CKEDITOR.config#removePlugins} setting to remove features from the editor | ||
786 | * or even better, [create a custom editor build](http://ckeditor.com/builder) with | ||
787 | * just the features that you will use. | ||
788 | * In some cases though, a single plugin may define a set of toolbar buttons and | ||
789 | * `removeButtons` may be useful when just a few of them are to be removed. | ||
790 | * | ||
791 | * @cfg {String} [removeButtons] | ||
792 | * @member CKEDITOR.config | ||
793 | */ | ||
794 | |||
795 | /** | ||
796 | * The toolbar definition used by the editor. It is created from the | ||
797 | * {@link CKEDITOR.config#toolbar} option if it is set or automatically | ||
798 | * based on {@link CKEDITOR.config#toolbarGroups}. | ||
799 | * | ||
800 | * @readonly | ||
801 | * @property {Object} toolbar | ||
802 | * @member CKEDITOR.editor | ||
803 | */ | ||