diff --git a/editor/components/block-drop-zone/index.js b/editor/components/block-drop-zone/index.js index 62197d9357d25..f6b080a058d1d 100644 --- a/editor/components/block-drop-zone/index.js +++ b/editor/components/block-drop-zone/index.js @@ -137,11 +137,10 @@ export default compose( }, }; } ), - withSelect( ( select ) => { - const { templateLock } = select( 'core/editor' ).getEditorSettings(); - + withSelect( ( select, { rootUID } ) => { + const { getLockedState } = select( 'core/editor' ); return { - isLocked: !! templateLock, + isLocked: !! getLockedState( rootUID ), }; } ) )( BlockDropZone ); diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index 88059e8212490..880ab57bd7af2 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -618,10 +618,11 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { getSelectedBlocksInitialCaretPosition, getEditorSettings, hasSelectedInnerBlock, + getLockedState, } = select( 'core/editor' ); const isSelected = isBlockSelected( uid ); const isParentOfSelectedBlock = hasSelectedInnerBlock( uid ); - const { templateLock, hasFixedToolbar } = getEditorSettings(); + const { hasFixedToolbar } = getEditorSettings(); const block = getBlock( uid ); const previousBlockUid = getPreviousBlockUid( uid ); const previousBlock = getBlock( previousBlockUid ); @@ -642,7 +643,7 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { initialPosition: getSelectedBlocksInitialCaretPosition(), isEmptyDefaultBlock: block && isUnmodifiedDefaultBlock( block ), isPreviousBlockADefaultEmptyBlock: previousBlock && isUnmodifiedDefaultBlock( previousBlock ), - isLocked: !! templateLock, + isLocked: !! getLockedState( rootUID ), previousBlockUid, block, isSelected, diff --git a/editor/components/block-list/insertion-point.js b/editor/components/block-list/insertion-point.js index f205d6812dd68..cf814da14350c 100644 --- a/editor/components/block-list/insertion-point.js +++ b/editor/components/block-list/insertion-point.js @@ -78,7 +78,7 @@ export default compose( getBlock, isBlockInsertionPointVisible, isTyping, - getEditorSettings, + getLockedState, } = select( 'core/editor' ); const blockIndex = uid ? getBlockIndex( uid, rootUID ) : -1; const insertIndex = blockIndex; @@ -92,13 +92,13 @@ export default compose( ); return { - templateLock: getEditorSettings().templateLock, + isLocked: !! getLockedState( insertionPoint.rootUID ), showInserter: ! isTyping() && canShowInserter, index: insertIndex, showInsertionPoint, }; } ), - ifCondition( ( { templateLock } ) => ! templateLock ), + ifCondition( ( { isLocked } ) => ! isLocked ), withDispatch( ( dispatch ) => { const { insertDefaultBlock, startTyping } = dispatch( 'core/editor' ); return { diff --git a/editor/components/block-mover/index.js b/editor/components/block-mover/index.js index 1cb87dce0be59..01989c6578699 100644 --- a/editor/components/block-mover/index.js +++ b/editor/components/block-mover/index.js @@ -107,15 +107,14 @@ export class BlockMover extends Component { export default compose( withSelect( ( select, { uids, rootUID } ) => { - const { getBlock, getBlockIndex, getEditorSettings } = select( 'core/editor' ); + const { getBlock, getBlockIndex, getLockedState } = select( 'core/editor' ); const firstUID = first( castArray( uids ) ); const block = getBlock( firstUID ); - const { templateLock } = getEditorSettings(); return { firstIndex: getBlockIndex( firstUID, rootUID ), blockType: block ? getBlockType( block.name ) : null, - isLocked: templateLock === 'all', + isLocked: getLockedState( rootUID ) === 'all', }; } ), withDispatch( ( dispatch, { uids, rootUID } ) => { diff --git a/editor/components/block-settings-menu/block-duplicate-button.js b/editor/components/block-settings-menu/block-duplicate-button.js index bf66e8fc4f243..b7766b6b277a5 100644 --- a/editor/components/block-settings-menu/block-duplicate-button.js +++ b/editor/components/block-settings-menu/block-duplicate-button.js @@ -37,12 +37,11 @@ export function BlockDuplicateButton( { blocks, onDuplicate, onClick = noop, isL export default compose( withSelect( ( select, { uids, rootUID } ) => { - const { getBlocksByUID, getBlockIndex, getEditorSettings } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getBlocksByUID, getBlockIndex, getLockedState } = select( 'core/editor' ); return { blocks: getBlocksByUID( uids ), index: getBlockIndex( last( castArray( uids ) ), rootUID ), - isLocked: !! templateLock, + isLocked: !! getLockedState( rootUID ), }; } ), withDispatch( ( dispatch, { blocks, index, rootUID } ) => ( { diff --git a/editor/components/block-settings-menu/block-remove-button.js b/editor/components/block-settings-menu/block-remove-button.js index a9fe8f121eb37..a33968653f873 100644 --- a/editor/components/block-settings-menu/block-remove-button.js +++ b/editor/components/block-settings-menu/block-remove-button.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { flow, noop } from 'lodash'; +import { castArray, flow, noop, some } from 'lodash'; /** * WordPress dependencies @@ -36,11 +36,12 @@ export default compose( dispatch( 'core/editor' ).removeBlocks( uids ); }, } ) ), - withSelect( ( select ) => { - const { templateLock } = select( 'core/editor' ).getEditorSettings(); - + withSelect( ( select, { uids } ) => { + const { getBlockRootUID, getLockedState } = select( 'core/editor' ); return { - isLocked: !! templateLock, + isLocked: some( castArray( uids ), ( uid ) => { + return !! getLockedState( getBlockRootUID( uid ) ); + } ), }; } ), )( BlockRemoveButton ); diff --git a/editor/components/block-settings-menu/block-transformations.js b/editor/components/block-settings-menu/block-transformations.js index 8f936e2503752..6e8033fc1de8f 100644 --- a/editor/components/block-settings-menu/block-transformations.js +++ b/editor/components/block-settings-menu/block-transformations.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { noop } from 'lodash'; +import { noop, some } from 'lodash'; /** * WordPress dependencies @@ -52,10 +52,9 @@ function BlockTransformations( { blocks, small = false, onTransform, onClick = n } export default compose( [ withSelect( ( select, { uids } ) => { - const { getEditorSettings, getBlocksByUID } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getBlockRootUID, getBlocksByUID, getLockedState } = select( 'core/editor' ); return { - isLocked: !! templateLock, + isLocked: some( uids, ( uid ) => !! getLockedState( getBlockRootUID( uid ) ) ), blocks: getBlocksByUID( uids ), }; } ), diff --git a/editor/components/block-switcher/index.js b/editor/components/block-switcher/index.js index 23441f8b3da71..43a65275d169b 100644 --- a/editor/components/block-switcher/index.js +++ b/editor/components/block-switcher/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { castArray, some } from 'lodash'; + /** * WordPress dependencies */ @@ -98,11 +103,10 @@ export function BlockSwitcher( { blocks, onTransform, isLocked } ) { export default compose( withSelect( ( select, ownProps ) => { - const { getBlock, getEditorSettings } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getBlock, getBlockRootUID, getLockedState } = select( 'core/editor' ); return { blocks: ownProps.uids.map( getBlock ), - isLocked: !! templateLock, + isLocked: some( castArray( ownProps.uids ), ( uid ) => !! getLockedState( getBlockRootUID( uid ) ) ), }; } ), withDispatch( ( dispatch, ownProps ) => ( { diff --git a/editor/components/default-block-appender/index.js b/editor/components/default-block-appender/index.js index 5a844824ba62b..62d4f2e65fc5f 100644 --- a/editor/components/default-block-appender/index.js +++ b/editor/components/default-block-appender/index.js @@ -67,18 +67,18 @@ export function DefaultBlockAppender( { } export default compose( withSelect( ( select, ownProps ) => { - const { getBlockCount, getBlock, getEditorSettings } = select( 'core/editor' ); + const { getBlockCount, getBlock, getEditorSettings, getLockedState } = select( 'core/editor' ); const { isTipVisible } = select( 'core/nux' ); const isEmpty = ! getBlockCount( ownProps.rootUID ); const lastBlock = getBlock( ownProps.lastBlockUID ); const isLastBlockDefault = get( lastBlock, [ 'name' ] ) === getDefaultBlockName(); - const { templateLock, bodyPlaceholder } = getEditorSettings(); + const { bodyPlaceholder } = getEditorSettings(); return { isVisible: isEmpty || ! isLastBlockDefault, showPrompt: isEmpty, - isLocked: !! templateLock, + isLocked: !! getLockedState( ownProps.rootUID ), placeholder: bodyPlaceholder, hasTip: isTipVisible( 'core/editor.inserter' ), }; diff --git a/editor/components/editor-global-keyboard-shortcuts/index.js b/editor/components/editor-global-keyboard-shortcuts/index.js index a6d7da92fbab9..ba99d4a772cda 100644 --- a/editor/components/editor-global-keyboard-shortcuts/index.js +++ b/editor/components/editor-global-keyboard-shortcuts/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { first, last } from 'lodash'; +import { first, last, some } from 'lodash'; /** * WordPress dependencies @@ -98,16 +98,17 @@ export default compose( [ getBlockOrder, getMultiSelectedBlockUids, hasMultiSelection, - getEditorSettings, isEditedPostDirty, + getBlockRootUID, + getLockedState, } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const multiSelectedBlockUids = getMultiSelectedBlockUids(); return { uids: getBlockOrder(), multiSelectedBlockUids: getMultiSelectedBlockUids(), hasMultiSelection: hasMultiSelection(), - isLocked: !! templateLock, + isLocked: some( multiSelectedBlockUids, ( uid ) => !! getLockedState( getBlockRootUID( uid ) ) ), isDirty: isEditedPostDirty(), }; } ), diff --git a/editor/components/inner-blocks/index.js b/editor/components/inner-blocks/index.js index 04399b3dcbe61..c3cbc942f97eb 100644 --- a/editor/components/inner-blocks/index.js +++ b/editor/components/inner-blocks/index.js @@ -20,6 +20,7 @@ function InnerBlocks( { BlockList, layouts, allowedBlocks, + lock, template, isSmallScreen, isSelectedBlockInRoot, @@ -30,7 +31,7 @@ function InnerBlocks( { return (
- +
); } diff --git a/editor/components/inserter-with-shortcuts/index.js b/editor/components/inserter-with-shortcuts/index.js index 8d22af14586ba..64b67d3f11b62 100644 --- a/editor/components/inserter-with-shortcuts/index.js +++ b/editor/components/inserter-with-shortcuts/index.js @@ -49,11 +49,10 @@ function InserterWithShortcuts( { items, isLocked, onInsert } ) { export default compose( withSelect( ( select, { rootUID } ) => { - const { getEditorSettings, getInserterItems } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getInserterItems, getLockedState } = select( 'core/editor' ); return { items: getInserterItems( rootUID ), - isLocked: !! templateLock, + isLocked: !! getLockedState( rootUID ), }; } ), withDispatch( ( dispatch, ownProps ) => { diff --git a/editor/store/selectors.js b/editor/store/selectors.js index 41c52acfbf9cd..56f69a804ab1f 100644 --- a/editor/store/selectors.js +++ b/editor/store/selectors.js @@ -1326,20 +1326,20 @@ export const canInsertBlockType = createSelector( return false; } - const { allowedBlockTypes, templateLock } = getEditorSettings( state ); + const { allowedBlockTypes } = getEditorSettings( state ); const isBlockAllowedInEditor = checkAllowList( allowedBlockTypes, blockName, true ); if ( ! isBlockAllowedInEditor ) { return false; } - const isEditorLocked = !! templateLock; - if ( isEditorLocked ) { + const isLocked = !! getLockedState( state, parentUID ); + if ( isLocked ) { return false; } const parentBlockListSettings = getBlockListSettings( state, parentUID ); - const parentAllowedBlocks = get( parentBlockListSettings, [ 'supportedBlocks' ] ); + const parentAllowedBlocks = get( parentBlockListSettings, [ 'allowedBlocks' ] ); const hasParentAllowedBlock = checkAllowList( parentAllowedBlocks, blockName ); const blockAllowedParentBlocks = blockType.parent; @@ -1834,3 +1834,22 @@ export function getSupportedBlocks( state, uid, globallyEnabledBlockTypes ) { export function getEditorSettings( state ) { return state.settings; } + +/* + * Returns the locked state in the context of a given root block. + * + * @param {Object} state Editor state. + * @param {?string} rootUID Block UID. + * + * @return {?string} Locked state in the context of a given block. + */ +export function getLockedState( state, rootUID = null ) { + if ( rootUID === null ) { + return getTemplateLock( state ); + } + const blockListSettings = getBlockListSettings( state, rootUID ); + if ( ! blockListSettings ) { + return null; + } + return blockListSettings.lock; +} diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index 4fba033320937..d8a47854ea483 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -2964,7 +2964,7 @@ describe( 'selectors', () => { }, blockListSettings: { block1: { - supportedBlocks: [ 'core/test-block-c' ], + allowedBlocks: [ 'core/test-block-c' ], }, }, settings: {}, @@ -2983,7 +2983,7 @@ describe( 'selectors', () => { }, blockListSettings: { block1: { - supportedBlocks: [ 'core/test-block-b' ], + allowedBlocks: [ 'core/test-block-b' ], }, }, settings: {}, @@ -3002,7 +3002,7 @@ describe( 'selectors', () => { }, blockListSettings: { block1: { - supportedBlocks: [], + allowedBlocks: [], }, }, settings: {}, diff --git a/editor/utils/block-list.js b/editor/utils/block-list.js index 2bbfe34cdc326..e61b1bab2297c 100644 --- a/editor/utils/block-list.js +++ b/editor/utils/block-list.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { isEqual, noop, omit } from 'lodash'; +import { noop, omit } from 'lodash'; /** * WordPress dependencies @@ -11,6 +11,7 @@ import { synchronizeBlocksWithTemplate, } from '@wordpress/blocks'; import { withSelect, withDispatch } from '@wordpress/data'; +import isShallowEqual from '@wordpress/is-shallow-equal'; /** * Internal dependencies @@ -56,12 +57,14 @@ export function createInnerBlockList( uid, renderBlockMenu = noop ) { componentDidMount() { INNER_BLOCK_LIST_CACHE[ uid ][ 1 ]++; - this.updateNestedSettings( { - supportedBlocks: this.props.allowedBlocks, - } ); + this.updateNestedSettings(); this.insertTemplateBlocks( this.props.template ); } + componentDidUpdate() { + this.updateNestedSettings(); + } + insertTemplateBlocks( template ) { const { block, insertBlocks } = this.props; if ( template && ! block.innerBlocks.length ) { @@ -71,9 +74,14 @@ export function createInnerBlockList( uid, renderBlockMenu = noop ) { } } - updateNestedSettings( newSettings ) { - if ( ! isEqual( this.props.blockListSettings, newSettings ) ) { - this.props.updateNestedSettings( newSettings ); + updateNestedSettings() { + const { allowedBlocks, lock, parentLock, blockListSettings, updateNestedSettings } = this.props; + const newSettings = { + allowedBlocks, + lock: lock === undefined ? parentLock : lock, + }; + if ( ! isShallowEqual( blockListSettings, newSettings ) ) { + updateNestedSettings( newSettings ); } } @@ -98,10 +106,11 @@ export function createInnerBlockList( uid, renderBlockMenu = noop ) { const InnerBlockListComponentContainer = compose( withSelect( ( select ) => { - const { getBlock, getBlockListSettings } = select( 'core/editor' ); + const { getBlock, getBlockListSettings, getBlockRootUID, getLockedState } = select( 'core/editor' ); return { block: getBlock( uid ), blockListSettings: getBlockListSettings( uid ), + parentLock: getLockedState( getBlockRootUID( uid ) ), }; } ), withDispatch( ( dispatch ) => {