From d3327028e59a55e4e087fc8ae69e5e8853f63201 Mon Sep 17 00:00:00 2001 From: Ella van Durpe Date: Tue, 21 Jan 2020 14:10:34 +0100 Subject: [PATCH] Block: use context to provide selected element --- .../components/block-list/block-popover.js | 15 ++++++----- .../src/components/block-list/block.js | 13 ++++----- .../components/block-list/root-container.js | 27 ++++++++++--------- packages/block-editor/src/store/actions.js | 12 --------- packages/block-editor/src/store/reducer.js | 20 -------------- packages/block-editor/src/store/selectors.js | 11 -------- 6 files changed, 30 insertions(+), 68 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block-popover.js b/packages/block-editor/src/components/block-list/block-popover.js index cb563c3319f21..d197e66396479 100644 --- a/packages/block-editor/src/components/block-list/block-popover.js +++ b/packages/block-editor/src/components/block-list/block-popover.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useState, useCallback } from '@wordpress/element'; +import { useState, useCallback, useContext } from '@wordpress/element'; import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { Popover } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; @@ -20,6 +20,7 @@ import { useViewportMatch } from '@wordpress/compose'; import BlockBreadcrumb from './breadcrumb'; import BlockContextualToolbar from './block-contextual-toolbar'; import Inserter from '../inserter'; +import { SelectedBlockNode } from './root-container'; function selector( select ) { const { @@ -61,6 +62,7 @@ function BlockPopover( { const isLargeViewport = useViewportMatch( 'medium' ); const [ isToolbarForced, setIsToolbarForced ] = useState( false ); const [ isInserterShown, setIsInserterShown ] = useState( false ); + let [ node ] = useContext( SelectedBlockNode ); const showEmptyBlockSideInserter = ! isNavigationMode && isEmptyDefaultBlock && isValid; const shouldShowBreadcrumb = isNavigationMode; @@ -92,7 +94,9 @@ function BlockPopover( { return null; } - let node = document.getElementById( 'block-' + capturingClientId ); + if ( capturingClientId ) { + node = document.getElementById( 'block-' + capturingClientId ); + } if ( ! node ) { return null; @@ -188,7 +192,6 @@ function wrapperSelector( select ) { getSelectedBlockClientId, getFirstMultiSelectedBlockClientId, getBlockRootClientId, - __unstableGetSelectedMountedBlock, __unstableGetBlockWithoutInnerBlocks, getBlockParents, getBlockListSettings, @@ -213,7 +216,7 @@ function wrapperSelector( select ) { // This will be the top most ancestor because getBlockParents() returns tree from top -> bottom const topmostAncestorWithCaptureDescendantsToolbarsIndex = findIndex( ancestorBlockListSettings, [ '__experimentalCaptureToolbars', true ] ); - let capturingClientId = clientId; + let capturingClientId; if ( topmostAncestorWithCaptureDescendantsToolbarsIndex !== -1 ) { capturingClientId = blockParentsClientIds[ topmostAncestorWithCaptureDescendantsToolbarsIndex ]; @@ -222,7 +225,6 @@ function wrapperSelector( select ) { return { clientId, rootClientId: getBlockRootClientId( clientId ), - isMounted: __unstableGetSelectedMountedBlock() === clientId, name, align: attributes.align, isValid, @@ -242,7 +244,6 @@ export default function WrappedBlockPopover() { const { clientId, rootClientId, - isMounted, name, align, isValid, @@ -251,7 +252,7 @@ export default function WrappedBlockPopover() { capturingClientId, } = selected; - if ( ! name || ! isMounted ) { + if ( ! name ) { return null; } diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 8902227bbd561..65b418b243ea4 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -28,7 +28,6 @@ import { withDispatch, withSelect, useSelect, - useDispatch, } from '@wordpress/data'; import { withViewportMatch } from '@wordpress/viewport'; import { compose, pure, ifCondition } from '@wordpress/compose'; @@ -43,7 +42,7 @@ import BlockCrashBoundary from './block-crash-boundary'; import BlockHtml from './block-html'; import { isInsideRootBlock } from '../../utils/dom'; import useMovingAnimation from './moving-animation'; -import { Context } from './root-container'; +import { Context, SelectedBlockNode } from './root-container'; function BlockListBlock( { mode, @@ -78,6 +77,7 @@ function BlockListBlock( { hasSelectedUI = true, } ) { const onSelectionStart = useContext( Context ); + const [ , setSelectedBlockNode ] = useContext( SelectedBlockNode ); // In addition to withSelect, we should favor using useSelect in this component going forward // to avoid leaking new props to the public API (editor.BlockListBlock filter) const { isDraggingBlocks } = useSelect( ( select ) => { @@ -85,16 +85,17 @@ function BlockListBlock( { isDraggingBlocks: select( 'core/block-editor' ).isDraggingBlocks(), }; }, [] ); - const { - __unstableSetSelectedMountedBlock, - } = useDispatch( 'core/block-editor' ); // Reference of the wrapper const wrapper = useRef( null ); useLayoutEffect( () => { if ( isSelected || isFirstMultiSelected ) { - __unstableSetSelectedMountedBlock( clientId ); + const node = wrapper.current; + setSelectedBlockNode( node ); + return () => { + setSelectedBlockNode( ( n ) => n === node ? null : n ); + }; } }, [ isSelected, isFirstMultiSelected ] ); diff --git a/packages/block-editor/src/components/block-list/root-container.js b/packages/block-editor/src/components/block-list/root-container.js index 5542b3edfe80a..aae8c476c418b 100644 --- a/packages/block-editor/src/components/block-list/root-container.js +++ b/packages/block-editor/src/components/block-list/root-container.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { createContext, forwardRef } from '@wordpress/element'; +import { createContext, forwardRef, useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; /** @@ -15,6 +15,7 @@ import BlockPopover from './block-popover'; /** @typedef {import('@wordpress/element').WPSyntheticEvent} WPSyntheticEvent */ export const Context = createContext(); +export const SelectedBlockNode = createContext(); function selector( select ) { const { @@ -80,17 +81,19 @@ function RootContainer( { children, className }, ref ) { selectedBlockClientId={ selectedBlockClientId } containerRef={ ref } > - -
- - { children } - -
+ + +
+ + { children } + +
+
); } diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 07106b6459777..b6a6552e1f019 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -930,15 +930,3 @@ export function * insertAfterBlock( clientId ) { const firstSelectedIndex = yield select( 'core/block-editor', 'getBlockIndex', clientId, rootClientId ); yield insertDefaultBlock( {}, rootClientId, firstSelectedIndex + 1 ); } - -/** - * Sets the client ID for the mounted and selected block. - * - * @param {Element} clientId The block's client ID. - */ -export function __unstableSetSelectedMountedBlock( clientId ) { - return { - type: 'SET_SELECTED_MOUNTED_BLOCK', - clientId, - }; -} diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 2471be0a1e23a..d7b3799a61a0d 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1347,7 +1347,6 @@ export function automaticChangeStatus( state, action ) { return; // Undoing an automatic change should still be possible after mouse // move. - case 'SET_SELECTED_MOUNTED_BLOCK': case 'STOP_TYPING': return state; } @@ -1355,24 +1354,6 @@ export function automaticChangeStatus( state, action ) { // Reset the state by default (for any action not handled). } -/** - * Reducer returning selected and mounted block. This state is useful for - * components rendering and positioning controls around the block's node. - * - * @param {boolean} state Current state. - * @param {Object} action Dispatched action. - * - * @return {boolean} Updated state. - */ -export function selectedMountedBlock( state, action ) { - switch ( action.type ) { - case 'SET_SELECTED_MOUNTED_BLOCK': - return action.clientId; - } - - return state; -} - export default combineReducers( { blocks, isTyping, @@ -1392,5 +1373,4 @@ export default combineReducers( { lastBlockAttributesChange, isNavigationMode, automaticChangeStatus, - selectedMountedBlock, } ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index ceff4cb964436..8c4d6c6395e7d 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1526,14 +1526,3 @@ export function isNavigationMode( state ) { export function didAutomaticChange( state ) { return !! state.automaticChangeStatus; } - -/** - * Gets the selected block's DOM node. - * - * @param {Object} state Global application state. - * - * @return {Element} The selected block's DOM node. - */ -export function __unstableGetSelectedMountedBlock( state ) { - return state.selectedMountedBlock; -}