From fa0da6a27d236f311732bcff35ac4810b1ceda2f Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 30 Jan 2023 17:48:36 +0800 Subject: [PATCH] Use experiment locking/unlocking system for block interface selector and actions (#47375) * Update block editor store to make the block interface API properly experimental * Unlock experimental block interface API before usage * Fix tests * Remove __experimental prefix from locked APIs * Update documentation Co-authored-by: Adam Zielinski * Fix incorrect `privateSettings` key --------- Co-authored-by: Adam Zielinski --- .../block-tools/selected-block-popover.js | 5 +- packages/block-editor/src/hooks/dimensions.js | 8 +-- packages/block-editor/src/store/actions.js | 63 +----------------- packages/block-editor/src/store/index.js | 14 ++-- .../block-editor/src/store/private-actions.js | 65 +++++++++++++++++++ .../src/store/private-selectors.js | 10 +++ packages/block-editor/src/store/selectors.js | 11 ---- .../block-editor/src/store/test/actions.js | 18 ----- .../src/store/test/private-actions.js | 22 +++++++ .../src/store/test/private-selectors.js | 24 +++++++ .../block-editor/src/store/test/selectors.js | 19 ------ 11 files changed, 136 insertions(+), 123 deletions(-) create mode 100644 packages/block-editor/src/store/private-actions.js create mode 100644 packages/block-editor/src/store/private-selectors.js create mode 100644 packages/block-editor/src/store/test/private-actions.js create mode 100644 packages/block-editor/src/store/test/private-selectors.js diff --git a/packages/block-editor/src/components/block-tools/selected-block-popover.js b/packages/block-editor/src/components/block-tools/selected-block-popover.js index 294813b1f34a15..6ad5b104ca0ea3 100644 --- a/packages/block-editor/src/components/block-tools/selected-block-popover.js +++ b/packages/block-editor/src/components/block-tools/selected-block-popover.js @@ -21,6 +21,7 @@ import { store as blockEditorStore } from '../../store'; import BlockPopover from '../block-popover'; import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props'; import Inserter from '../inserter'; +import { unlock } from '../../experiments'; function selector( select ) { const { @@ -28,10 +29,10 @@ function selector( select ) { isMultiSelecting, hasMultiSelection, isTyping, - __experimentalIsBlockInterfaceHidden: isBlockInterfaceHidden, + isBlockInterfaceHidden, getSettings, getLastMultiSelectedBlockClientId, - } = select( blockEditorStore ); + } = unlock( select( blockEditorStore ) ); return { editorMode: __unstableGetEditorMode(), diff --git a/packages/block-editor/src/hooks/dimensions.js b/packages/block-editor/src/hooks/dimensions.js index 5f17bbc6e59d94..f47c378662f371 100644 --- a/packages/block-editor/src/hooks/dimensions.js +++ b/packages/block-editor/src/hooks/dimensions.js @@ -59,6 +59,7 @@ import { } from './child-layout'; import useSetting from '../components/use-setting'; import { store as blockEditorStore } from '../store'; +import { unlock } from '../experiments'; export const DIMENSIONS_SUPPORT_KEY = 'dimensions'; export const SPACING_SUPPORT_KEY = 'spacing'; @@ -67,10 +68,9 @@ export const AXIAL_SIDES = [ 'vertical', 'horizontal' ]; function useVisualizerMouseOver() { const [ isMouseOver, setIsMouseOver ] = useState( false ); - const { - __experimentalHideBlockInterface: hideBlockInterface, - __experimentalShowBlockInterface: showBlockInterface, - } = useDispatch( blockEditorStore ); + const { hideBlockInterface, showBlockInterface } = unlock( + useDispatch( blockEditorStore ) + ); const onMouseOver = ( e ) => { e.stopPropagation(); hideBlockInterface(); diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 766a01a0428083..98bdf1bffc78c0 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -16,7 +16,6 @@ import { speak } from '@wordpress/a11y'; import { __, _n, sprintf } from '@wordpress/i18n'; import { create, insert, remove, toHTMLString } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; -import { Platform } from '@wordpress/element'; /** * Internal dependencies @@ -26,6 +25,7 @@ import { retrieveSelectedAttribute, START_OF_SELECTED_AREA, } from '../utils/selection'; +import { __experimentalUpdateSettings } from './private-actions'; /** @typedef {import('../components/use-on-block-drop/types').WPDropOperation} WPDropOperation */ @@ -1264,28 +1264,6 @@ export function toggleBlockMode( clientId ) { }; } -/** - * Returns an action object used in signalling that the block interface, eg. toolbar, outline, etc. should be hidden. - * - * @return {Object} Action object. - */ -export function __experimentalHideBlockInterface() { - return { - type: 'HIDE_BLOCK_INTERFACE', - }; -} - -/** - * Returns an action object used in signalling that the block interface, eg. toolbar, outline, etc. should be shown. - * - * @return {Object} Action object. - */ -export function __experimentalShowBlockInterface() { - return { - type: 'SHOW_BLOCK_INTERFACE', - }; -} - /** * Returns an action object used in signalling that the user has begun to type. * @@ -1446,45 +1424,6 @@ export function updateSettings( settings ) { return __experimentalUpdateSettings( settings, true ); } -/** - * A list of private/experimental block editor settings that - * should not become a part of the WordPress public API. - * BlockEditorProvider will remove these settings from the - * settings object it receives. - * - * @see https://github.com/WordPress/gutenberg/pull/46131 - */ -const privateSettings = [ 'inserterMediaCategories' ]; - -/** - * Action that updates the block editor settings and - * conditionally preserves the experimental ones. - * - * @param {Object} settings Updated settings - * @param {boolean} stripExperimentalSettings Whether to strip experimental settings. - * @return {Object} Action object - */ -export function __experimentalUpdateSettings( - settings, - stripExperimentalSettings = false -) { - let cleanSettings = settings; - // There are no plugins in the mobile apps, so there is no - // need to strip the experimental settings: - if ( stripExperimentalSettings && Platform.OS === 'web' ) { - cleanSettings = {}; - for ( const key in settings ) { - if ( ! privateSettings.includes( key ) ) { - cleanSettings[ key ] = settings[ key ]; - } - } - } - return { - type: 'UPDATE_SETTINGS', - settings: cleanSettings, - }; -} - /** * Action that signals that a temporary reusable block has been saved * in order to switch its temporary id with the real id. diff --git a/packages/block-editor/src/store/index.js b/packages/block-editor/src/store/index.js index 3a49dbd1ddb767..1cffdf9a389e0f 100644 --- a/packages/block-editor/src/store/index.js +++ b/packages/block-editor/src/store/index.js @@ -8,12 +8,12 @@ import { createReduxStore, registerStore } from '@wordpress/data'; */ import reducer from './reducer'; import * as selectors from './selectors'; -import * as allActions from './actions'; +import * as privateActions from './private-actions'; +import * as privateSelectors from './private-selectors'; +import * as actions from './actions'; import { STORE_NAME } from './constants'; import { unlock } from '../experiments'; -const { __experimentalUpdateSettings, ...actions } = allActions; - /** * Block editor data store configuration. * @@ -34,6 +34,8 @@ export const store = createReduxStore( STORE_NAME, { ...storeConfig, persist: [ 'preferences' ], } ); +unlock( store ).registerPrivateActions( privateActions ); +unlock( store ).registerPrivateSelectors( privateSelectors ); // We will be able to use the `register` function once we switch // the "preferences" persistence to use the new preferences package. @@ -41,7 +43,5 @@ const registeredStore = registerStore( STORE_NAME, { ...storeConfig, persist: [ 'preferences' ], } ); - -unlock( registeredStore ).registerPrivateActions( { - __experimentalUpdateSettings, -} ); +unlock( registeredStore ).registerPrivateActions( privateActions ); +unlock( registeredStore ).registerPrivateSelectors( privateSelectors ); diff --git a/packages/block-editor/src/store/private-actions.js b/packages/block-editor/src/store/private-actions.js new file mode 100644 index 00000000000000..faf227edc0de6f --- /dev/null +++ b/packages/block-editor/src/store/private-actions.js @@ -0,0 +1,65 @@ +/** + * WordPress dependencies + */ +import { Platform } from '@wordpress/element'; + +/** + * A list of private/experimental block editor settings that + * should not become a part of the WordPress public API. + * BlockEditorProvider will remove these settings from the + * settings object it receives. + * + * @see https://github.com/WordPress/gutenberg/pull/46131 + */ +const privateSettings = [ 'inserterMediaCategories' ]; + +/** + * Action that updates the block editor settings and + * conditionally preserves the experimental ones. + * + * @param {Object} settings Updated settings + * @param {boolean} stripExperimentalSettings Whether to strip experimental settings. + * @return {Object} Action object + */ +export function __experimentalUpdateSettings( + settings, + stripExperimentalSettings = false +) { + let cleanSettings = settings; + // There are no plugins in the mobile apps, so there is no + // need to strip the experimental settings: + if ( stripExperimentalSettings && Platform.OS === 'web' ) { + cleanSettings = {}; + for ( const key in settings ) { + if ( ! privateSettings.includes( key ) ) { + cleanSettings[ key ] = settings[ key ]; + } + } + } + return { + type: 'UPDATE_SETTINGS', + settings: cleanSettings, + }; +} + +/** + * Hides the block interface (eg. toolbar, outline, etc.) + * + * @return {Object} Action object. + */ +export function hideBlockInterface() { + return { + type: 'HIDE_BLOCK_INTERFACE', + }; +} + +/** + * Shows the block interface (eg. toolbar, outline, etc.) + * + * @return {Object} Action object. + */ +export function showBlockInterface() { + return { + type: 'SHOW_BLOCK_INTERFACE', + }; +} diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js new file mode 100644 index 00000000000000..dede6eccccbe50 --- /dev/null +++ b/packages/block-editor/src/store/private-selectors.js @@ -0,0 +1,10 @@ +/** + * Returns true if the block interface is hidden, or false otherwise. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether the block toolbar is hidden. + */ +export function isBlockInterfaceHidden( state ) { + return state.isBlockInterfaceHidden; +} diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 0020f4161b38d1..9d4a053be7332a 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1279,17 +1279,6 @@ export function isTyping( state ) { return state.isTyping; } -/** - * Returns true if the the block interface should be hidden, or false otherwise. - * - * @param {Object} state Global application state. - * - * @return {boolean} Whether the block toolbar is hidden. - */ -export function __experimentalIsBlockInterfaceHidden( state ) { - return state.isBlockInterfaceHidden; -} - /** * Returns true if the user is dragging blocks, or false otherwise. * diff --git a/packages/block-editor/src/store/test/actions.js b/packages/block-editor/src/store/test/actions.js index 82cf9831f104a2..45e432ad8bf3f8 100644 --- a/packages/block-editor/src/store/test/actions.js +++ b/packages/block-editor/src/store/test/actions.js @@ -27,7 +27,6 @@ const noop = () => {}; const { clearSelectedBlock, - __experimentalHideBlockInterface: hideBlockInterface, insertBlock, insertBlocks, mergeBlocks, @@ -40,7 +39,6 @@ const { replaceInnerBlocks, resetBlocks, selectBlock, - __experimentalShowBlockInterface: showBlockInterface, showInsertionPoint, startMultiSelect, startTyping, @@ -777,22 +775,6 @@ describe( 'actions', () => { } ); } ); - describe( 'hideBlockInterface', () => { - it( 'should return the HIDE_BLOCK_INTERFACE action', () => { - expect( hideBlockInterface() ).toEqual( { - type: 'HIDE_BLOCK_INTERFACE', - } ); - } ); - } ); - - describe( 'showBlockInterface', () => { - it( 'should return the SHOW_BLOCK_INTERFACE action', () => { - expect( showBlockInterface() ).toEqual( { - type: 'SHOW_BLOCK_INTERFACE', - } ); - } ); - } ); - describe( 'startTyping', () => { it( 'should return the START_TYPING action', () => { expect( startTyping() ).toEqual( { diff --git a/packages/block-editor/src/store/test/private-actions.js b/packages/block-editor/src/store/test/private-actions.js new file mode 100644 index 00000000000000..c4453547f6ce6a --- /dev/null +++ b/packages/block-editor/src/store/test/private-actions.js @@ -0,0 +1,22 @@ +/** + * Internal dependencies + */ +import { hideBlockInterface, showBlockInterface } from '../private-actions'; + +describe( 'private actions', () => { + describe( 'hideBlockInterface', () => { + it( 'should return the HIDE_BLOCK_INTERFACE action', () => { + expect( hideBlockInterface() ).toEqual( { + type: 'HIDE_BLOCK_INTERFACE', + } ); + } ); + } ); + + describe( 'showBlockInterface', () => { + it( 'should return the SHOW_BLOCK_INTERFACE action', () => { + expect( showBlockInterface() ).toEqual( { + type: 'SHOW_BLOCK_INTERFACE', + } ); + } ); + } ); +} ); diff --git a/packages/block-editor/src/store/test/private-selectors.js b/packages/block-editor/src/store/test/private-selectors.js new file mode 100644 index 00000000000000..2c287ceda0f88f --- /dev/null +++ b/packages/block-editor/src/store/test/private-selectors.js @@ -0,0 +1,24 @@ +/** + * Internal dependencies + */ +import { isBlockInterfaceHidden } from '../private-selectors'; + +describe( 'private selectors', () => { + describe( 'isBlockInterfaceHidden', () => { + it( 'should return the true if toggled true in state', () => { + const state = { + isBlockInterfaceHidden: true, + }; + + expect( isBlockInterfaceHidden( state ) ).toBe( true ); + } ); + + it( 'should return false if toggled false in state', () => { + const state = { + isBlockInterfaceHidden: false, + }; + + expect( isBlockInterfaceHidden( state ) ).toBe( false ); + } ); + } ); +} ); diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index 973451e237252d..08763c74efcb64 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -44,7 +44,6 @@ const { isBlockMultiSelected, isFirstMultiSelectedBlock, getBlockMode, - __experimentalIsBlockInterfaceHidden: isBlockInterfaceHidden, isTyping, isDraggingBlocks, getDraggedBlockClientIds, @@ -2259,24 +2258,6 @@ describe( 'selectors', () => { } ); } ); - describe( 'isBlockInterfaceHidden', () => { - it( 'should return the true if toggled true in state', () => { - const state = { - isBlockInterfaceHidden: true, - }; - - expect( isBlockInterfaceHidden( state ) ).toBe( true ); - } ); - - it( 'should return false if toggled false in state', () => { - const state = { - isBlockInterfaceHidden: false, - }; - - expect( isBlockInterfaceHidden( state ) ).toBe( false ); - } ); - } ); - describe( 'isTyping', () => { it( 'should return the isTyping flag if the block is selected', () => { const state = {