|
1 /* global tinymce, getUserSetting, setUserSetting */ |
|
2 |
|
3 // Set the minimum value for the modals z-index higher than #wpadminbar (100000) |
|
4 tinymce.ui.FloatPanel.zIndex = 100100; |
|
5 |
|
6 tinymce.PluginManager.add( 'wordpress', function( editor ) { |
|
7 var DOM = tinymce.DOM, |
|
8 each = tinymce.each, |
|
9 __ = editor.editorManager.i18n.translate, |
|
10 wpAdvButton, style, |
|
11 last = 0; |
|
12 |
|
13 if ( typeof window.jQuery !== 'undefined' ) { |
|
14 window.jQuery( document ).triggerHandler( 'tinymce-editor-setup', [ editor ] ); |
|
15 } |
|
16 |
|
17 function toggleToolbars( state ) { |
|
18 var iframe, initial, toolbars, |
|
19 pixels = 0; |
|
20 |
|
21 initial = ( state === 'hide' ); |
|
22 |
|
23 if ( editor.theme.panel ) { |
|
24 toolbars = editor.theme.panel.find('.toolbar:not(.menubar)'); |
|
25 } |
|
26 |
|
27 if ( ! toolbars || toolbars.length < 2 || ( state === 'hide' && ! toolbars[1].visible() ) ) { |
|
28 return; |
|
29 } |
|
30 |
|
31 if ( ! state && toolbars[1].visible() ) { |
|
32 state = 'hide'; |
|
33 } |
|
34 |
|
35 each( toolbars, function( toolbar, i ) { |
|
36 if ( i > 0 ) { |
|
37 if ( state === 'hide' ) { |
|
38 toolbar.hide(); |
|
39 pixels += 30; |
|
40 } else { |
|
41 toolbar.show(); |
|
42 pixels -= 30; |
|
43 } |
|
44 } |
|
45 }); |
|
46 |
|
47 if ( pixels && ! initial ) { |
|
48 // Resize iframe, not needed in iOS |
|
49 if ( ! tinymce.Env.iOS ) { |
|
50 iframe = editor.getContentAreaContainer().firstChild; |
|
51 DOM.setStyle( iframe, 'height', iframe.clientHeight + pixels ); |
|
52 } |
|
53 |
|
54 if ( state === 'hide' ) { |
|
55 setUserSetting('hidetb', '0'); |
|
56 wpAdvButton && wpAdvButton.active( false ); |
|
57 } else { |
|
58 setUserSetting('hidetb', '1'); |
|
59 wpAdvButton && wpAdvButton.active( true ); |
|
60 } |
|
61 } |
|
62 |
|
63 editor.fire( 'wp-toolbar-toggle' ); |
|
64 } |
|
65 |
|
66 // Add the kitchen sink button :) |
|
67 editor.addButton( 'wp_adv', { |
|
68 tooltip: 'Toolbar Toggle', |
|
69 cmd: 'WP_Adv', |
|
70 onPostRender: function() { |
|
71 wpAdvButton = this; |
|
72 wpAdvButton.active( getUserSetting( 'hidetb' ) === '1' ? true : false ); |
|
73 } |
|
74 }); |
|
75 |
|
76 // Hide the toolbars after loading |
|
77 editor.on( 'PostRender', function() { |
|
78 if ( editor.getParam( 'wordpress_adv_hidden', true ) && getUserSetting( 'hidetb', '0' ) === '0' ) { |
|
79 toggleToolbars( 'hide' ); |
|
80 } |
|
81 }); |
|
82 |
|
83 editor.addCommand( 'WP_Adv', function() { |
|
84 toggleToolbars(); |
|
85 }); |
|
86 |
|
87 editor.on( 'focus', function() { |
|
88 window.wpActiveEditor = editor.id; |
|
89 }); |
|
90 |
|
91 // Replace Read More/Next Page tags with images |
|
92 editor.on( 'BeforeSetContent', function( e ) { |
|
93 var title; |
|
94 |
|
95 if ( e.content ) { |
|
96 if ( e.content.indexOf( '<!--more' ) !== -1 ) { |
|
97 title = __( 'Read more...' ); |
|
98 |
|
99 e.content = e.content.replace( /<!--more(.*?)-->/g, function( match, moretext ) { |
|
100 return '<img src="' + tinymce.Env.transparentSrc + '" data-wp-more="more" data-wp-more-text="' + moretext + '" ' + |
|
101 'class="wp-more-tag mce-wp-more" title="' + title + '" data-mce-resize="false" data-mce-placeholder="1" />'; |
|
102 }); |
|
103 } |
|
104 |
|
105 if ( e.content.indexOf( '<!--nextpage-->' ) !== -1 ) { |
|
106 title = __( 'Page break' ); |
|
107 |
|
108 e.content = e.content.replace( /<!--nextpage-->/g, |
|
109 '<img src="' + tinymce.Env.transparentSrc + '" data-wp-more="nextpage" class="wp-more-tag mce-wp-nextpage" ' + |
|
110 'title="' + title + '" data-mce-resize="false" data-mce-placeholder="1" />' ); |
|
111 } |
|
112 } |
|
113 }); |
|
114 |
|
115 // Replace images with tags |
|
116 editor.on( 'PostProcess', function( e ) { |
|
117 if ( e.get ) { |
|
118 e.content = e.content.replace(/<img[^>]+>/g, function( image ) { |
|
119 var match, moretext = ''; |
|
120 |
|
121 if ( image.indexOf( 'data-wp-more="more"' ) !== -1 ) { |
|
122 if ( match = image.match( /data-wp-more-text="([^"]+)"/ ) ) { |
|
123 moretext = match[1]; |
|
124 } |
|
125 |
|
126 image = '<!--more' + moretext + '-->'; |
|
127 } else if ( image.indexOf( 'data-wp-more="nextpage"' ) !== -1 ) { |
|
128 image = '<!--nextpage-->'; |
|
129 } |
|
130 |
|
131 return image; |
|
132 }); |
|
133 } |
|
134 }); |
|
135 |
|
136 // Display the tag name instead of img in element path |
|
137 editor.on( 'ResolveName', function( event ) { |
|
138 var attr; |
|
139 |
|
140 if ( event.target.nodeName === 'IMG' && ( attr = editor.dom.getAttrib( event.target, 'data-wp-more' ) ) ) { |
|
141 event.name = attr; |
|
142 } |
|
143 }); |
|
144 |
|
145 // Register commands |
|
146 editor.addCommand( 'WP_More', function( tag ) { |
|
147 var parent, html, title, |
|
148 classname = 'wp-more-tag', |
|
149 dom = editor.dom, |
|
150 node = editor.selection.getNode(); |
|
151 |
|
152 tag = tag || 'more'; |
|
153 classname += ' mce-wp-' + tag; |
|
154 title = tag === 'more' ? 'Read more...' : 'Next page'; |
|
155 title = __( title ); |
|
156 html = '<img src="' + tinymce.Env.transparentSrc + '" title="' + title + '" class="' + classname + '" ' + |
|
157 'data-wp-more="' + tag + '" data-mce-resize="false" data-mce-placeholder="1" />'; |
|
158 |
|
159 // Most common case |
|
160 if ( node.nodeName === 'BODY' || ( node.nodeName === 'P' && node.parentNode.nodeName === 'BODY' ) ) { |
|
161 editor.insertContent( html ); |
|
162 return; |
|
163 } |
|
164 |
|
165 // Get the top level parent node |
|
166 parent = dom.getParent( node, function( found ) { |
|
167 if ( found.parentNode && found.parentNode.nodeName === 'BODY' ) { |
|
168 return true; |
|
169 } |
|
170 |
|
171 return false; |
|
172 }, editor.getBody() ); |
|
173 |
|
174 if ( parent ) { |
|
175 if ( parent.nodeName === 'P' ) { |
|
176 parent.appendChild( dom.create( 'p', null, html ).firstChild ); |
|
177 } else { |
|
178 dom.insertAfter( dom.create( 'p', null, html ), parent ); |
|
179 } |
|
180 |
|
181 editor.nodeChanged(); |
|
182 } |
|
183 }); |
|
184 |
|
185 editor.addCommand( 'WP_Code', function() { |
|
186 editor.formatter.toggle('code'); |
|
187 }); |
|
188 |
|
189 editor.addCommand( 'WP_Page', function() { |
|
190 editor.execCommand( 'WP_More', 'nextpage' ); |
|
191 }); |
|
192 |
|
193 editor.addCommand( 'WP_Help', function() { |
|
194 editor.windowManager.open({ |
|
195 url: tinymce.baseURL + '/wp-mce-help.php', |
|
196 title: 'Keyboard Shortcuts', |
|
197 width: 450, |
|
198 height: 420, |
|
199 classes: 'wp-help', |
|
200 buttons: { text: 'Close', onclick: 'close' } |
|
201 }); |
|
202 }); |
|
203 |
|
204 editor.addCommand( 'WP_Medialib', function() { |
|
205 if ( typeof wp !== 'undefined' && wp.media && wp.media.editor ) { |
|
206 wp.media.editor.open( editor.id ); |
|
207 } |
|
208 }); |
|
209 |
|
210 // Register buttons |
|
211 editor.addButton( 'wp_more', { |
|
212 tooltip: 'Insert Read More tag', |
|
213 onclick: function() { |
|
214 editor.execCommand( 'WP_More', 'more' ); |
|
215 } |
|
216 }); |
|
217 |
|
218 editor.addButton( 'wp_page', { |
|
219 tooltip: 'Page break', |
|
220 onclick: function() { |
|
221 editor.execCommand( 'WP_More', 'nextpage' ); |
|
222 } |
|
223 }); |
|
224 |
|
225 editor.addButton( 'wp_help', { |
|
226 tooltip: 'Keyboard Shortcuts', |
|
227 cmd: 'WP_Help' |
|
228 }); |
|
229 |
|
230 editor.addButton( 'wp_code', { |
|
231 tooltip: 'Code', |
|
232 cmd: 'WP_Code', |
|
233 stateSelector: 'code' |
|
234 }); |
|
235 |
|
236 // Menubar |
|
237 // Insert->Add Media |
|
238 if ( typeof wp !== 'undefined' && wp.media && wp.media.editor ) { |
|
239 editor.addMenuItem( 'add_media', { |
|
240 text: 'Add Media', |
|
241 icon: 'wp-media-library', |
|
242 context: 'insert', |
|
243 cmd: 'WP_Medialib' |
|
244 }); |
|
245 } |
|
246 |
|
247 // Insert "Read More..." |
|
248 editor.addMenuItem( 'wp_more', { |
|
249 text: 'Insert Read More tag', |
|
250 icon: 'wp_more', |
|
251 context: 'insert', |
|
252 onclick: function() { |
|
253 editor.execCommand( 'WP_More', 'more' ); |
|
254 } |
|
255 }); |
|
256 |
|
257 // Insert "Next Page" |
|
258 editor.addMenuItem( 'wp_page', { |
|
259 text: 'Page break', |
|
260 icon: 'wp_page', |
|
261 context: 'insert', |
|
262 onclick: function() { |
|
263 editor.execCommand( 'WP_More', 'nextpage' ); |
|
264 } |
|
265 }); |
|
266 |
|
267 editor.on( 'BeforeExecCommand', function(e) { |
|
268 if ( tinymce.Env.webkit && ( e.command === 'InsertUnorderedList' || e.command === 'InsertOrderedList' ) ) { |
|
269 if ( ! style ) { |
|
270 style = editor.dom.create( 'style', {'type': 'text/css'}, |
|
271 '#tinymce,#tinymce span,#tinymce li,#tinymce li>span,#tinymce p,#tinymce p>span{font:medium sans-serif;color:#000;line-height:normal;}'); |
|
272 } |
|
273 |
|
274 editor.getDoc().head.appendChild( style ); |
|
275 } |
|
276 }); |
|
277 |
|
278 editor.on( 'ExecCommand', function( e ) { |
|
279 if ( tinymce.Env.webkit && style && |
|
280 ( 'InsertUnorderedList' === e.command || 'InsertOrderedList' === e.command ) ) { |
|
281 |
|
282 editor.dom.remove( style ); |
|
283 } |
|
284 }); |
|
285 |
|
286 editor.on( 'init', function() { |
|
287 var env = tinymce.Env, |
|
288 bodyClass = ['mceContentBody'], // back-compat for themes that use this in editor-style.css... |
|
289 doc = editor.getDoc(), |
|
290 dom = editor.dom; |
|
291 |
|
292 if ( tinymce.Env.iOS ) { |
|
293 dom.addClass( doc.documentElement, 'ios' ); |
|
294 } |
|
295 |
|
296 if ( editor.getParam( 'directionality' ) === 'rtl' ) { |
|
297 bodyClass.push('rtl'); |
|
298 dom.setAttrib( doc.documentElement, 'dir', 'rtl' ); |
|
299 } |
|
300 |
|
301 if ( env.ie ) { |
|
302 if ( parseInt( env.ie, 10 ) === 9 ) { |
|
303 bodyClass.push('ie9'); |
|
304 } else if ( parseInt( env.ie, 10 ) === 8 ) { |
|
305 bodyClass.push('ie8'); |
|
306 } else if ( env.ie < 8 ) { |
|
307 bodyClass.push('ie7'); |
|
308 } |
|
309 } else if ( env.webkit ) { |
|
310 bodyClass.push('webkit'); |
|
311 } |
|
312 |
|
313 bodyClass.push('wp-editor'); |
|
314 |
|
315 each( bodyClass, function( cls ) { |
|
316 if ( cls ) { |
|
317 dom.addClass( doc.body, cls ); |
|
318 } |
|
319 }); |
|
320 |
|
321 // Remove invalid parent paragraphs when inserting HTML |
|
322 // TODO: still needed? |
|
323 editor.on( 'BeforeSetContent', function( e ) { |
|
324 if ( e.content ) { |
|
325 e.content = e.content.replace(/<p>\s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)( [^>]*)?>/gi, '<$1$2>'); |
|
326 e.content = e.content.replace(/<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)>\s*<\/p>/gi, '</$1>'); |
|
327 } |
|
328 }); |
|
329 |
|
330 if ( typeof window.jQuery !== 'undefined' ) { |
|
331 window.jQuery( document ).triggerHandler( 'tinymce-editor-init', [editor] ); |
|
332 } |
|
333 |
|
334 if ( window.tinyMCEPreInit && window.tinyMCEPreInit.dragDropUpload ) { |
|
335 dom.bind( doc, 'dragstart dragend dragover drop', function( event ) { |
|
336 if ( typeof window.jQuery !== 'undefined' ) { |
|
337 // Trigger the jQuery handlers. |
|
338 window.jQuery( document ).trigger( new window.jQuery.Event( event ) ); |
|
339 } |
|
340 }); |
|
341 } |
|
342 |
|
343 if ( editor.getParam( 'wp_paste_filters', true ) ) { |
|
344 if ( ! tinymce.Env.webkit ) { |
|
345 // In WebKit handled by removeWebKitStyles() |
|
346 editor.on( 'PastePreProcess', function( event ) { |
|
347 // Remove all inline styles |
|
348 event.content = event.content.replace( /(<[^>]+) style="[^"]*"([^>]*>)/gi, '$1$2' ); |
|
349 |
|
350 // Put back the internal styles |
|
351 event.content = event.content.replace(/(<[^>]+) data-mce-style=([^>]+>)/gi, '$1 style=$2' ); |
|
352 }); |
|
353 } |
|
354 |
|
355 editor.on( 'PastePostProcess', function( event ) { |
|
356 // Remove empty paragraphs |
|
357 each( dom.select( 'p', event.node ), function( node ) { |
|
358 if ( dom.isEmpty( node ) ) { |
|
359 dom.remove( node ); |
|
360 } |
|
361 }); |
|
362 }); |
|
363 } |
|
364 }); |
|
365 |
|
366 // Word count |
|
367 if ( typeof window.jQuery !== 'undefined' ) { |
|
368 editor.on( 'keyup', function( e ) { |
|
369 var key = e.keyCode || e.charCode; |
|
370 |
|
371 if ( key === last ) { |
|
372 return; |
|
373 } |
|
374 |
|
375 if ( 13 === key || 8 === last || 46 === last ) { |
|
376 window.jQuery( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ] ); |
|
377 } |
|
378 |
|
379 last = key; |
|
380 }); |
|
381 } |
|
382 |
|
383 editor.on( 'SaveContent', function( e ) { |
|
384 // If editor is hidden, we just want the textarea's value to be saved |
|
385 if ( ! editor.inline && editor.isHidden() ) { |
|
386 e.content = e.element.value; |
|
387 return; |
|
388 } |
|
389 |
|
390 // Keep empty paragraphs :( |
|
391 e.content = e.content.replace( /<p>(?:<br ?\/?>|\u00a0|\uFEFF| )*<\/p>/g, '<p> </p>' ); |
|
392 |
|
393 if ( editor.getParam( 'wpautop', true ) && typeof window.switchEditors !== 'undefined' ) { |
|
394 e.content = window.switchEditors.pre_wpautop( e.content ); |
|
395 } |
|
396 }); |
|
397 |
|
398 // Remove spaces from empty paragraphs. |
|
399 editor.on( 'BeforeSetContent', function( event ) { |
|
400 var paragraph = tinymce.Env.webkit ? '<p><br /></p>' : '<p></p>'; |
|
401 |
|
402 if ( event.content ) { |
|
403 event.content = event.content.replace( /<p>(?: |\u00a0|\uFEFF|\s)+<\/p>/gi, paragraph ); |
|
404 } |
|
405 }); |
|
406 |
|
407 editor.on( 'preInit', function() { |
|
408 // Don't replace <i> with <em> and <b> with <strong> and don't remove them when empty |
|
409 editor.schema.addValidElements( '@[id|accesskey|class|dir|lang|style|tabindex|title|contenteditable|draggable|dropzone|hidden|spellcheck|translate],i,b' ); |
|
410 |
|
411 if ( tinymce.Env.iOS ) { |
|
412 editor.settings.height = 300; |
|
413 } |
|
414 |
|
415 each( { |
|
416 c: 'JustifyCenter', |
|
417 r: 'JustifyRight', |
|
418 l: 'JustifyLeft', |
|
419 j: 'JustifyFull', |
|
420 q: 'mceBlockQuote', |
|
421 u: 'InsertUnorderedList', |
|
422 o: 'InsertOrderedList', |
|
423 s: 'unlink', |
|
424 m: 'WP_Medialib', |
|
425 z: 'WP_Adv', |
|
426 t: 'WP_More', |
|
427 d: 'Strikethrough', |
|
428 h: 'WP_Help', |
|
429 p: 'WP_Page', |
|
430 x: 'WP_Code' |
|
431 }, function( command, key ) { |
|
432 editor.shortcuts.add( 'access+' + key, '', command ); |
|
433 } ); |
|
434 |
|
435 editor.addShortcut( 'meta+s', '', function() { |
|
436 if ( typeof wp !== 'undefined' && wp.autosave ) { |
|
437 wp.autosave.server.triggerSave(); |
|
438 } |
|
439 } ); |
|
440 } ); |
|
441 |
|
442 /** |
|
443 * Experimental: create a floating toolbar. |
|
444 * This functionality will change in the next releases. Not recommended for use by plugins. |
|
445 */ |
|
446 ( function() { |
|
447 var Factory = tinymce.ui.Factory, |
|
448 settings = editor.settings, |
|
449 currentToolbar, |
|
450 currentSelection; |
|
451 |
|
452 function create( buttons ) { |
|
453 var toolbar, |
|
454 toolbarItems = [], |
|
455 buttonGroup; |
|
456 |
|
457 each( buttons, function( item ) { |
|
458 var itemName; |
|
459 |
|
460 function bindSelectorChanged() { |
|
461 var selection = editor.selection; |
|
462 |
|
463 if ( itemName === 'bullist' ) { |
|
464 selection.selectorChanged( 'ul > li', function( state, args ) { |
|
465 var i = args.parents.length, |
|
466 nodeName; |
|
467 |
|
468 while ( i-- ) { |
|
469 nodeName = args.parents[ i ].nodeName; |
|
470 |
|
471 if ( nodeName === 'OL' || nodeName == 'UL' ) { |
|
472 break; |
|
473 } |
|
474 } |
|
475 |
|
476 item.active( state && nodeName === 'UL' ); |
|
477 } ); |
|
478 } |
|
479 |
|
480 if ( itemName === 'numlist' ) { |
|
481 selection.selectorChanged( 'ol > li', function( state, args ) { |
|
482 var i = args.parents.length, |
|
483 nodeName; |
|
484 |
|
485 while ( i-- ) { |
|
486 nodeName = args.parents[ i ].nodeName; |
|
487 |
|
488 if ( nodeName === 'OL' || nodeName === 'UL' ) { |
|
489 break; |
|
490 } |
|
491 } |
|
492 |
|
493 item.active( state && nodeName === 'OL' ); |
|
494 } ); |
|
495 } |
|
496 |
|
497 if ( item.settings.stateSelector ) { |
|
498 selection.selectorChanged( item.settings.stateSelector, function( state ) { |
|
499 item.active( state ); |
|
500 }, true ); |
|
501 } |
|
502 |
|
503 if ( item.settings.disabledStateSelector ) { |
|
504 selection.selectorChanged( item.settings.disabledStateSelector, function( state ) { |
|
505 item.disabled( state ); |
|
506 } ); |
|
507 } |
|
508 } |
|
509 |
|
510 if ( item === '|' ) { |
|
511 buttonGroup = null; |
|
512 } else { |
|
513 if ( Factory.has( item ) ) { |
|
514 item = { |
|
515 type: item |
|
516 }; |
|
517 |
|
518 if ( settings.toolbar_items_size ) { |
|
519 item.size = settings.toolbar_items_size; |
|
520 } |
|
521 |
|
522 toolbarItems.push( item ); |
|
523 |
|
524 buttonGroup = null; |
|
525 } else { |
|
526 if ( ! buttonGroup ) { |
|
527 buttonGroup = { |
|
528 type: 'buttongroup', |
|
529 items: [] |
|
530 }; |
|
531 |
|
532 toolbarItems.push( buttonGroup ); |
|
533 } |
|
534 |
|
535 if ( editor.buttons[ item ] ) { |
|
536 itemName = item; |
|
537 item = editor.buttons[ itemName ]; |
|
538 |
|
539 if ( typeof item === 'function' ) { |
|
540 item = item(); |
|
541 } |
|
542 |
|
543 item.type = item.type || 'button'; |
|
544 |
|
545 if ( settings.toolbar_items_size ) { |
|
546 item.size = settings.toolbar_items_size; |
|
547 } |
|
548 |
|
549 item = Factory.create( item ); |
|
550 |
|
551 buttonGroup.items.push( item ); |
|
552 |
|
553 if ( editor.initialized ) { |
|
554 bindSelectorChanged(); |
|
555 } else { |
|
556 editor.on( 'init', bindSelectorChanged ); |
|
557 } |
|
558 } |
|
559 } |
|
560 } |
|
561 } ); |
|
562 |
|
563 toolbar = Factory.create( { |
|
564 type: 'panel', |
|
565 layout: 'stack', |
|
566 classes: 'toolbar-grp inline-toolbar-grp', |
|
567 ariaRoot: true, |
|
568 ariaRemember: true, |
|
569 items: [ { |
|
570 type: 'toolbar', |
|
571 layout: 'flow', |
|
572 items: toolbarItems |
|
573 } ] |
|
574 } ); |
|
575 |
|
576 function hide() { |
|
577 toolbar.hide(); |
|
578 } |
|
579 |
|
580 function reposition() { |
|
581 var top, left, minTop, className, |
|
582 windowPos, adminbar, mceToolbar, boundary, |
|
583 boundaryMiddle, boundaryVerticalMiddle, spaceTop, |
|
584 spaceBottom, windowWidth, toolbarWidth, toolbarHalf, |
|
585 iframe, iframePos, iframeWidth, iframeHeigth, |
|
586 toolbarNodeHeight, verticalSpaceNeeded, |
|
587 toolbarNode = this.getEl(), |
|
588 buffer = 5, |
|
589 margin = 8, |
|
590 adminbarHeight = 0; |
|
591 |
|
592 if ( ! currentSelection ) { |
|
593 return; |
|
594 } |
|
595 |
|
596 windowPos = window.pageYOffset || document.documentElement.scrollTop; |
|
597 adminbar = tinymce.$( '#wpadminbar' )[0]; |
|
598 mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0]; |
|
599 boundary = currentSelection.getBoundingClientRect(); |
|
600 boundaryMiddle = ( boundary.left + boundary.right ) / 2; |
|
601 boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2; |
|
602 spaceTop = boundary.top; |
|
603 spaceBottom = iframeHeigth - boundary.bottom; |
|
604 windowWidth = window.innerWidth; |
|
605 toolbarWidth = toolbarNode.offsetWidth; |
|
606 toolbarHalf = toolbarWidth / 2; |
|
607 iframe = document.getElementById( editor.id + '_ifr' ); |
|
608 iframePos = DOM.getPos( iframe ); |
|
609 iframeWidth = iframe.offsetWidth; |
|
610 iframeHeigth = iframe.offsetHeight; |
|
611 toolbarNodeHeight = toolbarNode.offsetHeight; |
|
612 verticalSpaceNeeded = toolbarNodeHeight + margin + buffer; |
|
613 |
|
614 if ( spaceTop >= verticalSpaceNeeded ) { |
|
615 className = ' mce-arrow-down'; |
|
616 top = boundary.top + iframePos.y - toolbarNodeHeight - margin; |
|
617 } else if ( spaceBottom >= verticalSpaceNeeded ) { |
|
618 className = ' mce-arrow-up'; |
|
619 top = boundary.bottom + iframePos.y; |
|
620 } else { |
|
621 top = buffer; |
|
622 |
|
623 if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) { |
|
624 className = ' mce-arrow-down'; |
|
625 } else { |
|
626 className = ' mce-arrow-up'; |
|
627 } |
|
628 } |
|
629 |
|
630 // Make sure the image toolbar is below the main toolbar. |
|
631 if ( mceToolbar ) { |
|
632 minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight; |
|
633 } else { |
|
634 minTop = iframePos.y; |
|
635 } |
|
636 |
|
637 // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window. |
|
638 if ( windowPos ) { |
|
639 if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) { |
|
640 adminbarHeight = adminbar.clientHeight; |
|
641 } |
|
642 |
|
643 if ( windowPos + adminbarHeight > minTop ) { |
|
644 minTop = windowPos + adminbarHeight; |
|
645 } |
|
646 } |
|
647 |
|
648 if ( top && minTop && ( minTop + buffer > top ) ) { |
|
649 top = minTop + buffer; |
|
650 className = ''; |
|
651 } |
|
652 |
|
653 left = boundaryMiddle - toolbarHalf; |
|
654 left += iframePos.x; |
|
655 |
|
656 if ( boundary.left < 0 || boundary.right > iframeWidth ) { |
|
657 left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2; |
|
658 } else if ( toolbarWidth >= windowWidth ) { |
|
659 className += ' mce-arrow-full'; |
|
660 left = 0; |
|
661 } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) || |
|
662 ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) { |
|
663 |
|
664 left = ( windowWidth - toolbarWidth ) / 2; |
|
665 } else if ( left < iframePos.x ) { |
|
666 className += ' mce-arrow-left'; |
|
667 left = boundary.left + iframePos.x; |
|
668 } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) { |
|
669 className += ' mce-arrow-right'; |
|
670 left = boundary.right - toolbarWidth + iframePos.x; |
|
671 } |
|
672 |
|
673 toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' ); |
|
674 toolbarNode.className += className; |
|
675 |
|
676 DOM.setStyles( toolbarNode, { 'left': left, 'top': top } ); |
|
677 |
|
678 return this; |
|
679 } |
|
680 |
|
681 toolbar.on( 'show', function() { |
|
682 currentToolbar = this; |
|
683 this.reposition(); |
|
684 } ); |
|
685 |
|
686 toolbar.on( 'hide', function() { |
|
687 currentToolbar = false; |
|
688 } ); |
|
689 |
|
690 toolbar.on( 'keydown', function( event ) { |
|
691 if ( event.keyCode === 27 ) { |
|
692 this.hide(); |
|
693 editor.focus(); |
|
694 } |
|
695 } ); |
|
696 |
|
697 toolbar.on( 'remove', function() { |
|
698 DOM.unbind( window, 'resize scroll', hide ); |
|
699 editor.dom.unbind( editor.getWin(), 'resize scroll', hide ); |
|
700 editor.off( 'blur hide', hide ); |
|
701 } ); |
|
702 |
|
703 editor.once( 'init', function() { |
|
704 DOM.bind( window, 'resize scroll', hide ); |
|
705 editor.dom.bind( editor.getWin(), 'resize scroll', hide ); |
|
706 editor.on( 'blur hide', hide ); |
|
707 } ); |
|
708 |
|
709 toolbar.reposition = reposition; |
|
710 toolbar.hide().renderTo( document.body ); |
|
711 |
|
712 return toolbar; |
|
713 } |
|
714 |
|
715 editor.shortcuts.add( 'alt+119', '', function() { |
|
716 var node; |
|
717 |
|
718 if ( currentToolbar ) { |
|
719 node = currentToolbar.find( 'toolbar' )[0]; |
|
720 node && node.focus( true ); |
|
721 } |
|
722 } ); |
|
723 |
|
724 editor.on( 'nodechange', function( event ) { |
|
725 var collapsed = editor.selection.isCollapsed(); |
|
726 |
|
727 var args = { |
|
728 element: event.element, |
|
729 parents: event.parents, |
|
730 collapsed: collapsed |
|
731 }; |
|
732 |
|
733 editor.fire( 'wptoolbar', args ); |
|
734 |
|
735 currentSelection = args.selection || args.element; |
|
736 |
|
737 currentToolbar && currentToolbar.hide(); |
|
738 args.toolbar && args.toolbar.show(); |
|
739 } ); |
|
740 |
|
741 editor.wp = editor.wp || {}; |
|
742 editor.wp._createToolbar = create; |
|
743 }()); |
|
744 |
|
745 function noop() {} |
|
746 |
|
747 // Expose some functions (back-compat) |
|
748 return { |
|
749 _showButtons: noop, |
|
750 _hideButtons: noop, |
|
751 _setEmbed: noop, |
|
752 _getEmbed: noop |
|
753 }; |
|
754 }); |