@wordpress/block-editor 14.3.2 → 14.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/build/components/block-heading-level-dropdown/index.js +3 -1
- package/build/components/block-heading-level-dropdown/index.js.map +1 -1
- package/build/components/block-list/block.js +27 -4
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build/components/block-list/zoom-out-separator.js +18 -1
- package/build/components/block-list/zoom-out-separator.js.map +1 -1
- package/build/components/block-switcher/utils.js +1 -1
- package/build/components/block-switcher/utils.js.map +1 -1
- package/build/components/block-variation-transforms/index.js +6 -3
- package/build/components/block-variation-transforms/index.js.map +1 -1
- package/build/components/media-placeholder/index.js +17 -19
- package/build/components/media-placeholder/index.js.map +1 -1
- package/build/components/rich-text/event-listeners/paste-handler.js +2 -13
- package/build/components/rich-text/event-listeners/paste-handler.js.map +1 -1
- package/build/components/rich-text/index.js +35 -25
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/writing-flow/index.js +1 -2
- package/build/components/writing-flow/index.js.map +1 -1
- package/build/components/writing-flow/use-arrow-nav.js +1 -4
- package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build/components/writing-flow/use-input.js +1 -31
- package/build/components/writing-flow/use-input.js.map +1 -1
- package/build/components/writing-flow/use-select-all.js +1 -14
- package/build/components/writing-flow/use-select-all.js.map +1 -1
- package/build/components/writing-flow/use-selection-observer.js +2 -6
- package/build/components/writing-flow/use-selection-observer.js.map +1 -1
- package/build/components/writing-flow/utils.js +0 -27
- package/build/components/writing-flow/utils.js.map +1 -1
- package/build/hooks/block-bindings.js +6 -13
- package/build/hooks/block-bindings.js.map +1 -1
- package/build/hooks/layout.js +12 -8
- package/build/hooks/layout.js.map +1 -1
- package/build/hooks/use-bindings-attributes.js +24 -29
- package/build/hooks/use-bindings-attributes.js.map +1 -1
- package/build/private-apis.js +0 -2
- package/build/private-apis.js.map +1 -1
- package/build/store/selectors.js +6 -3
- package/build/store/selectors.js.map +1 -1
- package/build/utils/block-bindings.js +48 -0
- package/build/utils/block-bindings.js.map +1 -1
- package/build/utils/index.js +7 -0
- package/build/utils/index.js.map +1 -1
- package/build-module/components/block-heading-level-dropdown/index.js +3 -1
- package/build-module/components/block-heading-level-dropdown/index.js.map +1 -1
- package/build-module/components/block-list/block.js +28 -7
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build-module/components/block-list/zoom-out-separator.js +18 -1
- package/build-module/components/block-list/zoom-out-separator.js.map +1 -1
- package/build-module/components/block-switcher/utils.js +1 -1
- package/build-module/components/block-switcher/utils.js.map +1 -1
- package/build-module/components/block-variation-transforms/index.js +6 -3
- package/build-module/components/block-variation-transforms/index.js.map +1 -1
- package/build-module/components/media-placeholder/index.js +18 -20
- package/build-module/components/media-placeholder/index.js.map +1 -1
- package/build-module/components/rich-text/event-listeners/paste-handler.js +2 -13
- package/build-module/components/rich-text/event-listeners/paste-handler.js.map +1 -1
- package/build-module/components/rich-text/index.js +35 -25
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/writing-flow/index.js +1 -2
- package/build-module/components/writing-flow/index.js.map +1 -1
- package/build-module/components/writing-flow/use-arrow-nav.js +1 -4
- package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build-module/components/writing-flow/use-input.js +1 -31
- package/build-module/components/writing-flow/use-input.js.map +1 -1
- package/build-module/components/writing-flow/use-select-all.js +1 -14
- package/build-module/components/writing-flow/use-select-all.js.map +1 -1
- package/build-module/components/writing-flow/use-selection-observer.js +2 -6
- package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
- package/build-module/components/writing-flow/utils.js +0 -26
- package/build-module/components/writing-flow/utils.js.map +1 -1
- package/build-module/hooks/block-bindings.js +6 -13
- package/build-module/hooks/block-bindings.js.map +1 -1
- package/build-module/hooks/layout.js +13 -9
- package/build-module/hooks/layout.js.map +1 -1
- package/build-module/hooks/use-bindings-attributes.js +24 -29
- package/build-module/hooks/use-bindings-attributes.js.map +1 -1
- package/build-module/private-apis.js +0 -2
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/selectors.js +6 -3
- package/build-module/store/selectors.js.map +1 -1
- package/build-module/utils/block-bindings.js +48 -0
- package/build-module/utils/block-bindings.js.map +1 -1
- package/build-module/utils/index.js +1 -0
- package/build-module/utils/index.js.map +1 -1
- package/build-style/content-rtl.css +12 -14
- package/build-style/content.css +12 -14
- package/build-style/style-rtl.css +4 -0
- package/build-style/style.css +4 -0
- package/package.json +20 -20
- package/src/components/block-heading-level-dropdown/index.js +7 -1
- package/src/components/block-list/block.js +47 -11
- package/src/components/block-list/content.scss +12 -0
- package/src/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/src/components/block-list/zoom-out-separator.js +14 -1
- package/src/components/block-switcher/test/use-transformed.patterns.js +3 -3
- package/src/components/block-switcher/test/utils.js +3 -3
- package/src/components/block-switcher/utils.js +1 -1
- package/src/components/block-toolbar/style.scss +7 -0
- package/src/components/block-variation-transforms/index.js +6 -7
- package/src/components/media-placeholder/content.scss +3 -19
- package/src/components/media-placeholder/index.js +17 -17
- package/src/components/rich-text/event-listeners/paste-handler.js +2 -7
- package/src/components/rich-text/index.js +37 -33
- package/src/components/writing-flow/index.js +0 -2
- package/src/components/writing-flow/use-arrow-nav.js +2 -9
- package/src/components/writing-flow/use-input.js +1 -36
- package/src/components/writing-flow/use-select-all.js +1 -18
- package/src/components/writing-flow/use-selection-observer.js +3 -14
- package/src/components/writing-flow/utils.js +0 -30
- package/src/hooks/block-bindings.js +9 -10
- package/src/hooks/layout.js +17 -12
- package/src/hooks/use-bindings-attributes.js +74 -76
- package/src/private-apis.js +0 -2
- package/src/store/selectors.js +6 -6
- package/src/store/test/private-selectors.js +2 -2
- package/src/store/test/selectors.js +10 -6
- package/src/utils/block-bindings.js +47 -0
- package/src/utils/index.js +1 -0
- package/build/components/writing-flow/use-event-redirect.js +0 -66
- package/build/components/writing-flow/use-event-redirect.js.map +0 -1
- package/build-module/components/writing-flow/use-event-redirect.js +0 -60
- package/build-module/components/writing-flow/use-event-redirect.js.map +0 -1
- package/src/components/writing-flow/use-event-redirect.js +0 -72
|
@@ -103,11 +103,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
103
103
|
const sources = useSelect( ( select ) =>
|
|
104
104
|
unlock( select( blocksStore ) ).getAllBlockBindingsSources()
|
|
105
105
|
);
|
|
106
|
-
const { name, clientId } = props;
|
|
107
|
-
const hasParentPattern = !! props.context[ 'pattern/overrides' ];
|
|
108
|
-
const hasPatternOverridesDefaultBinding =
|
|
109
|
-
props.attributes.metadata?.bindings?.[ DEFAULT_ATTRIBUTE ]
|
|
110
|
-
?.source === 'core/pattern-overrides';
|
|
106
|
+
const { name, clientId, context, setAttributes } = props;
|
|
111
107
|
const blockBindings = useMemo(
|
|
112
108
|
() =>
|
|
113
109
|
replacePatternOverrideDefaultBindings(
|
|
@@ -121,78 +117,87 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
121
117
|
// used purposely here to ensure `boundAttributes` is updated whenever
|
|
122
118
|
// there are attribute updates.
|
|
123
119
|
// `source.getValues` may also call a selector via `registry.select`.
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const attributes = {};
|
|
130
|
-
|
|
131
|
-
const blockBindingsBySource = new Map();
|
|
132
|
-
|
|
133
|
-
for ( const [ attributeName, binding ] of Object.entries(
|
|
134
|
-
blockBindings
|
|
135
|
-
) ) {
|
|
136
|
-
const { source: sourceName, args: sourceArgs } = binding;
|
|
137
|
-
const source = sources[ sourceName ];
|
|
138
|
-
if ( ! source || ! canBindAttribute( name, attributeName ) ) {
|
|
139
|
-
continue;
|
|
120
|
+
const updatedContext = {};
|
|
121
|
+
const boundAttributes = useSelect(
|
|
122
|
+
( select ) => {
|
|
123
|
+
if ( ! blockBindings ) {
|
|
124
|
+
return;
|
|
140
125
|
}
|
|
141
126
|
|
|
142
|
-
|
|
143
|
-
...blockBindingsBySource.get( source ),
|
|
144
|
-
[ attributeName ]: {
|
|
145
|
-
args: sourceArgs,
|
|
146
|
-
},
|
|
147
|
-
} );
|
|
148
|
-
}
|
|
127
|
+
const attributes = {};
|
|
149
128
|
|
|
150
|
-
|
|
151
|
-
for ( const [ source, bindings ] of blockBindingsBySource ) {
|
|
152
|
-
// Populate context.
|
|
153
|
-
const context = {};
|
|
129
|
+
const blockBindingsBySource = new Map();
|
|
154
130
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
131
|
+
for ( const [ attributeName, binding ] of Object.entries(
|
|
132
|
+
blockBindings
|
|
133
|
+
) ) {
|
|
134
|
+
const { source: sourceName, args: sourceArgs } = binding;
|
|
135
|
+
const source = sources[ sourceName ];
|
|
136
|
+
if (
|
|
137
|
+
! source ||
|
|
138
|
+
! canBindAttribute( name, attributeName )
|
|
139
|
+
) {
|
|
140
|
+
continue;
|
|
159
141
|
}
|
|
160
142
|
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
Object.keys( bindings ).forEach( ( attr ) => {
|
|
165
|
-
// Default to the the source label when `getValues` doesn't exist.
|
|
166
|
-
values[ attr ] = source.label;
|
|
167
|
-
} );
|
|
168
|
-
} else {
|
|
169
|
-
values = source.getValues( {
|
|
170
|
-
registry,
|
|
171
|
-
context,
|
|
172
|
-
clientId,
|
|
173
|
-
bindings,
|
|
174
|
-
} );
|
|
143
|
+
// Populate context.
|
|
144
|
+
for ( const key of source.usesContext || [] ) {
|
|
145
|
+
updatedContext[ key ] = blockContext[ key ];
|
|
175
146
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
147
|
+
|
|
148
|
+
blockBindingsBySource.set( source, {
|
|
149
|
+
...blockBindingsBySource.get( source ),
|
|
150
|
+
[ attributeName ]: {
|
|
151
|
+
args: sourceArgs,
|
|
152
|
+
},
|
|
153
|
+
} );
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if ( blockBindingsBySource.size ) {
|
|
157
|
+
for ( const [
|
|
158
|
+
source,
|
|
159
|
+
bindings,
|
|
160
|
+
] of blockBindingsBySource ) {
|
|
161
|
+
// Get values in batch if the source supports it.
|
|
162
|
+
let values = {};
|
|
163
|
+
if ( ! source.getValues ) {
|
|
164
|
+
Object.keys( bindings ).forEach( ( attr ) => {
|
|
165
|
+
// Default to the the source label when `getValues` doesn't exist.
|
|
166
|
+
values[ attr ] = source.label;
|
|
167
|
+
} );
|
|
185
168
|
} else {
|
|
186
|
-
|
|
169
|
+
values = source.getValues( {
|
|
170
|
+
select,
|
|
171
|
+
context: updatedContext,
|
|
172
|
+
clientId,
|
|
173
|
+
bindings,
|
|
174
|
+
} );
|
|
175
|
+
}
|
|
176
|
+
for ( const [ attributeName, value ] of Object.entries(
|
|
177
|
+
values
|
|
178
|
+
) ) {
|
|
179
|
+
if (
|
|
180
|
+
attributeName === 'url' &&
|
|
181
|
+
( ! value || ! isURLLike( value ) )
|
|
182
|
+
) {
|
|
183
|
+
// Return null if value is not a valid URL.
|
|
184
|
+
attributes[ attributeName ] = null;
|
|
185
|
+
} else {
|
|
186
|
+
attributes[ attributeName ] = value;
|
|
187
|
+
}
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
|
-
}
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
return attributes;
|
|
193
|
+
},
|
|
194
|
+
[ blockBindings, name, clientId, updatedContext, sources ]
|
|
195
|
+
);
|
|
194
196
|
|
|
195
|
-
const
|
|
197
|
+
const hasParentPattern = !! updatedContext[ 'pattern/overrides' ];
|
|
198
|
+
const hasPatternOverridesDefaultBinding =
|
|
199
|
+
props.attributes.metadata?.bindings?.[ DEFAULT_ATTRIBUTE ]
|
|
200
|
+
?.source === 'core/pattern-overrides';
|
|
196
201
|
|
|
197
202
|
const _setAttributes = useCallback(
|
|
198
203
|
( nextAttributes ) => {
|
|
@@ -236,18 +241,10 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
236
241
|
source,
|
|
237
242
|
bindings,
|
|
238
243
|
] of blockBindingsBySource ) {
|
|
239
|
-
// Populate context.
|
|
240
|
-
const context = {};
|
|
241
|
-
|
|
242
|
-
if ( source.usesContext?.length ) {
|
|
243
|
-
for ( const key of source.usesContext ) {
|
|
244
|
-
context[ key ] = blockContext[ key ];
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
244
|
source.setValues( {
|
|
249
|
-
registry,
|
|
250
|
-
|
|
245
|
+
select: registry.select,
|
|
246
|
+
dispatch: registry.dispatch,
|
|
247
|
+
context: updatedContext,
|
|
251
248
|
clientId,
|
|
252
249
|
bindings,
|
|
253
250
|
} );
|
|
@@ -277,7 +274,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
277
274
|
blockBindings,
|
|
278
275
|
name,
|
|
279
276
|
clientId,
|
|
280
|
-
|
|
277
|
+
updatedContext,
|
|
281
278
|
setAttributes,
|
|
282
279
|
sources,
|
|
283
280
|
hasPatternOverridesDefaultBinding,
|
|
@@ -291,6 +288,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
291
288
|
{ ...props }
|
|
292
289
|
attributes={ { ...props.attributes, ...boundAttributes } }
|
|
293
290
|
setAttributes={ _setAttributes }
|
|
291
|
+
context={ { ...context, ...updatedContext } }
|
|
294
292
|
/>
|
|
295
293
|
</>
|
|
296
294
|
);
|
package/src/private-apis.js
CHANGED
|
@@ -47,7 +47,6 @@ import { PrivatePublishDateTimePicker } from './components/publish-date-time-pic
|
|
|
47
47
|
import useSpacingSizes from './components/spacing-sizes-control/hooks/use-spacing-sizes';
|
|
48
48
|
import useBlockDisplayTitle from './components/block-title/use-block-display-title';
|
|
49
49
|
import TabbedSidebar from './components/tabbed-sidebar';
|
|
50
|
-
import { useBlockBindingsUtils } from './utils/block-bindings';
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* Private @wordpress/block-editor APIs.
|
|
@@ -92,6 +91,5 @@ lock( privateApis, {
|
|
|
92
91
|
useBlockDisplayTitle,
|
|
93
92
|
__unstableBlockStyleVariationOverridesWithConfig,
|
|
94
93
|
setBackgroundStyleDefaults,
|
|
95
|
-
useBlockBindingsUtils,
|
|
96
94
|
sectionRootClientIdKey,
|
|
97
95
|
} );
|
package/src/store/selectors.js
CHANGED
|
@@ -2467,7 +2467,7 @@ export const __experimentalGetPatternsByBlockTypes = createRegistrySelector(
|
|
|
2467
2467
|
* Determines the items that appear in the available pattern transforms list.
|
|
2468
2468
|
*
|
|
2469
2469
|
* For now we only handle blocks without InnerBlocks and take into account
|
|
2470
|
-
* the `
|
|
2470
|
+
* the `role` property of blocks' attributes for the transformation.
|
|
2471
2471
|
*
|
|
2472
2472
|
* We return the first set of possible eligible block patterns,
|
|
2473
2473
|
* by checking the `blockTypes` property. We still have to recurse through
|
|
@@ -2489,7 +2489,7 @@ export const __experimentalGetPatternTransformItems = createRegistrySelector(
|
|
|
2489
2489
|
}
|
|
2490
2490
|
/**
|
|
2491
2491
|
* For now we only handle blocks without InnerBlocks and take into account
|
|
2492
|
-
* the `
|
|
2492
|
+
* the `role` property of blocks' attributes for the transformation.
|
|
2493
2493
|
* Note that the blocks have been retrieved through `getBlock`, which doesn't
|
|
2494
2494
|
* return the inner blocks of an inner block controller, so we still need
|
|
2495
2495
|
* to check for this case too.
|
|
@@ -2964,10 +2964,10 @@ export const getBlockEditingMode = createRegistrySelector(
|
|
|
2964
2964
|
const templateLock = getTemplateLock( state, rootClientId );
|
|
2965
2965
|
if ( templateLock === 'contentOnly' ) {
|
|
2966
2966
|
const name = getBlockName( state, clientId );
|
|
2967
|
-
const
|
|
2968
|
-
select( blocksStore )
|
|
2969
|
-
|
|
2970
|
-
|
|
2967
|
+
const { hasContentRoleAttribute } = unlock(
|
|
2968
|
+
select( blocksStore )
|
|
2969
|
+
);
|
|
2970
|
+
const isContent = hasContentRoleAttribute( name );
|
|
2971
2971
|
return isContent ? 'contentOnly' : 'disabled';
|
|
2972
2972
|
}
|
|
2973
2973
|
const parentMode = getBlockEditingMode( state, rootClientId );
|
|
@@ -124,10 +124,10 @@ describe( 'private selectors', () => {
|
|
|
124
124
|
blockEditingModes: new Map( [] ),
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
-
const
|
|
127
|
+
const hasContentRoleAttribute = jest.fn( () => false );
|
|
128
128
|
getBlockEditingMode.registry = {
|
|
129
129
|
select: jest.fn( () => ( {
|
|
130
|
-
|
|
130
|
+
hasContentRoleAttribute,
|
|
131
131
|
} ) ),
|
|
132
132
|
};
|
|
133
133
|
|
|
@@ -15,6 +15,7 @@ import { select, dispatch } from '@wordpress/data';
|
|
|
15
15
|
*/
|
|
16
16
|
import * as selectors from '../selectors';
|
|
17
17
|
import { store } from '../';
|
|
18
|
+
import { lock } from '../../lock-unlock';
|
|
18
19
|
|
|
19
20
|
const {
|
|
20
21
|
getBlockName,
|
|
@@ -4372,11 +4373,14 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4372
4373
|
blockEditingModes: new Map( [] ),
|
|
4373
4374
|
};
|
|
4374
4375
|
|
|
4375
|
-
const
|
|
4376
|
+
const hasContentRoleAttribute = jest.fn( () => false );
|
|
4377
|
+
|
|
4378
|
+
const fauxPrivateAPIs = {};
|
|
4379
|
+
|
|
4380
|
+
lock( fauxPrivateAPIs, { hasContentRoleAttribute } );
|
|
4381
|
+
|
|
4376
4382
|
getBlockEditingMode.registry = {
|
|
4377
|
-
select: jest.fn( () =>
|
|
4378
|
-
__experimentalHasContentRoleAttribute,
|
|
4379
|
-
} ) ),
|
|
4383
|
+
select: jest.fn( () => fauxPrivateAPIs ),
|
|
4380
4384
|
};
|
|
4381
4385
|
|
|
4382
4386
|
it( 'should return default by default', () => {
|
|
@@ -4480,7 +4484,7 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4480
4484
|
},
|
|
4481
4485
|
},
|
|
4482
4486
|
};
|
|
4483
|
-
|
|
4487
|
+
hasContentRoleAttribute.mockReturnValueOnce( false );
|
|
4484
4488
|
expect(
|
|
4485
4489
|
getBlockEditingMode( state, 'b3247f75-fd94-4fef-97f9-5bfd162cc416' )
|
|
4486
4490
|
).toBe( 'disabled' );
|
|
@@ -4496,7 +4500,7 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4496
4500
|
},
|
|
4497
4501
|
},
|
|
4498
4502
|
};
|
|
4499
|
-
|
|
4503
|
+
hasContentRoleAttribute.mockReturnValueOnce( true );
|
|
4500
4504
|
expect(
|
|
4501
4505
|
getBlockEditingMode( state, 'b3247f75-fd94-4fef-97f9-5bfd162cc416' )
|
|
4502
4506
|
).toBe( 'contentOnly' );
|
|
@@ -13,6 +13,53 @@ function isObjectEmpty( object ) {
|
|
|
13
13
|
return ! object || Object.keys( object ).length === 0;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Contains utils to update the block `bindings` metadata.
|
|
18
|
+
*
|
|
19
|
+
* @typedef {Object} WPBlockBindingsUtils
|
|
20
|
+
*
|
|
21
|
+
* @property {Function} updateBlockBindings Updates the value of the bindings connected to block attributes.
|
|
22
|
+
* @property {Function} removeAllBlockBindings Removes the bindings property of the `metadata` attribute.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves the existing utils needed to update the block `bindings` metadata.
|
|
27
|
+
* They can be used to create, modify, or remove connections from the existing block attributes.
|
|
28
|
+
*
|
|
29
|
+
* It contains the following utils:
|
|
30
|
+
* - `updateBlockBindings`: Updates the value of the bindings connected to block attributes. It can be used to remove a specific binding by setting the value to `undefined`.
|
|
31
|
+
* - `removeAllBlockBindings`: Removes the bindings property of the `metadata` attribute.
|
|
32
|
+
*
|
|
33
|
+
* @return {?WPBlockBindingsUtils} Object containing the block bindings utils.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```js
|
|
37
|
+
* import { useBlockBindingsUtils } from '@wordpress/block-editor'
|
|
38
|
+
* const { updateBlockBindings, removeAllBlockBindings } = useBlockBindingsUtils();
|
|
39
|
+
*
|
|
40
|
+
* // Update url and alt attributes.
|
|
41
|
+
* updateBlockBindings( {
|
|
42
|
+
* url: {
|
|
43
|
+
* source: 'core/post-meta',
|
|
44
|
+
* args: {
|
|
45
|
+
* key: 'url_custom_field',
|
|
46
|
+
* },
|
|
47
|
+
* },
|
|
48
|
+
* alt: {
|
|
49
|
+
* source: 'core/post-meta',
|
|
50
|
+
* args: {
|
|
51
|
+
* key: 'text_custom_field',
|
|
52
|
+
* },
|
|
53
|
+
* },
|
|
54
|
+
* } );
|
|
55
|
+
*
|
|
56
|
+
* // Remove binding from url attribute.
|
|
57
|
+
* updateBlockBindings( { url: undefined } );
|
|
58
|
+
*
|
|
59
|
+
* // Remove bindings from all attributes.
|
|
60
|
+
* removeAllBlockBindings();
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
16
63
|
export function useBlockBindingsUtils() {
|
|
17
64
|
const { clientId } = useBlockEditContext();
|
|
18
65
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
package/src/utils/index.js
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = useEventRedirect;
|
|
7
|
-
var _compose = require("@wordpress/compose");
|
|
8
|
-
var _utils = require("./utils");
|
|
9
|
-
/**
|
|
10
|
-
* WordPress dependencies
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Internal dependencies
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Whenever content editable is enabled on writing flow, it will have focus, so
|
|
19
|
-
* we need to dispatch some events to the root of the selection to ensure
|
|
20
|
-
* compatibility with rich text. In the future, perhaps the rich text event
|
|
21
|
-
* handlers should be attached to the window instead.
|
|
22
|
-
*
|
|
23
|
-
* Alternatively, we could try to find a way to always maintain rich text focus.
|
|
24
|
-
*/
|
|
25
|
-
function useEventRedirect() {
|
|
26
|
-
return (0, _compose.useRefEffect)(node => {
|
|
27
|
-
function onInput(event) {
|
|
28
|
-
if (event.target !== node) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const {
|
|
32
|
-
ownerDocument
|
|
33
|
-
} = node;
|
|
34
|
-
const {
|
|
35
|
-
defaultView
|
|
36
|
-
} = ownerDocument;
|
|
37
|
-
const prototype = Object.getPrototypeOf(event);
|
|
38
|
-
const constructorName = prototype.constructor.name;
|
|
39
|
-
const Constructor = defaultView[constructorName];
|
|
40
|
-
const root = (0, _utils.getSelectionRoot)(ownerDocument);
|
|
41
|
-
if (!root || root === node) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const init = {};
|
|
45
|
-
for (const key in event) {
|
|
46
|
-
init[key] = event[key];
|
|
47
|
-
}
|
|
48
|
-
init.bubbles = false;
|
|
49
|
-
const newEvent = new Constructor(event.type, init);
|
|
50
|
-
const cancelled = !root.dispatchEvent(newEvent);
|
|
51
|
-
if (cancelled) {
|
|
52
|
-
event.preventDefault();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const events = ['beforeinput', 'input', 'compositionstart', 'compositionend', 'compositionupdate', 'keydown'];
|
|
56
|
-
events.forEach(eventType => {
|
|
57
|
-
node.addEventListener(eventType, onInput);
|
|
58
|
-
});
|
|
59
|
-
return () => {
|
|
60
|
-
events.forEach(eventType => {
|
|
61
|
-
node.removeEventListener(eventType, onInput);
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
}, []);
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=use-event-redirect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_compose","require","_utils","useEventRedirect","useRefEffect","node","onInput","event","target","ownerDocument","defaultView","prototype","Object","getPrototypeOf","constructorName","constructor","name","Constructor","root","getSelectionRoot","init","key","bubbles","newEvent","type","cancelled","dispatchEvent","preventDefault","events","forEach","eventType","addEventListener","removeEventListener"],"sources":["@wordpress/block-editor/src/components/writing-flow/use-event-redirect.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRefEffect } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport { getSelectionRoot } from './utils';\n\n/**\n * Whenever content editable is enabled on writing flow, it will have focus, so\n * we need to dispatch some events to the root of the selection to ensure\n * compatibility with rich text. In the future, perhaps the rich text event\n * handlers should be attached to the window instead.\n *\n * Alternatively, we could try to find a way to always maintain rich text focus.\n */\nexport default function useEventRedirect() {\n\treturn useRefEffect( ( node ) => {\n\t\tfunction onInput( event ) {\n\t\t\tif ( event.target !== node ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { ownerDocument } = node;\n\t\t\tconst { defaultView } = ownerDocument;\n\t\t\tconst prototype = Object.getPrototypeOf( event );\n\t\t\tconst constructorName = prototype.constructor.name;\n\t\t\tconst Constructor = defaultView[ constructorName ];\n\t\t\tconst root = getSelectionRoot( ownerDocument );\n\n\t\t\tif ( ! root || root === node ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst init = {};\n\n\t\t\tfor ( const key in event ) {\n\t\t\t\tinit[ key ] = event[ key ];\n\t\t\t}\n\n\t\t\tinit.bubbles = false;\n\n\t\t\tconst newEvent = new Constructor( event.type, init );\n\t\t\tconst cancelled = ! root.dispatchEvent( newEvent );\n\n\t\t\tif ( cancelled ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\n\t\tconst events = [\n\t\t\t'beforeinput',\n\t\t\t'input',\n\t\t\t'compositionstart',\n\t\t\t'compositionend',\n\t\t\t'compositionupdate',\n\t\t\t'keydown',\n\t\t];\n\n\t\tevents.forEach( ( eventType ) => {\n\t\t\tnode.addEventListener( eventType, onInput );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tevents.forEach( ( eventType ) => {\n\t\t\t\tnode.removeEventListener( eventType, onInput );\n\t\t\t} );\n\t\t};\n\t}, [] );\n}\n"],"mappings":";;;;;;AAGA,IAAAA,QAAA,GAAAC,OAAA;AAKA,IAAAC,MAAA,GAAAD,OAAA;AARA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASE,gBAAgBA,CAAA,EAAG;EAC1C,OAAO,IAAAC,qBAAY,EAAIC,IAAI,IAAM;IAChC,SAASC,OAAOA,CAAEC,KAAK,EAAG;MACzB,IAAKA,KAAK,CAACC,MAAM,KAAKH,IAAI,EAAG;QAC5B;MACD;MAEA,MAAM;QAAEI;MAAc,CAAC,GAAGJ,IAAI;MAC9B,MAAM;QAAEK;MAAY,CAAC,GAAGD,aAAa;MACrC,MAAME,SAAS,GAAGC,MAAM,CAACC,cAAc,CAAEN,KAAM,CAAC;MAChD,MAAMO,eAAe,GAAGH,SAAS,CAACI,WAAW,CAACC,IAAI;MAClD,MAAMC,WAAW,GAAGP,WAAW,CAAEI,eAAe,CAAE;MAClD,MAAMI,IAAI,GAAG,IAAAC,uBAAgB,EAAEV,aAAc,CAAC;MAE9C,IAAK,CAAES,IAAI,IAAIA,IAAI,KAAKb,IAAI,EAAG;QAC9B;MACD;MAEA,MAAMe,IAAI,GAAG,CAAC,CAAC;MAEf,KAAM,MAAMC,GAAG,IAAId,KAAK,EAAG;QAC1Ba,IAAI,CAAEC,GAAG,CAAE,GAAGd,KAAK,CAAEc,GAAG,CAAE;MAC3B;MAEAD,IAAI,CAACE,OAAO,GAAG,KAAK;MAEpB,MAAMC,QAAQ,GAAG,IAAIN,WAAW,CAAEV,KAAK,CAACiB,IAAI,EAAEJ,IAAK,CAAC;MACpD,MAAMK,SAAS,GAAG,CAAEP,IAAI,CAACQ,aAAa,CAAEH,QAAS,CAAC;MAElD,IAAKE,SAAS,EAAG;QAChBlB,KAAK,CAACoB,cAAc,CAAC,CAAC;MACvB;IACD;IAEA,MAAMC,MAAM,GAAG,CACd,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,CACT;IAEDA,MAAM,CAACC,OAAO,CAAIC,SAAS,IAAM;MAChCzB,IAAI,CAAC0B,gBAAgB,CAAED,SAAS,EAAExB,OAAQ,CAAC;IAC5C,CAAE,CAAC;IAEH,OAAO,MAAM;MACZsB,MAAM,CAACC,OAAO,CAAIC,SAAS,IAAM;QAChCzB,IAAI,CAAC2B,mBAAmB,CAAEF,SAAS,EAAExB,OAAQ,CAAC;MAC/C,CAAE,CAAC;IACJ,CAAC;EACF,CAAC,EAAE,EAAG,CAAC;AACR","ignoreList":[]}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { useRefEffect } from '@wordpress/compose';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Internal dependencies
|
|
8
|
-
*/
|
|
9
|
-
import { getSelectionRoot } from './utils';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Whenever content editable is enabled on writing flow, it will have focus, so
|
|
13
|
-
* we need to dispatch some events to the root of the selection to ensure
|
|
14
|
-
* compatibility with rich text. In the future, perhaps the rich text event
|
|
15
|
-
* handlers should be attached to the window instead.
|
|
16
|
-
*
|
|
17
|
-
* Alternatively, we could try to find a way to always maintain rich text focus.
|
|
18
|
-
*/
|
|
19
|
-
export default function useEventRedirect() {
|
|
20
|
-
return useRefEffect(node => {
|
|
21
|
-
function onInput(event) {
|
|
22
|
-
if (event.target !== node) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const {
|
|
26
|
-
ownerDocument
|
|
27
|
-
} = node;
|
|
28
|
-
const {
|
|
29
|
-
defaultView
|
|
30
|
-
} = ownerDocument;
|
|
31
|
-
const prototype = Object.getPrototypeOf(event);
|
|
32
|
-
const constructorName = prototype.constructor.name;
|
|
33
|
-
const Constructor = defaultView[constructorName];
|
|
34
|
-
const root = getSelectionRoot(ownerDocument);
|
|
35
|
-
if (!root || root === node) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const init = {};
|
|
39
|
-
for (const key in event) {
|
|
40
|
-
init[key] = event[key];
|
|
41
|
-
}
|
|
42
|
-
init.bubbles = false;
|
|
43
|
-
const newEvent = new Constructor(event.type, init);
|
|
44
|
-
const cancelled = !root.dispatchEvent(newEvent);
|
|
45
|
-
if (cancelled) {
|
|
46
|
-
event.preventDefault();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
const events = ['beforeinput', 'input', 'compositionstart', 'compositionend', 'compositionupdate', 'keydown'];
|
|
50
|
-
events.forEach(eventType => {
|
|
51
|
-
node.addEventListener(eventType, onInput);
|
|
52
|
-
});
|
|
53
|
-
return () => {
|
|
54
|
-
events.forEach(eventType => {
|
|
55
|
-
node.removeEventListener(eventType, onInput);
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
}, []);
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=use-event-redirect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useRefEffect","getSelectionRoot","useEventRedirect","node","onInput","event","target","ownerDocument","defaultView","prototype","Object","getPrototypeOf","constructorName","constructor","name","Constructor","root","init","key","bubbles","newEvent","type","cancelled","dispatchEvent","preventDefault","events","forEach","eventType","addEventListener","removeEventListener"],"sources":["@wordpress/block-editor/src/components/writing-flow/use-event-redirect.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRefEffect } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport { getSelectionRoot } from './utils';\n\n/**\n * Whenever content editable is enabled on writing flow, it will have focus, so\n * we need to dispatch some events to the root of the selection to ensure\n * compatibility with rich text. In the future, perhaps the rich text event\n * handlers should be attached to the window instead.\n *\n * Alternatively, we could try to find a way to always maintain rich text focus.\n */\nexport default function useEventRedirect() {\n\treturn useRefEffect( ( node ) => {\n\t\tfunction onInput( event ) {\n\t\t\tif ( event.target !== node ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { ownerDocument } = node;\n\t\t\tconst { defaultView } = ownerDocument;\n\t\t\tconst prototype = Object.getPrototypeOf( event );\n\t\t\tconst constructorName = prototype.constructor.name;\n\t\t\tconst Constructor = defaultView[ constructorName ];\n\t\t\tconst root = getSelectionRoot( ownerDocument );\n\n\t\t\tif ( ! root || root === node ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst init = {};\n\n\t\t\tfor ( const key in event ) {\n\t\t\t\tinit[ key ] = event[ key ];\n\t\t\t}\n\n\t\t\tinit.bubbles = false;\n\n\t\t\tconst newEvent = new Constructor( event.type, init );\n\t\t\tconst cancelled = ! root.dispatchEvent( newEvent );\n\n\t\t\tif ( cancelled ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\n\t\tconst events = [\n\t\t\t'beforeinput',\n\t\t\t'input',\n\t\t\t'compositionstart',\n\t\t\t'compositionend',\n\t\t\t'compositionupdate',\n\t\t\t'keydown',\n\t\t];\n\n\t\tevents.forEach( ( eventType ) => {\n\t\t\tnode.addEventListener( eventType, onInput );\n\t\t} );\n\n\t\treturn () => {\n\t\t\tevents.forEach( ( eventType ) => {\n\t\t\t\tnode.removeEventListener( eventType, onInput );\n\t\t\t} );\n\t\t};\n\t}, [] );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,YAAY,QAAQ,oBAAoB;;AAEjD;AACA;AACA;AACA,SAASC,gBAAgB,QAAQ,SAAS;;AAE1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,gBAAgBA,CAAA,EAAG;EAC1C,OAAOF,YAAY,CAAIG,IAAI,IAAM;IAChC,SAASC,OAAOA,CAAEC,KAAK,EAAG;MACzB,IAAKA,KAAK,CAACC,MAAM,KAAKH,IAAI,EAAG;QAC5B;MACD;MAEA,MAAM;QAAEI;MAAc,CAAC,GAAGJ,IAAI;MAC9B,MAAM;QAAEK;MAAY,CAAC,GAAGD,aAAa;MACrC,MAAME,SAAS,GAAGC,MAAM,CAACC,cAAc,CAAEN,KAAM,CAAC;MAChD,MAAMO,eAAe,GAAGH,SAAS,CAACI,WAAW,CAACC,IAAI;MAClD,MAAMC,WAAW,GAAGP,WAAW,CAAEI,eAAe,CAAE;MAClD,MAAMI,IAAI,GAAGf,gBAAgB,CAAEM,aAAc,CAAC;MAE9C,IAAK,CAAES,IAAI,IAAIA,IAAI,KAAKb,IAAI,EAAG;QAC9B;MACD;MAEA,MAAMc,IAAI,GAAG,CAAC,CAAC;MAEf,KAAM,MAAMC,GAAG,IAAIb,KAAK,EAAG;QAC1BY,IAAI,CAAEC,GAAG,CAAE,GAAGb,KAAK,CAAEa,GAAG,CAAE;MAC3B;MAEAD,IAAI,CAACE,OAAO,GAAG,KAAK;MAEpB,MAAMC,QAAQ,GAAG,IAAIL,WAAW,CAAEV,KAAK,CAACgB,IAAI,EAAEJ,IAAK,CAAC;MACpD,MAAMK,SAAS,GAAG,CAAEN,IAAI,CAACO,aAAa,CAAEH,QAAS,CAAC;MAElD,IAAKE,SAAS,EAAG;QAChBjB,KAAK,CAACmB,cAAc,CAAC,CAAC;MACvB;IACD;IAEA,MAAMC,MAAM,GAAG,CACd,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,CACT;IAEDA,MAAM,CAACC,OAAO,CAAIC,SAAS,IAAM;MAChCxB,IAAI,CAACyB,gBAAgB,CAAED,SAAS,EAAEvB,OAAQ,CAAC;IAC5C,CAAE,CAAC;IAEH,OAAO,MAAM;MACZqB,MAAM,CAACC,OAAO,CAAIC,SAAS,IAAM;QAChCxB,IAAI,CAAC0B,mBAAmB,CAAEF,SAAS,EAAEvB,OAAQ,CAAC;MAC/C,CAAE,CAAC;IACJ,CAAC;EACF,CAAC,EAAE,EAAG,CAAC;AACR","ignoreList":[]}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { useRefEffect } from '@wordpress/compose';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Internal dependencies
|
|
8
|
-
*/
|
|
9
|
-
import { getSelectionRoot } from './utils';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Whenever content editable is enabled on writing flow, it will have focus, so
|
|
13
|
-
* we need to dispatch some events to the root of the selection to ensure
|
|
14
|
-
* compatibility with rich text. In the future, perhaps the rich text event
|
|
15
|
-
* handlers should be attached to the window instead.
|
|
16
|
-
*
|
|
17
|
-
* Alternatively, we could try to find a way to always maintain rich text focus.
|
|
18
|
-
*/
|
|
19
|
-
export default function useEventRedirect() {
|
|
20
|
-
return useRefEffect( ( node ) => {
|
|
21
|
-
function onInput( event ) {
|
|
22
|
-
if ( event.target !== node ) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const { ownerDocument } = node;
|
|
27
|
-
const { defaultView } = ownerDocument;
|
|
28
|
-
const prototype = Object.getPrototypeOf( event );
|
|
29
|
-
const constructorName = prototype.constructor.name;
|
|
30
|
-
const Constructor = defaultView[ constructorName ];
|
|
31
|
-
const root = getSelectionRoot( ownerDocument );
|
|
32
|
-
|
|
33
|
-
if ( ! root || root === node ) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const init = {};
|
|
38
|
-
|
|
39
|
-
for ( const key in event ) {
|
|
40
|
-
init[ key ] = event[ key ];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
init.bubbles = false;
|
|
44
|
-
|
|
45
|
-
const newEvent = new Constructor( event.type, init );
|
|
46
|
-
const cancelled = ! root.dispatchEvent( newEvent );
|
|
47
|
-
|
|
48
|
-
if ( cancelled ) {
|
|
49
|
-
event.preventDefault();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const events = [
|
|
54
|
-
'beforeinput',
|
|
55
|
-
'input',
|
|
56
|
-
'compositionstart',
|
|
57
|
-
'compositionend',
|
|
58
|
-
'compositionupdate',
|
|
59
|
-
'keydown',
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
events.forEach( ( eventType ) => {
|
|
63
|
-
node.addEventListener( eventType, onInput );
|
|
64
|
-
} );
|
|
65
|
-
|
|
66
|
-
return () => {
|
|
67
|
-
events.forEach( ( eventType ) => {
|
|
68
|
-
node.removeEventListener( eventType, onInput );
|
|
69
|
-
} );
|
|
70
|
-
};
|
|
71
|
-
}, [] );
|
|
72
|
-
}
|