| 10 | editor.addButton( 'wp_img_remove', { |
| 11 | tooltip: 'Remove', |
| 12 | icon: 'dashicon dashicons-no', |
| 13 | onclick: function() { |
| 14 | removeImage( editor.selection.getNode() ); |
| 15 | } |
| 16 | } ); |
| 17 | |
| 18 | editor.addButton( 'wp_img_edit', { |
| 19 | tooltip: 'Edit', |
| 20 | icon: 'dashicon dashicons-edit', |
| 21 | onclick: function() { |
| 22 | editImage( editor.selection.getNode() ); |
| 23 | } |
| 24 | } ); |
| 25 | |
| 26 | each( { |
| 27 | alignleft: 'Align Left', |
| 28 | aligncenter: 'Align Center', |
| 29 | alignright: 'Align Right', |
| 30 | alignnone: 'Remove Alignment' |
| 31 | }, function( tooltip, name ) { |
| 32 | var direction = name.slice( 5 ); |
| 33 | |
| 34 | editor.addButton( 'wp_img_' + name, { |
| 35 | tooltip: tooltip, |
| 36 | icon: 'dashicon dashicons-align-' + direction, |
| 37 | cmd: 'alignnone' === name ? 'wpAlignNone' : 'Justify' + direction.slice( 0, 1 ).toUpperCase() + direction.slice( 1 ), |
| 38 | onPostRender: function() { |
| 39 | var self = this; |
| 40 | |
| 41 | editor.on( 'NodeChange', function( event ) { |
| 42 | var node; |
| 43 | |
| 44 | // Don't bother. |
| 45 | if ( event.element.nodeName !== 'IMG' ) { |
| 46 | return; |
| 47 | } |
| 48 | |
| 49 | node = editor.dom.getParent( event.element, '.wp-caption' ) || event.element; |
| 50 | |
| 51 | if ( 'alignnone' === name ) { |
| 52 | self.active( ! /\balign(left|center|right)\b/.test( node.className ) ); |
| 53 | } else { |
| 54 | self.active( editor.dom.hasClass( node, name ) ); |
| 55 | } |
| 56 | } ); |
| 57 | } |
| 58 | } ); |
| 59 | } ); |
| 60 | |
| 61 | function toolbarConfig() { |
| 62 | var toolbarItems = [], |
| 63 | buttonGroup; |
| 64 | |
| 65 | each( [ 'wp_img_alignleft', 'wp_img_aligncenter', 'wp_img_alignright', 'wp_img_alignnone', 'wp_img_edit', 'wp_img_remove' ], function( item ) { |
| 66 | var itemName; |
| 67 | |
| 68 | function bindSelectorChanged() { |
| 69 | var selection = editor.selection; |
| 70 | |
| 71 | if ( item.settings.stateSelector ) { |
| 72 | selection.selectorChanged( item.settings.stateSelector, function( state ) { |
| 73 | item.active( state ); |
| 74 | }, true ); |
| 75 | } |
| 76 | |
| 77 | if ( item.settings.disabledStateSelector ) { |
| 78 | selection.selectorChanged( item.settings.disabledStateSelector, function( state ) { |
| 79 | item.disabled( state ); |
| 80 | } ); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | if ( item === '|' ) { |
| 85 | buttonGroup = null; |
| 86 | } else { |
| 87 | if ( Factory.has( item ) ) { |
| 88 | item = { |
| 89 | type: item |
| 90 | }; |
| 91 | |
| 92 | if ( settings.toolbar_items_size ) { |
| 93 | item.size = settings.toolbar_items_size; |
| 94 | } |
| 95 | |
| 96 | toolbarItems.push( item ); |
| 97 | |
| 98 | buttonGroup = null; |
| 99 | } else { |
| 100 | if ( ! buttonGroup ) { |
| 101 | buttonGroup = { |
| 102 | type: 'buttongroup', |
| 103 | items: [] |
| 104 | }; |
| 105 | |
| 106 | toolbarItems.push( buttonGroup ); |
| 107 | } |
| 108 | |
| 109 | if ( editor.buttons[ item ] ) { |
| 110 | itemName = item; |
| 111 | item = editor.buttons[ itemName ]; |
| 112 | |
| 113 | if ( typeof item === 'function' ) { |
| 114 | item = item(); |
| 115 | } |
| 116 | |
| 117 | item.type = item.type || 'button'; |
| 118 | |
| 119 | if ( settings.toolbar_items_size ) { |
| 120 | item.size = settings.toolbar_items_size; |
| 121 | } |
| 122 | |
| 123 | item = Factory.create( item ); |
| 124 | buttonGroup.items.push( item ); |
| 125 | |
| 126 | if ( editor.initialized ) { |
| 127 | bindSelectorChanged(); |
| 128 | } else { |
| 129 | editor.on( 'init', bindSelectorChanged ); |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | } ); |
| 135 | |
| 136 | return { |
| 137 | type: 'panel', |
| 138 | layout: 'stack', |
| 139 | classes: 'toolbar-grp inline-toolbar-grp wp-image-toolbar', |
| 140 | ariaRoot: true, |
| 141 | ariaRemember: true, |
| 142 | items: [ |
| 143 | { |
| 144 | type: 'toolbar', |
| 145 | layout: 'flow', |
| 146 | items: toolbarItems |
| 147 | } |
| 148 | ] |
| 149 | }; |
| 150 | } |
| 151 | |
| 152 | tb = Factory.create( toolbarConfig() ).renderTo( document.body ).hide(); |
| 153 | |
| 154 | tb.reposition = function() { |
| 155 | var top, left, minTop, className, |
| 156 | toolbarEl = this.getEl(), |
| 157 | buffer = 5, |
| 158 | margin = 8, |
| 159 | boundary = editor.selection.getRng().getBoundingClientRect(), |
| 160 | boundaryMiddle = ( boundary.left + boundary.right ) / 2, |
| 161 | boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2, |
| 162 | spaceTop = boundary.top, |
| 163 | spaceBottom = iframeHeigth - boundary.bottom, |
| 164 | windowWidth = window.innerWidth, |
| 165 | toolbarWidth = toolbarEl.offsetWidth, |
| 166 | toolbarHalf = toolbarWidth / 2, |
| 167 | iframe = editor.getContentAreaContainer().firstChild, |
| 168 | iframePos = DOM.getPos( iframe ), |
| 169 | iframeWidth = iframe.offsetWidth, |
| 170 | iframeHeigth = iframe.offsetHeight, |
| 171 | toolbarElHeight = toolbarEl.offsetHeight, |
| 172 | verticalSpaceNeeded = toolbarElHeight + margin + buffer; |
| 173 | |
| 174 | if ( spaceTop >= verticalSpaceNeeded ) { |
| 175 | className = ' mce-arrow-down'; |
| 176 | top = boundary.top + iframePos.y - toolbarElHeight - margin; |
| 177 | } else if ( spaceBottom >= verticalSpaceNeeded ) { |
| 178 | className = ' mce-arrow-up'; |
| 179 | top = boundary.bottom + iframePos.y; |
| 180 | } else { |
| 181 | top = buffer; |
| 182 | |
| 183 | if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) { |
| 184 | className = ' mce-arrow-down'; |
| 185 | } else { |
| 186 | className = ' mce-arrow-up'; |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | minTop = tinymce.$( '.mce-tinymce .mce-toolbar-grp' )[0]; |
| 191 | |
| 192 | if ( minTop ) { |
| 193 | minTop = DOM.getPos( minTop ).y + minTop.clientHeight; |
| 194 | } else { |
| 195 | minTop = iframePos.top; |
| 196 | } |
| 197 | |
| 198 | if ( top && minTop && ( minTop + buffer > top ) ) { |
| 199 | top = minTop + buffer; |
| 200 | className = ''; |
| 201 | } |
| 202 | |
| 203 | left = boundaryMiddle - toolbarHalf; |
| 204 | left += iframePos.x; |
| 205 | |
| 206 | if ( toolbarWidth >= windowWidth ) { |
| 207 | className += ' mce-arrow-full'; |
| 208 | left = 0; |
| 209 | } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) || ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) { |
| 210 | left = ( windowWidth - toolbarWidth ) / 2; |
| 211 | } else if ( left < iframePos.x ) { |
| 212 | className += ' mce-arrow-left'; |
| 213 | left = boundary.left + iframePos.x; |
| 214 | } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) { |
| 215 | className += ' mce-arrow-right'; |
| 216 | left = boundary.right - toolbarWidth + iframePos.x; |
| 217 | } |
| 218 | |
| 219 | toolbarEl.className = toolbarEl.className.replace( / ?mce-arrow-[\w]+/g, '' ); |
| 220 | toolbarEl.className += className; |
| 221 | |
| 222 | DOM.setStyles( toolbarEl, { 'left': left, 'top': top } ); |
| 223 | |
| 224 | return this; |
| 225 | }; |
| 226 | |
| 227 | editor.on( 'nodechange', function( event ) { |
| 228 | if ( event.element.nodeName !== 'IMG' ) { |
| 229 | tb.hide(); |
| 230 | return; |
| 231 | } |
| 232 | |
| 233 | setTimeout( function() { |
| 234 | var element = editor.selection.getNode(); |
| 235 | |
| 236 | if ( element.nodeName === 'IMG' ) { |
| 237 | if ( tb._visible ) { |
| 238 | tb.reposition(); |
| 239 | } else { |
| 240 | tb.show(); |
| 241 | } |
| 242 | } else { |
| 243 | tb.hide(); |
| 244 | } |
| 245 | }, 50 ); |
| 246 | } ); |
| 247 | |
| 248 | tb.on( 'show', function() { |
| 249 | var self = this; |
| 250 | |
| 251 | setTimeout( function() { |
| 252 | self._visible && DOM.addClass( self.getEl(), 'mce-inline-toolbar-grp-active' ); |
| 253 | }, 100 ); |
| 254 | } ); |
| 255 | |
| 256 | tb.on( 'hide', function() { |
| 257 | DOM.removeClass( this.getEl(), 'mce-inline-toolbar-active' ); |
| 258 | } ); |
| 259 | |
| 260 | function hide() { |
| 261 | tb.hide(); |
| 262 | } |
| 263 | |
| 264 | DOM.bind( window, 'resize scroll', hide ); |
| 265 | |
| 266 | editor.on( 'init', function() { |
| 267 | DOM.bind( editor.getWin(), 'resize scroll', hide ); |
| 268 | } ); |
| 269 | |
| 270 | editor.on( 'blur hide', hide ); |
| 271 | |
| 272 | // 119 = F8 |
| 273 | editor.shortcuts.add( 'Alt+119', '', function() { |
| 274 | var item = tb.find( 'toolbar' )[0]; |
| 275 | |
| 276 | item && item.focus( true ); |
| 277 | } ); |
| 278 | |
452 | | function addToolbar( node ) { |
453 | | var rectangle, toolbarHtml, toolbar, left, |
454 | | dom = editor.dom; |
455 | | |
456 | | removeToolbar(); |
457 | | |
458 | | // Don't add to placeholders |
459 | | if ( ! node || node.nodeName !== 'IMG' || isPlaceholder( node ) ) { |
460 | | return; |
461 | | } |
462 | | |
463 | | dom.setAttrib( node, 'data-wp-imgselect', 1 ); |
464 | | rectangle = dom.getRect( node ); |
465 | | |
466 | | toolbarHtml = '<i class="dashicons dashicons-edit edit" data-mce-bogus="all"></i>' + |
467 | | '<i class="dashicons dashicons-no-alt remove" data-mce-bogus="all"></i>'; |
468 | | |
469 | | toolbar = dom.create( 'p', { |
470 | | 'id': 'wp-image-toolbar', |
471 | | 'data-mce-bogus': 'all', |
472 | | 'contenteditable': false |
473 | | }, toolbarHtml ); |
474 | | |
475 | | if ( editor.rtl ) { |
476 | | left = rectangle.x + rectangle.w - 82; |
477 | | } else { |
478 | | left = rectangle.x; |
479 | | } |
480 | | |
481 | | editor.getBody().appendChild( toolbar ); |
482 | | dom.setStyles( toolbar, { |
483 | | top: rectangle.y, |
484 | | left: left |
485 | | }); |
486 | | |
487 | | toolbarActive = true; |
488 | | } |
489 | | |
490 | | function removeToolbar() { |
491 | | var toolbar = editor.dom.get( 'wp-image-toolbar' ); |
492 | | |
493 | | if ( toolbar ) { |
494 | | editor.dom.remove( toolbar ); |
495 | | } |
496 | | |
497 | | editor.dom.setAttrib( editor.dom.select( 'img[data-wp-imgselect]' ), 'data-wp-imgselect', null ); |
498 | | |
499 | | editingImage = false; |
500 | | toolbarActive = false; |
501 | | } |
502 | | |
503 | | function isPlaceholder( node ) { |
504 | | var dom = editor.dom; |
505 | | |
506 | | if ( dom.hasClass( node, 'mceItem' ) || dom.getAttrib( node, 'data-mce-placeholder' ) || |
507 | | dom.getAttrib( node, 'data-mce-object' ) ) { |
508 | | |
509 | | return true; |
510 | | } |
511 | | |
512 | | return false; |
513 | | } |
514 | | |
515 | | function isToolbarButton( node ) { |
516 | | return ( node && node.nodeName === 'I' && node.parentNode.id === 'wp-image-toolbar' ); |
517 | | } |
518 | | |
519 | | function edit( event ) { |
520 | | var image, |
521 | | node = event.target, |
522 | | dom = editor.dom; |
523 | | |
524 | | // Don't trigger on right-click |
525 | | if ( event.button && event.button > 1 ) { |
526 | | return; |
527 | | } |
528 | | |
529 | | if ( isToolbarButton( node ) ) { |
530 | | image = dom.select( 'img[data-wp-imgselect]' )[0]; |
531 | | |
532 | | if ( image ) { |
533 | | editor.selection.select( image ); |
534 | | |
535 | | if ( dom.hasClass( node, 'remove' ) ) { |
536 | | removeImage( image ); |
537 | | } else if ( dom.hasClass( node, 'edit' ) ) { |
538 | | if ( ! editingImage ) { |
539 | | editImage( image ); |
540 | | editingImage = true; |
541 | | } |
542 | | } |
543 | | } |
544 | | |
545 | | event.preventDefault(); |
546 | | } else if ( node.nodeName === 'IMG' && ! editor.dom.getAttrib( node, 'data-wp-imgselect' ) && ! isPlaceholder( node ) ) { |
547 | | addToolbar( node ); |
548 | | } else if ( node.nodeName !== 'IMG' ) { |
549 | | removeToolbar(); |
550 | | } |
551 | | } |
552 | | |
553 | | if ( 'ontouchend' in document ) { |
554 | | editor.on( 'click', function( event ) { |
555 | | var target = event.target; |
556 | | |
557 | | if ( editingImage && target.nodeName === 'IMG' ) { |
558 | | event.preventDefault(); |
559 | | } |
560 | | |
561 | | if ( isToolbarButton( target ) ) { |
562 | | event.preventDefault(); |
563 | | event.stopPropagation(); |
564 | | } |
565 | | }); |
566 | | } |
567 | | |
568 | | editor.on( 'mouseup touchend', edit ); |
569 | | |