From f4cf0472891fca2f4c9659bf0ab6c78bf55f398f Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Tue, 23 Apr 2024 20:31:05 +0800 Subject: [PATCH 01/16] Remove the lock icon block content only blocks --- .../block-settings-menu-controls/index.js | 17 ++++++++++++----- .../components/list-view/block-select-button.js | 13 ++++++++++++- .../src/components/list-view/block.js | 4 ++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/block-settings-menu-controls/index.js b/packages/block-editor/src/components/block-settings-menu-controls/index.js index 8b43827605c53e..d043ae34aa0d27 100644 --- a/packages/block-editor/src/components/block-settings-menu-controls/index.js +++ b/packages/block-editor/src/components/block-settings-menu-controls/index.js @@ -27,15 +27,20 @@ import { BlockRenameControl, useBlockRename } from '../block-rename'; const { Fill, Slot } = createSlotFill( 'BlockSettingsMenuControls' ); const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => { - const { selectedBlocks, selectedClientIds } = useSelect( + const { selectedBlocks, selectedClientIds, isContentOnly } = useSelect( ( select ) => { - const { getBlockNamesByClientId, getSelectedBlockClientIds } = - select( blockEditorStore ); + const { + getBlockNamesByClientId, + getSelectedBlockClientIds, + getBlockEditingMode, + } = select( blockEditorStore ); const ids = clientIds !== null ? clientIds : getSelectedBlockClientIds(); return { selectedBlocks: getBlockNamesByClientId( ids ), selectedClientIds: ids, + isContentOnly: + getBlockEditingMode( ids[ 0 ] ) === 'contentOnly', }; }, [ clientIds ] @@ -43,8 +48,10 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => { const { canLock } = useBlockLock( selectedClientIds[ 0 ] ); const { canRename } = useBlockRename( selectedBlocks[ 0 ] ); - const showLockButton = selectedClientIds.length === 1 && canLock; - const showRenameButton = selectedClientIds.length === 1 && canRename; + const showLockButton = + selectedClientIds.length === 1 && canLock && ! isContentOnly; + const showRenameButton = + selectedClientIds.length === 1 && canRename && ! isContentOnly; // Check if current selection of blocks is Groupable or Ungroupable // and pass this props down to ConvertToGroupButton. diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index 101fb527b03b4e..605e22f226b25f 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -16,6 +16,7 @@ import { forwardRef } from '@wordpress/element'; import { Icon, lockSmall as lock, pinSmall } from '@wordpress/icons'; import { SPACE, ENTER } from '@wordpress/keycodes'; import { __, sprintf } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -26,6 +27,7 @@ import useBlockDisplayTitle from '../block-title/use-block-display-title'; import ListViewExpander from './expander'; import { useBlockLock } from '../block-lock'; import useListViewImages from './use-list-view-images'; +import { store as blockEditorStore } from '../../store'; function ListViewBlockSelectButton( { @@ -51,6 +53,15 @@ function ListViewBlockSelectButton( context: 'list-view', } ); const { isLocked } = useBlockLock( clientId ); + const { isContentOnly } = useSelect( + ( select ) => ( { + isContentOnly: + select( blockEditorStore ).getBlockEditingMode( clientId ) === + 'contentOnly', + } ), + [ clientId ] + ); + const shouldShowLockIcon = isLocked && ! isContentOnly; const isSticky = blockInformation?.positionType === 'sticky'; const images = useListViewImages( { clientId, isExpanded } ); @@ -147,7 +158,7 @@ function ListViewBlockSelectButton( ) ) } ) : null } - { isLocked && ( + { shouldShowLockIcon && ( diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index cdbc5939e6a2ab..0e530e87ed6cb7 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -130,8 +130,8 @@ function ListViewBlock( { // since that menu is part of the toolbar in the editor canvas. // List View respects this by also hiding the block settings menu. hasBlockSupport( blockName, '__experimentalToolbar', true ) && - // Don't show the settings menu if block is disabled or content only. - blockEditingMode === 'default'; + // Don't show the settings menu if block is disabled. + blockEditingMode !== 'disabled'; const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__description-${ instanceId }`; From 328439ce9a4fe6d3d74f1dea8248078e4775d01e Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 26 Apr 2024 09:25:17 +0800 Subject: [PATCH 02/16] Add content only description for patterns and templates --- .../block-settings-menu-controls/index.js | 2 +- .../block-settings-dropdown.js | 20 ++- .../content-only-settings-menu.js | 118 ++++++++++++++++++ .../components/block-settings-menu/style.scss | 4 + .../editor/src/components/provider/index.js | 2 + packages/editor/src/style.scss | 1 + 6 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 packages/editor/src/components/block-settings-menu/content-only-settings-menu.js create mode 100644 packages/editor/src/components/block-settings-menu/style.scss diff --git a/packages/block-editor/src/components/block-settings-menu-controls/index.js b/packages/block-editor/src/components/block-settings-menu-controls/index.js index d043ae34aa0d27..4ee58f80e82b53 100644 --- a/packages/block-editor/src/components/block-settings-menu-controls/index.js +++ b/packages/block-editor/src/components/block-settings-menu-controls/index.js @@ -106,7 +106,7 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => { { __( 'Move to' ) } ) } - { fillProps?.count === 1 && ( + { fillProps?.count === 1 && ! isContentOnly && ( { const { @@ -73,6 +74,7 @@ export function BlockSettingsDropdown( { getSelectedBlockClientIds, getBlockAttributes, getOpenedBlockSettingsMenu, + getBlockEditingMode, } = unlock( select( blockEditorStore ) ); const { getActiveBlockVariation } = select( blocksStore ); @@ -96,6 +98,8 @@ export function BlockSettingsDropdown( { getPreviousBlockClientId( firstBlockClientId ), selectedBlockClientIds: getSelectedBlockClientIds(), openedBlockSettingsMenu: getOpenedBlockSettingsMenu(), + isContentOnly: + getBlockEditingMode( firstBlockClientId ) === 'contentOnly', }; }, [ firstBlockClientId ] @@ -231,11 +235,15 @@ export function BlockSettingsDropdown( { clientId={ firstBlockClientId } /> ) } - + { ! isContentOnly && ( + + ) } { canDuplicate && ( ) } - { canCopyStyles && ( + { canCopyStyles && ! isContentOnly && ( { + const { + getBlockEditingMode, + getBlockParentsByBlockName, + getSettings, + getBlockAttributes, + } = select( blockEditorStore ); + const contentOnly = + getBlockEditingMode( clientId ) === 'contentOnly'; + if ( ! contentOnly ) return {}; + const patternParent = getBlockParentsByBlockName( + clientId, + 'core/block', + true + )[ 0 ]; + + let record; + if ( patternParent ) { + record = select( coreStore ).getEntityRecord( + 'postType', + 'wp_block', + getBlockAttributes( patternParent ).ref + ); + } else { + const templateId = select( editorStore ).getCurrentTemplateId(); + if ( templateId ) { + record = select( coreStore ).getEntityRecord( + 'postType', + 'wp_template', + templateId + ); + } + } + return { + entity: record, + onNavigateToEntityRecord: + getSettings().onNavigateToEntityRecord, + }; + }, + [ clientId ] + ); + + if ( ! entity ) return null; + + const isPattern = entity.type === 'wp_block'; + + return ( + <> + + + { isPattern + ? sprintf( + // translators: %s: pattern's title. + __( + 'This block is part of the synced pattern: "%s". To move, delete, or edit other properties, you must edit the pattern.' + ), + entity.title.raw + ) + : sprintf( + // translators: %s: template's title. + __( + 'This block is part of the template: "%s". To move, delete, or edit other properties, you must edit the template.' + ), + entity.title.rendered + ) } + + + { + onNavigateToEntityRecord( { + postId: entity.id, + postType: entity.type, + } ); + } } + > + { isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) } + + + ); +} + +export default function TemplateContentOnlySettingsMenu() { + return ( + + { ( { selectedClientIds } ) => + selectedClientIds.length === 1 && ( + + ) + } + + ); +} diff --git a/packages/editor/src/components/block-settings-menu/style.scss b/packages/editor/src/components/block-settings-menu/style.scss new file mode 100644 index 00000000000000..53fa391d28ef04 --- /dev/null +++ b/packages/editor/src/components/block-settings-menu/style.scss @@ -0,0 +1,4 @@ +.editor-content-only-settings-menu__description { + padding: $grid-unit; + min-width: 235px; +} diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index df0fb488c69dc1..4f359104ea02da 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -28,6 +28,7 @@ import useCommands from '../commands'; import BlockRemovalWarnings from '../block-removal-warnings'; import StartPageOptions from '../start-page-options'; import KeyboardShortcutHelpModal from '../keyboard-shortcut-help-modal'; +import ContentOnlySettingsMenu from '../block-settings-menu/content-only-settings-menu'; const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); const { PatternsMenuItems } = unlock( editPatternsPrivateApis ); @@ -264,6 +265,7 @@ export const ExperimentalEditorProvider = withRegistryProvider( { ! settings.__unstableIsPreviewMode && ( <> + { mode === 'template-locked' && ( ) } diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss index b382fd82c583ae..dcc693c08b80a7 100644 --- a/packages/editor/src/style.scss +++ b/packages/editor/src/style.scss @@ -3,6 +3,7 @@ @import "./components/autocompleters/style.scss"; @import "./components/block-manager/style.scss"; @import "./components/collapsible-block-toolbar/style.scss"; +@import "./components/block-settings-menu/style.scss"; @import "./components/document-bar/style.scss"; @import "./components/document-outline/style.scss"; @import "./components/document-tools/style.scss"; From 5fb135d4d81dc12489f189570a9e77a2f0e18f43 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 29 Apr 2024 13:25:43 +0800 Subject: [PATCH 03/16] Tweak strings --- .../block-settings-menu/content-only-settings-menu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 0fe33f1bb7915f..8500453942ff80 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -76,14 +76,14 @@ function ContentOnlySettingsMenuItems( { clientId } ) { ? sprintf( // translators: %s: pattern's title. __( - 'This block is part of the synced pattern: "%s". To move, delete, or edit other properties, you must edit the pattern.' + 'This block belongs to "%s". Edit the pattern to move or delete it.' ), entity.title.raw ) : sprintf( // translators: %s: template's title. __( - 'This block is part of the template: "%s". To move, delete, or edit other properties, you must edit the template.' + 'This block belongs to "%s". Edit the template to move or delete it.' ), entity.title.rendered ) } From ef80458a0246c3b9f50d1d5049df26444c9658cf Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 29 Apr 2024 13:31:02 +0800 Subject: [PATCH 04/16] Remove convert template menu item if the block is content only --- .../components/template-part-converter/index.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/edit-site/src/components/template-part-converter/index.js b/packages/edit-site/src/components/template-part-converter/index.js index 7694735cbb3025..ac679e8de6d6bc 100644 --- a/packages/edit-site/src/components/template-part-converter/index.js +++ b/packages/edit-site/src/components/template-part-converter/index.js @@ -27,12 +27,23 @@ export default function TemplatePartConverter() { } function TemplatePartConverterMenuItem( { clientIds, onClose } ) { - const blocks = useSelect( - ( select ) => - select( blockEditorStore ).getBlocksByClientId( clientIds ), + const { isContentOnly, blocks } = useSelect( + ( select ) => { + const { getBlocksByClientId, getBlockEditingMode } = + select( blockEditorStore ); + return { + blocks: getBlocksByClientId( clientIds ), + isContentOnly: + clientIds.length === 1 && + getBlockEditingMode( clientIds[ 0 ] ) === 'contentOnly', + }; + }, [ clientIds ] ); + // Do not show the convert button if the block is in content-only mode. + if ( isContentOnly ) return null; + // Allow converting a single template part to standard blocks. if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) { return ( From 574019be9adf69ef0af27f4ef7d9c12991a9d59d Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 29 Apr 2024 15:37:19 +0800 Subject: [PATCH 05/16] Fix canMoveBlock with block editing mode --- packages/block-editor/src/store/selectors.js | 6 ++++-- .../block-settings-menu/content-only-settings-menu.js | 2 +- .../content-only-settings-menu.native.js | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 4ce85afb8cfd1e..176c15557c8386 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1759,14 +1759,16 @@ export function canMoveBlock( state, clientId, rootClientId = null ) { if ( attributes === null ) { return true; } + if ( getBlockEditingMode( state, rootClientId ) !== 'default' ) { + return false; + } if ( attributes.lock?.move !== undefined ) { return ! attributes.lock.move; } if ( getTemplateLock( state, rootClientId ) === 'all' ) { return false; } - - return getBlockEditingMode( state, rootClientId ) !== 'disabled'; + return true; } /** diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 8500453942ff80..13b298d4026d84 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -103,7 +103,7 @@ function ContentOnlySettingsMenuItems( { clientId } ) { ); } -export default function TemplateContentOnlySettingsMenu() { +export default function ContentOnlySettingsMenu() { return ( { ( { selectedClientIds } ) => diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js new file mode 100644 index 00000000000000..b10c08c3000b02 --- /dev/null +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js @@ -0,0 +1,3 @@ +export default function ContentOnlySettingsMenu() { + return null; +} From 91807e1298df63c6e7892af153a124c66be5cef5 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 2 May 2024 16:05:35 +0800 Subject: [PATCH 06/16] Address code review and hide non pattern/template menu --- .../src/components/block-actions/index.js | 6 +- .../src/components/list-view/block.js | 68 +++++++++++-------- .../content-only-settings-menu.js | 7 +- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/packages/block-editor/src/components/block-actions/index.js b/packages/block-editor/src/components/block-actions/index.js index 2b3c883dfc367a..b34f8eea936155 100644 --- a/packages/block-editor/src/components/block-actions/index.js +++ b/packages/block-editor/src/components/block-actions/index.js @@ -31,10 +31,12 @@ export default function BlockActions( { getDirectInsertBlock, canMoveBlocks, canRemoveBlocks, + getBlockEditingMode, } = select( blockEditorStore ); const blocks = getBlocksByClientId( clientIds ); const rootClientId = getBlockRootClientId( clientIds[ 0 ] ); + const rootBlockEditingMode = getBlockEditingMode( rootClientId ); const canInsertDefaultBlock = canInsertBlockType( getDefaultBlockName(), rootClientId @@ -46,7 +48,9 @@ export default function BlockActions( { return { canMove: canMoveBlocks( clientIds, rootClientId ), canRemove: canRemoveBlocks( clientIds, rootClientId ), - canInsertBlock: canInsertDefaultBlock || !! directInsertBlock, + canInsertBlock: + ( canInsertDefaultBlock || !! directInsertBlock ) && + rootBlockEditingMode === 'default', canCopyStyles: blocks.every( ( block ) => { return ( !! block && diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 0e530e87ed6cb7..52e828d547d062 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -104,34 +104,46 @@ function ListViewBlock( { const blockInformation = useBlockDisplayInformation( clientId ); - const { block, blockName, blockEditingMode, allowRightClickOverrides } = - useSelect( - ( select ) => { - const { - getBlock, - getBlockName, - getBlockEditingMode, - getSettings, - } = select( blockEditorStore ); - - return { - block: getBlock( clientId ), - blockName: getBlockName( clientId ), - blockEditingMode: getBlockEditingMode( clientId ), - allowRightClickOverrides: - getSettings().allowRightClickOverrides, - }; - }, - [ clientId ] - ); - - const showBlockActions = - // When a block hides its toolbar it also hides the block settings menu, - // since that menu is part of the toolbar in the editor canvas. - // List View respects this by also hiding the block settings menu. - hasBlockSupport( blockName, '__experimentalToolbar', true ) && - // Don't show the settings menu if block is disabled. - blockEditingMode !== 'disabled'; + const { block, allowRightClickOverrides, showBlockActions } = useSelect( + ( select ) => { + const { + getBlock, + getBlockName, + getSettings, + getContentLockingParent, + getBlockEditingMode, + getTemplateLock, + } = unlock( select( blockEditorStore ) ); + const _blockName = getBlockName( clientId ); + const isContentOnly = + getBlockEditingMode( clientId ) === 'contentOnly'; + const contentLockingParent = getContentLockingParent( clientId ); + // Don't show the block actions for template lock contentOnly. + // This block currently doesn't have any action to display in the menu dropdown. + const isContentLockingParentTemplateLock = + getTemplateLock( contentLockingParent ) === 'contentOnly'; + // When a block hides its toolbar it also hides the block settings menu, + // since that menu is part of the toolbar in the editor canvas. + // List View respects this by also hiding the block settings menu. + const hasToolbar = hasBlockSupport( + _blockName, + '__experimentalToolbar', + true + ); + + return { + block: getBlock( clientId ), + blockName: _blockName, + allowRightClickOverrides: + getSettings().allowRightClickOverrides, + showBlockActions: + hasToolbar && + ! ( isContentOnly && isContentLockingParentTemplateLock ), + }; + }, + [ clientId ] + ); + const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__description-${ instanceId }`; diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 13b298d4026d84..232ef0eafe6fa5 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -42,8 +42,11 @@ function ContentOnlySettingsMenuItems( { clientId } ) { getBlockAttributes( patternParent ).ref ); } else { - const templateId = select( editorStore ).getCurrentTemplateId(); - if ( templateId ) { + const { getCurrentPostType, getCurrentTemplateId } = + select( editorStore ); + const currentPostType = getCurrentPostType(); + const templateId = getCurrentTemplateId(); + if ( currentPostType === 'page' && templateId ) { record = select( coreStore ).getEntityRecord( 'postType', 'wp_template', From fe2f5cca1b58ecfec70caa5e7194a5b14bba8a1c Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 2 May 2024 16:20:12 +0800 Subject: [PATCH 07/16] Fix lint errors --- .../src/components/template-part-converter/index.js | 4 +++- .../block-settings-menu/content-only-settings-menu.js | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/edit-site/src/components/template-part-converter/index.js b/packages/edit-site/src/components/template-part-converter/index.js index ac679e8de6d6bc..de47eb6ae26f4d 100644 --- a/packages/edit-site/src/components/template-part-converter/index.js +++ b/packages/edit-site/src/components/template-part-converter/index.js @@ -42,7 +42,9 @@ function TemplatePartConverterMenuItem( { clientIds, onClose } ) { ); // Do not show the convert button if the block is in content-only mode. - if ( isContentOnly ) return null; + if ( isContentOnly ) { + return null; + } // Allow converting a single template part to standard blocks. if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) { diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 232ef0eafe6fa5..61da7356f5e648 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -27,7 +27,9 @@ function ContentOnlySettingsMenuItems( { clientId } ) { } = select( blockEditorStore ); const contentOnly = getBlockEditingMode( clientId ) === 'contentOnly'; - if ( ! contentOnly ) return {}; + if ( ! contentOnly ) { + return {}; + } const patternParent = getBlockParentsByBlockName( clientId, 'core/block', @@ -63,7 +65,9 @@ function ContentOnlySettingsMenuItems( { clientId } ) { [ clientId ] ); - if ( ! entity ) return null; + if ( ! entity ) { + return null; + } const isPattern = entity.type === 'wp_block'; From a1f066f77ccc9bc6061db1961094969d0d189ff7 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 3 May 2024 14:47:26 +0800 Subject: [PATCH 08/16] Show description for template lock content only --- .../src/components/list-view/block.js | 38 +++-------- .../content-only-settings-menu.js | 65 +++++++++++++++++-- 2 files changed, 70 insertions(+), 33 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 52e828d547d062..c3ba9afe8cc165 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -104,46 +104,26 @@ function ListViewBlock( { const blockInformation = useBlockDisplayInformation( clientId ); - const { block, allowRightClickOverrides, showBlockActions } = useSelect( + const { block, blockName, allowRightClickOverrides } = useSelect( ( select ) => { - const { - getBlock, - getBlockName, - getSettings, - getContentLockingParent, - getBlockEditingMode, - getTemplateLock, - } = unlock( select( blockEditorStore ) ); - const _blockName = getBlockName( clientId ); - const isContentOnly = - getBlockEditingMode( clientId ) === 'contentOnly'; - const contentLockingParent = getContentLockingParent( clientId ); - // Don't show the block actions for template lock contentOnly. - // This block currently doesn't have any action to display in the menu dropdown. - const isContentLockingParentTemplateLock = - getTemplateLock( contentLockingParent ) === 'contentOnly'; - // When a block hides its toolbar it also hides the block settings menu, - // since that menu is part of the toolbar in the editor canvas. - // List View respects this by also hiding the block settings menu. - const hasToolbar = hasBlockSupport( - _blockName, - '__experimentalToolbar', - true - ); + const { getBlock, getBlockName, getSettings } = + select( blockEditorStore ); return { block: getBlock( clientId ), - blockName: _blockName, + blockName: getBlockName( clientId ), allowRightClickOverrides: getSettings().allowRightClickOverrides, - showBlockActions: - hasToolbar && - ! ( isContentOnly && isContentLockingParentTemplateLock ), }; }, [ clientId ] ); + const showBlockActions = + // When a block hides its toolbar it also hides the block settings menu, + // since that menu is part of the toolbar in the editor canvas. + // List View respects this by also hiding the block settings menu. + hasBlockSupport( blockName, '__experimentalToolbar', true ); const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__description-${ instanceId }`; diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 61da7356f5e648..fb4a2d3cb00293 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -5,18 +5,20 @@ import { BlockSettingsMenuControls, __unstableBlockSettingsMenuFirstItem as BlockSettingsMenuFirstItem, store as blockEditorStore, + useBlockDisplayInformation, } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; import { __experimentalText as Text, MenuItem } from '@wordpress/components'; -import { useSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; -function ContentOnlySettingsMenuItems( { clientId } ) { +function ContentOnlySettingsMenuItems( { clientId, onClose } ) { const { entity, onNavigateToEntityRecord } = useSelect( ( select ) => { const { @@ -66,7 +68,12 @@ function ContentOnlySettingsMenuItems( { clientId } ) { ); if ( ! entity ) { - return null; + return ( + + ); } const isPattern = entity.type === 'wp_block'; @@ -110,13 +117,63 @@ function ContentOnlySettingsMenuItems( { clientId } ) { ); } +function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { + const { contentLockingParent } = useSelect( + ( select ) => { + const { getContentLockingParent } = unlock( + select( blockEditorStore ) + ); + return { + contentLockingParent: getContentLockingParent( clientId ), + }; + }, + [ clientId ] + ); + const blockDisplayInformation = + useBlockDisplayInformation( contentLockingParent ); + const { updateBlockAttributes } = useDispatch( blockEditorStore ); + + if ( ! blockDisplayInformation?.title ) return null; + + return ( + <> + + + { sprintf( + // translators: %s: block's title. + __( + 'Only the content of blocks inside "%s" can be edited.' + ), + blockDisplayInformation.title + ) } + + + { + updateBlockAttributes( contentLockingParent, { + templateLock: undefined, + } ); + onClose(); + } } + > + { __( 'Remove template lock' ) } + + + ); +} + export default function ContentOnlySettingsMenu() { return ( - { ( { selectedClientIds } ) => + { ( { selectedClientIds, onClose } ) => selectedClientIds.length === 1 && ( ) } From d404f33a6796231c167c62f22f49f10f83fc39bd Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 3 May 2024 17:07:59 +0800 Subject: [PATCH 09/16] Fix lint errors --- .../block-settings-menu/content-only-settings-menu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index fb4a2d3cb00293..9cc4baaa0fcd54 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -133,7 +133,9 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { useBlockDisplayInformation( contentLockingParent ); const { updateBlockAttributes } = useDispatch( blockEditorStore ); - if ( ! blockDisplayInformation?.title ) return null; + if ( ! blockDisplayInformation?.title ) { + return null; + } return ( <> From 038919d7c516ce0f569c57a7690cd07ff12c7787 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 6 May 2024 09:49:01 +0800 Subject: [PATCH 10/16] Reword template lock --- .../block-settings-menu/content-only-settings-menu.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 9cc4baaa0fcd54..43f73867611b05 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -148,7 +148,7 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { { sprintf( // translators: %s: block's title. __( - 'Only the content of blocks inside "%s" can be edited.' + 'The parent "%s" block is partially locked, preventing the movement or deletion of child blocks, as well as the addition of any inner blocks.' ), blockDisplayInformation.title ) } @@ -162,7 +162,11 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { onClose(); } } > - { __( 'Remove template lock' ) } + { sprintf( + // translators: %s: block's title. + __( 'Unlock "%s"' ), + blockDisplayInformation.title + ) } ); From a13071f55295ae3224f98625d9cd281192b53d64 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 9 May 2024 12:32:39 +0900 Subject: [PATCH 11/16] Fix move to still showing in the menu --- .../block-settings-menu-controls/index.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/block-settings-menu-controls/index.js b/packages/block-editor/src/components/block-settings-menu-controls/index.js index 4ee58f80e82b53..1edf02eb368945 100644 --- a/packages/block-editor/src/components/block-settings-menu-controls/index.js +++ b/packages/block-editor/src/components/block-settings-menu-controls/index.js @@ -96,16 +96,18 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => { /> ) } { fills } - { fillProps?.canMove && ! fillProps?.onlyBlock && ( - - { __( 'Move to' ) } - - ) } + { fillProps?.canMove && + ! fillProps?.onlyBlock && + ! isContentOnly && ( + + { __( 'Move to' ) } + + ) } { fillProps?.count === 1 && ! isContentOnly && ( Date: Fri, 10 May 2024 10:03:35 +0900 Subject: [PATCH 12/16] Change to modify --- .../block-editor/src/hooks/content-lock-ui.js | 49 ++++++------------- .../block-editor/src/store/private-actions.js | 19 +++++++ .../content-only-settings-menu.js | 13 +++-- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/packages/block-editor/src/hooks/content-lock-ui.js b/packages/block-editor/src/hooks/content-lock-ui.js index eff6cc9a2d8af3..7cca4b325b09d7 100644 --- a/packages/block-editor/src/hooks/content-lock-ui.js +++ b/packages/block-editor/src/hooks/content-lock-ui.js @@ -20,7 +20,6 @@ import { unlock } from '../lock-unlock'; // also includes artifacts on the store (actions, reducers, and selector). function ContentLockControlsPure( { clientId, isSelected } ) { - const { getBlockListSettings, getSettings } = useSelect( blockEditorStore ); const { templateLock, isLockedByParent, isEditingAsBlocks } = useSelect( ( select ) => { const { @@ -37,16 +36,11 @@ function ContentLockControlsPure( { clientId, isSelected } ) { [ clientId ] ); - const { - updateSettings, - updateBlockListSettings, - __unstableSetTemporarilyEditingAsBlocks, - } = useDispatch( blockEditorStore ); - const { stopEditingAsBlocks } = unlock( useDispatch( blockEditorStore ) ); + const { stopEditingAsBlocks, modifyContentLockBlock } = unlock( + useDispatch( blockEditorStore ) + ); const isContentLocked = ! isLockedByParent && templateLock === 'contentOnly'; - const { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } = - useDispatch( blockEditorStore ); const stopEditingAsBlockCallback = useCallback( () => { stopEditingAsBlocks( clientId ); @@ -73,30 +67,19 @@ function ContentLockControlsPure( { clientId, isSelected } ) { ) } { showStartEditingAsBlocks && ( - { ( { onClose } ) => ( - { - __unstableMarkNextChangeAsNotPersistent(); - updateBlockAttributes( clientId, { - templateLock: undefined, - } ); - updateBlockListSettings( clientId, { - ...getBlockListSettings( clientId ), - templateLock: false, - } ); - const focusModeToRevert = - getSettings().focusMode; - updateSettings( { focusMode: true } ); - __unstableSetTemporarilyEditingAsBlocks( - clientId, - focusModeToRevert - ); - onClose(); - } } - > - { __( 'Modify' ) } - - ) } + { ( { selectedClientIds, onClose } ) => + selectedClientIds.length === 1 && + selectedClientIds[ 0 ] === clientId && ( + { + modifyContentLockBlock( clientId ); + onClose(); + } } + > + { __( 'Modify' ) } + + ) + } ) } diff --git a/packages/block-editor/src/store/private-actions.js b/packages/block-editor/src/store/private-actions.js index 6cfccb17287ff9..fea2dd7306adc9 100644 --- a/packages/block-editor/src/store/private-actions.js +++ b/packages/block-editor/src/store/private-actions.js @@ -391,3 +391,22 @@ export function expandBlock( clientId ) { clientId, }; } + +export const modifyContentLockBlock = + ( clientId ) => + ( { select, dispatch } ) => { + dispatch.__unstableMarkNextChangeAsNotPersistent(); + dispatch.updateBlockAttributes( clientId, { + templateLock: undefined, + } ); + dispatch.updateBlockListSettings( clientId, { + ...select.getBlockListSettings( clientId ), + templateLock: false, + } ); + const focusModeToRevert = select.getSettings().focusMode; + dispatch.updateSettings( { focusMode: true } ); + dispatch.__unstableSetTemporarilyEditingAsBlocks( + clientId, + focusModeToRevert + ); + }; diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 43f73867611b05..833f1601aeef76 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -131,7 +131,11 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { ); const blockDisplayInformation = useBlockDisplayInformation( contentLockingParent ); - const { updateBlockAttributes } = useDispatch( blockEditorStore ); + // Disable reason: We're using a hook here so it has to be on top-level. + // eslint-disable-next-line @wordpress/no-unused-vars-before-return + const { modifyContentLockBlock, selectBlock } = unlock( + useDispatch( blockEditorStore ) + ); if ( ! blockDisplayInformation?.title ) { return null; @@ -156,15 +160,14 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { { - updateBlockAttributes( contentLockingParent, { - templateLock: undefined, - } ); + selectBlock( contentLockingParent ); + modifyContentLockBlock( contentLockingParent ); onClose(); } } > { sprintf( // translators: %s: block's title. - __( 'Unlock "%s"' ), + __( 'Modify "%s"' ), blockDisplayInformation.title ) } From a4b487732b996b2bf18c2fe45f62d2e6d383905b Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 10 May 2024 10:34:05 +0900 Subject: [PATCH 13/16] Reword the description --- .../block-settings-menu/content-only-settings-menu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index 833f1601aeef76..a1f793fc33e163 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -90,14 +90,14 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { ? sprintf( // translators: %s: pattern's title. __( - 'This block belongs to "%s". Edit the pattern to move or delete it.' + 'This block is part of the pattern: "%s". Edit the pattern to move or delete it.' ), entity.title.raw ) : sprintf( // translators: %s: template's title. __( - 'This block belongs to "%s". Edit the template to move or delete it.' + 'This block is part of the template: "%s". Edit the template to move or delete it.' ), entity.title.rendered ) } From a767bd1a65a54db24ea72c07d533e405b936b025 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 10 May 2024 14:43:53 +0900 Subject: [PATCH 14/16] Reword --- .../content-only-settings-menu.js | 90 ++++++++----------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js index a1f793fc33e163..4683dd38593a59 100644 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.js @@ -10,7 +10,7 @@ import { import { store as coreStore } from '@wordpress/core-data'; import { __experimentalText as Text, MenuItem } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -81,38 +81,30 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) { return ( <> - { + onNavigateToEntityRecord( { + postId: entity.id, + postType: entity.type, + } ); + } } > - { isPattern - ? sprintf( - // translators: %s: pattern's title. - __( - 'This block is part of the pattern: "%s". Edit the pattern to move or delete it.' - ), - entity.title.raw - ) - : sprintf( - // translators: %s: template's title. - __( - 'This block is part of the template: "%s". Edit the template to move or delete it.' - ), - entity.title.rendered - ) } - + { isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) } + - { - onNavigateToEntityRecord( { - postId: entity.id, - postType: entity.type, - } ); - } } + - { isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) } - + { isPattern + ? __( + 'Edit the pattern to move, delete, or make further changes to this block.' + ) + : __( + 'Edit the template to move, delete, or make further changes to this block.' + ) } + ); } @@ -144,33 +136,25 @@ function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) { return ( <> - { + selectBlock( contentLockingParent ); + modifyContentLockBlock( contentLockingParent ); + onClose(); + } } > - { sprintf( - // translators: %s: block's title. - __( - 'The parent "%s" block is partially locked, preventing the movement or deletion of child blocks, as well as the addition of any inner blocks.' - ), - blockDisplayInformation.title - ) } - + { __( 'Unlock' ) } + - { - selectBlock( contentLockingParent ); - modifyContentLockBlock( contentLockingParent ); - onClose(); - } } + - { sprintf( - // translators: %s: block's title. - __( 'Modify "%s"' ), - blockDisplayInformation.title + { __( + 'Temporarily unlock the parent block to edit, delete or make further changes to this block.' ) } - + ); } From 68d272286fe866481f5f833e54ce01713a8817b0 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 10 May 2024 16:28:50 +0900 Subject: [PATCH 15/16] Add docblock and delete unused code --- packages/block-editor/src/store/private-actions.js | 5 +++++ .../block-settings-menu/content-only-settings-menu.native.js | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) delete mode 100644 packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js diff --git a/packages/block-editor/src/store/private-actions.js b/packages/block-editor/src/store/private-actions.js index fea2dd7306adc9..28a7b1da98f73f 100644 --- a/packages/block-editor/src/store/private-actions.js +++ b/packages/block-editor/src/store/private-actions.js @@ -392,6 +392,11 @@ export function expandBlock( clientId ) { }; } +/** + * Temporarily modify/unlock the content-only block for editions. + * + * @param {string} clientId The client id of the block. + */ export const modifyContentLockBlock = ( clientId ) => ( { select, dispatch } ) => { diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js deleted file mode 100644 index b10c08c3000b02..00000000000000 --- a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function ContentOnlySettingsMenu() { - return null; -} From f730206469d393103a85554aff86dc42d6bbcb8f Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 10 May 2024 16:44:28 +0900 Subject: [PATCH 16/16] Add back native code --- .../block-settings-menu/content-only-settings-menu.native.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js diff --git a/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js new file mode 100644 index 00000000000000..11cebce87bbba5 --- /dev/null +++ b/packages/editor/src/components/block-settings-menu/content-only-settings-menu.native.js @@ -0,0 +1,4 @@ +// Render nothing in native for now. +export default function ContentOnlySettingsMenu() { + return null; +}