Skip to content

Commit

Permalink
Only set block editing mode on first load
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Feb 21, 2024
1 parent c4b422a commit 6f53cc9
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 63 deletions.
94 changes: 31 additions & 63 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import {
store as blockEditorStore,
BlockControls,
} from '@wordpress/block-editor';
import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
import {
privateApis as patternsPrivateApis,
store as patternsStore,
} from '@wordpress/patterns';
import { parse, cloneBlock } from '@wordpress/blocks';
import { RichTextData } from '@wordpress/rich-text';

Expand All @@ -38,7 +41,11 @@ import { name as patternBlockName } from './index';
import { unlock } from '../lock-unlock';

const { useLayoutClasses } = unlock( blockEditorPrivateApis );
const { PARTIAL_SYNCING_SUPPORTED_BLOCKS } = unlock( patternsPrivateApis );
const {
hasOverridableAttributes,
hasOverridableBlocks,
getOverridableAttributes,
} = unlock( patternsPrivateApis );

const fullAlignments = [ 'full', 'wide', 'left', 'right' ];

Expand Down Expand Up @@ -71,33 +78,6 @@ const useInferredLayout = ( blocks, parentLayout ) => {
}, [ blocks, parentLayout ] );
};

function hasOverridableAttributes( block ) {
return (
Object.keys( PARTIAL_SYNCING_SUPPORTED_BLOCKS ).includes(
block.name
) &&
!! block.attributes.metadata?.bindings &&
Object.values( block.attributes.metadata.bindings ).some(
( binding ) => binding.source === 'core/pattern-overrides'
)
);
}

function hasOverridableBlocks( blocks ) {
return blocks.some( ( block ) => {
if ( hasOverridableAttributes( block ) ) return true;
return hasOverridableBlocks( block.innerBlocks );
} );
}

function getOverridableAttributes( block ) {
return Object.entries( block.attributes.metadata.bindings )
.filter(
( [ , binding ] ) => binding.source === 'core/pattern-overrides'
)
.map( ( [ attributeKey ] ) => attributeKey );
}

