-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
pattern-overrides.js
100 lines (91 loc) · 2.98 KB
/
pattern-overrides.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* WordPress dependencies
*/
import { store as blockEditorStore } from '@wordpress/block-editor';
const CONTENT = 'content';
export default {
name: 'core/pattern-overrides',
getValues( { select, clientId, context, bindings } ) {
const patternOverridesContent = context[ 'pattern/overrides' ];
const { getBlockAttributes } = select( blockEditorStore );
const currentBlockAttributes = getBlockAttributes( clientId );
const overridesValues = {};
for ( const attributeName of Object.keys( bindings ) ) {
const overridableValue =
patternOverridesContent?.[
currentBlockAttributes?.metadata?.name
]?.[ attributeName ];
// If it has not been overriden, return the original value.
// Check undefined because empty string is a valid value.
if ( overridableValue === undefined ) {
overridesValues[ attributeName ] =
currentBlockAttributes[ attributeName ];
continue;
} else {
overridesValues[ attributeName ] =
overridableValue === '' ? undefined : overridableValue;
}
}
return overridesValues;
},
setValues( { select, dispatch, clientId, bindings } ) {
const { getBlockAttributes, getBlockParentsByBlockName, getBlocks } =
select( blockEditorStore );
const currentBlockAttributes = getBlockAttributes( clientId );
const blockName = currentBlockAttributes?.metadata?.name;
if ( ! blockName ) {
return;
}
const [ patternClientId ] = getBlockParentsByBlockName(
clientId,
'core/block',
true
);
// Extract the updated attributes from the source bindings.
const attributes = Object.entries( bindings ).reduce(
( attrs, [ key, { newValue } ] ) => {
attrs[ key ] = newValue;
return attrs;
},
{}
);
// If there is no pattern client ID, sync blocks with the same name and same attributes.
if ( ! patternClientId ) {
const syncBlocksWithSameName = ( blocks ) => {
for ( const block of blocks ) {
if ( block.attributes?.metadata?.name === blockName ) {
dispatch( blockEditorStore ).updateBlockAttributes(
block.clientId,
attributes
);
}
syncBlocksWithSameName( block.innerBlocks );
}
};
syncBlocksWithSameName( getBlocks() );
return;
}
const currentBindingValue =
getBlockAttributes( patternClientId )?.[ CONTENT ];
dispatch( blockEditorStore ).updateBlockAttributes( patternClientId, {
[ CONTENT ]: {
...currentBindingValue,
[ blockName ]: {
...currentBindingValue?.[ blockName ],
...Object.entries( attributes ).reduce(
( acc, [ key, value ] ) => {
// TODO: We need a way to represent `undefined` in the serialized overrides.
// Also see: https://github.com/WordPress/gutenberg/pull/57249#discussion_r1452987871
// We use an empty string to represent undefined for now until
// we support a richer format for overrides and the block bindings API.
acc[ key ] = value === undefined ? '' : value;
return acc;
},
{}
),
},
},
} );
},
canUserEditValue: () => true,
};