Skip to content

Commit

Permalink
Use experiment locking/unlocking system for block interface selector …
Browse files Browse the repository at this point in the history
…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 <adam@adamziel.com>

* Fix incorrect `privateSettings` key

---------

Co-authored-by: Adam Zielinski <adam@adamziel.com>
  • Loading branch information
talldan and adamziel committed Jan 30, 2023
1 parent 6611f8e commit fa0da6a
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ 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 {
__unstableGetEditorMode,
isMultiSelecting,
hasMultiSelection,
isTyping,
__experimentalIsBlockInterfaceHidden: isBlockInterfaceHidden,
isBlockInterfaceHidden,
getSettings,
getLastMultiSelectedBlockClientId,
} = select( blockEditorStore );
} = unlock( select( blockEditorStore ) );

return {
editorMode: __unstableGetEditorMode(),
Expand Down
8 changes: 4 additions & 4 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();
Expand Down
63 changes: 1 addition & 62 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */

Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
Expand Down
14 changes: 7 additions & 7 deletions packages/block-editor/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -34,14 +34,14 @@ 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.
const registeredStore = registerStore( STORE_NAME, {
...storeConfig,
persist: [ 'preferences' ],
} );

unlock( registeredStore ).registerPrivateActions( {
__experimentalUpdateSettings,
} );
unlock( registeredStore ).registerPrivateActions( privateActions );
unlock( registeredStore ).registerPrivateSelectors( privateSelectors );
65 changes: 65 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
@@ -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',
};
}
10 changes: 10 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
@@ -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;
}
11 changes: 0 additions & 11 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
18 changes: 0 additions & 18 deletions packages/block-editor/src/store/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const noop = () => {};

const {
clearSelectedBlock,
__experimentalHideBlockInterface: hideBlockInterface,
insertBlock,
insertBlocks,
mergeBlocks,
Expand All @@ -40,7 +39,6 @@ const {
replaceInnerBlocks,
resetBlocks,
selectBlock,
__experimentalShowBlockInterface: showBlockInterface,
showInsertionPoint,
startMultiSelect,
startTyping,
Expand Down Expand Up @@ -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( {
Expand Down
22 changes: 22 additions & 0 deletions packages/block-editor/src/store/test/private-actions.js
Original file line number Diff line number Diff line change
@@ -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',
} );
} );
} );
} );
24 changes: 24 additions & 0 deletions packages/block-editor/src/store/test/private-selectors.js
Original file line number Diff line number Diff line change
@@ -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 );
} );
} );
} );
19 changes: 0 additions & 19 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ const {
isBlockMultiSelected,
isFirstMultiSelectedBlock,
getBlockMode,
__experimentalIsBlockInterfaceHidden: isBlockInterfaceHidden,
isTyping,
isDraggingBlocks,
getDraggedBlockClientIds,
Expand Down Expand Up @@ -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 = {
Expand Down

1 comment on commit fa0da6a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in fa0da6a.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4042566598
📝 Reported issues:

Please sign in to comment.