diff --git a/src/wp-admin/js/editor-expand.js b/src/wp-admin/js/editor-expand.js index fac78239ac..db7561e62a 100644 --- a/src/wp-admin/js/editor-expand.js +++ b/src/wp-admin/js/editor-expand.js @@ -177,7 +177,7 @@ var node = editor.selection.getNode(), range, view, offset; - if ( editor.plugins.wpview && ( view = editor.plugins.wpview.getView( node ) ) ) { + if ( editor.wp && editor.wp.getView && ( view = editor.wp.getView( node ) ) ) { offset = view.getBoundingClientRect(); } else { range = editor.selection.getRng(); diff --git a/src/wp-includes/css/editor.css b/src/wp-includes/css/editor.css index 5f40aa6d76..41099dbed6 100644 --- a/src/wp-includes/css/editor.css +++ b/src/wp-includes/css/editor.css @@ -170,7 +170,6 @@ div.mce-inline-toolbar-grp { box-sizing: border-box; margin-bottom: 8px; position: absolute; - visibility: hidden; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; @@ -178,7 +177,7 @@ div.mce-inline-toolbar-grp { z-index: 100100; /* Same as the other TinyMCE "panels" */ } -div.mce-wp-image-toolbar > div.mce-stack-layout { +div.mce-inline-toolbar-grp > div.mce-stack-layout { padding: 1px; } @@ -262,10 +261,6 @@ div.mce-inline-toolbar-grp.mce-arrow-full > div { overflow-x: auto; } -div.mce-inline-toolbar-grp-active { - visibility: visible; -} - div.mce-toolbar-grp > div { padding: 3px; } diff --git a/src/wp-includes/js/mce-view.js b/src/wp-includes/js/mce-view.js index 36b9470267..dad9ddc8c7 100644 --- a/src/wp-includes/js/mce-view.js +++ b/src/wp-includes/js/mce-view.js @@ -405,10 +405,6 @@ window.wp = window.wp || {}; '
' + '

\u00a0

' + '
' + - '
' + - ( this.edit ? '
' : '' ) + - '
' + - '
' + '
' + '
' + '

\u00a0

' + diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js b/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js index 12601cce99..9aa5462b2c 100644 --- a/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js @@ -432,6 +432,307 @@ tinymce.PluginManager.add( 'wordpress', function( editor ) { wp.autosave.server.triggerSave(); } }); + + /** + * Experimental: create a floating toolbar. + * This functionality will change in the next releases. Not recommennded for use by plugins. + */ + ( function() { + var DOM = tinymce.DOM, + each = tinymce.each, + Factory = tinymce.ui.Factory, + settings = editor.settings, + currentToolbar, + currentSelection; + + function create( buttons ) { + var toolbar, + toolbarItems = [], + buttonGroup; + + each( buttons, function( item ) { + var itemName; + + function bindSelectorChanged() { + var selection = editor.selection; + + if ( itemName === 'bullist' ) { + selection.selectorChanged( 'ul > li', function( state, args ) { + var i = args.parents.length, + nodeName; + + while ( i-- ) { + nodeName = args.parents[ i ].nodeName; + + if ( nodeName === 'OL' || nodeName == 'UL' ) { + break; + } + } + + item.active( state && nodeName === 'UL' ); + } ); + } + + if ( itemName === 'numlist' ) { + selection.selectorChanged( 'ol > li', function( state, args ) { + var i = args.parents.length, + nodeName; + + while ( i-- ) { + nodeName = args.parents[ i ].nodeName; + + if ( nodeName === 'OL' || nodeName === 'UL' ) { + break; + } + } + + item.active( state && nodeName === 'OL' ); + } ); + } + + if ( item.settings.stateSelector ) { + selection.selectorChanged( item.settings.stateSelector, function( state ) { + item.active( state ); + }, true ); + } + + if ( item.settings.disabledStateSelector ) { + selection.selectorChanged( item.settings.disabledStateSelector, function( state ) { + item.disabled( state ); + } ); + } + } + + if ( item === '|' ) { + buttonGroup = null; + } else { + if ( Factory.has( item ) ) { + item = { + type: item + }; + + if ( settings.toolbar_items_size ) { + item.size = settings.toolbar_items_size; + } + + toolbarItems.push( item ); + + buttonGroup = null; + } else { + if ( ! buttonGroup ) { + buttonGroup = { + type: 'buttongroup', + items: [] + }; + + toolbarItems.push( buttonGroup ); + } + + if ( editor.buttons[ item ] ) { + itemName = item; + item = editor.buttons[ itemName ]; + + if ( typeof item === 'function' ) { + item = item(); + } + + item.type = item.type || 'button'; + + if ( settings.toolbar_items_size ) { + item.size = settings.toolbar_items_size; + } + + item = Factory.create( item ); + + buttonGroup.items.push( item ); + + if ( editor.initialized ) { + bindSelectorChanged(); + } else { + editor.on( 'init', bindSelectorChanged ); + } + } + } + } + } ); + + toolbar = Factory.create( { + type: 'panel', + layout: 'stack', + classes: 'toolbar-grp inline-toolbar-grp', + ariaRoot: true, + ariaRemember: true, + items: [ { + type: 'toolbar', + layout: 'flow', + items: toolbarItems + } ] + } ); + + function hide() { + toolbar.hide(); + } + + function reposition() { + var top, left, minTop, className, + windowPos, adminbar, mceToolbar, boundary, + boundaryMiddle, boundaryVerticalMiddle, spaceTop, + spaceBottom, windowWidth, toolbarWidth, toolbarHalf, + iframe, iframePos, iframeWidth, iframeHeigth, + toolbarNodeHeight, verticalSpaceNeeded, + toolbarNode = this.getEl(), + buffer = 5, + margin = 8, + adminbarHeight = 0; + + windowPos = window.pageYOffset || document.documentElement.scrollTop; + adminbar = tinymce.$( '#wpadminbar' )[0]; + mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0]; + boundary = currentSelection.getBoundingClientRect(); + boundaryMiddle = ( boundary.left + boundary.right ) / 2; + boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2; + spaceTop = boundary.top; + spaceBottom = iframeHeigth - boundary.bottom; + windowWidth = window.innerWidth; + toolbarWidth = toolbarNode.offsetWidth; + toolbarHalf = toolbarWidth / 2; + iframe = document.getElementById( editor.id + '_ifr' ); + iframePos = DOM.getPos( iframe ); + iframeWidth = iframe.offsetWidth; + iframeHeigth = iframe.offsetHeight; + toolbarNodeHeight = toolbarNode.offsetHeight; + verticalSpaceNeeded = toolbarNodeHeight + margin + buffer; + + if ( spaceTop >= verticalSpaceNeeded ) { + className = ' mce-arrow-down'; + top = boundary.top + iframePos.y - toolbarNodeHeight - margin; + } else if ( spaceBottom >= verticalSpaceNeeded ) { + className = ' mce-arrow-up'; + top = boundary.bottom + iframePos.y; + } else { + top = buffer; + + if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) { + className = ' mce-arrow-down'; + } else { + className = ' mce-arrow-up'; + } + } + + // Make sure the image toolbar is below the main toolbar. + if ( mceToolbar ) { + minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight; + } else { + minTop = iframePos.y; + } + + // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window. + if ( windowPos ) { + if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) { + adminbarHeight = adminbar.clientHeight; + } + + if ( windowPos + adminbarHeight > minTop ) { + minTop = windowPos + adminbarHeight; + } + } + + if ( top && minTop && ( minTop + buffer > top ) ) { + top = minTop + buffer; + className = ''; + } + + left = boundaryMiddle - toolbarHalf; + left += iframePos.x; + + if ( boundary.left < 0 || boundary.right > iframeWidth ) { + left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2; + } else if ( toolbarWidth >= windowWidth ) { + className += ' mce-arrow-full'; + left = 0; + } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) || + ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) { + + left = ( windowWidth - toolbarWidth ) / 2; + } else if ( left < iframePos.x ) { + className += ' mce-arrow-left'; + left = boundary.left + iframePos.x; + } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) { + className += ' mce-arrow-right'; + left = boundary.right - toolbarWidth + iframePos.x; + } + + toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' ); + toolbarNode.className += className; + + DOM.setStyles( toolbarNode, { 'left': left, 'top': top } ); + + return this; + } + + toolbar.on( 'show', function() { + currentToolbar = this; + this.reposition(); + } ); + + toolbar.on( 'hide', function() { + currentToolbar = false; + } ); + + toolbar.on( 'keydown', function( event ) { + if ( event.keyCode === 27 ) { + this.hide(); + editor.focus(); + } + } ); + + toolbar.on( 'remove', function() { + DOM.unbind( window, 'resize scroll', hide ); + editor.dom.unbind( editor.getWin(), 'resize scroll', hide ); + editor.off( 'blur hide', hide ); + } ); + + editor.once( 'init', function() { + DOM.bind( window, 'resize scroll', hide ); + editor.dom.bind( editor.getWin(), 'resize scroll', hide ); + editor.on( 'blur hide', hide ); + } ); + + toolbar.reposition = reposition; + toolbar.hide().renderTo( document.body ); + + return toolbar; + } + + editor.shortcuts.add( 'alt+119', '', function() { + var node; + + if ( currentToolbar ) { + node = currentToolbar.find( 'toolbar' )[0]; + node && node.focus( true ); + } + } ); + + editor.on( 'nodechange', function( event ) { + var collapsed = editor.selection.isCollapsed(); + + var args = { + element: event.element, + parents: event.parents, + collapsed: collapsed + }; + + editor.fire( 'wptoolbar', args ); + + currentSelection = args.selection || args.element; + + currentToolbar && currentToolbar.hide(); + args.toolbar && args.toolbar.show(); + } ); + + editor.wp = editor.wp || {}; + editor.wp._createToolbar = create; + }()); function noop() {} diff --git a/src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js b/src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js index 89bf33a1b4..19839617d0 100644 --- a/src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpeditimage/plugin.js @@ -1,13 +1,8 @@ /* global tinymce */ tinymce.PluginManager.add( 'wpeditimage', function( editor ) { var floatingToolbar, serializer, - DOM = tinymce.DOM, - settings = editor.settings, - Factory = tinymce.ui.Factory, each = tinymce.each, - iOS = tinymce.Env.iOS, - toolbarIsHidden = true, - editorWrapParent = tinymce.$( '#postdivrich' ); + iOS = tinymce.Env.iOS; function isPlaceholder( node ) { return !! ( editor.dom.getAttrib( node, 'data-mce-placeholder' ) || editor.dom.getAttrib( node, 'data-mce-object' ) ); @@ -64,294 +59,29 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) { } ); } ); - function toolbarConfig() { - var toolbarItems = [], - buttonGroup; - - each( [ 'wp_img_alignleft', 'wp_img_aligncenter', 'wp_img_alignright', 'wp_img_alignnone', 'wp_img_edit', 'wp_img_remove' ], function( item ) { - var itemName; - - function bindSelectorChanged() { - var selection = editor.selection; - - if ( item.settings.stateSelector ) { - selection.selectorChanged( item.settings.stateSelector, function( state ) { - item.active( state ); - }, true ); - } - - if ( item.settings.disabledStateSelector ) { - selection.selectorChanged( item.settings.disabledStateSelector, function( state ) { - item.disabled( state ); - } ); - } - } - - if ( item === '|' ) { - buttonGroup = null; - } else { - if ( Factory.has( item ) ) { - item = { - type: item - }; - - if ( settings.toolbar_items_size ) { - item.size = settings.toolbar_items_size; - } - - toolbarItems.push( item ); - - buttonGroup = null; - } else { - if ( ! buttonGroup ) { - buttonGroup = { - type: 'buttongroup', - items: [] - }; - - toolbarItems.push( buttonGroup ); - } - - if ( editor.buttons[ item ] ) { - itemName = item; - item = editor.buttons[ itemName ]; - - if ( typeof item === 'function' ) { - item = item(); - } - - item.type = item.type || 'button'; - - if ( settings.toolbar_items_size ) { - item.size = settings.toolbar_items_size; - } - - item = Factory.create( item ); - buttonGroup.items.push( item ); - - if ( editor.initialized ) { - bindSelectorChanged(); - } else { - editor.on( 'init', bindSelectorChanged ); - } - } - } - } - } ); - - return { - type: 'panel', - layout: 'stack', - classes: 'toolbar-grp inline-toolbar-grp wp-image-toolbar', - ariaRoot: true, - ariaRemember: true, - items: [ - { - type: 'toolbar', - layout: 'flow', - items: toolbarItems - } - ] - }; - } - - floatingToolbar = Factory.create( toolbarConfig() ).renderTo( document.body ).hide(); - - floatingToolbar.reposition = function() { - var top, left, minTop, className, - windowPos, adminbar, mceToolbar, boundary, - boundaryMiddle, boundaryVerticalMiddle, spaceTop, - spaceBottom, windowWidth, toolbarWidth, toolbarHalf, - iframe, iframePos, iframeWidth, iframeHeigth, - toolbarNodeHeight, verticalSpaceNeeded, - toolbarNode = this.getEl(), - buffer = 5, - margin = 8, - adminbarHeight = 0, - imageNode = editor.selection.getNode(); - - if ( ! imageNode || imageNode.nodeName !== 'IMG' ) { - return this; + editor.on( 'wptoolbar', function( event ) { + if ( event.element.nodeName === 'IMG' && ! isPlaceholder( event.element ) ) { + event.toolbar = floatingToolbar; } + } ); - windowPos = window.pageYOffset || document.documentElement.scrollTop; - adminbar = tinymce.$( '#wpadminbar' )[0]; - mceToolbar = tinymce.$( '.mce-toolbar-grp', editor.getContainer() )[0]; - boundary = imageNode.getBoundingClientRect(); - boundaryMiddle = ( boundary.left + boundary.right ) / 2; - boundaryVerticalMiddle = ( boundary.top + boundary.bottom ) / 2; - spaceTop = boundary.top; - spaceBottom = iframeHeigth - boundary.bottom; - windowWidth = window.innerWidth; - toolbarWidth = toolbarNode.offsetWidth; - toolbarHalf = toolbarWidth / 2; - iframe = document.getElementById( editor.id + '_ifr' ); - iframePos = DOM.getPos( iframe ); - iframeWidth = iframe.offsetWidth; - iframeHeigth = iframe.offsetHeight; - toolbarNodeHeight = toolbarNode.offsetHeight; - verticalSpaceNeeded = toolbarNodeHeight + margin + buffer; - - if ( iOS ) { - top = boundary.top + iframePos.y + margin; - } else { - if ( spaceTop >= verticalSpaceNeeded ) { - className = ' mce-arrow-down'; - top = boundary.top + iframePos.y - toolbarNodeHeight - margin; - } else if ( spaceBottom >= verticalSpaceNeeded ) { - className = ' mce-arrow-up'; - top = boundary.bottom + iframePos.y; - } else { - top = buffer; - - if ( boundaryVerticalMiddle >= verticalSpaceNeeded ) { - className = ' mce-arrow-down'; - } else { - className = ' mce-arrow-up'; - } - } - } - - // Make sure the image toolbar is below the main toolbar. - if ( mceToolbar ) { - minTop = DOM.getPos( mceToolbar ).y + mceToolbar.clientHeight; - } else { - minTop = iframePos.y; - } - - // Make sure the image toolbar is below the adminbar (if visible) or below the top of the window. - if ( windowPos ) { - if ( adminbar && adminbar.getBoundingClientRect().top === 0 ) { - adminbarHeight = adminbar.clientHeight; - } - - if ( windowPos + adminbarHeight > minTop ) { - minTop = windowPos + adminbarHeight; - } - } - - if ( top && minTop && ( minTop + buffer > top ) ) { - top = minTop + buffer; - className = ''; - } - - left = boundaryMiddle - toolbarHalf; - left += iframePos.x; - - if ( boundary.left < 0 || boundary.right > iframeWidth ) { - left = iframePos.x + ( iframeWidth - toolbarWidth ) / 2; - } else if ( toolbarWidth >= windowWidth ) { - className += ' mce-arrow-full'; - left = 0; - } else if ( ( left < 0 && boundary.left + toolbarWidth > windowWidth ) || - ( left + toolbarWidth > windowWidth && boundary.right - toolbarWidth < 0 ) ) { - - left = ( windowWidth - toolbarWidth ) / 2; - } else if ( left < iframePos.x ) { - className += ' mce-arrow-left'; - left = boundary.left + iframePos.x; - } else if ( left + toolbarWidth > iframeWidth + iframePos.x ) { - className += ' mce-arrow-right'; - left = boundary.right - toolbarWidth + iframePos.x; - } - - if ( ! iOS ) { - toolbarNode.className = toolbarNode.className.replace( / ?mce-arrow-[\w]+/g, '' ); - toolbarNode.className += className; - } - - DOM.setStyles( toolbarNode, { 'left': left, 'top': top } ); - - return this; - }; - + // Safari on iOS fails to select image nodes in contentEditoble mode on touch/click. + // Select them again. if ( iOS ) { - // Safari on iOS fails to select image nodes in contentEditoble mode on touch/click. - // Select them again. editor.on( 'click', function( event ) { if ( event.target.nodeName === 'IMG' ) { var node = event.target; window.setTimeout( function() { editor.selection.select( node ); + editor.nodeChanged(); }, 200 ); } else { floatingToolbar.hide(); } - }); + } ); } - editor.on( 'nodechange', function( event ) { - var delay = iOS ? 350 : 100; - - if ( event.element.nodeName !== 'IMG' || isPlaceholder( event.element ) ) { - floatingToolbar.hide(); - return; - } - - setTimeout( function() { - var element = editor.selection.getNode(); - - if ( element.nodeName === 'IMG' && ! isPlaceholder( element ) ) { - if ( floatingToolbar._visible ) { - floatingToolbar.reposition(); - } else { - floatingToolbar.show(); - } - } else { - floatingToolbar.hide(); - } - }, delay ); - } ); - - function hide() { - if ( ! toolbarIsHidden ) { - floatingToolbar.hide(); - } - } - - floatingToolbar.on( 'show', function() { - toolbarIsHidden = false; - - if ( this._visible ) { - this.reposition(); - DOM.addClass( this.getEl(), 'mce-inline-toolbar-grp-active' ); - } - } ); - - floatingToolbar.on( 'hide', function() { - toolbarIsHidden = true; - DOM.removeClass( this.getEl(), 'mce-inline-toolbar-grp-active' ); - } ); - - floatingToolbar.on( 'keydown', function( event ) { - if ( event.keyCode === 27 ) { - hide(); - editor.focus(); - } - } ); - - DOM.bind( window, 'resize scroll', function() { - if ( ! toolbarIsHidden && editorWrapParent.hasClass( 'wp-editor-expand' ) ) { - hide(); - } - }); - - editor.on( 'init', function() { - editor.dom.bind( editor.getWin(), 'scroll', hide ); - }); - - editor.on( 'blur hide', hide ); - - // 119 = F8 - editor.shortcuts.add( 'Alt+119', '', function() { - var node = floatingToolbar.find( 'toolbar' )[0]; - - if ( node ) { - node.focus( true ); - } - }); - function parseShortcode( content ) { return content.replace( /(?:

)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?/g, function( a, b, c ) { var id, align, classes, caption, img, width, @@ -814,6 +544,17 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) { dom.addClass( editor.getBody(), captionClass ); + if ( editor.wp._createToolbar ) { + floatingToolbar = editor.wp._createToolbar( [ + 'wp_img_alignleft', + 'wp_img_aligncenter', + 'wp_img_alignright', + 'wp_img_alignnone', + 'wp_img_edit', + 'wp_img_remove' + ] ); + } + // Add caption field to the default image dialog editor.on( 'wpLoadImageForm', function( event ) { if ( editor.getParam( 'wpeditimage_disable_captions' ) ) { @@ -1226,6 +967,11 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) { } } ); + // Add to editor.wp + editor.wp = editor.wp || {}; + editor.wp.isPlaceholder = isPlaceholder; + + // Back-compat. return { _do_shcode: parseShortcode, _get_shcode: getShortcode diff --git a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js index e89915f5aa..6252ef9fb1 100644 --- a/src/wp-includes/js/tinymce/plugins/wpview/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpview/plugin.js @@ -12,7 +12,13 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { firstFocus = true, _noop = function() { return false; }, isios = /iPad|iPod|iPhone/.test( navigator.userAgent ), - cursorInterval, lastKeyDownNode, setViewCursorTries, focus, execCommandView, execCommandBefore; + cursorInterval, + lastKeyDownNode, + setViewCursorTries, + focus, + execCommandView, + execCommandBefore, + toolbar; function getView( node ) { return getParent( node, 'wpview-wrap' ); @@ -86,62 +92,39 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { return; } - // Adjust the toolbar position and bail if node is already selected. - if ( viewNode === selected ) { - adjustToolbarPosition( viewNode ); - return; - } + if ( viewNode !== selected ) { + // Make sure that the editor is focused. + // It is possible that the editor is not focused when the mouse event fires + // without focus, the selection will not work properly. + editor.getBody().focus(); - // Make sure that the editor is focused. - // It is possible that the editor is not focused when the mouse event fires - // without focus, the selection will not work properly. - editor.getBody().focus(); + deselect(); + selected = viewNode; + dom.setAttrib( viewNode, 'data-mce-selected', 1 ); - deselect(); - selected = viewNode; - dom.setAttrib( viewNode, 'data-mce-selected', 1 ); - adjustToolbarPosition( viewNode ); + clipboard = dom.create( 'div', { + 'class': 'wpview-clipboard', + 'contenteditable': 'true' + }, wp.mce.views.getText( viewNode ) ); - clipboard = dom.create( 'div', { - 'class': 'wpview-clipboard', - 'contenteditable': 'true' - }, wp.mce.views.getText( viewNode ) ); + editor.dom.select( '.wpview-body', viewNode )[0].appendChild( clipboard ); - editor.dom.select( '.wpview-body', viewNode )[0].appendChild( clipboard ); + // Both of the following are necessary to prevent manipulating the selection/focus + dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop ); + dom.bind( selected, 'beforedeactivate focusin focusout', _stop ); - // Both of the following are necessary to prevent manipulating the selection/focus - dom.bind( clipboard, 'beforedeactivate focusin focusout', _stop ); - dom.bind( selected, 'beforedeactivate focusin focusout', _stop ); - - // select the hidden div - if ( isios ) { - editor.selection.select( clipboard ); - } else { - editor.selection.select( clipboard, true ); + // select the hidden div + if ( isios ) { + editor.selection.select( clipboard ); + } else { + editor.selection.select( clipboard, true ); + } } editor.nodeChanged(); editor.fire( 'wpview-selected', viewNode ); } - function adjustToolbarPosition( viewNode ) { - var delta = 0, - toolbar = editor.$( viewNode ).find( '.toolbar' ), - editorToolbar = tinymce.$( editor.editorContainer ).find( '.mce-toolbar-grp' )[0], - editorToolbarBottom = ( editorToolbar && editorToolbar.getBoundingClientRect().bottom ) || 0; - - if ( toolbar.length && editor.iframeElement ) { - // 48 = 43 for the toolbar + 5 buffer - delta = viewNode.getBoundingClientRect().top + editor.iframeElement.getBoundingClientRect().top - editorToolbarBottom - 48; - } - - if ( delta < 0 ) { - toolbar.removeClass( 'mce-arrow-down' ).css({ top: ( -43 + delta * -1 ) }); - } else if ( delta > 0 && ! toolbar.hasClass( 'mce-arrow-down' ) ) { - toolbar.addClass( 'mce-arrow-down' ).css({ top: '' }); - } - } - /** * Deselect a selected view and remove clipboard */ @@ -257,6 +240,11 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { selection = editor.selection, MutationObserver = window.MutationObserver || window.WebKitMutationObserver; + toolbar = editor.wp._createToolbar( [ + 'wp_view_edit', + 'wp_view_remove' + ] ); + // When a view is selected, ensure content that is being pasted // or inserted is added to a text node (instead of the view). editor.on( 'BeforeSetContent', function() { @@ -298,22 +286,6 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { event.stopImmediatePropagation(); event.preventDefault(); - if ( ( event.type === 'touchend' || event.type === 'mousedown' ) && ! event.metaKey && ! event.ctrlKey ) { - if ( editor.dom.hasClass( event.target, 'edit' ) ) { - - // In IE need to transfer focus from the non-editable view back to the editor. - if ( Env.ie ) { - editor.focus(); - } - - wp.mce.views.edit( editor, view ); - return false; - } else if ( editor.dom.hasClass( event.target, 'remove' ) ) { - removeView( view ); - return false; - } - } - if ( event.type === 'touchend' && scrolled ) { scrolled = false; } else { @@ -685,6 +657,34 @@ tinymce.PluginManager.add( 'wpview', function( editor ) { } }); + editor.addButton( 'wp_view_edit', { + tooltip: 'Edit ', // trailing space is needed, used for context + icon: 'dashicon dashicons-edit', + onclick: function() { + selected && wp.mce.views.edit( editor, selected ); + } + } ); + + editor.addButton( 'wp_view_remove', { + tooltip: 'Remove', + icon: 'dashicon dashicons-no', + onclick: function() { + selected && removeView( selected ); + } + } ); + + editor.on( 'wptoolbar', function( event ) { + if ( selected ) { + event.element = selected; + event.toolbar = toolbar; + } + } ); + + // Add to editor.wp + editor.wp = editor.wp || {}; + editor.wp.getView = getView; + + // Keep for back-compat. return { getView: getView }; diff --git a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css index 47a820baa8..f088a5e7aa 100644 --- a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css +++ b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css @@ -319,91 +319,6 @@ audio { display: none; } -.wpview-wrap .toolbar { - position: absolute; - top: -43px; - left: 45%; - left: calc(50% - 32px); - display: none; - z-index: 100; - background-color: #f5f5f5; - border: 1px solid #aaa; - padding: 1px; - cursor: default; - -webkit-border-radius: 2px; - border-radius: 2px; - -webkit-box-shadow: 0 1px 4px rgba( 0, 0, 0, 0.2 ); - box-shadow: 0 1px 4px rgba( 0, 0, 0, 0.2 ); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin-bottom: 8px; -} - -.wpview-wrap[data-mce-selected] .toolbar { - display: block; -} - -.wpview-wrap .toolbar:before, -.wpview-wrap .toolbar:after { - position: absolute; - left: 50%; - display: block; - width: 0; - height: 0; - border-style: solid; - border-color: transparent; - border-width: 9px; - margin-left: -9px; - content: ''; -} - -.wpview-wrap .toolbar:after { - border-width: 8px; - margin-left: -8px; -} - -.wpview-wrap .toolbar.mce-arrow-down:before { - bottom: -18px; - border-top-color: #aaa; -} - -.wpview-wrap .toolbar.mce-arrow-down:after { - bottom: -16px; - border-top-color: #f5f5f5; -} - -.wpview-wrap .toolbar.mce-arrow-up:before { - top: -18px; - border-bottom-color: #aaa; -} - -.wpview-wrap .toolbar.mce-arrow-up:after { - top: -16px; - border-bottom-color: #f5f5f5; -} - -.wpview-wrap .toolbar div { - margin: 2px; - padding: 2px 3px; - width: 20px; - height: 20px; - color: #777; - cursor: pointer; - font-size: 20px; - border: 1px solid transparent; - border-radius: 2px; -} - -.wpview-wrap .toolbar div:hover { - background-color: #fafafa; - border-color: #999; - color: #222; - -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 ); - box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba( 0, 0, 0, 0.08 ); - outline: none; -} - .wpview-wrap .loading-placeholder { border: 1px dashed #ccc; padding: 10px; @@ -455,22 +370,6 @@ audio { background: transparent; } -.ie8 .wpview-wrap .toolbar div, -.ie7 .wpview-wrap .toolbar div { - display: inline; - padding: 4px; -} - -.ie8 .dashicons-edit, -.ie7 .dashicons-edit { - background-image: url(images/dashicon-edit.png); -} - -.ie8 .dashicons-no, -.ie7 .dashicons-no { - background-image: url(images/dashicon-no.png); -} - .wpview-error { border: 1px solid #dedede; padding: 1em 0; @@ -497,19 +396,6 @@ audio { font-family: 'Open Sans', sans-serif; } -.wont-play { - padding: 4px 0; -} - -.wont-play p { - font-size: 13px; - line-height: 1.3; - display: block; - width: 70%; - margin: 0 15%; - text-align: center; -} - .wpview-type-gallery:after { content: ''; display: table; @@ -536,7 +422,6 @@ audio { margin: auto; } - .gallery .gallery-item { float: left; margin: 0;