      1 ﻿/*
      2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
      3 For licensing, see LICENSE.html 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 {
     13 	var toolbox = function()
     14 	{
     15 		this.toolbars = [];
     16 		this.focusCommandExecuted = false;
     17 	};
     18
     19 	toolbox.prototype.focus = function()
     20 	{
     21 		for ( var t = 0, toolbar ; toolbar = this.toolbars[ t++ ] ; )
     22 		{
     23 			for ( var i = 0, item ; item = toolbar.items[ i++ ] ; )
     24 			{
     25 				if ( item.focus )
     26 				{
     27 					item.focus();
     28 					return;
     29 				}
     30 			}
     31 		}
     32 	};
     33
     34 	var commands =
     35 	{
     36 		toolbarFocus :
     37 		{
     38 			modes : { wysiwyg : 1, source : 1 },
     39
     40 			exec : function( editor )
     41 			{
     42 				if ( editor.toolbox )
     43 				{
     44 					editor.toolbox.focusCommandExecuted = true;
     45
     46 					// Make the first button focus accessible. (#3417)
     47 					if ( CKEDITOR.env.ie )
     48 						setTimeout( function(){ editor.toolbox.focus(); }, 100 );
     49 					else
     50 						editor.toolbox.focus();
     51 				}
     52 			}
     53 		}
     54 	};
     55
     56 	CKEDITOR.plugins.add( 'toolbar',
     57 	{
     58 		init : function( editor )
     59 		{
     60 			var itemKeystroke = function( item, keystroke )
     61 			{
     62 				switch ( keystroke )
     63 				{
     64 					case 39 :					// RIGHT-ARROW
     65 					case 9 :					// TAB
     66 						// Look for the next item in the toolbar.
     67 						while ( ( item = item.next || ( item.toolbar.next && item.toolbar.next.items[ 0 ] ) ) && !item.focus )
     68 						{ /*jsl:pass*/ }
     69
     70 						// If available, just focus it, otherwise focus the
     71 						// first one.
     72 						if ( item )
     73 							item.focus();
     74 						else
     75 							editor.toolbox.focus();
     76
     77 						return false;
     78
     79 					case 37 :					// LEFT-ARROW
     80 					case CKEDITOR.SHIFT + 9 :	// SHIFT + TAB
     81 						// Look for the previous item in the toolbar.
     82 						while ( ( item = item.previous || ( item.toolbar.previous && item.toolbar.previous.items[ item.toolbar.previous.items.length - 1 ] ) ) && !item.focus )
     83 						{ /*jsl:pass*/ }
     84
     85 						// If available, just focus it, otherwise focus the
     86 						// last one.
     87 						if ( item )
     88 							item.focus();
     89 						else
     90 						{
     91 							var lastToolbarItems = editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ].items;
     92 							lastToolbarItems[ lastToolbarItems.length - 1 ].focus();
     93 						}
     94
     95 						return false;
     96
     97 					case 27 :					// ESC
     98 						editor.focus();
     99 						return false;
    100
    101 					case 13 :					// ENTER
    102 					case 32 :					// SPACE
    103 						item.execute();
    104 						return false;
    105 				}
    106 				return true;
    107 			};
    108
    109 			editor.on( 'themeSpace', function( event )
    110 				{
    111 					if ( event.data.space == editor.config.toolbarLocation )
    112 					{
    113 						editor.toolbox = new toolbox();
    114
    115 						var output = [ '<div class="cke_toolbox"' ],
    116 							expanded =  editor.config.toolbarStartupExpanded,
    117 							groupStarted;
    118
    119 						output.push( expanded ? '>' : ' style="display:none">' );
    120
    121 						var toolbars = editor.toolbox.toolbars,
    122 							toolbar =
    123 									( editor.config.toolbar instanceof Array ) ?
    124 										editor.config.toolbar
    125 									:
    126 										editor.config[ 'toolbar_' + editor.config.toolbar ];
    127
    128 						for ( var r = 0 ; r < toolbar.length ; r++ )
    129 						{
    130 							var row = toolbar[ r ],
    131 								toolbarId = 'cke_' + CKEDITOR.tools.getNextNumber(),
    132 								toolbarObj = { id : toolbarId, items : [] };
    133
    134 							if ( groupStarted )
    135 							{
    136 								output.push( '</div>' );
    137 								groupStarted = 0;
    138 							}
    139
    140 							if ( row === '/' )
    141 							{
    142 								output.push( '<div class="cke_break"></div>' );
    143 								continue;
    144 							}
    145
    146 							output.push( '<span id="', toolbarId, '" class="cke_toolbar"><span class="cke_toolbar_start"></span>' );
    147
    148 							// Add the toolbar to the "editor.toolbox.toolbars"
    149 							// array.
    150 							var index = toolbars.push( toolbarObj ) - 1;
    151
    152 							// Create the next/previous reference.
    153 							if ( index > 0 )
    154 							{
    155 								toolbarObj.previous = toolbars[ index - 1 ];
    156 								toolbarObj.previous.next = toolbarObj;
    157 							}
    158
    159 							// Create all items defined for this toolbar.
    160 							for ( var i = 0 ; i < row.length ; i++ )
    161 							{
    162 								var item,
    163 									itemName = row[ i ];
    164
    165 								if ( itemName == '-' )
    166 									item = CKEDITOR.ui.separator;
    167 								else
    168 									item = editor.ui.create( itemName );
    169
    170 								if ( item )
    171 								{
    172 									if ( item.canGroup )
    173 									{
    174 										if ( !groupStarted )
    175 										{
    176 											output.push( '<span class="cke_toolgroup">' );
    177 											groupStarted = 1;
    178 										}
    179 									}
    180 									else if ( groupStarted )
    181 									{
    182 										output.push( '</span>' );
    183 										groupStarted = 0;
    184 									}
    185
    186 									var itemObj = item.render( editor, output );
    187 									index = toolbarObj.items.push( itemObj ) - 1;
    188
    189 									if ( index > 0 )
    190 									{
    191 										itemObj.previous = toolbarObj.items[ index - 1 ];
    192 										itemObj.previous.next = itemObj;
    193 									}
    194
    195 									itemObj.toolbar = toolbarObj;
    196 									itemObj.onkey = itemKeystroke;
    197
    198 									/*
    199 									 * Fix for #3052:
    200 									 * Prevent JAWS from focusing the toolbar after document load.
    201 									 */
    202 									itemObj.onfocus = function()
    203 									{
    204 										if ( !editor.toolbox.focusCommandExecuted )
    205 											editor.focus();
    206 									};
    207 								}
    208 							}
    209
    210 							if ( groupStarted )
    211 							{
    212 								output.push( '</span>' );
    213 								groupStarted = 0;
    214 							}
    215
    216 							output.push( '<span class="cke_toolbar_end"></span></span>' );
    217 						}
    218
    219 						output.push( '</div>' );
    220
    221 						if ( editor.config.toolbarCanCollapse )
    222 						{
    223 							var collapserFn = CKEDITOR.tools.addFunction(
    224 								function()
    225 								{
    226 									editor.execCommand( 'toolbarCollapse' );
    227 								} );
    228
    229 							var collapserId = 'cke_' + CKEDITOR.tools.getNextNumber();
    230
    231 							editor.addCommand( 'toolbarCollapse',
    232 								{
    233 									exec : function( editor )
    234 									{
    235 										var collapser = CKEDITOR.document.getById( collapserId );
    236 										var toolbox = collapser.getPrevious();
    237 										var contents = editor.getThemeSpace( 'contents' );
    238 										var toolboxContainer = toolbox.getParent();
    239 										var contentHeight = parseInt( contents.$.style.height, 10 );
    240 										var previousHeight = toolboxContainer.$.offsetHeight;
    241
    242 										if ( toolbox.isVisible() )
    243 										{
    244 											toolbox.hide();
    245 											collapser.addClass( 'cke_toolbox_collapser_min' );
    246 										}
    247 										else
    248 										{
    249 											toolbox.show();
    250 											collapser.removeClass( 'cke_toolbox_collapser_min' );
    251 										}
    252
    253 										var dy = toolboxContainer.$.offsetHeight - previousHeight;
    254 										contents.setStyle( 'height', ( contentHeight - dy ) + 'px' );
    255 									},
    256
    257 									modes : { wysiwyg : 1, source : 1 }
    258 								} );
    259
    260 							output.push( '<a id="' + collapserId + '" class="cke_toolbox_collapser' );
    261
    262 							if ( !expanded )
    263 								output.push( ' cke_toolbox_collapser_min' );
    264
    265 							output.push( '" onclick="CKEDITOR.tools.callFunction(' + collapserFn + ')"></a>' );
    266 						}
    267
    268 						event.data.html += output.join( '' );
    269 					}
    270 				});
    271
    272 			editor.addCommand( 'toolbarFocus', commands.toolbarFocus );
    273 		}
    274 	});
    275 })();
    276
    277 /**
    278  * The UI element that renders a toolbar separator.
    279  * @type Object
    280  * @example
    281  */
    282 CKEDITOR.ui.separator =
    283 {
    284 	render : function( editor, output )
    285 	{
    286 		output.push( '<span class="cke_separator"></span>' );
    287 		return {};
    288 	}
    289 };
    290
    291 /**
    292  * The "theme space" to which rendering the toolbar. For the default theme,
    293  * the recommended options are "top" and "bottom".
    294  * @type String
    295  * @default 'top'
    296  * @see CKEDITOR.config.theme
    297  * @example
    298  * config.toolbarLocation = 'bottom';
    299  */
    300 CKEDITOR.config.toolbarLocation = 'top';
    301
    302 /**
    303  * The toolbar definition. It is an array of toolbars (strips),
    304  * each one being also an array, containing a list of UI items.
    305  * @type Array
    306  * @example
    307  * // Defines a toolbar with only one strip containing the "Source" button, a
    308  * // separator and the "Bold" and "Italic" buttons.
    309  * <b>CKEDITOR.config.toolbar_Basic =
    310  * [
    311  *     [ 'Source', '-', 'Bold', 'Italic' ]
    312  * ]</b>;
    313  */
    314 CKEDITOR.config.toolbar_Basic =
    315 [
    316 	['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About']
    317 ];
    318
    319 CKEDITOR.config.toolbar_Full =
    320 [
    321 	['Source','-','Save','NewPage','Preview','-','Templates'],
    322 	['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
    323 	['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
    324 	['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
    325 	'/',
    326 	['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
    327 	['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
    328 	['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
    329 	['Link','Unlink','Anchor'],	['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
    330 	'/',
    331 	['Styles','Format','Font','FontSize'],
    332 	['TextColor','BGColor'],
    333 	['Maximize', 'ShowBlocks','-','About']
    334 ];
    335
    336 /**
    337  * The toolbox (alias toolbar) definition. It is a toolbar name or an array of toolbars (strips),
    338  * each one being also an array, containing a list of UI items.
    339  * @type Array or String
    340  * @example
    341  * // Defines a toolbar with only one strip containing the "Source" button, a
    342  * // separator and the "Bold" and "Italic" buttons.
    343  * <b>CKEDITOR.config.toolbar =
    344  * [
    345  *     [ 'Source', '-', 'Bold', 'Italic' ]
    346  * ]</b>;
    347  * // Load toolbar_Name where Name = Basic.
    348  * <b>CKEDITOR.config.toolbar = 'Basic';
    349  */
    350 CKEDITOR.config.toolbar = 'Full';
    351
    352 CKEDITOR.config.toolbarCanCollapse = true;
    353 CKEDITOR.config.toolbarStartupExpanded = true;
    354