-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathpattern-overrides.js
123 lines (111 loc) · 3.8 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* WordPress dependencies
*/
import { _x } from '@wordpress/i18n';
import { store as blockEditorStore } from '@wordpress/block-editor';
const CONTENT = 'content';
export default {
name: 'core/pattern-overrides',
label: _x( 'Pattern Overrides', 'block bindings source' ),
getValue( { registry, clientId, context, attributeName } ) {
const patternOverridesContent = context[ 'pattern/overrides' ];
const { getBlockAttributes } = registry.select( blockEditorStore );
const currentBlockAttributes = getBlockAttributes( clientId );
if ( ! patternOverridesContent ) {
return currentBlockAttributes[ attributeName ];
}
const overridableValue =
patternOverridesContent?.[
currentBlockAttributes?.metadata?.name
]?.[ attributeName ];
// If there is no pattern client ID, or it is not overwritten, return the default value.
if ( overridableValue === undefined ) {
return currentBlockAttributes[ attributeName ];
}
return overridableValue === '' ? undefined : overridableValue;
},
// When `getValuesInBatch` is defined, this is not running.
// Keeping it here to show the different possibilities.
getValuesInBatch( { registry, clientId, context, sourceBindings } ) {
const patternOverridesContent = context[ 'pattern/overrides' ];
if ( ! patternOverridesContent ) {
return {};
}
const { getBlockAttributes } = registry.select( blockEditorStore );
const currentBlockAttributes = getBlockAttributes( clientId );
const overridesValues = {};
for ( const attributeName of Object.keys( sourceBindings ) ) {
const overridableValue =
patternOverridesContent?.[
currentBlockAttributes?.metadata?.name
]?.[ attributeName ];
overridesValues[ attributeName ] =
overridableValue === '' ? undefined : overridableValue;
}
return overridesValues;
},
setValuesInBatch( { registry, clientId, sourceBindings } ) {
const { getBlockAttributes, getBlockParentsByBlockName, getBlocks } =
registry.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( sourceBindings ).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 ) {
registry
.dispatch( blockEditorStore )
.updateBlockAttributes(
block.clientId,
attributes
);
}
syncBlocksWithSameName( block.innerBlocks );
}
};
syncBlocksWithSameName( getBlocks() );
return;
}
const currentBindingValue =
getBlockAttributes( patternClientId )?.[ CONTENT ];
registry
.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,
};