diff --git a/editor/components/block-drop-zone/index.js b/editor/components/block-drop-zone/index.js index 62197d9357d254..d2652837525224 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 { getTemplateLock } = select( 'core/editor' ); return { - isLocked: !! templateLock, + isLocked: !! getTemplateLock( rootUID ), }; } ) )( BlockDropZone ); diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index 9e1c1b238bf0a1..929b2fcd03e813 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -596,13 +596,16 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { getSelectedBlocksInitialCaretPosition, getEditorSettings, hasSelectedInnerBlock, + getTemplateLock, } = 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 ); + const templateLock = getTemplateLock( rootUID ); + return { nextBlockUid: getNextBlockUid( uid ), isPartOfMultiSelection: isBlockMultiSelected( uid ) || isAncestorMultiSelected( uid ), diff --git a/editor/components/block-list/insertion-point.js b/editor/components/block-list/insertion-point.js index 960f3f8793f0bb..0d2f5f18fcde0d 100644 --- a/editor/components/block-list/insertion-point.js +++ b/editor/components/block-list/insertion-point.js @@ -83,7 +83,7 @@ export default compose( getBlock, isBlockInsertionPointVisible, isTyping, - getEditorSettings, + getTemplateLock, } = select( 'core/editor' ); const blockIndex = uid ? getBlockIndex( uid, rootUID ) : -1; const insertIndex = blockIndex; @@ -97,13 +97,13 @@ export default compose( ); return { - templateLock: getEditorSettings().templateLock, + isLocked: !! getTemplateLock( 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 1cb87dce0be59c..1ac35a6a26b551 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, getTemplateLock } = 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: getTemplateLock( 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 bf66e8fc4f243f..c9b15fa4f8bbb1 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, getTemplateLock } = select( 'core/editor' ); return { blocks: getBlocksByUID( uids ), index: getBlockIndex( last( castArray( uids ) ), rootUID ), - isLocked: !! templateLock, + isLocked: !! getTemplateLock( 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 5c54ccc95f2bca..08bcc5befd27cf 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 @@ -38,11 +38,14 @@ export default compose( dispatch( 'core/editor' ).removeBlocks( uids ); }, } ) ), - withSelect( ( select ) => { - const { templateLock } = select( 'core/editor' ).getEditorSettings(); - + withSelect( ( select, { uids } ) => { + const { getBlockRootUID, getTemplateLock } = select( 'core/editor' ); return { - isLocked: !! templateLock, + isLocked: some( castArray( uids ), ( uid ) => { + const rootUID = getBlockRootUID( uid ); + const templateLock = getTemplateLock( rootUID ); + return templateLock === 'all'; + } ), }; } ), )( BlockRemoveButton ); diff --git a/editor/components/block-switcher/index.js b/editor/components/block-switcher/index.js index 286190136ba5f1..32c72ab55eecd1 100644 --- a/editor/components/block-switcher/index.js +++ b/editor/components/block-switcher/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { get } from 'lodash'; +import { castArray, get, some } from 'lodash'; /** * WordPress dependencies @@ -128,11 +128,10 @@ export class BlockSwitcher extends Component { export default compose( withSelect( ( select, ownProps ) => { - const { getBlock, getEditorSettings } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getBlock, getBlockRootUID, getTemplateLock } = select( 'core/editor' ); return { blocks: ownProps.uids.map( getBlock ), - isLocked: !! templateLock, + isLocked: some( castArray( ownProps.uids ), ( uid ) => !! getTemplateLock( getBlockRootUID( uid ) ) ), }; } ), withDispatch( ( dispatch, ownProps ) => ( { diff --git a/editor/components/default-block-appender/index.js b/editor/components/default-block-appender/index.js index 292a4fc89ec292..f769f3a47688f6 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, getTemplateLock } = 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: !! getTemplateLock( 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 2ecb467d225f4b..4780d6577fdfa7 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 @@ -96,16 +96,17 @@ export default compose( [ getBlockOrder, getMultiSelectedBlockUids, hasMultiSelection, - getEditorSettings, isEditedPostDirty, + getBlockRootUID, + getTemplateLock, } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const multiSelectedBlockUids = getMultiSelectedBlockUids(); return { uids: getBlockOrder(), - multiSelectedBlockUids: getMultiSelectedBlockUids(), + multiSelectedBlockUids, hasMultiSelection: hasMultiSelection(), - isLocked: !! templateLock, + isLocked: some( multiSelectedBlockUids, ( uid ) => !! getTemplateLock( getBlockRootUID( uid ) ) ), isDirty: isEditedPostDirty(), }; } ), diff --git a/editor/components/inner-blocks/index.js b/editor/components/inner-blocks/index.js index 9ecd6a70fecaac..11c71b466bed22 100644 --- a/editor/components/inner-blocks/index.js +++ b/editor/components/inner-blocks/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { pick, get } from 'lodash'; +import { pick } from 'lodash'; import classnames from 'classnames'; /** @@ -43,15 +43,19 @@ class InnerBlocks extends Component { updateNestedSettings() { const { blockListSettings, - allowedBlocks: nextAllowedBlocks, + allowedBlocks, + templateLock, + parentLock, updateNestedSettings, } = this.props; - const allowedBlocks = get( blockListSettings, [ 'allowedBlocks' ] ); - if ( ! isShallowEqual( allowedBlocks, nextAllowedBlocks ) ) { - updateNestedSettings( { - allowedBlocks: nextAllowedBlocks, - } ); + const newSettings = { + allowedBlocks, + templateLock: templateLock === undefined ? parentLock : templateLock, + }; + + if ( ! isShallowEqual( blockListSettings, newSettings ) ) { + updateNestedSettings( newSettings ); } } @@ -60,6 +64,7 @@ class InnerBlocks extends Component { uid, layouts, allowedBlocks, + templateLock, template, isSmallScreen, isSelectedBlockInRoot, @@ -73,7 +78,7 @@ class InnerBlocks extends Component {
); @@ -89,13 +94,16 @@ InnerBlocks = compose( [ hasSelectedInnerBlock, getBlock, getBlockListSettings, + getBlockRootUID, + getTemplateLock, } = select( 'core/editor' ); const { uid } = ownProps; - + const parentUID = getBlockRootUID( uid ); return { isSelectedBlockInRoot: isBlockSelected( uid ) || hasSelectedInnerBlock( uid ), block: getBlock( uid ), blockListSettings: getBlockListSettings( uid ), + parentLock: getTemplateLock( parentUID ), }; } ), withDispatch( ( dispatch, ownProps ) => { diff --git a/editor/components/inserter-with-shortcuts/index.js b/editor/components/inserter-with-shortcuts/index.js index 83c282ad594ab0..c75366d454b511 100644 --- a/editor/components/inserter-with-shortcuts/index.js +++ b/editor/components/inserter-with-shortcuts/index.js @@ -50,11 +50,10 @@ function InserterWithShortcuts( { items, isLocked, onInsert } ) { export default compose( withSelect( ( select, { rootUID } ) => { - const { getEditorSettings, getInserterItems } = select( 'core/editor' ); - const { templateLock } = getEditorSettings(); + const { getInserterItems, getTemplateLock } = select( 'core/editor' ); return { items: getInserterItems( rootUID ), - isLocked: !! templateLock, + isLocked: !! getTemplateLock( rootUID ), }; } ), withDispatch( ( dispatch, ownProps ) => { diff --git a/editor/store/selectors.js b/editor/store/selectors.js index 7de91d61691841..c1fa0e87600136 100644 --- a/editor/store/selectors.js +++ b/editor/store/selectors.js @@ -1192,12 +1192,22 @@ export function getTemplate( state ) { /** * Returns the defined block template lock + * in the context of a given root block or in the global context. * * @param {boolean} state + * @param {?string} rootUID Block UID. + * * @return {?string} Block Template Lock */ -export function getTemplateLock( state ) { - return state.settings.templateLock; +export function getTemplateLock( state, rootUID ) { + if ( ! rootUID ) { + return state.settings.templateLock; + } + const blockListSettings = getBlockListSettings( state, rootUID ); + if ( ! blockListSettings ) { + return null; + } + return blockListSettings.templateLock; } /** @@ -1358,15 +1368,15 @@ 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 = !! getTemplateLock( state, parentUID ); + if ( isLocked ) { return false; } diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index 57c6abb152a759..8bbdb1f9a2c9c3 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -3606,13 +3606,52 @@ describe( 'selectors', () => { } ); describe( 'getTemplateLock', () => { - it( 'should return the template object', () => { + it( 'should return the general template lock if no uid was set', () => { const state = { settings: { templateLock: 'all' }, }; expect( getTemplateLock( state ) ).toBe( 'all' ); } ); + + it( 'should return null if the specified uid was not found ', () => { + const state = { + settings: { templateLock: 'all' }, + blockListSettings: { + chicken: { + templateLock: 'insert', + }, + }, + }; + + expect( getTemplateLock( state, 'ribs' ) ).toBe( null ); + } ); + + it( 'should return null if template lock was not set on the specified block', () => { + const state = { + settings: { templateLock: 'all' }, + blockListSettings: { + chicken: { + test: 'tes1t', + }, + }, + }; + + expect( getTemplateLock( state, 'ribs' ) ).toBe( null ); + } ); + + it( 'should return the template lock for the specified uid', () => { + const state = { + settings: { templateLock: 'all' }, + blockListSettings: { + chicken: { + templateLock: 'insert', + }, + }, + }; + + expect( getTemplateLock( state, 'chicken' ) ).toBe( 'insert' ); + } ); } ); describe( 'isPermalinkEditable', () => {