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 041bef836afc0e..e393710dc5a47c 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 0b58f730f9bfbe..9f0da275012308 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 eff7ad5c16ff11..cb6698bb3df4c1 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;