From d84857e057b7eb667d47a51479d263da1174ec1f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 15:57:14 +1200 Subject: [PATCH 01/16] Set pattern block edit mode to disabled --- .../src/components/block-list/block.js | 6 +- .../src/components/block-toolbar/index.js | 1 + .../block-tools/block-contextual-toolbar.js | 108 +++++++++ .../src/components/list-view/block.js | 2 +- .../src/store/private-selectors.js | 6 +- packages/block-library/src/block/block.json | 1 + packages/block-library/src/block/edit.js | 10 + .../document-actions/index.js | 212 ++++++++++++++++++ 8 files changed, 342 insertions(+), 4 deletions(-) create mode 100644 packages/block-editor/src/components/block-tools/block-contextual-toolbar.js create mode 100644 packages/edit-site/src/components/header-edit-mode/document-actions/index.js diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index ff5915981acdf..7ea274000f632 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -141,8 +141,9 @@ function BlockListBlock( { ); const blockType = getBlockType( name ); + const isSyncedUserPattern = blockType?.name === 'core/block'; - if ( blockEditingMode === 'disabled' ) { + if ( blockEditingMode === 'disabled' && ! isSyncedUserPattern ) { wrapperProps = { ...wrapperProps, tabIndex: -1, @@ -220,7 +221,8 @@ function BlockListBlock( { clientId, className: classnames( { - 'is-editing-disabled': blockEditingMode === 'disabled', + 'is-editing-disabled': + blockEditingMode === 'disabled' && ! isSyncedUserPattern, 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks, }, diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 7bb52a7e8f090..64967108baf63 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -136,6 +136,7 @@ export function PrivateBlockToolbar( { const isMultiToolbar = blockClientIds.length > 1; const isSynced = isReusableBlock( blockType ) || isTemplatePart( blockType ); + const isSyncedUserPattern = isReusableBlock( blockType ); // Shifts the toolbar to make room for the parent block selector. const classes = classnames( 'block-editor-block-contextual-toolbar', { diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js new file mode 100644 index 0000000000000..d7dc102e81a19 --- /dev/null +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -0,0 +1,108 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + hasBlockSupport, + store as blocksStore, + isReusableBlock, +} from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import NavigableToolbar from '../navigable-toolbar'; +import BlockToolbar from '../block-toolbar'; +import { store as blockEditorStore } from '../../store'; +import { useHasAnyBlockControls } from '../block-controls/use-has-block-controls'; + +export default function BlockContextualToolbar( { + focusOnMount, + isFixed, + ...props +} ) { + const { + blockType, + blockEditingMode, + hasParents, + showParentSelector, + selectedBlockClientId, + } = useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + getBlockEditingMode, + } = select( blockEditorStore ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( _selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); + + return { + selectedBlockClientId: _selectedBlockClientId, + blockType: + _selectedBlockClientId && + getBlockType( getBlockName( _selectedBlockClientId ) ), + blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), + hasParents: parents.length, + showParentSelector: + parentBlockType && + getBlockEditingMode( firstParentClientId ) === 'default' && + hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ) && + selectedBlockClientIds.length <= 1 && + getBlockEditingMode( _selectedBlockClientId ) === 'default', + }; + }, [] ); + + const isToolbarEnabled = + blockType && + hasBlockSupport( blockType, '__experimentalToolbar', true ); + const hasAnyBlockControls = useHasAnyBlockControls(); + + const isSyncedUserPattern = isReusableBlock( blockType ); + if ( + ! isToolbarEnabled || + ( blockEditingMode !== 'default' && + ! isSyncedUserPattern && + ! hasAnyBlockControls ) + ) { + return null; + } + + // Shifts the toolbar to make room for the parent block selector. + const classes = classnames( 'block-editor-block-contextual-toolbar', { + 'has-parent': hasParents && showParentSelector, + 'is-fixed': isFixed, + } ); + + return ( + + + + ); +} diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 4957f79fa0d48..795db1f40b7d8 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -89,7 +89,7 @@ function ListViewBlock( { // 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'; + ( blockEditingMode === 'default' || blockName === 'core/block' ); const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__${ instanceId }`; const blockPositionDescription = getBlockPositionDescription( diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index c4220e6e7e516..eb029f6e506fd 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -10,6 +10,7 @@ import { getBlockOrder, getBlockParents, getBlockEditingMode, + getBlockName, } from './selectors'; /** @@ -77,7 +78,10 @@ export const isBlockSubtreeDisabled = createSelector( export const getEnabledClientIdsTree = createSelector( ( state, rootClientId = '' ) => { return getBlockOrder( state, rootClientId ).flatMap( ( clientId ) => { - if ( getBlockEditingMode( state, clientId ) !== 'disabled' ) { + if ( + getBlockEditingMode( state, clientId ) !== 'disabled' || + getBlockName( state, clientId ) === 'core/block' + ) { return [ { clientId, diff --git a/packages/block-library/src/block/block.json b/packages/block-library/src/block/block.json index aeccdbfc1051d..811c0984cf25d 100644 --- a/packages/block-library/src/block/block.json +++ b/packages/block-library/src/block/block.json @@ -7,6 +7,7 @@ "description": "Create and save content to reuse across your site. Update the pattern, and the changes apply everywhere it’s used.", "keywords": [ "reusable" ], "textdomain": "default", + "usesContext": [ "postId" ], "attributes": { "ref": { "type": "number" diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index e86ed9b59c62b..ddd6eef3f8259 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -14,6 +14,8 @@ import { Spinner, TextControl, PanelBody, + ToolbarButton, + ToolbarGroup, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { @@ -26,6 +28,7 @@ import { Warning, privateApis as blockEditorPrivateApis, store as blockEditorStore, + BlockControls, } from '@wordpress/block-editor'; import { getBlockSupport, parse } from '@wordpress/blocks'; @@ -268,6 +271,13 @@ export default function ReusableBlockEdit( { return ( + + + + { __( 'Edit' ) } + + + select( editSiteStore ).isPage(), + [] + ); + return isPage ? : ; +} + +function PageDocumentActions() { + const { isEditingPage, hasResolved, isFound, title } = useSelect( + ( select ) => { + const { getEditedPostContext } = select( editSiteStore ); + const { getEditedEntityRecord, hasFinishedResolution } = + select( coreStore ); + const { getRenderingMode } = select( editorStore ); + const context = getEditedPostContext(); + const queryArgs = [ 'postType', context.postType, context.postId ]; + const page = getEditedEntityRecord( ...queryArgs ); + return { + isEditingPage: + !! context.postId && getRenderingMode() !== 'template-only', + hasResolved: hasFinishedResolution( + 'getEditedEntityRecord', + queryArgs + ), + isFound: !! page, + title: page?.title, + }; + }, + [] + ); + + const { setRenderingMode } = useDispatch( editorStore ); + const [ isAnimated, setIsAnimated ] = useState( false ); + const isLoading = useRef( true ); + + useEffect( () => { + if ( ! isLoading.current ) { + setIsAnimated( true ); + } + isLoading.current = false; + }, [ isEditingPage ] ); + + if ( ! hasResolved ) { + return null; + } + + if ( ! isFound ) { + return ( +
+ { __( 'Document not found' ) } +
+ ); + } + + return isEditingPage ? ( + + { title } + + ) : ( + setRenderingMode( 'template-locked' ) } + /> + ); +} + +function TemplateDocumentActions( { className, onBack } ) { + const { isLoaded, record, getTitle, icon } = useEditedEntityRecord(); + + if ( ! isLoaded ) { + return null; + } + + if ( ! record ) { + return ( +
+ { __( 'Document not found' ) } +
+ ); + } + + let typeIcon = icon; + if ( record.type === NAVIGATION_POST_TYPE ) { + typeIcon = navigationIcon; + } else if ( record.type === PATTERN_TYPES.user ) { + typeIcon = symbol; + } + + const { refererId } = getQueryArgs( window.location.href ); + + if ( ! onBack && refererId ) { + onBack = () => + ( document.location = `post.php?post=${ refererId }&action=edit` ); + } + + return ( + + + { typeLabels[ record.type ] ?? + typeLabels[ TEMPLATE_POST_TYPE ] } + + { getTitle() } + + ); +} + +function BaseDocumentActions( { className, icon, children, onBack } ) { + const { open: openCommandCenter } = useDispatch( commandsStore ); + return ( +
+ { onBack && ( + + ) } + +
+ ); +} From 49408fc30db247843cc30717c84f3653970907f1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:00:06 +1200 Subject: [PATCH 02/16] remove editing mode changes --- .../block-editor/src/components/block-list/block.js | 6 ++---- .../src/components/block-toolbar/index.js | 1 - .../block-tools/block-contextual-toolbar.js | 11 ++--------- .../block-editor/src/components/list-view/block.js | 2 +- packages/block-editor/src/store/private-selectors.js | 6 +----- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 7ea274000f632..ff5915981acdf 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -141,9 +141,8 @@ function BlockListBlock( { ); const blockType = getBlockType( name ); - const isSyncedUserPattern = blockType?.name === 'core/block'; - if ( blockEditingMode === 'disabled' && ! isSyncedUserPattern ) { + if ( blockEditingMode === 'disabled' ) { wrapperProps = { ...wrapperProps, tabIndex: -1, @@ -221,8 +220,7 @@ function BlockListBlock( { clientId, className: classnames( { - 'is-editing-disabled': - blockEditingMode === 'disabled' && ! isSyncedUserPattern, + 'is-editing-disabled': blockEditingMode === 'disabled', 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks, }, diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 64967108baf63..7bb52a7e8f090 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -136,7 +136,6 @@ export function PrivateBlockToolbar( { const isMultiToolbar = blockClientIds.length > 1; const isSynced = isReusableBlock( blockType ) || isTemplatePart( blockType ); - const isSyncedUserPattern = isReusableBlock( blockType ); // Shifts the toolbar to make room for the parent block selector. const classes = classnames( 'block-editor-block-contextual-toolbar', { diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index d7dc102e81a19..c3f0c1797058a 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -7,11 +7,7 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { - hasBlockSupport, - store as blocksStore, - isReusableBlock, -} from '@wordpress/blocks'; +import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; /** @@ -73,12 +69,9 @@ export default function BlockContextualToolbar( { hasBlockSupport( blockType, '__experimentalToolbar', true ); const hasAnyBlockControls = useHasAnyBlockControls(); - const isSyncedUserPattern = isReusableBlock( blockType ); if ( ! isToolbarEnabled || - ( blockEditingMode !== 'default' && - ! isSyncedUserPattern && - ! hasAnyBlockControls ) + ( blockEditingMode !== 'default' && ! hasAnyBlockControls ) ) { return null; } diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 795db1f40b7d8..4957f79fa0d48 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -89,7 +89,7 @@ function ListViewBlock( { // 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' || blockName === 'core/block' ); + blockEditingMode === 'default'; const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__${ instanceId }`; const blockPositionDescription = getBlockPositionDescription( diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index eb029f6e506fd..c4220e6e7e516 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -10,7 +10,6 @@ import { getBlockOrder, getBlockParents, getBlockEditingMode, - getBlockName, } from './selectors'; /** @@ -78,10 +77,7 @@ export const isBlockSubtreeDisabled = createSelector( export const getEnabledClientIdsTree = createSelector( ( state, rootClientId = '' ) => { return getBlockOrder( state, rootClientId ).flatMap( ( clientId ) => { - if ( - getBlockEditingMode( state, clientId ) !== 'disabled' || - getBlockName( state, clientId ) === 'core/block' - ) { + if ( getBlockEditingMode( state, clientId ) !== 'disabled' ) { return [ { clientId, From 4ace1234b4568d219b032fe41b0d5cb925082c7f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Nov 2023 13:47:40 +1300 Subject: [PATCH 03/16] remove extra line --- .../src/components/block-tools/block-contextual-toolbar.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index c3f0c1797058a..b24a25ee60ed4 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -68,7 +68,6 @@ export default function BlockContextualToolbar( { blockType && hasBlockSupport( blockType, '__experimentalToolbar', true ); const hasAnyBlockControls = useHasAnyBlockControls(); - if ( ! isToolbarEnabled || ( blockEditingMode !== 'default' && ! hasAnyBlockControls ) From 6553bcff22ffa7395b221b2db999f6c878fd557b Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Nov 2023 14:02:35 +1300 Subject: [PATCH 04/16] Modify the getBlockEditingMode selector instead of explicitly setting the pattern block mode --- packages/block-editor/src/store/selectors.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index c0441cd3b3755..5a695be855bc7 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2928,6 +2928,19 @@ export const getBlockEditingMode = createRegistrySelector( if ( ! clientId ) { return 'default'; } + const syncedPatternParent = getBlockParentsByBlockName( + state, + clientId, + 'core/block' + ); + + if ( syncedPatternParent?.length > 0 ) { + const attributes = getBlockAttributes( state, clientId ); + return attributes.connections?.attributes?.content?.source === + 'pattern_attributes' + ? 'contentOnly' + : 'disabled'; + } const rootClientId = getBlockRootClientId( state, clientId ); const templateLock = getTemplateLock( state, rootClientId ); if ( templateLock === 'contentOnly' ) { From 95cec7aa9f5b6f3511d416a1f49f7a3c57553784 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Nov 2023 15:34:29 +1300 Subject: [PATCH 05/16] Stop the between inserter showing in synced pattern blocks --- .../src/components/block-list/use-in-between-inserter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js index a60453716ff29..044e5b185a224 100644 --- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js +++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js @@ -28,6 +28,7 @@ export function useInBetweenInserter() { getTemplateLock, __unstableIsWithinBlockOverlay, getBlockEditingMode, + getBlockName, } = useSelect( blockEditorStore ); const { showInsertionPoint, hideInsertionPoint } = useDispatch( blockEditorStore ); @@ -75,7 +76,8 @@ export function useInBetweenInserter() { if ( getTemplateLock( rootClientId ) || - getBlockEditingMode( rootClientId ) === 'disabled' + getBlockEditingMode( rootClientId ) === 'disabled' || + getBlockName( rootClientId ) === 'core/block' ) { return; } From b95a0a3122677ee21db4cc3bead750e75c806aa4 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:01:20 +1200 Subject: [PATCH 06/16] Move setting of editing mode of children to the pattern block --- packages/block-editor/src/store/selectors.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 5a695be855bc7..c0441cd3b3755 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2928,19 +2928,6 @@ export const getBlockEditingMode = createRegistrySelector( if ( ! clientId ) { return 'default'; } - const syncedPatternParent = getBlockParentsByBlockName( - state, - clientId, - 'core/block' - ); - - if ( syncedPatternParent?.length > 0 ) { - const attributes = getBlockAttributes( state, clientId ); - return attributes.connections?.attributes?.content?.source === - 'pattern_attributes' - ? 'contentOnly' - : 'disabled'; - } const rootClientId = getBlockRootClientId( state, clientId ); const templateLock = getTemplateLock( state, rootClientId ); if ( templateLock === 'contentOnly' ) { From 1a0a4ac9471948a99581e94b4ae2858a9c14da97 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Nov 2023 16:28:51 +1300 Subject: [PATCH 07/16] Remove edit locking from core block as these will be edit locked by default with partial syncing --- packages/block-editor/src/components/block-lock/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-lock/modal.js b/packages/block-editor/src/components/block-lock/modal.js index cfafa6c031bbd..c08159faa05fd 100644 --- a/packages/block-editor/src/components/block-lock/modal.js +++ b/packages/block-editor/src/components/block-lock/modal.js @@ -25,7 +25,7 @@ import useBlockDisplayInformation from '../use-block-display-information'; import { store as blockEditorStore } from '../../store'; // Entity based blocks which allow edit locking -const ALLOWS_EDIT_LOCKING = [ 'core/block', 'core/navigation' ]; +const ALLOWS_EDIT_LOCKING = [ 'core/navigation' ]; function getTemplateLockValue( lock ) { // Prevents all operations. From 333c2057c44861c3918f04d5e2530a8180c0c6ad Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:02:00 +1200 Subject: [PATCH 08/16] Apply edit mode recursively so nested innerBlocks covered --- packages/block-library/src/block/edit.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index ddd6eef3f8259..d6536ad0a6b9f 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -58,6 +58,14 @@ function getPartiallySyncedAttributes( block ) { const fullAlignments = [ 'full', 'wide', 'left', 'right' ]; +function setBlockEditMode( setEditMode, block ) { + const editMode = isPartiallySynced( block ) ? 'contentOnly' : 'disabled'; + setEditMode( block.clientId, editMode ); + block.innerBlocks.forEach( ( innerBlock ) => + setBlockEditMode( setEditMode, innerBlock ) + ); +} + const useInferredLayout = ( blocks, parentLayout ) => { const initialInferredAlignmentRef = useRef(); From 9c538c4d24dfa1f47ffaf5e14cbe4684415f285f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:02:58 +1200 Subject: [PATCH 09/16] Only show edit button if user has edit permissions for pattern --- packages/block-library/src/block/edit.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index d6536ad0a6b9f..ff22db457c08b 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -156,6 +156,7 @@ export default function ReusableBlockEdit( { 'wp_block', ref ); + const isMissing = hasResolved && ! record; const initialOverrides = useRef( overrides ); const defaultValuesRef = useRef( {} ); @@ -279,13 +280,15 @@ export default function ReusableBlockEdit( { return ( - - - - { __( 'Edit' ) } - - - + { userCanEdit && ( + + + + { __( 'Edit' ) } + + + + ) } Date: Wed, 29 Nov 2023 12:12:07 +1300 Subject: [PATCH 10/16] Show content in inspector panel --- .../block-editor/src/components/block-inspector/index.js | 3 ++- packages/block-editor/src/store/selectors.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 18cd72cde057d..085242ff52107 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -92,7 +92,8 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { blockType: _blockType, topLevelLockedBlock: __unstableGetContentLockingParent( _selectedBlockClientId ) || - ( getTemplateLock( _selectedBlockClientId ) === 'contentOnly' + ( getTemplateLock( _selectedBlockClientId ) === 'contentOnly' || + _selectedBlockName === 'core/block' ? _selectedBlockClientId : undefined ), }; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index c0441cd3b3755..82114393907e3 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2806,8 +2806,9 @@ export const __unstableGetContentLockingParent = createSelector( while ( state.blocks.parents.has( current ) ) { current = state.blocks.parents.get( current ); if ( - current && - getTemplateLock( state, current ) === 'contentOnly' + getBlockName( state, current ) === 'core/block' || + ( current && + getTemplateLock( state, current ) === 'contentOnly' ) ) { result = current; } From 26d3e01b192d16e8059d03aad62228a312767611 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:03:53 +1200 Subject: [PATCH 11/16] Remove name edit --- packages/block-library/src/block/edit.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index ff22db457c08b..1c67649cfa030 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -12,8 +12,6 @@ import { useEntityProp, useEntityRecord } from '@wordpress/core-data'; import { Placeholder, Spinner, - TextControl, - PanelBody, ToolbarButton, ToolbarGroup, } from '@wordpress/components'; @@ -23,7 +21,6 @@ import { __experimentalRecursionProvider as RecursionProvider, __experimentalUseHasRecursion as useHasRecursion, InnerBlocks, - InspectorControls, useBlockProps, Warning, privateApis as blockEditorPrivateApis, @@ -289,17 +286,6 @@ export default function ReusableBlockEdit( { ) } - - - - - { children === null ? (
) : ( From cc024a3df43bdb6c33d3435414e6a68bfb8a606e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:04:34 +1200 Subject: [PATCH 12/16] Changes from code review --- packages/block-library/src/block/edit.js | 14 ++++++++------ .../header-edit-mode/document-actions/index.js | 11 +++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 1c67649cfa030..0af183e0e2b8c 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -55,12 +55,14 @@ function getPartiallySyncedAttributes( block ) { const fullAlignments = [ 'full', 'wide', 'left', 'right' ]; -function setBlockEditMode( setEditMode, block ) { - const editMode = isPartiallySynced( block ) ? 'contentOnly' : 'disabled'; - setEditMode( block.clientId, editMode ); - block.innerBlocks.forEach( ( innerBlock ) => - setBlockEditMode( setEditMode, innerBlock ) - ); +function setBlockEditMode( setEditMode, blocks ) { + blocks.forEach( ( block ) => { + const editMode = isPartiallySynced( block ) + ? 'contentOnly' + : 'disabled'; + setEditMode( block.clientId, editMode ); + setBlockEditMode( setEditMode, block.innerBlocks ); + } ); } const useInferredLayout = ( blocks, parentLayout ) => { diff --git a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js index e9960657053a1..eca5abb729be6 100644 --- a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js +++ b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js @@ -27,7 +27,7 @@ import { displayShortcut } from '@wordpress/keycodes'; import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '@wordpress/editor'; import { useRef, useState, useEffect } from '@wordpress/element'; -import { getQueryArgs } from '@wordpress/url'; +import { getQueryArgs, addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -147,9 +147,12 @@ function TemplateDocumentActions( { className, onBack } ) { const { refererId } = getQueryArgs( window.location.href ); - if ( ! onBack && refererId ) { - onBack = () => - ( document.location = `post.php?post=${ refererId }&action=edit` ); + if ( ! onBack && ! isNaN( refererId ) ) { + const url = addQueryArgs( 'post.php', { + action: 'edit', + post: refererId, + } ); + onBack = () => ( document.location = url ); } return ( From decc373f0442ac022fffe2f40961a8b563c62d51 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:28:09 +1200 Subject: [PATCH 13/16] Fix rebase conflict issues --- packages/block-library/src/block/edit.js | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 0af183e0e2b8c..562c9428e8e64 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; */ import { useRegistry, useSelect, useDispatch } from '@wordpress/data'; import { useRef, useMemo, useEffect } from '@wordpress/element'; -import { useEntityProp, useEntityRecord } from '@wordpress/core-data'; +import { useEntityRecord, store as coreStore } from '@wordpress/core-data'; import { Placeholder, Spinner, @@ -28,6 +28,7 @@ import { BlockControls, } from '@wordpress/block-editor'; import { getBlockSupport, parse } from '@wordpress/blocks'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -147,6 +148,7 @@ export default function ReusableBlockEdit( { attributes: { ref, overrides }, __unstableParentLayout: parentLayout, clientId: patternClientId, + context: { postId }, } ) { const registry = useRegistry(); const hasAlreadyRendered = useHasRecursion( ref ); @@ -164,7 +166,50 @@ export default function ReusableBlockEdit( { __unstableMarkNextChangeAsNotPersistent, setBlockEditingMode, } = useDispatch( blockEditorStore ); - const { getBlockEditingMode } = useSelect( blockEditorStore ); + + const { editUrl, innerBlocks, userCanEdit, getBlockEditingMode } = + useSelect( + ( select ) => { + const { canUser } = select( coreStore ); + const { + getSettings, + getBlocks, + getBlockEditingMode: editingMode, + } = select( blockEditorStore ); + + const blocks = getBlocks( patternClientId ); + const isBlockTheme = getSettings().__unstableIsBlockBasedTheme; + const canEdit = canUser( 'update', 'blocks', ref ); + const defaultUrl = addQueryArgs( 'post.php', { + action: 'edit', + post: ref, + } ); + const siteEditorUrl = addQueryArgs( 'site-editor.php', { + postType: 'wp_block', + postId: ref, + categoryType: 'pattern', + canvas: 'edit', + refererId: postId, + } ); + + // For editing link to the site editor if the theme and user permissions support it. + return { + innerBlocks: blocks, + editUrl: + canUser( 'read', 'templates' ) && isBlockTheme + ? siteEditorUrl + : defaultUrl, + userCanEdit: canEdit, + getBlockEditingMode: editingMode, + }; + }, + [ patternClientId, postId, ref ] + ); + + useEffect( + () => setBlockEditMode( setBlockEditingMode, innerBlocks ), + [ innerBlocks, setBlockEditingMode ] + ); useEffect( () => { if ( ! record?.content?.raw ) return; @@ -194,17 +239,12 @@ export default function ReusableBlockEdit( { setBlockEditingMode, ] ); - const innerBlocks = useSelect( - ( select ) => select( blockEditorStore ).getBlocks( patternClientId ), - [ patternClientId ] - ); - - const [ title, setTitle ] = useEntityProp( - 'postType', - 'wp_block', - 'title', - ref - ); + // const [ title, setTitle ] = useEntityProp( + // 'postType', + // 'wp_block', + // 'title', + // ref + // ); const { alignment, layout } = useInferredLayout( innerBlocks, From 2dc14b7c5277b0dacdbe1203fa17f147aba1c691 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:33:04 +1200 Subject: [PATCH 14/16] Some more rebase tidy up --- .../block-tools/block-contextual-toolbar.js | 100 -------- packages/block-library/src/block/edit.js | 7 - .../document-actions/index.js | 215 ------------------ 3 files changed, 322 deletions(-) delete mode 100644 packages/block-editor/src/components/block-tools/block-contextual-toolbar.js delete mode 100644 packages/edit-site/src/components/header-edit-mode/document-actions/index.js diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js deleted file mode 100644 index b24a25ee60ed4..0000000000000 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; -import { useSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import NavigableToolbar from '../navigable-toolbar'; -import BlockToolbar from '../block-toolbar'; -import { store as blockEditorStore } from '../../store'; -import { useHasAnyBlockControls } from '../block-controls/use-has-block-controls'; - -export default function BlockContextualToolbar( { - focusOnMount, - isFixed, - ...props -} ) { - const { - blockType, - blockEditingMode, - hasParents, - showParentSelector, - selectedBlockClientId, - } = useSelect( ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - getBlockEditingMode, - } = select( blockEditorStore ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( _selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); - - return { - selectedBlockClientId: _selectedBlockClientId, - blockType: - _selectedBlockClientId && - getBlockType( getBlockName( _selectedBlockClientId ) ), - blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), - hasParents: parents.length, - showParentSelector: - parentBlockType && - getBlockEditingMode( firstParentClientId ) === 'default' && - hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ) && - selectedBlockClientIds.length <= 1 && - getBlockEditingMode( _selectedBlockClientId ) === 'default', - }; - }, [] ); - - const isToolbarEnabled = - blockType && - hasBlockSupport( blockType, '__experimentalToolbar', true ); - const hasAnyBlockControls = useHasAnyBlockControls(); - if ( - ! isToolbarEnabled || - ( blockEditingMode !== 'default' && ! hasAnyBlockControls ) - ) { - return null; - } - - // Shifts the toolbar to make room for the parent block selector. - const classes = classnames( 'block-editor-block-contextual-toolbar', { - 'has-parent': hasParents && showParentSelector, - 'is-fixed': isFixed, - } ); - - return ( - - - - ); -} diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 562c9428e8e64..32347b98407d6 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -239,13 +239,6 @@ export default function ReusableBlockEdit( { setBlockEditingMode, ] ); - // const [ title, setTitle ] = useEntityProp( - // 'postType', - // 'wp_block', - // 'title', - // ref - // ); - const { alignment, layout } = useInferredLayout( innerBlocks, parentLayout diff --git a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js deleted file mode 100644 index eca5abb729be6..0000000000000 --- a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { __, isRTL } from '@wordpress/i18n'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { - Button, - VisuallyHidden, - __experimentalText as Text, - __experimentalHStack as HStack, -} from '@wordpress/components'; -import { BlockIcon } from '@wordpress/block-editor'; -import { store as commandsStore } from '@wordpress/commands'; -import { - chevronLeftSmall, - chevronRightSmall, - page as pageIcon, - navigation as navigationIcon, - symbol, -} from '@wordpress/icons'; -import { displayShortcut } from '@wordpress/keycodes'; -import { store as coreStore } from '@wordpress/core-data'; -import { store as editorStore } from '@wordpress/editor'; -import { useRef, useState, useEffect } from '@wordpress/element'; -import { getQueryArgs, addQueryArgs } from '@wordpress/url'; - -/** - * Internal dependencies - */ -import useEditedEntityRecord from '../../use-edited-entity-record'; -import { store as editSiteStore } from '../../../store'; -import { - TEMPLATE_POST_TYPE, - NAVIGATION_POST_TYPE, - TEMPLATE_PART_POST_TYPE, - PATTERN_TYPES, - PATTERN_SYNC_TYPES, -} from '../../../utils/constants'; - -const typeLabels = { - [ PATTERN_TYPES.user ]: __( 'Editing pattern:' ), - [ NAVIGATION_POST_TYPE ]: __( 'Editing navigation menu:' ), - [ TEMPLATE_POST_TYPE ]: __( 'Editing template:' ), - [ TEMPLATE_PART_POST_TYPE ]: __( 'Editing template part:' ), -}; - -export default function DocumentActions() { - const isPage = useSelect( - ( select ) => select( editSiteStore ).isPage(), - [] - ); - return isPage ? : ; -} - -function PageDocumentActions() { - const { isEditingPage, hasResolved, isFound, title } = useSelect( - ( select ) => { - const { getEditedPostContext } = select( editSiteStore ); - const { getEditedEntityRecord, hasFinishedResolution } = - select( coreStore ); - const { getRenderingMode } = select( editorStore ); - const context = getEditedPostContext(); - const queryArgs = [ 'postType', context.postType, context.postId ]; - const page = getEditedEntityRecord( ...queryArgs ); - return { - isEditingPage: - !! context.postId && getRenderingMode() !== 'template-only', - hasResolved: hasFinishedResolution( - 'getEditedEntityRecord', - queryArgs - ), - isFound: !! page, - title: page?.title, - }; - }, - [] - ); - - const { setRenderingMode } = useDispatch( editorStore ); - const [ isAnimated, setIsAnimated ] = useState( false ); - const isLoading = useRef( true ); - - useEffect( () => { - if ( ! isLoading.current ) { - setIsAnimated( true ); - } - isLoading.current = false; - }, [ isEditingPage ] ); - - if ( ! hasResolved ) { - return null; - } - - if ( ! isFound ) { - return ( -
- { __( 'Document not found' ) } -
- ); - } - - return isEditingPage ? ( - - { title } - - ) : ( - setRenderingMode( 'template-locked' ) } - /> - ); -} - -function TemplateDocumentActions( { className, onBack } ) { - const { isLoaded, record, getTitle, icon } = useEditedEntityRecord(); - - if ( ! isLoaded ) { - return null; - } - - if ( ! record ) { - return ( -
- { __( 'Document not found' ) } -
- ); - } - - let typeIcon = icon; - if ( record.type === NAVIGATION_POST_TYPE ) { - typeIcon = navigationIcon; - } else if ( record.type === PATTERN_TYPES.user ) { - typeIcon = symbol; - } - - const { refererId } = getQueryArgs( window.location.href ); - - if ( ! onBack && ! isNaN( refererId ) ) { - const url = addQueryArgs( 'post.php', { - action: 'edit', - post: refererId, - } ); - onBack = () => ( document.location = url ); - } - - return ( - - - { typeLabels[ record.type ] ?? - typeLabels[ TEMPLATE_POST_TYPE ] } - - { getTitle() } - - ); -} - -function BaseDocumentActions( { className, icon, children, onBack } ) { - const { open: openCommandCenter } = useDispatch( commandsStore ); - return ( -
- { onBack && ( - - ) } - -
- ); -} From a9f1bc5aa95c385e464dbc644b27c239afb6b5e7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Dec 2023 16:48:54 +1200 Subject: [PATCH 15/16] Fix back link in site editor --- packages/block-library/src/block/edit.js | 2 +- .../edit-site/src/components/block-editor/back-button.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 32347b98407d6..3c2d76d3639e6 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -189,7 +189,7 @@ export default function ReusableBlockEdit( { postId: ref, categoryType: 'pattern', canvas: 'edit', - refererId: postId, + syncedPatternId: postId, } ); // For editing link to the site editor if the theme and user permissions support it. diff --git a/packages/edit-site/src/components/block-editor/back-button.js b/packages/edit-site/src/components/block-editor/back-button.js index 924dedd4f853e..75dc0a33d7afd 100644 --- a/packages/edit-site/src/components/block-editor/back-button.js +++ b/packages/edit-site/src/components/block-editor/back-button.js @@ -5,6 +5,7 @@ import { Button } from '@wordpress/components'; import { arrowLeft } from '@wordpress/icons'; import { __ } from '@wordpress/i18n'; import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { getQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -24,9 +25,10 @@ function BackButton() { const isNavigationMenu = location.params.postType === NAVIGATION_POST_TYPE; const previousTemplateId = location.state?.fromTemplateId; - const isFocusMode = isTemplatePart || isNavigationMenu; + const { syncedPatternId } = getQueryArgs( window.location.href ); + const isFocusMode = isTemplatePart || isNavigationMenu || syncedPatternId; - if ( ! isFocusMode || ! previousTemplateId ) { + if ( ! isFocusMode || ( ! previousTemplateId && ! syncedPatternId ) ) { return null; } From e73f5313d68d40046d0ae2af629573ae0b04104d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Dec 2023 15:15:34 +1300 Subject: [PATCH 16/16] Put all parts behind experiment --- packages/block-editor/src/components/block-inspector/index.js | 3 ++- .../src/components/block-list/use-in-between-inserter.js | 3 ++- packages/block-editor/src/store/selectors.js | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 085242ff52107..9cb3b89a7bc25 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -93,7 +93,8 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { topLevelLockedBlock: __unstableGetContentLockingParent( _selectedBlockClientId ) || ( getTemplateLock( _selectedBlockClientId ) === 'contentOnly' || - _selectedBlockName === 'core/block' + ( _selectedBlockName === 'core/block' && + window.__experimentalPatternPartialSyncing ) ? _selectedBlockClientId : undefined ), }; diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js index 044e5b185a224..bd323ed057d73 100644 --- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js +++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js @@ -77,7 +77,8 @@ export function useInBetweenInserter() { if ( getTemplateLock( rootClientId ) || getBlockEditingMode( rootClientId ) === 'disabled' || - getBlockName( rootClientId ) === 'core/block' + ( getBlockName( rootClientId ) === 'core/block' && + window.__experimentalPatternPartialSyncing ) ) { return; } diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 82114393907e3..0ed8a55bcd536 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2806,7 +2806,8 @@ export const __unstableGetContentLockingParent = createSelector( while ( state.blocks.parents.has( current ) ) { current = state.blocks.parents.get( current ); if ( - getBlockName( state, current ) === 'core/block' || + ( getBlockName( state, current ) === 'core/block' && + window.__experimentalPatternPartialSyncing ) || ( current && getTemplateLock( state, current ) === 'contentOnly' ) ) {