From 97052385630ef6095473d213ef19b236ecc41f1f Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 23 Feb 2024 16:50:53 +0100 Subject: [PATCH] Block bindings: fix Enter on disabled rich text --- .../src/components/block-edit/context.js | 1 + .../src/components/block-edit/index.js | 6 +- .../src/components/rich-text/index.js | 94 ++++++++++--------- .../src/components/rich-text/use-enter.js | 4 + 4 files changed, 60 insertions(+), 45 deletions(-) diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index b280cc9c51f6b8..e8480912a87f03 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -6,6 +6,7 @@ import { createContext, useContext } from '@wordpress/element'; export const mayDisplayControlsKey = Symbol( 'mayDisplayControls' ); export const mayDisplayParentControlsKey = Symbol( 'mayDisplayParentControls' ); export const blockEditingModeKey = Symbol( 'blockEditingMode' ); +export const blockBindingsKey = Symbol( 'blockBindings' ); export const DEFAULT_BLOCK_EDIT_CONTEXT = { name: '', diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 457cd919f89381..4e94a8a427510d 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -14,6 +14,7 @@ import { mayDisplayControlsKey, mayDisplayParentControlsKey, blockEditingModeKey, + blockBindingsKey, } from './context'; /** @@ -41,7 +42,8 @@ export default function BlockEdit( { attributes = {}, __unstableLayoutClassNames, } = props; - const { layout = null } = attributes; + const { layout = null, metadata = {} } = attributes; + const { bindings } = metadata; const layoutSupport = hasBlockSupport( name, 'layout', false ) || hasBlockSupport( name, '__experimentalLayout', false ); @@ -62,6 +64,7 @@ export default function BlockEdit( { [ mayDisplayControlsKey ]: mayDisplayControls, [ mayDisplayParentControlsKey ]: mayDisplayParentControls, [ blockEditingModeKey ]: blockEditingMode, + [ blockBindingsKey ]: bindings, } ), [ name, @@ -73,6 +76,7 @@ export default function BlockEdit( { mayDisplayControls, mayDisplayParentControls, blockEditingMode, + bindings, ] ) } > diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 5f94206c78752f..458f5a96609b65 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -26,6 +26,7 @@ import { getBlockType, store as blocksStore } from '@wordpress/blocks'; */ import { useBlockEditorAutocompleteProps } from '../autocomplete'; import { useBlockEditContext } from '../block-edit'; +import { blockBindingsKey } from '../block-edit/context'; import FormatToolbarContainer from './format-toolbar-container'; import { store as blockEditorStore } from '../../store'; import { useUndoAutomaticChange } from './use-undo-automatic-change'; @@ -117,11 +118,9 @@ export function RichTextWrapper( props = removeNativeProps( props ); const anchorRef = useRef(); - const { - clientId, - isSelected: isBlockSelected, - name: blockName, - } = useBlockEditContext(); + const context = useBlockEditContext(); + const { clientId, isSelected: isBlockSelected, name: blockName } = context; + const blockBindings = context[ blockBindingsKey ]; const selector = ( select ) => { // Avoid subscribing to the block editor store if the block is not // selected. @@ -129,12 +128,10 @@ export function RichTextWrapper( return { isSelected: false }; } - const { getSelectionStart, getSelectionEnd, getBlockAttributes } = + const { getSelectionStart, getSelectionEnd } = select( blockEditorStore ); const selectionStart = getSelectionStart(); const selectionEnd = getSelectionEnd(); - const blockBindings = - getBlockAttributes( clientId )?.metadata?.bindings; let isSelected; @@ -147,48 +144,57 @@ export function RichTextWrapper( isSelected = selectionStart.clientId === clientId; } - // Disable Rich Text editing if block bindings specify that. - let disableBoundBlocks = false; - if ( blockBindings && blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS ) { - const blockTypeAttributes = getBlockType( blockName ).attributes; - const { getBlockBindingsSource } = unlock( select( blocksStore ) ); - for ( const [ attribute, args ] of Object.entries( - blockBindings - ) ) { - if ( - blockTypeAttributes?.[ attribute ]?.source !== 'rich-text' - ) { - break; - } - - // If the source is not defined, or if its value of `lockAttributesEditing` is `true`, disable it. - const blockBindingsSource = getBlockBindingsSource( - args.source - ); - if ( - ! blockBindingsSource || - blockBindingsSource.lockAttributesEditing - ) { - disableBoundBlocks = true; - break; - } - } - } - return { selectionStart: isSelected ? selectionStart.offset : undefined, selectionEnd: isSelected ? selectionEnd.offset : undefined, isSelected, - disableBoundBlocks, }; }; - const { selectionStart, selectionEnd, isSelected, disableBoundBlocks } = - useSelect( selector, [ - clientId, - identifier, - originalIsSelected, - isBlockSelected, - ] ); + const { selectionStart, selectionEnd, isSelected } = useSelect( selector, [ + clientId, + identifier, + originalIsSelected, + isBlockSelected, + ] ); + + const disableBoundBlocks = useSelect( + ( select ) => { + // Disable Rich Text editing if block bindings specify that. + let _disableBoundBlocks = false; + if ( blockBindings && blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS ) { + const blockTypeAttributes = + getBlockType( blockName ).attributes; + const { getBlockBindingsSource } = unlock( + select( blocksStore ) + ); + for ( const [ attribute, args ] of Object.entries( + blockBindings + ) ) { + if ( + blockTypeAttributes?.[ attribute ]?.source !== + 'rich-text' + ) { + break; + } + + // If the source is not defined, or if its value of `lockAttributesEditing` is `true`, disable it. + const blockBindingsSource = getBlockBindingsSource( + args.source + ); + if ( + ! blockBindingsSource || + blockBindingsSource.lockAttributesEditing + ) { + _disableBoundBlocks = true; + break; + } + } + } + + return _disableBoundBlocks; + }, + [ blockBindings, blockName ] + ); const shouldDisableEditing = disableEditing || disableBoundBlocks; diff --git a/packages/block-editor/src/components/rich-text/use-enter.js b/packages/block-editor/src/components/rich-text/use-enter.js index 4daf70e7fa3c74..6b40a82d72d4b2 100644 --- a/packages/block-editor/src/components/rich-text/use-enter.js +++ b/packages/block-editor/src/components/rich-text/use-enter.js @@ -21,6 +21,10 @@ export function useEnter( props ) { propsRef.current = props; return useRefEffect( ( element ) => { function onKeyDown( event ) { + if ( event.target.contentEditable !== 'true' ) { + return; + } + if ( event.defaultPrevented ) { return; }