diff --git a/tinymce-single/blocks.js b/tinymce-single/blocks.js index 7fe08c09006dc..064e2ce48da5e 100644 --- a/tinymce-single/blocks.js +++ b/tinymce-single/blocks.js @@ -59,6 +59,20 @@ getControls: function() { return _controls; }, + getParentBlock: function( node ) { + var editor = window.tinyMCE.activeEditor; + var rootNode = editor.getBody(); + + if ( node === rootNode || ! editor.getBody().contains( node ) ) { + return null; + } + + while ( node.parentNode !== rootNode ) { + node = node.parentNode; + } + + return node; + }, getSelectedBlocks: function() { var editor = window.tinyMCE.activeEditor; var selection = window.getSelection(); diff --git a/tinymce-single/tinymce/block.css b/tinymce-single/tinymce/block.css index 96817f2eb1b98..88efecdce96de 100644 --- a/tinymce-single/tinymce/block.css +++ b/tinymce-single/tinymce/block.css @@ -265,6 +265,11 @@ div.mce-inline-toolbar-grp.block-toolbar > div.mce-stack-layout { border: 2px solid #e0e5e9; } +.block-outline-hover:before { + border: none; + border-left: 2px solid #e0e5e9; +} + .block-outline-handle { position: absolute; width: 20px; diff --git a/tinymce-single/tinymce/block.js b/tinymce-single/tinymce/block.js index 9bc36351f0932..b3ee97b045ed9 100644 --- a/tinymce-single/tinymce/block.js +++ b/tinymce-single/tinymce/block.js @@ -178,6 +178,9 @@ editor.on( 'preinit', function() { var DOM = tinymce.DOM; var hidden = true; + var hoverTarget; + var dragTarget; + var isDragging = false; editor.addButton( 'block', { icon: 'gridicons-posts', @@ -310,64 +313,73 @@ var blockToolbarWidth = 0; - function createBlockOutline() { + function createBlockOutline( hover ) { var outline = document.createElement( 'div' ); var handleLeft = document.createElement( 'div' ); var handleRight = document.createElement( 'div' ); - outline.className = 'block-outline'; + if ( hover ) { + outline.className = 'block-outline block-outline-hover'; + } else { + outline.className = 'block-outline'; + } + handleLeft.className = 'block-outline-handle block-outline-handle-right'; handleRight.className = 'block-outline-handle block-outline-handle-left'; outline.appendChild( handleLeft ); outline.appendChild( handleRight ); document.body.appendChild( outline ); - var target; - DOM.bind( outline, 'mousedown', function( event ) { var newEvent = Object.assign( {}, event ); - target = getSelectedBlock(); + if ( hover ) { + dragTarget = hoverTarget; + } else { + dragTarget = getSelectedBlock(); + } - if ( target.getAttribute( 'contenteditable' ) !== 'false' ) { - target.setAttribute( 'contenteditable', 'false' ); + if ( dragTarget.getAttribute( 'contenteditable' ) !== 'false' ) { + dragTarget.setAttribute( 'contenteditable', 'false' ); } - newEvent.target = target; + newEvent.target = dragTarget; editor.fire( 'mousedown', newEvent ); } ); - editor.on( 'dragstart', function( event ) { - if ( ! target ) { - event.preventDefault(); - return; - } + return outline; + } - hidden = true; + editor.on( 'dragstart', function( event ) { + if ( ! dragTarget ) { + event.preventDefault(); + return; + } - hideBlockUI(); + isDragging = true; + hidden = true; - target.setAttribute( 'data-wp-block-dragging', 'true' ); + hideBlockUI(); - function end( event ) { - DOM.unbind( editor.getDoc(), 'mouseup', end ); + dragTarget.setAttribute( 'data-wp-block-dragging', 'true' ); - target = null; + function end( event ) { + DOM.unbind( editor.getDoc(), 'mouseup', end ); - setTimeout( function() { - editor.$( '*[data-wp-block-dragging]' ) - .attr( 'data-wp-block-dragging', null ) - .attr( 'contenteditable', null ); - editor.nodeChanged(); - } ); - } + isDragging = false; + dragTarget = null; - DOM.bind( editor.getDoc(), 'mouseup', end ); - } ); + setTimeout( function() { + editor.$( '*[data-wp-block-dragging]' ) + .attr( 'data-wp-block-dragging', null ) + .attr( 'contenteditable', null ); + editor.nodeChanged(); + } ); + } - return outline; - } + DOM.bind( editor.getDoc(), 'mouseup', end ); + } ); function createInsertToolbar() { var insert = editor.wp._createToolbar( [ 'add' ] ); @@ -590,6 +602,7 @@ var UI = { outline: createBlockOutline(), + hoverOutline: createBlockOutline( true ), insert: createInsertToolbar(), insertMenu: createInsertMenu(), inline: createInlineToolbar(), @@ -597,6 +610,31 @@ blocks: createBlockToolbars() }; + editor.on( 'mouseover', function( event ) { + var target = wp.blocks.getParentBlock( event.target ); + + if ( target && target !== hoverTarget ) { + if ( isDragging || wp.blocks.getSelectedBlock() === hoverTarget ) { + DOM.setStyles( UI.hoverOutline, { + display: 'none' + } ); + } else { + var rect = target.getBoundingClientRect(); + + DOM.setStyles( UI.hoverOutline, { + display: 'block', + position: 'absolute', + left: rect.left + 'px', + top: rect.top + window.pageYOffset + 'px', + height: rect.height + 'px', + width: rect.width + 'px' + } ); + } + + hoverTarget = target; + } + } ); + var range; editor.on( 'blur', function() {