function applyInitialContentValuesToInnerBlocks(
blocks,
content = {},
Expand Down Expand Up @@ -177,22 +157,6 @@ function getContentValuesFromInnerBlocks( blocks, defaultValues ) {
return Object.keys( content ).length > 0 ? content : undefined;
}

function setBlockEditMode( setEditMode, blocks, mode ) {
blocks.forEach( ( block ) => {
const editMode =
mode ||
( hasOverridableAttributes( block ) ? 'contentOnly' : 'disabled' );
setEditMode( block.clientId, editMode );

setBlockEditMode(
setEditMode,
block.innerBlocks,
// Disable editing for nested patterns.
block.name === patternBlockName ? 'disabled' : mode
);
} );
}

export default function ReusableBlockEdit( {
name,
attributes: { ref, content },
Expand Down Expand Up @@ -222,6 +186,7 @@ export default function ReusableBlockEdit( {
setBlockEditingMode,
} = useDispatch( blockEditorStore );
const { syncDerivedUpdates } = unlock( useDispatch( blockEditorStore ) );
const { syncPatternEditingMode } = unlock( useDispatch( patternsStore ) );

const {
innerBlocks,
Expand Down Expand Up @@ -253,16 +218,6 @@ export default function ReusableBlockEdit( {
[ patternClientId, ref ]
);

// Sync the editing mode of the pattern block with the inner blocks.
useEffect( () => {
setBlockEditMode(
setBlockEditingMode,
innerBlocks,
// Disable editing if the pattern itself is disabled.
editingMode === 'disabled' ? 'disabled' : undefined
);
}, [ editingMode, innerBlocks, setBlockEditingMode ] );

const canOverrideBlocks = useMemo(
() => hasOverridableBlocks( innerBlocks ),
[ innerBlocks ]
Expand All @@ -285,16 +240,20 @@ export default function ReusableBlockEdit( {
// Replace the contents of the blocks with the overrides.
registry.batch( () => {
setBlockEditingMode( patternClientId, 'default' );
syncDerivedUpdates( () => {
replaceInnerBlocks(
patternClientId,
applyInitialContentValuesToInnerBlocks(
initialBlocks,
initialContent.current,
defaultContent.current
)
const blocksWithInitialContent =
applyInitialContentValuesToInnerBlocks(
initialBlocks,
initialContent.current,
defaultContent.current
);
syncDerivedUpdates( () => {
replaceInnerBlocks( patternClientId, blocksWithInitialContent );
} );
syncPatternEditingMode(
patternClientId,
// Disable editing if the pattern itself is disabled.
originalEditingMode === 'disabled' ? 'disabled' : undefined
);
setBlockEditingMode( patternClientId, originalEditingMode );
} );
}, [
Expand All @@ -306,8 +265,17 @@ export default function ReusableBlockEdit( {
getBlockEditingMode,
setBlockEditingMode,
syncDerivedUpdates,
syncPatternEditingMode,
] );

// Sync the editing mode of the pattern block with the inner blocks.
useEffect( () => {
syncPatternEditingMode(
patternClientId,
editingMode === 'disabled' ? 'disabled' : undefined
);
}, [ editingMode, patternClientId, syncPatternEditingMode ] );

const { alignment, layout } = useInferredLayout(
innerBlocks,
parentLayout
Expand Down
8 changes: 8 additions & 0 deletions packages/patterns/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ import {
PATTERN_SYNC_TYPES,
PARTIAL_SYNCING_SUPPORTED_BLOCKS,
} from './constants';
import {
hasOverridableAttributes,
hasOverridableBlocks,
getOverridableAttributes,
} from './utils';

export const privateApis = {};
lock( privateApis, {
Expand All @@ -43,4 +48,7 @@ lock( privateApis, {
EXCLUDED_PATTERN_SOURCES,
PATTERN_SYNC_TYPES,
PARTIAL_SYNCING_SUPPORTED_BLOCKS,
hasOverridableAttributes,
hasOverridableBlocks,
getOverridableAttributes,
} );
36 changes: 36 additions & 0 deletions packages/patterns/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
* Internal dependencies
*/
import { PATTERN_SYNC_TYPES } from '../constants';
import { hasOverridableAttributes } from '../utils';

/**
* Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.
Expand Down Expand Up @@ -137,3 +138,38 @@ export function setEditingPattern( clientId, isEditing ) {
isEditing,
};
}

/**
* Returns a generator converting a synced pattern block into a static block.
*
* @param {string} clientId The client ID of the pattern block.
* @param {string} [mode] The explicit editing mode to set if defined.
*/
export const syncPatternEditingMode =
( clientId, mode ) =>
( { registry } ) => {
const patternBlocks = registry
.select( blockEditorStore )
.getBlocks( clientId );
const { setBlockEditingMode } = registry.dispatch( blockEditorStore );

function recursivelySetEditMode( blocks ) {
blocks.forEach( ( block ) => {
const editMode =
mode ||
( hasOverridableAttributes( block )
? 'contentOnly'
: 'disabled' );
setBlockEditingMode( block.clientId, editMode );
recursivelySetEditMode(
block.innerBlocks,
// Disable editing for nested patterns.
block.name === 'core/block' ? 'disabled' : mode
);
} );
}

registry.batch( () => {
recursivelySetEditMode( patternBlocks );
} );
};
31 changes: 31 additions & 0 deletions packages/patterns/src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Internal dependencies
*/
import { PARTIAL_SYNCING_SUPPORTED_BLOCKS } from './constants';

export function hasOverridableAttributes( block ) {
return (
Object.keys( PARTIAL_SYNCING_SUPPORTED_BLOCKS ).includes(
block.name
) &&
!! block.attributes.metadata?.bindings &&
Object.values( block.attributes.metadata.bindings ).some(
( binding ) => binding.source === 'core/pattern-overrides'
)
);
}

export function hasOverridableBlocks( blocks ) {
return blocks.some( ( block ) => {
if ( hasOverridableAttributes( block ) ) return true;
return hasOverridableBlocks( block.innerBlocks );
} );
}

export function getOverridableAttributes( block ) {
return Object.entries( block.attributes.metadata.bindings )
.filter(
( [ , binding ] ) => binding.source === 'core/pattern-overrides'
)
.map( ( [ attributeKey ] ) => attributeKey );
}

0 comments on commit 6f53cc9

Please sign in to comment.