]>
Commit | Line | Data |
---|---|---|
c63493c8 IB |
1 | /* exported ToolbarConfigurator */ |
2 | /* global ToolbarConfigurator */ | |
3 | ||
4 | 'use strict'; | |
5 | ||
6 | window.ToolbarConfigurator = {}; | |
7 | ||
8 | ( function() { | |
9 | /** | |
10 | * @class ToolbarConfigurator.FullToolbarEditor | |
11 | * @constructor | |
12 | */ | |
13 | function FullToolbarEditor() { | |
14 | this.instanceid = 'fte' + CKEDITOR.tools.getNextId(); | |
15 | this.textarea = new CKEDITOR.dom.element( 'textarea' ); | |
16 | this.textarea.setAttributes( { | |
17 | id: this.instanceid, | |
18 | name: this.instanceid, | |
19 | contentEditable: true | |
20 | } ); | |
21 | ||
22 | this.buttons = null; | |
23 | this.editorInstance = null; | |
24 | } | |
25 | ||
26 | // Expose the class. | |
27 | ToolbarConfigurator.FullToolbarEditor = FullToolbarEditor; | |
28 | ||
29 | /** | |
30 | * @param {Function} callback | |
31 | * @param {Object} cfg | |
32 | */ | |
33 | FullToolbarEditor.prototype.init = function( callback ) { | |
34 | var that = this; | |
35 | ||
36 | document.body.appendChild( this.textarea.$ ); | |
37 | ||
38 | CKEDITOR.replace( this.instanceid ); | |
39 | ||
40 | this.editorInstance = CKEDITOR.instances[ this.instanceid ]; | |
41 | ||
42 | this.editorInstance.once( 'configLoaded', function( e ) { | |
43 | var cfg = e.editor.config; | |
44 | ||
45 | // We want all the buttons. | |
46 | delete cfg.removeButtons; | |
47 | delete cfg.toolbarGroups; | |
48 | delete cfg.toolbar; | |
49 | ToolbarConfigurator.AbstractToolbarModifier.extendPluginsConfig( cfg ); | |
50 | ||
51 | e.editor.once( 'loaded', function() { | |
52 | that.buttons = FullToolbarEditor.toolbarToButtons( that.editorInstance.toolbar ); | |
53 | ||
54 | that.buttonsByGroup = FullToolbarEditor.groupButtons( that.buttons ); | |
55 | ||
56 | that.buttonNamesByGroup = that.groupButtonNamesByGroup( that.buttons ); | |
57 | ||
58 | e.editor.container.hide(); | |
59 | ||
60 | if ( typeof callback === 'function' ) | |
61 | callback( that.buttons ); | |
62 | } ); | |
63 | } ); | |
64 | }; | |
65 | ||
66 | /** | |
67 | * Group array of button names by their group parents. | |
68 | * | |
69 | * @param {Array} buttons | |
70 | * @returns {Object} | |
71 | */ | |
72 | FullToolbarEditor.prototype.groupButtonNamesByGroup = function( buttons ) { | |
73 | var that = this, | |
74 | groups = FullToolbarEditor.groupButtons( buttons ); | |
75 | ||
76 | for ( var groupName in groups ) { | |
77 | var currGroup = groups[ groupName ]; | |
78 | ||
79 | groups[ groupName ] = FullToolbarEditor.map( currGroup, function( button ) { | |
80 | return that.getCamelCasedButtonName( button.name ); | |
81 | } ); | |
82 | } | |
83 | ||
84 | return groups; | |
85 | }; | |
86 | ||
87 | /** | |
88 | * Returns group literal. | |
89 | * | |
90 | * @param {String} name | |
91 | * @returns {Object} | |
92 | */ | |
93 | FullToolbarEditor.prototype.getGroupByName = function( name ) { | |
94 | var groups = this.editorInstance.config.toolbarGroups || this.getFullToolbarGroupsConfig(); | |
95 | ||
96 | var max = groups.length; | |
97 | for ( var i = 0; i < max; i += 1 ) { | |
98 | if ( groups[ i ].name === name ) | |
99 | return groups[ i ]; | |
100 | } | |
101 | ||
102 | return null; | |
103 | }; | |
104 | ||
105 | /** | |
106 | * @param {String} name | |
107 | * @returns {String | null} | |
108 | */ | |
109 | FullToolbarEditor.prototype.getCamelCasedButtonName = function( name ) { | |
110 | var items = this.editorInstance.ui.items; | |
111 | ||
112 | for ( var key in items ) { | |
113 | if ( items[ key ].name == name ) | |
114 | return key; | |
115 | } | |
116 | ||
117 | return null; | |
118 | }; | |
119 | ||
120 | /** | |
121 | * Returns full toolbarGroups config value which is used when | |
122 | * there is no toolbarGroups field in config. | |
123 | * | |
124 | * @param {Boolean} [pickSeparators=false] | |
125 | * @returns {Array} | |
126 | */ | |
127 | FullToolbarEditor.prototype.getFullToolbarGroupsConfig = function( pickSeparators ) { | |
128 | pickSeparators = ( pickSeparators === true ? true : false ); | |
129 | ||
130 | var result = [], | |
131 | toolbarGroups = this.editorInstance.toolbar; | |
132 | ||
133 | var max = toolbarGroups.length; | |
134 | for ( var i = 0; i < max; i += 1 ) { | |
135 | var currentGroup = toolbarGroups[ i ], | |
136 | copiedGroup = {}; | |
137 | ||
138 | if ( typeof currentGroup.name != 'string' ) { | |
139 | // this is not a group | |
140 | if ( pickSeparators ) { | |
141 | result.push( '/' ); | |
142 | } | |
143 | continue; | |
144 | } | |
145 | ||
146 | copiedGroup.name = currentGroup.name; | |
147 | if ( currentGroup.groups ) | |
148 | copiedGroup.groups = Array.prototype.slice.call( currentGroup.groups ); | |
149 | ||
150 | result.push( copiedGroup ); | |
151 | } | |
152 | ||
153 | return result; | |
154 | }; | |
155 | ||
156 | /** | |
157 | * Filters array items based on checker provided in second argument. | |
158 | * Returns new array. | |
159 | * | |
160 | * @param {Array} arr | |
161 | * @param {Function} checker | |
162 | * @returns {Array} | |
163 | */ | |
164 | FullToolbarEditor.filter = function( arr, checker ) { | |
165 | var max = ( arr && arr.length ? arr.length : 0 ), | |
166 | result = []; | |
167 | ||
168 | for ( var i = 0; i < max; i += 1 ) { | |
169 | if ( checker( arr[ i ] ) ) | |
170 | result.push( arr[ i ] ); | |
171 | } | |
172 | ||
173 | return result; | |
174 | }; | |
175 | ||
176 | /** | |
177 | * Simplified http://underscorejs.org/#map functionality | |
178 | * | |
179 | * @param {Array | Object} enumerable | |
180 | * @param {Function} modifier | |
181 | * @returns {Array | Object} | |
182 | */ | |
183 | FullToolbarEditor.map = function( enumerable, modifier ) { | |
184 | var result; | |
185 | ||
186 | if ( CKEDITOR.tools.isArray( enumerable ) ) { | |
187 | result = []; | |
188 | ||
189 | var max = enumerable.length; | |
190 | for ( var i = 0; i < max; i += 1 ) | |
191 | result.push( modifier( enumerable[ i ] ) ); | |
192 | } else { | |
193 | result = {}; | |
194 | ||
195 | for ( var key in enumerable ) | |
196 | result[ key ] = modifier( enumerable[ key ] ); | |
197 | } | |
198 | ||
199 | return result; | |
200 | }; | |
201 | ||
202 | /** | |
203 | * Group buttons by their parent names. | |
204 | * | |
205 | * @static | |
206 | * @param {Array} buttons | |
207 | * @returns {Object} The object (`name => group`) representing CKEDITOR.ui.button or CKEDITOR.ui.richCombo | |
208 | */ | |
209 | FullToolbarEditor.groupButtons = function( buttons ) { | |
210 | var groups = {}; | |
211 | ||
212 | var max = buttons.length; | |
213 | for ( var i = 0; i < max; i += 1 ) { | |
214 | var currBtn = buttons[ i ], | |
215 | currBtnGroupName = currBtn.toolbar.split( ',' )[ 0 ]; | |
216 | ||
217 | groups[ currBtnGroupName ] = groups[ currBtnGroupName ] || []; | |
218 | ||
219 | groups[ currBtnGroupName ].push( currBtn ); | |
220 | } | |
221 | ||
222 | return groups; | |
223 | }; | |
224 | ||
225 | /** | |
226 | * Pick all buttons from toolbar. | |
227 | * | |
228 | * @static | |
229 | * @param {Array} groups | |
230 | * @returns {Array} | |
231 | */ | |
232 | FullToolbarEditor.toolbarToButtons = function( groups ) { | |
233 | var buttons = []; | |
234 | ||
235 | var max = groups.length; | |
236 | for ( var i = 0; i < max; i += 1 ) { | |
237 | var currentGroup = groups[ i ]; | |
238 | ||
239 | if ( typeof currentGroup == 'object' ) | |
240 | buttons = buttons.concat( FullToolbarEditor.groupToButtons( groups[ i ] ) ); | |
241 | } | |
242 | ||
243 | return buttons; | |
244 | }; | |
245 | ||
246 | /** | |
247 | * Creates HTML button representation for view. | |
248 | * | |
249 | * @static | |
250 | * @param {CKEDITOR.ui.button | CKEDITOR.ui.richCombo} button | |
251 | * @returns {CKEDITOR.dom.element} | |
252 | */ | |
253 | FullToolbarEditor.createToolbarButton = function( button ) { | |
254 | var $button = new CKEDITOR.dom.element( 'a' ), | |
255 | icon = FullToolbarEditor.createIcon( button.name, button.icon, button.command ); | |
256 | ||
257 | $button.setStyle( 'float', 'none' ); | |
258 | ||
259 | $button.addClass( 'cke_' + ( CKEDITOR.lang.dir == 'rtl' ? 'rtl' : 'ltr' ) ); | |
260 | ||
261 | if ( button instanceof CKEDITOR.ui.button ) { | |
262 | $button.addClass( 'cke_button' ); | |
263 | $button.addClass( 'cke_toolgroup' ); | |
264 | ||
265 | $button.append( icon ); | |
266 | } else if ( CKEDITOR.ui.richCombo && button instanceof CKEDITOR.ui.richCombo ) { | |
267 | var comboLabel = new CKEDITOR.dom.element( 'span' ), | |
268 | comboOpen = new CKEDITOR.dom.element( 'span' ), | |
269 | comboArrow = new CKEDITOR.dom.element( 'span' ); | |
270 | ||
271 | $button.addClass( 'cke_combo_button' ); | |
272 | ||
273 | comboLabel.addClass( 'cke_combo_text' ); | |
274 | comboLabel.addClass( 'cke_combo_inlinelabel' ); | |
275 | comboLabel.setText( button.label ); | |
276 | ||
277 | comboOpen.addClass( 'cke_combo_open' ); | |
278 | comboArrow.addClass( 'cke_combo_arrow' ); | |
279 | comboOpen.append( comboArrow ); | |
280 | ||
281 | $button.append( comboLabel ); | |
282 | $button.append( comboOpen ); | |
283 | } | |
284 | ||
285 | return $button; | |
286 | }; | |
287 | ||
288 | /** | |
289 | * Create and return icon element. | |
290 | * | |
291 | * @param {String} name | |
292 | * @param {String} icon | |
293 | * @param {String} command | |
294 | * @static | |
295 | * @returns {CKEDITOR.dom.element} | |
296 | */ | |
297 | FullToolbarEditor.createIcon = function( name, icon, command ) { | |
298 | var iconStyle = CKEDITOR.skin.getIconStyle( name, ( CKEDITOR.lang.dir == 'rtl' ) ); | |
299 | ||
300 | // We don't know exactly how to get icon style. Especially for extra plugins, | |
301 | // Which definition may vary. | |
302 | iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( icon, ( CKEDITOR.lang.dir == 'rtl' ) ); | |
303 | iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( command, ( CKEDITOR.lang.dir == 'rtl' ) ); | |
304 | ||
305 | var iconElement = new CKEDITOR.dom.element( 'span' ); | |
306 | ||
307 | iconElement.addClass( 'cke_button_icon' ); | |
308 | iconElement.addClass( 'cke_button__' + name + '_icon' ); | |
309 | iconElement.setAttribute( 'style', iconStyle ); | |
310 | iconElement.setStyle( 'float', 'none' ); | |
311 | ||
312 | return iconElement; | |
313 | }; | |
314 | ||
315 | /** | |
316 | * Create and return button element | |
317 | * | |
318 | * @param {String} text | |
319 | * @param {String} cssClasses | |
320 | * @returns {CKEDITOR.dom.element} | |
321 | */ | |
322 | FullToolbarEditor.createButton = function( text, cssClasses ) { | |
323 | var $button = new CKEDITOR.dom.element( 'button' ); | |
324 | ||
325 | $button.addClass( 'button-a' ); | |
326 | ||
327 | $button.setAttribute( 'type', 'button' ); | |
328 | ||
329 | if ( typeof cssClasses == 'string' ) { | |
330 | cssClasses = cssClasses.split( ' ' ); | |
331 | ||
332 | var i = cssClasses.length; | |
333 | while ( i-- ) { | |
334 | $button.addClass( cssClasses[ i ] ); | |
335 | } | |
336 | } | |
337 | ||
338 | $button.setHtml( text ); | |
339 | ||
340 | return $button; | |
341 | }; | |
342 | ||
343 | /** | |
344 | * @static | |
345 | * @param {Object} group | |
346 | * @returns {Array} representing HTML buttons for view | |
347 | */ | |
348 | FullToolbarEditor.groupToButtons = function( group ) { | |
349 | var buttons = [], | |
350 | items = group.items; | |
351 | ||
352 | var max = items ? items.length : 0; | |
353 | for ( var i = 0; i < max; i += 1 ) { | |
354 | var item = items[ i ]; | |
355 | ||
356 | if ( item instanceof CKEDITOR.ui.button || CKEDITOR.ui.richCombo && item instanceof CKEDITOR.ui.richCombo ) { | |
357 | item.$ = FullToolbarEditor.createToolbarButton( item ); | |
358 | buttons.push( item ); | |
359 | } | |
360 | } | |
361 | ||
362 | return buttons; | |
363 | }; | |
364 | ||
365 | } )(); |