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