From 3b21c5294993eff77ba8c0b9b15cef507045869c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Wed, 30 Mar 2022 21:14:57 +0300 Subject: [PATCH 1/6] Quote v2: implement exiting on Enter at end --- packages/block-library/src/paragraph/edit.js | 6 ++ .../block-library/src/paragraph/use-enter.js | 72 +++++++++++++++++++ packages/block-library/src/quote/block.json | 1 + 3 files changed, 79 insertions(+) create mode 100644 packages/block-library/src/paragraph/use-enter.js diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js index c6a2988a3d0645..b48d3f0ee837ad 100644 --- a/packages/block-library/src/paragraph/edit.js +++ b/packages/block-library/src/paragraph/edit.js @@ -23,6 +23,11 @@ import { import { createBlock } from '@wordpress/blocks'; import { formatLtr } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { useExitOnEnterAtEnd } from './use-enter'; + const name = 'core/paragraph'; function ParagraphRTLControl( { direction, setDirection } ) { @@ -57,6 +62,7 @@ function ParagraphBlock( { const { align, content, direction, dropCap, placeholder } = attributes; const isDropCapFeatureEnabled = useSetting( 'typography.dropCap' ); const blockProps = useBlockProps( { + ref: useExitOnEnterAtEnd( { clientId, content } ), className: classnames( { 'has-drop-cap': dropCap, [ `has-text-align-${ align }` ]: align, diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js new file mode 100644 index 00000000000000..7b259d29d78c28 --- /dev/null +++ b/packages/block-library/src/paragraph/use-enter.js @@ -0,0 +1,72 @@ +/** + * WordPress dependencies + */ +import { useRef } from '@wordpress/element'; +import { useRefEffect } from '@wordpress/compose'; +import { ENTER } from '@wordpress/keycodes'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { hasBlockSupport } from '@wordpress/blocks'; + +export function useExitOnEnterAtEnd( props ) { + const { moveBlocksToPosition } = useDispatch( blockEditorStore ); + const { + getBlockRootClientId, + getBlockIndex, + getBlockOrder, + getBlockName, + } = useSelect( blockEditorStore ); + const propsRef = useRef( props ); + propsRef.current = props; + return useRefEffect( ( element ) => { + function onKeyDown( event ) { + if ( event.defaultPrevented ) { + return; + } + + if ( event.keyCode !== ENTER ) { + return; + } + + const { content, clientId } = propsRef.current; + + // The paragraph should be empty. + if ( content.length ) { + return; + } + + const wrapperClientId = getBlockRootClientId( clientId ); + + if ( + ! hasBlockSupport( + getBlockName( wrapperClientId ), + '__experimentalExitOnEnterAtEnd', + false + ) + ) { + return; + } + + const order = getBlockOrder( wrapperClientId ); + + // It should be the last block. + if ( order.indexOf( clientId ) !== order.length - 1 ) { + return; + } + + event.preventDefault(); + + moveBlocksToPosition( + [ clientId ], + wrapperClientId, + getBlockRootClientId( wrapperClientId ), + getBlockIndex( wrapperClientId ) + 1 + ); + } + + element.addEventListener( 'keydown', onKeyDown ); + return () => { + element.removeEventListener( 'keydown', onKeyDown ); + }; + }, [] ); +} diff --git a/packages/block-library/src/quote/block.json b/packages/block-library/src/quote/block.json index 74b72078c5c453..dd04a6b23ddf78 100644 --- a/packages/block-library/src/quote/block.json +++ b/packages/block-library/src/quote/block.json @@ -30,6 +30,7 @@ "supports": { "anchor": true, "__experimentalSlashInserter": true, + "__experimentalExitOnEnterAtEnd": true, "typography": { "fontSize": true, "lineHeight": true, From 49426909fc64def9e80d4fb35ca322c25ea4971c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 5 Apr 2022 13:51:39 +0100 Subject: [PATCH 2/6] Support splitting in the middle of a quote block --- .../block-library/src/paragraph/use-enter.js | 52 ++++++++++++++----- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js index 7b259d29d78c28..11ddfb39da4593 100644 --- a/packages/block-library/src/paragraph/use-enter.js +++ b/packages/block-library/src/paragraph/use-enter.js @@ -4,17 +4,25 @@ import { useRef } from '@wordpress/element'; import { useRefEffect } from '@wordpress/compose'; import { ENTER } from '@wordpress/keycodes'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect, useDispatch, useRegistry } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; -import { hasBlockSupport } from '@wordpress/blocks'; +import { hasBlockSupport, createBlock } from '@wordpress/blocks'; export function useExitOnEnterAtEnd( props ) { - const { moveBlocksToPosition } = useDispatch( blockEditorStore ); + const { batch } = useRegistry(); + const { + moveBlocksToPosition, + replaceInnerBlocks, + duplicateBlocks, + insertBlock, + } = useDispatch( blockEditorStore ); const { getBlockRootClientId, getBlockIndex, getBlockOrder, getBlockName, + getBlock, + getNextBlockClientId, } = useSelect( blockEditorStore ); const propsRef = useRef( props ); propsRef.current = props; @@ -49,19 +57,39 @@ export function useExitOnEnterAtEnd( props ) { const order = getBlockOrder( wrapperClientId ); + event.preventDefault(); + + const position = order.indexOf( clientId ); // It should be the last block. - if ( order.indexOf( clientId ) !== order.length - 1 ) { + if ( position === order.length - 1 ) { + moveBlocksToPosition( + [ clientId ], + wrapperClientId, + getBlockRootClientId( wrapperClientId ), + getBlockIndex( wrapperClientId ) + 1 + ); return; } - event.preventDefault(); - - moveBlocksToPosition( - [ clientId ], - wrapperClientId, - getBlockRootClientId( wrapperClientId ), - getBlockIndex( wrapperClientId ) + 1 - ); + const wrapperBlock = getBlock( wrapperClientId ); + batch( () => { + duplicateBlocks( [ wrapperClientId ] ); + const blockIndex = getBlockIndex( wrapperClientId ); + replaceInnerBlocks( + wrapperClientId, + wrapperBlock.innerBlocks.splice( 0, position ) + ); + replaceInnerBlocks( + getNextBlockClientId( wrapperClientId ), + wrapperBlock.innerBlocks.splice( position ) + ); + insertBlock( + createBlock( 'core/paragraph' ), + blockIndex + 1, + getBlockRootClientId( wrapperClientId ), + true + ); + } ); } element.addEventListener( 'keydown', onKeyDown ); From 9921a88fd88ead8614220f2acba736ece4bcb5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 20 Apr 2022 18:48:59 +0200 Subject: [PATCH 3/6] Fix split in the middle --- packages/block-library/src/paragraph/use-enter.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js index 11ddfb39da4593..952d6436f5f909 100644 --- a/packages/block-library/src/paragraph/use-enter.js +++ b/packages/block-library/src/paragraph/use-enter.js @@ -60,7 +60,8 @@ export function useExitOnEnterAtEnd( props ) { event.preventDefault(); const position = order.indexOf( clientId ); - // It should be the last block. + + // If it is the last block, exit. if ( position === order.length - 1 ) { moveBlocksToPosition( [ clientId ], @@ -71,17 +72,19 @@ export function useExitOnEnterAtEnd( props ) { return; } + // If it is in the middle, split the block in two. const wrapperBlock = getBlock( wrapperClientId ); batch( () => { duplicateBlocks( [ wrapperClientId ] ); const blockIndex = getBlockIndex( wrapperClientId ); + replaceInnerBlocks( wrapperClientId, - wrapperBlock.innerBlocks.splice( 0, position ) + wrapperBlock.innerBlocks.slice( 0, position ) ); replaceInnerBlocks( getNextBlockClientId( wrapperClientId ), - wrapperBlock.innerBlocks.splice( position ) + wrapperBlock.innerBlocks.slice( position ) ); insertBlock( createBlock( 'core/paragraph' ), From 9ae5c6ad75ec87954240812c1778eb0412112956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 20 Apr 2022 18:50:58 +0200 Subject: [PATCH 4/6] Rename so it conveys "exit at end" & "split on middle" --- packages/block-library/src/paragraph/use-enter.js | 4 ++-- packages/block-library/src/quote/block.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js index 952d6436f5f909..19de4956098314 100644 --- a/packages/block-library/src/paragraph/use-enter.js +++ b/packages/block-library/src/paragraph/use-enter.js @@ -8,7 +8,7 @@ import { useSelect, useDispatch, useRegistry } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { hasBlockSupport, createBlock } from '@wordpress/blocks'; -export function useExitOnEnterAtEnd( props ) { +export function useOnEnter( props ) { const { batch } = useRegistry(); const { moveBlocksToPosition, @@ -48,7 +48,7 @@ export function useExitOnEnterAtEnd( props ) { if ( ! hasBlockSupport( getBlockName( wrapperClientId ), - '__experimentalExitOnEnterAtEnd', + '__experimentalOnEnter', false ) ) { diff --git a/packages/block-library/src/quote/block.json b/packages/block-library/src/quote/block.json index dd04a6b23ddf78..c4726f3cdaa0c3 100644 --- a/packages/block-library/src/quote/block.json +++ b/packages/block-library/src/quote/block.json @@ -30,7 +30,7 @@ "supports": { "anchor": true, "__experimentalSlashInserter": true, - "__experimentalExitOnEnterAtEnd": true, + "__experimentalOnEnter": true, "typography": { "fontSize": true, "lineHeight": true, From a2f7e79a26161a6e2d12cd2e73655ced49565e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 20 Apr 2022 19:01:10 +0200 Subject: [PATCH 5/6] Push missed rename --- packages/block-library/src/paragraph/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js index b48d3f0ee837ad..d6c79cfe262920 100644 --- a/packages/block-library/src/paragraph/edit.js +++ b/packages/block-library/src/paragraph/edit.js @@ -26,7 +26,7 @@ import { formatLtr } from '@wordpress/icons'; /** * Internal dependencies */ -import { useExitOnEnterAtEnd } from './use-enter'; +import { useOnEnter } from './use-enter'; const name = 'core/paragraph'; @@ -62,7 +62,7 @@ function ParagraphBlock( { const { align, content, direction, dropCap, placeholder } = attributes; const isDropCapFeatureEnabled = useSetting( 'typography.dropCap' ); const blockProps = useBlockProps( { - ref: useExitOnEnterAtEnd( { clientId, content } ), + ref: useOnEnter( { clientId, content } ), className: classnames( { 'has-drop-cap': dropCap, [ `has-text-align-${ align }` ]: align, From 23df8d4ee033ac1a9754adb17efdcfa500bab4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Wed, 20 Apr 2022 19:04:46 +0200 Subject: [PATCH 6/6] Do not copy empty paragraph into new block --- packages/block-library/src/paragraph/use-enter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js index 19de4956098314..22bef120ef17c9 100644 --- a/packages/block-library/src/paragraph/use-enter.js +++ b/packages/block-library/src/paragraph/use-enter.js @@ -84,7 +84,7 @@ export function useOnEnter( props ) { ); replaceInnerBlocks( getNextBlockClientId( wrapperClientId ), - wrapperBlock.innerBlocks.slice( position ) + wrapperBlock.innerBlocks.slice( position + 1 ) ); insertBlock( createBlock( 'core/paragraph' ),