From d544ad7f1051708c46cb9a2c9f4187453e185811 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 12:19:14 +0300 Subject: [PATCH 1/6] Block editor: remove root appender --- packages/block-editor/src/components/block-list/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index f906372bfa8154..6d4ab6d18b9b9d 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -210,8 +210,7 @@ function Items( { getBlockEditingMode( rootClientId ) !== 'disabled' && __unstableGetEditorMode() !== 'zoom-out' - : rootClientId === selectedBlockClientId || - ( ! rootClientId && ! selectedBlockClientId ) ), + : rootClientId === selectedBlockClientId ), }; }, [ rootClientId, hasAppender, hasCustomAppender ] From 506a5d00fe5df79f037da74de03d5d4e823b2319 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 12:26:25 +0300 Subject: [PATCH 2/6] Still show for empty editor --- packages/block-editor/src/components/block-list/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 6d4ab6d18b9b9d..825deb9f5b4368 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -210,7 +210,10 @@ function Items( { getBlockEditingMode( rootClientId ) !== 'disabled' && __unstableGetEditorMode() !== 'zoom-out' - : rootClientId === selectedBlockClientId ), + : rootClientId === selectedBlockClientId || + ( ! rootClientId && + ! selectedBlockClientId && + ! _order.length ) ), }; }, [ rootClientId, hasAppender, hasCustomAppender ] From 14eb9a34362b257895ba7c13ed3f65c0b227caa4 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 13:52:17 +0300 Subject: [PATCH 3/6] Fix e2e tests --- test/e2e/specs/editor/plugins/custom-post-types.spec.js | 4 +--- test/e2e/specs/editor/various/copy-cut-paste.spec.js | 8 ++------ .../editor/various/keyboard-navigable-blocks.spec.js | 8 -------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/test/e2e/specs/editor/plugins/custom-post-types.spec.js b/test/e2e/specs/editor/plugins/custom-post-types.spec.js index 01dde03650ef73..9aabe4e7454f9f 100644 --- a/test/e2e/specs/editor/plugins/custom-post-types.spec.js +++ b/test/e2e/specs/editor/plugins/custom-post-types.spec.js @@ -72,9 +72,7 @@ test.describe( 'Test Custom Post Types', () => { page, } ) => { await admin.createNewPost( { postType: 'leg_block_in_tpl' } ); - await editor.canvas - .locator( 'role=button[name="Add default block"i]' ) - .click(); + await editor.insertBlock( { name: 'core/paragraph' } ); await page.keyboard.type( 'Hello there' ); await expect.poll( editor.getBlocks ).toMatchObject( [ diff --git a/test/e2e/specs/editor/various/copy-cut-paste.spec.js b/test/e2e/specs/editor/various/copy-cut-paste.spec.js index ec0cbab9ca809b..a4055af4813949 100644 --- a/test/e2e/specs/editor/various/copy-cut-paste.spec.js +++ b/test/e2e/specs/editor/various/copy-cut-paste.spec.js @@ -64,9 +64,7 @@ test.describe( 'Copy/cut/paste', () => { await page.evaluate( () => { window.wp.data.dispatch( 'core/block-editor' ).clearSelectedBlock(); } ); - await editor.canvas - .locator( 'role=button[name="Add default block"i]' ) - .click(); + await editor.insertBlock( { name: 'core/paragraph' } ); await pageUtils.pressKeys( 'primary+v' ); expect( await editor.getEditedPostContent() ).toMatchSnapshot(); } ); @@ -85,9 +83,7 @@ test.describe( 'Copy/cut/paste', () => { await page.evaluate( () => { window.wp.data.dispatch( 'core/block-editor' ).clearSelectedBlock(); } ); - await editor.canvas - .locator( 'role=button[name="Add default block"i]' ) - .click(); + await editor.insertBlock( { name: 'core/paragraph' } ); await pageUtils.pressKeys( 'primary+v' ); expect( await editor.getEditedPostContent() ).toMatchSnapshot(); } ); diff --git a/test/e2e/specs/editor/various/keyboard-navigable-blocks.spec.js b/test/e2e/specs/editor/various/keyboard-navigable-blocks.spec.js index 51b08359d12698..6a7125d04f7a6a 100644 --- a/test/e2e/specs/editor/various/keyboard-navigable-blocks.spec.js +++ b/test/e2e/specs/editor/various/keyboard-navigable-blocks.spec.js @@ -107,14 +107,6 @@ test.describe( 'Order of block keyboard navigation', () => { .focus(); } ); - await pageUtils.pressKeys( 'shift+Tab' ); - await KeyboardNavigableBlocks.expectLabelToHaveFocus( 'Add block' ); - - await pageUtils.pressKeys( 'shift+Tab' ); - await KeyboardNavigableBlocks.expectLabelToHaveFocus( - 'Add default block' - ); - await pageUtils.pressKeys( 'shift+Tab' ); await KeyboardNavigableBlocks.expectLabelToHaveFocus( 'Paragraph Block. Row 2. 1' From 19b67691347a5ab007e8636d6d4063ebe4d569fb Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 14:19:26 +0300 Subject: [PATCH 4/6] Try appending on bottom padding click --- .../src/components/editor-canvas/index.js | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/components/editor-canvas/index.js b/packages/editor/src/components/editor-canvas/index.js index 363d52b124aa0a..2fcc4f541e858b 100644 --- a/packages/editor/src/components/editor-canvas/index.js +++ b/packages/editor/src/components/editor-canvas/index.js @@ -17,10 +17,10 @@ import { __experimentalUseResizeCanvas as useResizeCanvas, } from '@wordpress/block-editor'; import { useEffect, useRef, useMemo } from '@wordpress/element'; -import { useSelect } from '@wordpress/data'; +import { useRegistry, useSelect } from '@wordpress/data'; import { parse } from '@wordpress/blocks'; import { store as coreStore } from '@wordpress/core-data'; -import { useMergeRefs } from '@wordpress/compose'; +import { useMergeRefs, useRefEffect } from '@wordpress/compose'; /** * Internal dependencies @@ -39,8 +39,6 @@ const { useFlashEditableBlocks, } = unlock( blockEditorPrivateApis ); -const noop = () => {}; - /** * These post types have a special editor where they don't allow you to fill the title * and they don't apply the layout styles. @@ -97,6 +95,7 @@ function EditorCanvas( { iframeProps, children, } ) { + const registry = useRegistry(); const { renderingMode, postContentAttributes, @@ -308,9 +307,39 @@ function EditorCanvas( { const localRef = useRef(); const typewriterRef = useTypewriter(); + const paddingAppenderRef = useRefEffect( ( node ) => { + function onMouseDown( event ) { + if ( event.target !== node ) { + return; + } + + // only handle clicks under the last child + const lastChild = node.lastElementChild; + if ( ! lastChild ) { + return; + } + + const lastChildRect = lastChild.getBoundingClientRect(); + if ( event.clientY < lastChildRect.bottom ) { + return; + } + + const { insertDefaultBlock } = + registry.dispatch( blockEditorStore ); + + insertDefaultBlock(); + + event.preventDefault(); + } + node.addEventListener( 'mousedown', onMouseDown ); + return () => { + node.removeEventListener( 'mousedown', onMouseDown ); + }; + }, [] ); const contentRef = useMergeRefs( [ localRef, - renderingMode === 'post-only' ? typewriterRef : noop, + renderingMode === 'post-only' ? typewriterRef : null, + renderingMode === 'post-only' ? paddingAppenderRef : null, useFlashEditableBlocks( { isEnabled: renderingMode === 'template-locked', } ), From 1f8497fe975b0da79604b079276dd2d039f5e521 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 18:14:53 +0300 Subject: [PATCH 5/6] Polish: select last block if empty default block --- .../src/components/editor-canvas/index.js | 36 ++-------- .../editor-canvas/use-padding-appender.js | 66 +++++++++++++++++++ 2 files changed, 70 insertions(+), 32 deletions(-) create mode 100644 packages/editor/src/components/editor-canvas/use-padding-appender.js diff --git a/packages/editor/src/components/editor-canvas/index.js b/packages/editor/src/components/editor-canvas/index.js index 2fcc4f541e858b..3c7599e27b9885 100644 --- a/packages/editor/src/components/editor-canvas/index.js +++ b/packages/editor/src/components/editor-canvas/index.js @@ -17,10 +17,10 @@ import { __experimentalUseResizeCanvas as useResizeCanvas, } from '@wordpress/block-editor'; import { useEffect, useRef, useMemo } from '@wordpress/element'; -import { useRegistry, useSelect } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; import { parse } from '@wordpress/blocks'; import { store as coreStore } from '@wordpress/core-data'; -import { useMergeRefs, useRefEffect } from '@wordpress/compose'; +import { useMergeRefs } from '@wordpress/compose'; /** * Internal dependencies @@ -30,6 +30,7 @@ import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import EditTemplateBlocksNotification from './edit-template-blocks-notification'; import useSelectNearestEditableBlock from '../../hooks/use-select-nearest-editable-block'; +import { usePaddingAppender } from './use-padding-appender'; const { LayoutStyle, @@ -95,7 +96,6 @@ function EditorCanvas( { iframeProps, children, } ) { - const registry = useRegistry(); const { renderingMode, postContentAttributes, @@ -307,35 +307,7 @@ function EditorCanvas( { const localRef = useRef(); const typewriterRef = useTypewriter(); - const paddingAppenderRef = useRefEffect( ( node ) => { - function onMouseDown( event ) { - if ( event.target !== node ) { - return; - } - - // only handle clicks under the last child - const lastChild = node.lastElementChild; - if ( ! lastChild ) { - return; - } - - const lastChildRect = lastChild.getBoundingClientRect(); - if ( event.clientY < lastChildRect.bottom ) { - return; - } - - const { insertDefaultBlock } = - registry.dispatch( blockEditorStore ); - - insertDefaultBlock(); - - event.preventDefault(); - } - node.addEventListener( 'mousedown', onMouseDown ); - return () => { - node.removeEventListener( 'mousedown', onMouseDown ); - }; - }, [] ); + const paddingAppenderRef = usePaddingAppender(); const contentRef = useMergeRefs( [ localRef, renderingMode === 'post-only' ? typewriterRef : null, diff --git a/packages/editor/src/components/editor-canvas/use-padding-appender.js b/packages/editor/src/components/editor-canvas/use-padding-appender.js new file mode 100644 index 00000000000000..c091443495740d --- /dev/null +++ b/packages/editor/src/components/editor-canvas/use-padding-appender.js @@ -0,0 +1,66 @@ +/** + * WordPress dependencies + */ +import { useRegistry } from '@wordpress/data'; +import { useRefEffect } from '@wordpress/compose'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; + +export function usePaddingAppender() { + const registry = useRegistry(); + return useRefEffect( + ( node ) => { + function onMouseDown( event ) { + if ( event.target !== node ) { + return; + } + + const { ownerDocument } = node; + const { defaultView } = ownerDocument; + + const paddingBottom = defaultView.parseInt( + defaultView.getComputedStyle( node ).paddingBottom, + 10 + ); + + if ( ! paddingBottom ) { + return; + } + + // only handle clicks under the last child + const lastChild = node.lastElementChild; + if ( ! lastChild ) { + return; + } + + const lastChildRect = lastChild.getBoundingClientRect(); + if ( event.clientY < lastChildRect.bottom ) { + return; + } + + event.preventDefault(); + + const blockOrder = registry + .select( blockEditorStore ) + .getBlockOrder( '' ); + const lastBlockClientId = blockOrder[ blockOrder.length - 1 ]; + const lastBlock = registry + .select( blockEditorStore ) + .getBlock( lastBlockClientId ); + const { selectBlock, insertDefaultBlock } = + registry.dispatch( blockEditorStore ); + + if ( isUnmodifiedDefaultBlock( lastBlock ) ) { + selectBlock( lastBlockClientId ); + } else { + insertDefaultBlock(); + } + } + node.addEventListener( 'mousedown', onMouseDown ); + return () => { + node.removeEventListener( 'mousedown', onMouseDown ); + }; + }, + [ registry ] + ); +} From a78fe15b252d13e0c304cc615cf8fd81e741b8b1 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 12 Apr 2024 18:39:18 +0300 Subject: [PATCH 6/6] Move to edit-post --- .../src/components/visual-editor/index.js | 4 ++++ .../visual-editor}/use-padding-appender.js | 0 .../src/components/editor-canvas/index.js | 7 +++---- .../editor/various/inserting-blocks.spec.js | 21 +++++++++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) rename packages/{editor/src/components/editor-canvas => edit-post/src/components/visual-editor}/use-padding-appender.js (100%) diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 74dffb35fcd273..0b36ef6da01d1a 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -19,6 +19,7 @@ import { store as blocksStore } from '@wordpress/blocks'; */ import { store as editPostStore } from '../../store'; import { unlock } from '../../lock-unlock'; +import { usePaddingAppender } from './use-padding-appender'; const { EditorCanvas } = unlock( editorPrivateApis ); @@ -53,6 +54,8 @@ export default function VisualEditor( { styles } ) { [] ); + const paddingAppenderRef = usePaddingAppender(); + let paddingBottom; // Add a constant padding for the typewritter effect. When typing at the @@ -91,6 +94,7 @@ export default function VisualEditor( { styles } ) { // We should auto-focus the canvas (title) on load. // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus={ ! isWelcomeGuideVisible } + contentRef={ paddingAppenderRef } /> ); diff --git a/packages/editor/src/components/editor-canvas/use-padding-appender.js b/packages/edit-post/src/components/visual-editor/use-padding-appender.js similarity index 100% rename from packages/editor/src/components/editor-canvas/use-padding-appender.js rename to packages/edit-post/src/components/visual-editor/use-padding-appender.js diff --git a/packages/editor/src/components/editor-canvas/index.js b/packages/editor/src/components/editor-canvas/index.js index 3c7599e27b9885..5b45f42be92a9a 100644 --- a/packages/editor/src/components/editor-canvas/index.js +++ b/packages/editor/src/components/editor-canvas/index.js @@ -30,7 +30,6 @@ import { store as editorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import EditTemplateBlocksNotification from './edit-template-blocks-notification'; import useSelectNearestEditableBlock from '../../hooks/use-select-nearest-editable-block'; -import { usePaddingAppender } from './use-padding-appender'; const { LayoutStyle, @@ -94,6 +93,7 @@ function EditorCanvas( { styles, disableIframe = false, iframeProps, + contentRef, children, } ) { const { @@ -307,11 +307,10 @@ function EditorCanvas( { const localRef = useRef(); const typewriterRef = useTypewriter(); - const paddingAppenderRef = usePaddingAppender(); - const contentRef = useMergeRefs( [ + contentRef = useMergeRefs( [ localRef, + contentRef, renderingMode === 'post-only' ? typewriterRef : null, - renderingMode === 'post-only' ? paddingAppenderRef : null, useFlashEditableBlocks( { isEnabled: renderingMode === 'template-locked', } ), diff --git a/test/e2e/specs/editor/various/inserting-blocks.spec.js b/test/e2e/specs/editor/various/inserting-blocks.spec.js index 8d7f996597224c..b3da80c12ab099 100644 --- a/test/e2e/specs/editor/various/inserting-blocks.spec.js +++ b/test/e2e/specs/editor/various/inserting-blocks.spec.js @@ -26,6 +26,27 @@ test.describe( 'Inserting blocks (@firefox, @webkit)', () => { await requestUtils.deleteAllPatternCategories(); } ); + test( 'inserts a default block on bottom padding click', async ( { + admin, + editor, + } ) => { + await admin.createNewPost(); + await editor.insertBlock( { name: 'core/image' } ); + const body = editor.canvas.locator( 'body' ); + const box = await body.boundingBox(); + await body.click( { + position: { + x: box.width / 2, + y: box.height - 10, + }, + } ); + + expect( await editor.getBlocks() ).toMatchObject( [ + { name: 'core/image' }, + { name: 'core/paragraph' }, + ] ); + } ); + test( 'inserts blocks by dragging and dropping from the global inserter', async ( { admin, page,