From c9f8abe1f835caf358fd851c0cf188b6cb214883 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 19 Jan 2021 10:13:12 +0100 Subject: [PATCH] Fix deadzone --- .../components/block-list/insertion-point.js | 100 ++++++++++++------ packages/e2e-test-utils/src/inserter.js | 2 +- .../specs/editor/various/writing-flow.test.js | 38 +------ 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index 041bef836afc0..e393710dc5a47 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -6,8 +6,14 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useSelect } from '@wordpress/data'; -import { useState, useEffect, useCallback } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { + useState, + useEffect, + useCallback, + useRef, + useMemo, +} from '@wordpress/element'; import { Popover } from '@wordpress/components'; import { isRTL } from '@wordpress/i18n'; @@ -19,9 +25,7 @@ import { getBlockDOMNode } from '../../utils/dom'; function InsertionPointInserter( { clientId, setIsInserterForced } ) { return ( - /* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
setIsInserterForced( true ) } className={ classnames( 'block-editor-block-list__insertion-point-inserter' ) } @@ -46,6 +50,9 @@ function InsertionPointPopover( { containerRef, showInsertionPoint, } ) { + const { selectBlock } = useDispatch( 'core/block-editor' ); + const ref = useRef(); + const { previousElement, nextElement, orientation, isHidden } = useSelect( ( select ) => { const { @@ -91,32 +98,46 @@ function InsertionPointPopover( { [ clientId, rootClientId ] ); + const style = useMemo( () => { + if ( ! previousElement || ! nextElement ) { + return {}; + } + const previousRect = previousElement.getBoundingClientRect(); + const nextRect = nextElement.getBoundingClientRect(); + + return orientation === 'vertical' + ? { + width: previousElement.offsetWidth, + height: nextRect.top - previousRect.bottom, + } + : { + width: isRTL() + ? previousRect.left - nextRect.right + : nextRect.left - previousRect.right, + height: previousElement.offsetHeight, + }; + }, [ previousElement, nextElement ] ); + const getAnchorRect = useCallback( () => { const previousRect = previousElement.getBoundingClientRect(); const nextRect = nextElement.getBoundingClientRect(); if ( orientation === 'vertical' ) { - const center = - previousRect.bottom + - ( nextRect.top - previousRect.bottom ) / 2; return { - top: center, + top: previousRect.bottom, left: previousRect.left, right: previousRect.right, - bottom: center, + bottom: nextRect.top, }; } - const center = - ( isRTL() ? previousRect.left : previousRect.right ) + - Math.abs( nextRect.left - previousRect.right ) / 2; return { top: previousRect.top, - left: center, - right: center, + left: isRTL() ? nextRect.right : previousRect.right, + right: isRTL() ? previousRect.left : nextRect.left, bottom: previousRect.bottom, }; }, [ previousElement, nextElement ] ); - if ( ! previousElement || isHidden ) { + if ( ! previousElement ) { return null; } @@ -125,6 +146,27 @@ function InsertionPointPopover( { 'is-' + orientation ); + function onClick( event ) { + if ( event.target === ref.current ) { + selectBlock( clientId, -1 ); + } + } + + function onFocus( event ) { + // Only handle click on the wrapper specifically, and not an event + // bubbled from the inserter itself. + if ( event.target !== ref.current ) { + setIsInserterForced( true ); + } + } + + /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ + // While ideally it would be enough to capture the + // bubbling focus event from the Inserter, due to the + // characteristics of click focusing of `button`s in + // Firefox and Safari, it is not reliable. + // + // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus return (
- { ( showInsertionPoint || - isInserterShown || - isInserterForced ) && ( -
- ) } - { ( isInserterShown || isInserterForced ) && ( + { ! isHidden && + ( showInsertionPoint || + isInserterShown || + isInserterForced ) && ( +
+ ) } + { ! isHidden && ( isInserterShown || isInserterForced ) && ( ); + /* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ } export default function useInsertionPoint( ref ) { diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index 0b58f730f9bfb..9f0da27501230 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -16,7 +16,7 @@ export async function openGlobalBlockInserter() { if ( await isGlobalInserterOpen() ) { // If global inserter is already opened, reset to an initial state where // the default (first) tab is selected. - const tab = await page.$( + const tab = await page.waitForSelector( '.block-editor-inserter__tabs .components-tab-panel__tabs-item:nth-of-type(1):not(.is-active)' ); diff --git a/packages/e2e-tests/specs/editor/various/writing-flow.test.js b/packages/e2e-tests/specs/editor/various/writing-flow.test.js index eff7ad5c16ff1..cb6698bb3df4c 100644 --- a/packages/e2e-tests/specs/editor/various/writing-flow.test.js +++ b/packages/e2e-tests/specs/editor/various/writing-flow.test.js @@ -535,11 +535,11 @@ describe( 'Writing Flow', () => { await page.mouse.move( x, y ); await page.waitForSelector( - '.block-editor-block-list__insertion-point-inserter' + '.block-editor-block-list__insertion-point' ); const inserter = await page.$( - '.block-editor-block-list__insertion-point-inserter' + '.block-editor-block-list__insertion-point' ); const inserterRect = await inserter.boundingBox(); const lowerInserterY = inserterRect.y + ( 2 * inserterRect.height ) / 3; @@ -550,36 +550,6 @@ describe( 'Writing Flow', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); - it( 'should not have a dead zone between blocks (upper)', async () => { - await page.keyboard.press( 'Enter' ); - await page.keyboard.type( '1' ); - await page.keyboard.press( 'Enter' ); - await page.keyboard.type( '2' ); - - // Find a point outside the paragraph between the blocks where it's - // expected that the sibling inserter would be placed. - const paragraph = await page.$( '[data-type="core/paragraph"]' ); - const paragraphRect = await paragraph.boundingBox(); - const x = paragraphRect.x + ( 2 * paragraphRect.width ) / 3; - const y = paragraphRect.y + paragraphRect.height + 1; - - await page.mouse.move( x, y ); - await page.waitForSelector( - '.block-editor-block-list__insertion-point-inserter' - ); - - const inserter = await page.$( - '.block-editor-block-list__insertion-point-inserter' - ); - const inserterRect = await inserter.boundingBox(); - const upperInserterY = inserterRect.y + inserterRect.height / 3; - - await page.mouse.click( x, upperInserterY ); - await page.keyboard.type( '3' ); - - expect( await getEditedPostContent() ).toMatchSnapshot(); - } ); - it( 'should not have a dead zone above an aligned block', async () => { await page.keyboard.press( 'Enter' ); await page.keyboard.type( '1' ); @@ -602,11 +572,11 @@ describe( 'Writing Flow', () => { await page.mouse.move( x, y ); await page.waitForSelector( - '.block-editor-block-list__insertion-point-inserter' + '.block-editor-block-list__insertion-point' ); const inserter = await page.$( - '.block-editor-block-list__insertion-point-inserter' + '.block-editor-block-list__insertion-point' ); const inserterRect = await inserter.boundingBox(); const lowerInserterY = inserterRect.y + ( 2 * inserterRect.height ) / 3;