]>
git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blob - sources/plugins/toolbar/plugin.js
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
7 * @fileOverview The "toolbar" plugin. Renders the default toolbar interface in
12 var toolbox = function() {
14 this.focusCommandExecuted
= false;
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
++ ]; ) {
30 modes: { wysiwyg: 1, source: 1 },
33 exec: function( editor
) {
34 if ( editor
.toolbox
) {
35 editor
.toolbox
.focusCommandExecuted
= true;
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();
44 editor
.toolbox
.focus();
51 CKEDITOR
.plugins
.add( 'toolbar', {
53 // jscs:disable maximumLineLength
54 lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,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,oc,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
57 init: function( editor
) {
60 var itemKeystroke = function( item
, keystroke
) {
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;
68 toolbarGroupCycling
= toolbarGroupCycling
=== undefined || toolbarGroupCycling
;
70 switch ( keystroke
) {
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 ] );
79 toolbar
= ( ( toolbar
? toolbar
.previous : item
.toolbar
.previous
) || editor
.toolbox
.toolbars
[ editor
.toolbox
.toolbars
.length
- 1 ] );
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
;
102 // Look for the next item in the toolbar.
105 // If it's the last item, cycle to the first one.
106 if ( !next
&& toolbarGroupCycling
) next
= item
.toolbar
.items
[ 0 ];
108 while ( next
&& !next
.focus
);
110 // If available, just focus it, otherwise focus the
116 itemKeystroke( item
, 9 );
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 );
127 // Send left arrow key.
128 itemKeystroke( item
, keystroke
== 40 ? rightKeyCode : leftKeyCode
);
135 // Look for the previous item in the toolbar.
136 next
= next
.previous
;
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 ];
141 while ( next
&& !next
.focus
);
143 // If available, just focus it, otherwise focus the
149 // Send a SHIFT + TAB.
150 itemKeystroke( item
, CKEDITOR
.SHIFT
+ 9 );
168 editor
.on( 'uiSpace', function( event
) {
169 if ( event
.data
.space
!= editor
.config
.toolbarLocation
)
172 // Create toolbar only once.
173 event
.removeListener();
175 editor
.toolbox
= new toolbox();
177 var labelId
= CKEDITOR
.tools
.getNextId();
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;">'
184 var expanded
= editor
.config
.toolbarStartupExpanded
!== false,
185 groupStarted
, pendingSeparator
;
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">' ) );
192 var toolbars
= editor
.toolbox
.toolbars
,
193 toolbar
= getToolbarConfig( editor
),
194 toolbarLength
= toolbar
.length
;
196 for ( var r
= 0; r
< toolbarLength
; r
++ ) {
201 lastToolbarInRow
= row
!== '/' && ( toolbar
[ r
+ 1 ] === '/' || r
== toolbarLength
- 1 ),
204 // It's better to check if the row object is really
205 // available because it's a common mistake to leave
206 // an extra comma in the toolbar definition
207 // settings, which leads on the editor not loading
208 // at all in IE. (#3983)
212 if ( groupStarted
) {
213 output
.push( '</span>' );
215 pendingSeparator
= 0;
219 output
.push( '<span class="cke_toolbar_break"></span>' );
223 items
= row
.items
|| row
;
225 // Create all items defined for this toolbar.
226 for ( var i
= 0; i
< items
.length
; i
++ ) {
227 var item
= items
[ i
],
231 if ( item
.type
== CKEDITOR
.UI_SEPARATOR
) {
232 // Do not add the separator immediately. Just save
233 // it be included if we already have something in
234 // the toolbar and if a new item is to be added (later).
235 pendingSeparator
= groupStarted
&& item
;
239 canGroup
= item
.canGroup
!== false;
241 // Initialize the toolbar first, if needed.
243 // Create the basic toolbar object.
244 toolbarId
= CKEDITOR
.tools
.getNextId();
245 toolbarObj
= { id: toolbarId
, items: [] };
246 toolbarName
= row
.name
&& ( editor
.lang
.toolbar
.toolbarGroups
[ row
.name
] || row
.name
);
248 // Output the toolbar opener.
249 output
.push( '<span id="', toolbarId
, '" class="cke_toolbar' + ( lastToolbarInRow
? ' cke_toolbar_last"' : '"' ),
250 ( toolbarName
? ' aria-labelledby="' + toolbarId
+ '_label"' : '' ), ' role="toolbar">' );
252 // If a toolbar name is available, send the voice label.
253 toolbarName
&& output
.push( '<span id="', toolbarId
, '_label" class="cke_voice_label">', toolbarName
, '</span>' );
255 output
.push( '<span class="cke_toolbar_start"></span>' );
257 // Add the toolbar to the "editor.toolbox.toolbars"
259 var index
= toolbars
.push( toolbarObj
) - 1;
261 // Create the next/previous reference.
263 toolbarObj
.previous
= toolbars
[ index
- 1 ];
264 toolbarObj
.previous
.next
= toolbarObj
;
269 if ( !groupStarted
) {
270 output
.push( '<span class="cke_toolgroup" role="presentation">' );
273 } else if ( groupStarted
) {
274 output
.push( '</span>' );
278 function addItem( item
) { // jshint ignore:line
279 var itemObj
= item
.render( editor
, output
);
280 index
= toolbarObj
.items
.push( itemObj
) - 1;
283 itemObj
.previous
= toolbarObj
.items
[ index
- 1 ];
284 itemObj
.previous
.next
= itemObj
;
287 itemObj
.toolbar
= toolbarObj
;
288 itemObj
.onkey
= itemKeystroke
;
291 // Prevent JAWS from focusing the toolbar after document load.
292 itemObj
.onfocus = function() {
293 if ( !editor
.toolbox
.focusCommandExecuted
)
298 if ( pendingSeparator
) {
299 addItem( pendingSeparator
);
300 pendingSeparator
= 0;
307 if ( groupStarted
) {
308 output
.push( '</span>' );
310 pendingSeparator
= 0;
314 output
.push( '<span class="cke_toolbar_end"></span></span>' );
317 if ( editor
.config
.toolbarCanCollapse
)
318 output
.push( '</span>' );
320 // Not toolbar collapser for inline mode.
321 if ( editor
.config
.toolbarCanCollapse
&& editor
.elementMode
!= CKEDITOR
.ELEMENT_MODE_INLINE
) {
322 var collapserFn
= CKEDITOR
.tools
.addFunction( function() {
323 editor
.execCommand( 'toolbarCollapse' );
326 editor
.on( 'destroy', function() {
327 CKEDITOR
.tools
.removeFunction( collapserFn
);
330 editor
.addCommand( 'toolbarCollapse', {
332 exec: function( editor
) {
333 var collapser
= editor
.ui
.space( 'toolbar_collapser' ),
334 toolbox
= collapser
.getPrevious(),
335 contents
= editor
.ui
.space( 'contents' ),
336 toolboxContainer
= toolbox
.getParent(),
337 contentHeight
= parseInt( contents
.$.style
.height
, 10 ),
338 previousHeight
= toolboxContainer
.$.offsetHeight
,
339 minClass
= 'cke_toolbox_collapser_min',
340 collapsed
= collapser
.hasClass( minClass
);
344 collapser
.addClass( minClass
);
345 collapser
.setAttribute( 'title', editor
.lang
.toolbar
.toolbarExpand
);
348 collapser
.removeClass( minClass
);
349 collapser
.setAttribute( 'title', editor
.lang
.toolbar
.toolbarCollapse
);
352 // Update collapser symbol.
353 collapser
.getFirst().setText( collapsed
? '\u25B2' : // BLACK UP-POINTING TRIANGLE
354 '\u25C0' ); // BLACK LEFT-POINTING TRIANGLE
356 var dy
= toolboxContainer
.$.offsetHeight
- previousHeight
;
357 contents
.setStyle( 'height', ( contentHeight
- dy
) + 'px' );
359 editor
.fire( 'resize', {
360 outerHeight: editor
.container
.$.offsetHeight
,
361 contentsHeight: contents
.$.offsetHeight
,
362 outerWidth: editor
.container
.$.offsetWidth
366 modes: { wysiwyg: 1, source: 1 }
369 editor
.setKeystroke( CKEDITOR
.ALT
+ ( CKEDITOR
.env
.ie
|| CKEDITOR
.env
.webkit
? 189 : 109 ) /*-*/, 'toolbarCollapse' );
371 output
.push( '<a title="' + ( expanded
? editor
.lang
.toolbar
.toolbarCollapse : editor
.lang
.toolbar
.toolbarExpand
) +
372 '" id="' + editor
.ui
.spaceId( 'toolbar_collapser' ) +
373 '" tabIndex="-1" class="cke_toolbox_collapser' );
376 output
.push( ' cke_toolbox_collapser_min' );
378 output
.push( '" onclick="CKEDITOR.tools.callFunction(' + collapserFn
+ ')">', '<span class="cke_arrow">▲</span>', // BLACK UP-POINTING TRIANGLE
382 output
.push( '</span>' );
383 event
.data
.html
+= output
.join( '' );
386 editor
.on( 'destroy', function() {
387 if ( this.toolbox
) {
391 toolbars
= this.toolbox
.toolbars
;
392 for ( ; index
< toolbars
.length
; index
++ ) {
393 items
= toolbars
[ index
].items
;
394 for ( i
= 0; i
< items
.length
; i
++ ) {
395 instance
= items
[ i
];
396 if ( instance
.clickFn
)
397 CKEDITOR
.tools
.removeFunction( instance
.clickFn
);
398 if ( instance
.keyDownFn
)
399 CKEDITOR
.tools
.removeFunction( instance
.keyDownFn
);
405 // Manage editor focus when navigating the toolbar.
406 editor
.on( 'uiReady', function() {
407 var toolbox
= editor
.ui
.space( 'toolbox' );
408 toolbox
&& editor
.focusManager
.add( toolbox
, 1 );
411 editor
.addCommand( 'toolbarFocus', commands
.toolbarFocus
);
412 editor
.setKeystroke( CKEDITOR
.ALT
+ 121 /*F10*/, 'toolbarFocus' );
414 editor
.ui
.add( '-', CKEDITOR
.UI_SEPARATOR
, {} );
415 editor
.ui
.addHandler( CKEDITOR
.UI_SEPARATOR
, {
418 render: function( editor
, output
) {
419 output
.push( '<span class="cke_toolbar_separator" role="separator"></span>' );
428 function getToolbarConfig( editor
) {
429 var removeButtons
= editor
.config
.removeButtons
;
431 removeButtons
= removeButtons
&& removeButtons
.split( ',' );
433 function buildToolbarConfig() {
435 // Object containing all toolbar groups used by ui items.
436 var lookup
= getItemDefinedGroups();
438 // Take the base for the new toolbar, which is basically a toolbar
439 // definition without items.
440 var toolbar
= CKEDITOR
.tools
.clone( editor
.config
.toolbarGroups
) || getPrivateToolbarGroups( editor
);
442 // Fill the toolbar groups with the available ui items.
443 for ( var i
= 0; i
< toolbar
.length
; i
++ ) {
444 var toolbarGroup
= toolbar
[ i
];
446 // Skip toolbar break.
447 if ( toolbarGroup
== '/' )
449 // Handle simply group name item.
450 else if ( typeof toolbarGroup
== 'string' )
451 toolbarGroup
= toolbar
[ i
] = { name: toolbarGroup
};
453 var items
, subGroups
= toolbarGroup
.groups
;
455 // Look for items that match sub groups.
457 for ( var j
= 0, sub
; j
< subGroups
.length
; j
++ ) {
458 sub
= subGroups
[ j
];
460 // If any ui item is registered for this subgroup.
461 items
= lookup
[ sub
];
462 items
&& fillGroup( toolbarGroup
, items
);
466 // Add the main group items as well.
467 items
= lookup
[ toolbarGroup
.name
];
468 items
&& fillGroup( toolbarGroup
, items
);
474 // Returns an object containing all toolbar groups used by ui items.
475 function getItemDefinedGroups() {
477 itemName
, item
, itemToolbar
, group
, order
;
479 for ( itemName
in editor
.ui
.items
) {
480 item
= editor
.ui
.items
[ itemName
];
481 itemToolbar
= item
.toolbar
|| 'others';
483 // Break the toolbar property into its parts: "group_name[,order]".
484 itemToolbar
= itemToolbar
.split( ',' );
485 group
= itemToolbar
[ 0 ];
486 order
= parseInt( itemToolbar
[ 1 ] || -1, 10 );
488 // Initialize the group, if necessary.
489 groups
[ group
] || ( groups
[ group
] = [] );
491 // Push the data used to build the toolbar later.
492 groups
[ group
].push( { name: itemName
, order: order
} );
496 // Put the items in the right order.
497 for ( group
in groups
) {
498 groups
[ group
] = groups
[ group
].sort( function( a
, b
) {
499 return a
.order
== b
.order
? 0 :
502 a
.order
< b
.order
? -1 :
510 function fillGroup( toolbarGroup
, uiItems
) {
511 if ( uiItems
.length
) {
512 if ( toolbarGroup
.items
)
513 toolbarGroup
.items
.push( editor
.ui
.create( '-' ) );
515 toolbarGroup
.items
= [];
518 while ( ( item
= uiItems
.shift() ) ) {
519 name
= typeof item
== 'string' ? item : item
.name
;
521 // Ignore items that are configured to be removed.
522 if ( !removeButtons
|| CKEDITOR
.tools
.indexOf( removeButtons
, name
) == -1 ) {
523 item
= editor
.ui
.create( name
);
528 if ( !editor
.addFeature( item
) )
531 toolbarGroup
.items
.push( item
);
537 function populateToolbarConfig( config
) {
541 for ( i
= 0; i
< config
.length
; ++i
) {
546 toolbar
.push( group
);
547 else if ( CKEDITOR
.tools
.isArray( group
) ) {
548 fillGroup( newGroup
, CKEDITOR
.tools
.clone( group
) );
549 toolbar
.push( newGroup
);
551 else if ( group
.items
) {
552 fillGroup( newGroup
, CKEDITOR
.tools
.clone( group
.items
) );
553 newGroup
.name
= group
.name
;
554 toolbar
.push( newGroup
);
561 var toolbar
= editor
.config
.toolbar
;
563 // If it is a string, return the relative "toolbar_name" config.
564 if ( typeof toolbar
== 'string' )
565 toolbar
= editor
.config
[ 'toolbar_' + toolbar
];
567 return ( editor
.toolbar
= toolbar
? populateToolbarConfig( toolbar
) : buildToolbarConfig() );
571 * Adds a toolbar group. See {@link CKEDITOR.config#toolbarGroups} for more details.
573 * **Note:** This method will not modify toolbar groups set explicitly by
574 * {@link CKEDITOR.config#toolbarGroups}. It will only extend the default setting.
576 * @param {String} name Toolbar group name.
577 * @param {Number/String} previous The name of the toolbar group after which this one
578 * should be added or `0` if this group should be the first one.
579 * @param {String} [subgroupOf] The name of the parent group.
580 * @member CKEDITOR.ui
582 CKEDITOR
.ui
.prototype.addToolbarGroup = function( name
, previous
, subgroupOf
) {
583 // The toolbarGroups from the privates is the one we gonna use for automatic toolbar creation.
584 var toolbarGroups
= getPrivateToolbarGroups( this.editor
),
585 atStart
= previous
=== 0,
586 newGroup
= { name: name
};
589 // Transform the subgroupOf name in the real subgroup object.
590 subgroupOf
= CKEDITOR
.tools
.search( toolbarGroups
, function( group
) {
591 return group
.name
== subgroupOf
;
595 !subgroupOf
.groups
&& ( subgroupOf
.groups
= [] ) ;
598 // Search the "previous" item and add the new one after it.
599 previous
= CKEDITOR
.tools
.indexOf( subgroupOf
.groups
, previous
);
600 if ( previous
>= 0 ) {
601 subgroupOf
.groups
.splice( previous
+ 1, 0, name
);
606 // If no previous found.
609 subgroupOf
.groups
.splice( 0, 0, name
);
611 subgroupOf
.groups
.push( name
);
614 // Ignore "previous" if subgroupOf has not been found.
620 // Transform the "previous" name into its index.
621 previous
= CKEDITOR
.tools
.indexOf( toolbarGroups
, function( group
) {
622 return group
.name
== previous
;
627 toolbarGroups
.splice( 0, 0, name
);
628 else if ( typeof previous
== 'number' )
629 toolbarGroups
.splice( previous
+ 1, 0, newGroup
);
631 toolbarGroups
.push( name
);
634 function getPrivateToolbarGroups( editor
) {
635 return editor
._
.toolbarGroups
|| ( editor
._
.toolbarGroups
= [
636 { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
637 { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
638 { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
641 { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
642 { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
656 * Separator UI element.
659 * @property {String} [='separator']
662 CKEDITOR
.UI_SEPARATOR
= 'separator';
665 * The part of the user interface where the toolbar will be rendered. For the default
666 * editor implementation, the recommended options are `'top'` and `'bottom'`.
668 * Please note that this option is only applicable to [classic](#!/guide/dev_framed)
669 * (`iframe`-based) editor. In case of [inline](#!/guide/dev_inline) editor the toolbar
670 * position is set dynamically depending on the position of the editable element on the screen.
672 * Read more in the [documentation](#!/guide/dev_toolbarlocation)
673 * and see the [SDK sample](http://sdk.ckeditor.com/samples/toolbarlocation.html).
675 * config.toolbarLocation = 'bottom';
678 * @member CKEDITOR.config
680 CKEDITOR
.config
.toolbarLocation
= 'top';
683 * The toolbox (alias toolbar) definition. It is a toolbar name or an array of
684 * toolbars (strips), each one being also an array, containing a list of UI items.
686 * If set to `null`, the toolbar will be generated automatically using all available buttons
687 * and {@link #toolbarGroups} as a toolbar groups layout.
689 * In CKEditor 4.5+ you can generate your toolbar customization code by using the [visual
690 * toolbar configurator](http://docs.ckeditor.com/#!/guide/dev_toolbar).
692 * // Defines a toolbar with only one strip containing the "Source" button, a
693 * // separator, and the "Bold" and "Italic" buttons.
695 * [ 'Source', '-', 'Bold', 'Italic' ]
698 * // Similar to the example above, defines a "Basic" toolbar with only one strip containing three buttons.
699 * // Note that this setting is composed by "toolbar_" added to the toolbar name, which in this case is called "Basic".
700 * // This second part of the setting name can be anything. You must use this name in the CKEDITOR.config.toolbar setting
701 * // in order to instruct the editor which `toolbar_(name)` setting should be used.
702 * config.toolbar_Basic = [
703 * [ 'Source', '-', 'Bold', 'Italic' ]
705 * // Load toolbar_Name where Name = Basic.
706 * config.toolbar = 'Basic';
708 * @cfg {Array/String} [toolbar=null]
709 * @member CKEDITOR.config
713 * The toolbar groups definition.
715 * If the toolbar layout is not explicitly defined by the {@link #toolbar} setting, then
716 * this setting is used to group all defined buttons (see {@link CKEDITOR.ui#addButton}).
717 * Buttons are associated with toolbar groups by the `toolbar` property in their definition objects.
719 * New groups may be dynamically added during the editor and plugin initialization by
720 * {@link CKEDITOR.ui#addToolbarGroup}. This is only possible if the default setting was used.
722 * // Default setting.
723 * config.toolbarGroups = [
724 * { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
725 * { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
726 * { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
729 * { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
730 * { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
732 * { name: 'insert' },
734 * { name: 'styles' },
735 * { name: 'colors' },
737 * { name: 'others' },
741 * @cfg {Array} [toolbarGroups=see example]
742 * @member CKEDITOR.config
746 * Whether the toolbar can be collapsed by the user. If disabled, the Collapse Toolbar
747 * button will not be displayed.
749 * config.toolbarCanCollapse = true;
751 * @cfg {Boolean} [toolbarCanCollapse=false]
752 * @member CKEDITOR.config
756 * Whether the toolbar must start expanded when the editor is loaded.
758 * Setting this option to `false` will affect the toolbar only when
759 * {@link #toolbarCanCollapse} is set to `true`:
761 * config.toolbarCanCollapse = true;
762 * config.toolbarStartupExpanded = false;
764 * @cfg {Boolean} [toolbarStartupExpanded=true]
765 * @member CKEDITOR.config
769 * When enabled, causes the *Arrow* keys navigation to cycle within the current
770 * toolbar group. Otherwise the *Arrow* keys will move through all items available in
771 * the toolbar. The *Tab* key will still be used to quickly jump among the
774 * config.toolbarGroupCycling = false;
777 * @cfg {Boolean} [toolbarGroupCycling=true]
778 * @member CKEDITOR.config
782 * List of toolbar button names that must not be rendered. This will also work
783 * for non-button toolbar items, like the Font drop-down list.
785 * config.removeButtons = 'Underline,JustifyCenter';
787 * This configuration option should not be overused. The recommended way is to use the
788 * {@link CKEDITOR.config#removePlugins} setting to remove features from the editor
789 * or even better, [create a custom editor build](http://ckeditor.com/builder) with
790 * just the features that you will use.
791 * In some cases though, a single plugin may define a set of toolbar buttons and
792 * `removeButtons` may be useful when just a few of them are to be removed.
794 * @cfg {String} [removeButtons]
795 * @member CKEDITOR.config
799 * The toolbar definition used by the editor. It is created from the
800 * {@link CKEDITOR.config#toolbar} option if it is set or automatically
801 * based on {@link CKEDITOR.config#toolbarGroups}.
804 * @property {Object} toolbar
805 * @member CKEDITOR.editor