@wordpress/block-editor 15.10.1-next.ba3aee3a2.0 → 15.11.0
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/CHANGELOG.md +2 -0
- package/build/components/block-bindings/attribute-control.cjs +1 -1
- package/build/components/block-bindings/attribute-control.cjs.map +1 -1
- package/build/components/block-bindings/source-fields-list.cjs +1 -1
- package/build/components/block-bindings/source-fields-list.cjs.map +1 -1
- package/build/components/block-edit/context.cjs +5 -0
- package/build/components/block-edit/context.cjs.map +2 -2
- package/build/components/block-edit/index.cjs +3 -0
- package/build/components/block-edit/index.cjs.map +2 -2
- package/build/components/block-inspector/index.cjs +2 -9
- package/build/components/block-inspector/index.cjs.map +2 -2
- package/build/components/block-list/block.cjs +3 -0
- package/build/components/block-list/block.cjs.map +2 -2
- package/build/components/block-tools/index.cjs +82 -70
- package/build/components/block-tools/index.cjs.map +2 -2
- package/build/components/block-visibility/block-visibility-info.cjs +0 -59
- package/build/components/block-visibility/block-visibility-info.cjs.map +3 -3
- package/build/components/block-visibility/constants.cjs +10 -5
- package/build/components/block-visibility/constants.cjs.map +2 -2
- package/build/components/block-visibility/index.cjs +13 -5
- package/build/components/block-visibility/index.cjs.map +3 -3
- package/build/components/block-visibility/modal.cjs +397 -0
- package/build/components/block-visibility/modal.cjs.map +7 -0
- package/build/components/block-visibility/toolbar.cjs +1 -1
- package/build/components/block-visibility/toolbar.cjs.map +2 -2
- package/build/components/block-visibility/use-block-visibility.cjs +13 -17
- package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
- package/build/components/block-visibility/utils.cjs +81 -0
- package/build/components/block-visibility/utils.cjs.map +7 -0
- package/build/components/block-visibility/viewport-menu-item.cjs +61 -0
- package/build/components/block-visibility/viewport-menu-item.cjs.map +7 -0
- package/build/components/block-visibility/viewport-toolbar.cjs +89 -0
- package/build/components/block-visibility/viewport-toolbar.cjs.map +7 -0
- package/build/components/button-block-appender/index.cjs +23 -19
- package/build/components/button-block-appender/index.cjs.map +2 -2
- package/build/components/font-sizes/font-size-picker.cjs +2 -1
- package/build/components/font-sizes/font-size-picker.cjs.map +2 -2
- package/build/components/inner-blocks/use-inner-block-template-sync.cjs +1 -1
- package/build/components/inner-blocks/use-inner-block-template-sync.cjs.map +1 -1
- package/build/components/inserter/menu.cjs +6 -2
- package/build/components/inserter/menu.cjs.map +2 -2
- package/build/components/inspector-controls/fill.cjs +4 -25
- package/build/components/inspector-controls/fill.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +6 -6
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
- package/build/components/list-view/block-select-button.cjs +2 -2
- package/build/components/list-view/block-select-button.cjs.map +2 -2
- package/build/components/list-view/block.cjs +39 -22
- package/build/components/list-view/block.cjs.map +2 -2
- package/build/components/rich-text/index.cjs +1 -1
- package/build/components/rich-text/index.cjs.map +1 -1
- package/build/components/url-input/index.cjs +2 -0
- package/build/components/url-input/index.cjs.map +2 -2
- package/build/components/use-block-commands/index.cjs +1 -1
- package/build/components/use-block-commands/index.cjs.map +2 -2
- package/build/hooks/block-fields/index.cjs +92 -217
- package/build/hooks/block-fields/index.cjs.map +3 -3
- package/build/hooks/block-fields/link/index.cjs +13 -32
- package/build/hooks/block-fields/link/index.cjs.map +2 -2
- package/build/hooks/block-fields/media/index.cjs +36 -67
- package/build/hooks/block-fields/media/index.cjs.map +2 -2
- package/build/hooks/block-fields/rich-text/index.cjs +1 -5
- package/build/hooks/block-fields/rich-text/index.cjs.map +2 -2
- package/build/hooks/cross-origin-isolation.cjs +102 -0
- package/build/hooks/cross-origin-isolation.cjs.map +7 -0
- package/build/hooks/index.cjs +3 -1
- package/build/hooks/index.cjs.map +3 -3
- package/build/hooks/list-view.cjs +27 -10
- package/build/hooks/list-view.cjs.map +2 -2
- package/build/hooks/utils.cjs +3 -2
- package/build/hooks/utils.cjs.map +2 -2
- package/build/layouts/flex.cjs +6 -2
- package/build/layouts/flex.cjs.map +2 -2
- package/build/store/private-selectors.cjs +33 -1
- package/build/store/private-selectors.cjs.map +3 -3
- package/build/store/reducer.cjs +1 -1
- package/build/store/reducer.cjs.map +1 -1
- package/build/store/selectors.cjs +14 -9
- package/build/store/selectors.cjs.map +2 -2
- package/build-module/components/block-bindings/attribute-control.mjs +1 -1
- package/build-module/components/block-bindings/attribute-control.mjs.map +1 -1
- package/build-module/components/block-bindings/source-fields-list.mjs +1 -1
- package/build-module/components/block-bindings/source-fields-list.mjs.map +1 -1
- package/build-module/components/block-edit/context.mjs +4 -0
- package/build-module/components/block-edit/context.mjs.map +2 -2
- package/build-module/components/block-edit/index.mjs +4 -0
- package/build-module/components/block-edit/index.mjs.map +2 -2
- package/build-module/components/block-inspector/index.mjs +2 -9
- package/build-module/components/block-inspector/index.mjs.map +2 -2
- package/build-module/components/block-list/block.mjs +3 -0
- package/build-module/components/block-list/block.mjs.map +2 -2
- package/build-module/components/block-tools/index.mjs +85 -73
- package/build-module/components/block-tools/index.mjs.map +2 -2
- package/build-module/components/block-visibility/block-visibility-info.mjs +0 -59
- package/build-module/components/block-visibility/block-visibility-info.mjs.map +3 -3
- package/build-module/components/block-visibility/constants.mjs +8 -4
- package/build-module/components/block-visibility/constants.mjs.map +2 -2
- package/build-module/components/block-visibility/index.mjs +13 -6
- package/build-module/components/block-visibility/index.mjs.map +2 -2
- package/build-module/components/block-visibility/modal.mjs +384 -0
- package/build-module/components/block-visibility/modal.mjs.map +7 -0
- package/build-module/components/block-visibility/toolbar.mjs +1 -1
- package/build-module/components/block-visibility/toolbar.mjs.map +2 -2
- package/build-module/components/block-visibility/use-block-visibility.mjs +13 -13
- package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
- package/build-module/components/block-visibility/utils.mjs +55 -0
- package/build-module/components/block-visibility/utils.mjs.map +7 -0
- package/build-module/components/block-visibility/viewport-menu-item.mjs +40 -0
- package/build-module/components/block-visibility/viewport-menu-item.mjs.map +7 -0
- package/build-module/components/block-visibility/viewport-toolbar.mjs +68 -0
- package/build-module/components/block-visibility/viewport-toolbar.mjs.map +7 -0
- package/build-module/components/button-block-appender/index.mjs +23 -19
- package/build-module/components/button-block-appender/index.mjs.map +2 -2
- package/build-module/components/font-sizes/font-size-picker.mjs +2 -1
- package/build-module/components/font-sizes/font-size-picker.mjs.map +2 -2
- package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs +1 -1
- package/build-module/components/inner-blocks/use-inner-block-template-sync.mjs.map +1 -1
- package/build-module/components/inserter/menu.mjs +6 -2
- package/build-module/components/inserter/menu.mjs.map +2 -2
- package/build-module/components/inspector-controls/fill.mjs +6 -22
- package/build-module/components/inspector-controls/fill.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +6 -6
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
- package/build-module/components/list-view/block-select-button.mjs +2 -2
- package/build-module/components/list-view/block-select-button.mjs.map +2 -2
- package/build-module/components/list-view/block.mjs +39 -22
- package/build-module/components/list-view/block.mjs.map +2 -2
- package/build-module/components/rich-text/index.mjs +1 -1
- package/build-module/components/rich-text/index.mjs.map +1 -1
- package/build-module/components/url-input/index.mjs +2 -0
- package/build-module/components/url-input/index.mjs.map +2 -2
- package/build-module/components/use-block-commands/index.mjs +1 -1
- package/build-module/components/use-block-commands/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/index.mjs +85 -218
- package/build-module/hooks/block-fields/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/link/index.mjs +13 -32
- package/build-module/hooks/block-fields/link/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/media/index.mjs +36 -67
- package/build-module/hooks/block-fields/media/index.mjs.map +2 -2
- package/build-module/hooks/block-fields/rich-text/index.mjs +1 -5
- package/build-module/hooks/block-fields/rich-text/index.mjs.map +2 -2
- package/build-module/hooks/cross-origin-isolation.mjs +100 -0
- package/build-module/hooks/cross-origin-isolation.mjs.map +7 -0
- package/build-module/hooks/index.mjs +3 -1
- package/build-module/hooks/index.mjs.map +2 -2
- package/build-module/hooks/list-view.mjs +27 -10
- package/build-module/hooks/list-view.mjs.map +2 -2
- package/build-module/hooks/utils.mjs +5 -3
- package/build-module/hooks/utils.mjs.map +2 -2
- package/build-module/layouts/flex.mjs +6 -2
- package/build-module/layouts/flex.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +34 -1
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +1 -1
- package/build-module/store/reducer.mjs.map +1 -1
- package/build-module/store/selectors.mjs +14 -9
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-style/content-rtl.css +4 -1
- package/build-style/content.css +4 -1
- package/build-style/style-rtl.css +48 -0
- package/build-style/style.css +48 -0
- package/package.json +39 -39
- package/src/components/block-bindings/attribute-control.js +1 -1
- package/src/components/block-bindings/source-fields-list.js +1 -1
- package/src/components/block-edit/context.js +3 -0
- package/src/components/block-edit/index.js +6 -0
- package/src/components/block-inspector/index.js +2 -6
- package/src/components/block-list/block.js +3 -0
- package/src/components/block-list/block.native.js +5 -0
- package/src/components/block-list/content.scss +4 -1
- package/src/components/block-patterns-list/stories/index.story.jsx +1 -1
- package/src/components/block-tools/index.js +45 -33
- package/src/components/block-visibility/block-visibility-info.js +0 -1
- package/src/components/block-visibility/constants.js +7 -3
- package/src/components/block-visibility/index.js +21 -3
- package/src/components/block-visibility/modal.js +358 -0
- package/src/components/block-visibility/style.scss +58 -0
- package/src/components/block-visibility/test/use-block-visibility.js +12 -56
- package/src/components/block-visibility/test/utils.js +266 -0
- package/src/components/block-visibility/toolbar.js +1 -1
- package/src/components/block-visibility/use-block-visibility.js +18 -21
- package/src/components/block-visibility/utils.js +95 -0
- package/src/components/block-visibility/viewport-menu-item.js +42 -0
- package/src/components/block-visibility/viewport-toolbar.js +88 -0
- package/src/components/button-block-appender/index.js +2 -2
- package/src/components/font-sizes/font-size-picker.js +1 -0
- package/src/components/inner-blocks/use-inner-block-template-sync.js +1 -1
- package/src/components/inserter/menu.js +6 -2
- package/src/components/inspector-controls/fill.js +10 -20
- package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +11 -8
- package/src/components/list-view/block-select-button.js +2 -2
- package/src/components/list-view/block.js +47 -25
- package/src/components/rich-text/index.js +1 -1
- package/src/components/url-input/index.js +2 -0
- package/src/components/use-block-commands/index.js +4 -3
- package/src/hooks/block-fields/index.js +127 -292
- package/src/hooks/block-fields/link/index.js +13 -51
- package/src/hooks/block-fields/media/index.js +35 -106
- package/src/hooks/block-fields/rich-text/index.js +1 -5
- package/src/hooks/block-fields/styles.scss +2 -0
- package/src/hooks/cross-origin-isolation.js +143 -0
- package/src/hooks/index.js +3 -1
- package/src/hooks/list-view.js +40 -10
- package/src/hooks/utils.js +4 -0
- package/src/layouts/flex.js +8 -3
- package/src/layouts/test/flex.js +53 -0
- package/src/store/private-selectors.js +64 -1
- package/src/store/reducer.js +1 -1
- package/src/store/selectors.js +21 -15
- package/src/store/test/private-selectors.js +80 -0
- package/src/style.scss +1 -0
- package/src/components/block-visibility/styles.scss +0 -10
- /package/src/components/block-icon/stories/{index.story.js → index.story.ts} +0 -0
- /package/src/components/contrast-checker/stories/{index.story.js → index.story.ts} +0 -0
|
@@ -24,9 +24,8 @@ import { useInspectorPopoverPlacement } from '../use-inspector-popover-placement
|
|
|
24
24
|
import { getMediaSelectKey } from '../../../store/private-keys';
|
|
25
25
|
import { store as blockEditorStore } from '../../../store';
|
|
26
26
|
|
|
27
|
-
function MediaThumbnail( { data, field, attachment } ) {
|
|
28
|
-
const
|
|
29
|
-
const { allowedTypes = [], multiple = false } = config;
|
|
27
|
+
function MediaThumbnail( { data, field, attachment, config } ) {
|
|
28
|
+
const { allowedTypes = [], multiple = false } = config || {};
|
|
30
29
|
|
|
31
30
|
if ( multiple ) {
|
|
32
31
|
return 'todo multiple';
|
|
@@ -53,7 +52,7 @@ function MediaThumbnail( { data, field, attachment } ) {
|
|
|
53
52
|
const value = field.getValue( { item: data } );
|
|
54
53
|
const url = value?.url;
|
|
55
54
|
|
|
56
|
-
if ( url ) {
|
|
55
|
+
if ( allowedTypes[ 0 ] === 'image' && url ) {
|
|
57
56
|
return (
|
|
58
57
|
<div className="block-editor-content-only-controls__media-thumbnail">
|
|
59
58
|
<img alt="" width={ 24 } height={ 24 } src={ url } />
|
|
@@ -85,19 +84,11 @@ export default function Media( { data, field, onChange, config = {} } ) {
|
|
|
85
84
|
isControl: true,
|
|
86
85
|
} );
|
|
87
86
|
const value = field.getValue( { item: data } );
|
|
88
|
-
const {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
value: newFieldValue,
|
|
94
|
-
} );
|
|
95
|
-
onChange( mappedChanges );
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// Check if featured image is supported by checking if it's in the mapping
|
|
99
|
-
const hasFeaturedImageSupport =
|
|
100
|
-
fieldDef?.mapping && 'featuredImage' in fieldDef.mapping;
|
|
87
|
+
const {
|
|
88
|
+
allowedTypes = [],
|
|
89
|
+
multiple = false,
|
|
90
|
+
useFeaturedImage = false,
|
|
91
|
+
} = config;
|
|
101
92
|
|
|
102
93
|
const id = value?.id;
|
|
103
94
|
const url = value?.url;
|
|
@@ -147,107 +138,44 @@ export default function Media( { data, field, onChange, config = {} } ) {
|
|
|
147
138
|
multiple={ multiple }
|
|
148
139
|
popoverProps={ popoverProps }
|
|
149
140
|
onReset={ () => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
key === 'id' ||
|
|
157
|
-
key === 'src' ||
|
|
158
|
-
key === 'url'
|
|
159
|
-
) {
|
|
160
|
-
resetValue[ key ] = undefined;
|
|
161
|
-
} else if ( key === 'caption' || key === 'alt' ) {
|
|
162
|
-
resetValue[ key ] = '';
|
|
163
|
-
}
|
|
164
|
-
} );
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Turn off featured image when resetting (only if it's in the mapping)
|
|
168
|
-
if ( hasFeaturedImageSupport ) {
|
|
169
|
-
resetValue.featuredImage = false;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Merge with existing value to preserve other field properties
|
|
173
|
-
updateAttributes( { ...value, ...resetValue } );
|
|
141
|
+
onChange(
|
|
142
|
+
field.setValue( {
|
|
143
|
+
item: data,
|
|
144
|
+
value: {},
|
|
145
|
+
} )
|
|
146
|
+
);
|
|
174
147
|
} }
|
|
175
|
-
{ ...(
|
|
148
|
+
{ ...( useFeaturedImage && {
|
|
176
149
|
useFeaturedImage: !! value?.featuredImage,
|
|
177
150
|
onToggleFeaturedImage: () => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
151
|
+
onChange(
|
|
152
|
+
field.setValue( {
|
|
153
|
+
item: data,
|
|
154
|
+
value: {
|
|
155
|
+
featuredImage: ! value?.featuredImage,
|
|
156
|
+
},
|
|
157
|
+
} )
|
|
158
|
+
);
|
|
182
159
|
},
|
|
183
160
|
} ) }
|
|
184
161
|
onSelect={ ( selectedMedia ) => {
|
|
185
162
|
if ( selectedMedia.id && selectedMedia.url ) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
selectedMedia.mime_type.startsWith( 'video/' )
|
|
191
|
-
) {
|
|
192
|
-
mediaType = 'video';
|
|
193
|
-
} else if (
|
|
194
|
-
selectedMedia.mime_type.startsWith( 'audio/' )
|
|
195
|
-
) {
|
|
196
|
-
mediaType = 'audio';
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Build new value dynamically based on what's in the mapping
|
|
201
|
-
const newValue = {};
|
|
202
|
-
|
|
203
|
-
// Iterate over mapping keys and set values for supported properties
|
|
204
|
-
if ( fieldDef?.mapping ) {
|
|
205
|
-
Object.keys( fieldDef.mapping ).forEach(
|
|
206
|
-
( key ) => {
|
|
207
|
-
if ( key === 'id' ) {
|
|
208
|
-
newValue[ key ] = selectedMedia.id;
|
|
209
|
-
} else if (
|
|
210
|
-
key === 'src' ||
|
|
211
|
-
key === 'url'
|
|
212
|
-
) {
|
|
213
|
-
newValue[ key ] = selectedMedia.url;
|
|
214
|
-
} else if ( key === 'type' ) {
|
|
215
|
-
newValue[ key ] = mediaType;
|
|
216
|
-
} else if (
|
|
217
|
-
key === 'link' &&
|
|
218
|
-
selectedMedia.link
|
|
219
|
-
) {
|
|
220
|
-
newValue[ key ] = selectedMedia.link;
|
|
221
|
-
} else if (
|
|
222
|
-
key === 'caption' &&
|
|
223
|
-
! value?.caption &&
|
|
224
|
-
selectedMedia.caption
|
|
225
|
-
) {
|
|
226
|
-
newValue[ key ] = selectedMedia.caption;
|
|
227
|
-
} else if (
|
|
228
|
-
key === 'alt' &&
|
|
229
|
-
! value?.alt &&
|
|
230
|
-
selectedMedia.alt
|
|
231
|
-
) {
|
|
232
|
-
newValue[ key ] = selectedMedia.alt;
|
|
233
|
-
} else if (
|
|
234
|
-
key === 'poster' &&
|
|
235
|
-
selectedMedia.poster
|
|
236
|
-
) {
|
|
237
|
-
newValue[ key ] = selectedMedia.poster;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
);
|
|
241
|
-
}
|
|
163
|
+
const newValue = {
|
|
164
|
+
...selectedMedia,
|
|
165
|
+
mediaType: selectedMedia.media_type,
|
|
166
|
+
};
|
|
242
167
|
|
|
243
168
|
// Turn off featured image when manually selecting media
|
|
244
|
-
if (
|
|
169
|
+
if ( useFeaturedImage ) {
|
|
245
170
|
newValue.featuredImage = false;
|
|
246
171
|
}
|
|
247
172
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
173
|
+
onChange(
|
|
174
|
+
field.setValue( {
|
|
175
|
+
item: data,
|
|
176
|
+
value: newValue,
|
|
177
|
+
} )
|
|
178
|
+
);
|
|
251
179
|
}
|
|
252
180
|
} }
|
|
253
181
|
renderToggle={ ( buttonProps ) => (
|
|
@@ -268,6 +196,7 @@ export default function Media( { data, field, onChange, config = {} } ) {
|
|
|
268
196
|
attachment={ attachment }
|
|
269
197
|
field={ field }
|
|
270
198
|
data={ data }
|
|
199
|
+
config={ config }
|
|
271
200
|
/>
|
|
272
201
|
<span className="block-editor-content-only-controls__media-title">
|
|
273
202
|
{
|
|
@@ -33,10 +33,6 @@ export default function RichTextControl( {
|
|
|
33
33
|
const attrValue = field.getValue( { item: data } );
|
|
34
34
|
const fieldConfig = field.config || {};
|
|
35
35
|
const { clientId } = config;
|
|
36
|
-
const updateAttributes = ( html ) => {
|
|
37
|
-
const mappedChanges = field.setValue( { item: data, value: html } );
|
|
38
|
-
onChange( mappedChanges );
|
|
39
|
-
};
|
|
40
36
|
const [ selection, setSelection ] = useState( {
|
|
41
37
|
start: undefined,
|
|
42
38
|
end: undefined,
|
|
@@ -107,7 +103,7 @@ export default function RichTextControl( {
|
|
|
107
103
|
} = useRichText( {
|
|
108
104
|
value: attrValue,
|
|
109
105
|
onChange( html, { __unstableFormats, __unstableText } ) {
|
|
110
|
-
|
|
106
|
+
onChange( field.setValue( { item: data, value: html } ) );
|
|
111
107
|
Object.values( changeHandlers ).forEach( ( changeHandler ) => {
|
|
112
108
|
changeHandler( __unstableFormats, __unstableText );
|
|
113
109
|
} );
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { addFilter } from '@wordpress/hooks';
|
|
5
|
+
import { createHigherOrderComponent } from '@wordpress/compose';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Adds crossorigin and credentialless attributes to elements as needed.
|
|
9
|
+
*
|
|
10
|
+
* @param {Element} el The element to modify.
|
|
11
|
+
*/
|
|
12
|
+
function addCrossOriginAttributes( el ) {
|
|
13
|
+
// Add the crossorigin attribute if missing.
|
|
14
|
+
if ( ! el.hasAttribute( 'crossorigin' ) ) {
|
|
15
|
+
el.setAttribute( 'crossorigin', 'anonymous' );
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// For iframes, add the credentialless attribute.
|
|
19
|
+
if ( el.nodeName === 'IFRAME' && ! el.hasAttribute( 'credentialless' ) ) {
|
|
20
|
+
// Do not modify the iframed editor canvas.
|
|
21
|
+
if ( el.getAttribute( 'src' )?.startsWith( 'blob:' ) ) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
el.setAttribute( 'credentialless', '' );
|
|
26
|
+
|
|
27
|
+
// Reload the iframe to ensure the new attribute is taken into account.
|
|
28
|
+
const origSrc = el.getAttribute( 'src' ) || '';
|
|
29
|
+
el.setAttribute( 'src', '' );
|
|
30
|
+
el.setAttribute( 'src', origSrc );
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Only add the mutation observer if the site is cross-origin isolated.
|
|
35
|
+
if ( window.crossOriginIsolated ) {
|
|
36
|
+
/*
|
|
37
|
+
* Detects dynamically added DOM nodes that are missing the `crossorigin` attribute.
|
|
38
|
+
*/
|
|
39
|
+
const observer = new window.MutationObserver( ( mutations ) => {
|
|
40
|
+
mutations.forEach( ( mutation ) => {
|
|
41
|
+
[ mutation.addedNodes, mutation.target ].forEach( ( value ) => {
|
|
42
|
+
const nodes =
|
|
43
|
+
value instanceof window.NodeList ? value : [ value ];
|
|
44
|
+
nodes.forEach( ( node ) => {
|
|
45
|
+
const el = node;
|
|
46
|
+
|
|
47
|
+
if ( ! el.querySelectorAll ) {
|
|
48
|
+
// Most likely a text node.
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
el.querySelectorAll(
|
|
53
|
+
'img,source,script,video,link,iframe'
|
|
54
|
+
).forEach( ( v ) => {
|
|
55
|
+
addCrossOriginAttributes( v );
|
|
56
|
+
} );
|
|
57
|
+
|
|
58
|
+
if ( el.nodeName === 'IFRAME' ) {
|
|
59
|
+
const iframeNode = el;
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* Sandboxed iframes should not get modified. For example embedding a tweet served in a sandboxed
|
|
63
|
+
* iframe, the tweet itself would not be modified.
|
|
64
|
+
*/
|
|
65
|
+
const isEmbedSandboxIframe =
|
|
66
|
+
iframeNode.classList.contains(
|
|
67
|
+
'components-sandbox'
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if ( ! isEmbedSandboxIframe ) {
|
|
71
|
+
iframeNode.addEventListener( 'load', () => {
|
|
72
|
+
if ( iframeNode.contentDocument ) {
|
|
73
|
+
observer.observe(
|
|
74
|
+
iframeNode.contentDocument,
|
|
75
|
+
{
|
|
76
|
+
childList: true,
|
|
77
|
+
attributes: true,
|
|
78
|
+
subtree: true,
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
} );
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (
|
|
87
|
+
[
|
|
88
|
+
'IMG',
|
|
89
|
+
'SOURCE',
|
|
90
|
+
'SCRIPT',
|
|
91
|
+
'VIDEO',
|
|
92
|
+
'LINK',
|
|
93
|
+
'IFRAME',
|
|
94
|
+
].includes( el.nodeName )
|
|
95
|
+
) {
|
|
96
|
+
addCrossOriginAttributes( el );
|
|
97
|
+
}
|
|
98
|
+
} );
|
|
99
|
+
} );
|
|
100
|
+
} );
|
|
101
|
+
} );
|
|
102
|
+
|
|
103
|
+
observer.observe( document.body, {
|
|
104
|
+
childList: true,
|
|
105
|
+
attributes: true,
|
|
106
|
+
subtree: true,
|
|
107
|
+
} );
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Only apply the embed preview filter when cross-origin isolated.
|
|
111
|
+
if ( window.crossOriginIsolated ) {
|
|
112
|
+
const supportsCredentialless =
|
|
113
|
+
'credentialless' in window.HTMLIFrameElement.prototype;
|
|
114
|
+
|
|
115
|
+
const disableEmbedPreviews = createHigherOrderComponent(
|
|
116
|
+
( BlockEdit ) => ( props ) => {
|
|
117
|
+
if ( 'core/embed' !== props.name ) {
|
|
118
|
+
return <BlockEdit { ...props } />;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// List of embeds that do not support a preview is from packages/block-library/src/embed/variations.js.
|
|
122
|
+
const previewable =
|
|
123
|
+
supportsCredentialless &&
|
|
124
|
+
! [ 'facebook', 'smugmug' ].includes(
|
|
125
|
+
props.attributes.providerNameSlug
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<BlockEdit
|
|
130
|
+
{ ...props }
|
|
131
|
+
attributes={ { ...props.attributes, previewable } }
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
'withDisabledEmbedPreview'
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
addFilter(
|
|
139
|
+
'editor.BlockEdit',
|
|
140
|
+
'media-experiments/disable-embed-previews',
|
|
141
|
+
disableEmbedPreviews
|
|
142
|
+
);
|
|
143
|
+
}
|
package/src/hooks/index.js
CHANGED
|
@@ -7,13 +7,14 @@ import {
|
|
|
7
7
|
createBlockSaveFilter,
|
|
8
8
|
} from './utils';
|
|
9
9
|
import './compat';
|
|
10
|
+
import './cross-origin-isolation';
|
|
10
11
|
import align from './align';
|
|
11
12
|
import background from './background';
|
|
12
13
|
import './lock';
|
|
13
14
|
import allowedBlocks from './allowed-blocks';
|
|
14
15
|
import anchor from './anchor';
|
|
15
16
|
import ariaLabel from './aria-label';
|
|
16
|
-
import './block-fields';
|
|
17
|
+
import blockFields from './block-fields';
|
|
17
18
|
import customClassName from './custom-class-name';
|
|
18
19
|
import './generated-class-name';
|
|
19
20
|
import style from './style';
|
|
@@ -55,6 +56,7 @@ createBlockEditFilter(
|
|
|
55
56
|
blockBindingsPanel,
|
|
56
57
|
childLayout,
|
|
57
58
|
allowedBlocks,
|
|
59
|
+
blockFields,
|
|
58
60
|
listView,
|
|
59
61
|
autoInspectorControls,
|
|
60
62
|
].filter( Boolean )
|
package/src/hooks/list-view.js
CHANGED
|
@@ -5,13 +5,15 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
import { PanelBody } from '@wordpress/components';
|
|
6
6
|
import { useSelect } from '@wordpress/data';
|
|
7
7
|
import { store as blocksStore, hasBlockSupport } from '@wordpress/blocks';
|
|
8
|
+
import { useContext } from '@wordpress/element';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Internal dependencies
|
|
11
12
|
*/
|
|
12
|
-
import InspectorControls from '../components/inspector-controls';
|
|
13
13
|
import { store as blockEditorStore } from '../store';
|
|
14
14
|
import { PrivateListView } from '../components/list-view';
|
|
15
|
+
import InspectorControls from '../components/inspector-controls/fill';
|
|
16
|
+
import { PrivateBlockContext } from '../components/block-list/private-block-context';
|
|
15
17
|
|
|
16
18
|
export const LIST_VIEW_SUPPORT_KEY = 'listView';
|
|
17
19
|
|
|
@@ -34,23 +36,50 @@ export function hasListViewSupport( nameOrType ) {
|
|
|
34
36
|
* @return {Element|null} List view inspector controls or null.
|
|
35
37
|
*/
|
|
36
38
|
export function ListViewPanel( { clientId, name } ) {
|
|
39
|
+
const { isSelectionWithinCurrentSection } =
|
|
40
|
+
useContext( PrivateBlockContext );
|
|
37
41
|
const isEnabled = hasListViewSupport( name );
|
|
38
|
-
const { hasChildren, blockTitle } = useSelect(
|
|
39
|
-
( select ) =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const { hasChildren, blockTitle, isNestedListView } = useSelect(
|
|
43
|
+
( select ) => {
|
|
44
|
+
const { getBlockCount, getBlockParents, getBlockName } =
|
|
45
|
+
select( blockEditorStore );
|
|
46
|
+
|
|
47
|
+
// When the ListView is shown in a section, avoid showing List Views
|
|
48
|
+
// for both parent and child blocks that have support. In this situation
|
|
49
|
+
// the parent will show the child anyway in its List.
|
|
50
|
+
// Search parents to see if there's one that also has support, and if so
|
|
51
|
+
// skip rendering.
|
|
52
|
+
// This matches closely the logic in the `BlockCard` component.
|
|
53
|
+
let _isNestedListView = false;
|
|
54
|
+
if ( isSelectionWithinCurrentSection ) {
|
|
55
|
+
const parents = getBlockParents( clientId, true );
|
|
56
|
+
_isNestedListView = parents.find( ( parentId ) => {
|
|
57
|
+
const parentName = getBlockName( parentId );
|
|
58
|
+
return (
|
|
59
|
+
parentName === 'core/navigation' ||
|
|
60
|
+
hasBlockSupport( parentName, 'listView' )
|
|
61
|
+
);
|
|
62
|
+
} );
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
hasChildren: !! getBlockCount( clientId ),
|
|
67
|
+
blockTitle: select( blocksStore ).getBlockType( name )?.title,
|
|
68
|
+
isNestedListView: _isNestedListView,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
[ clientId, name, isSelectionWithinCurrentSection ]
|
|
45
72
|
);
|
|
46
73
|
|
|
47
|
-
if ( ! isEnabled ) {
|
|
74
|
+
if ( ! isEnabled || isNestedListView ) {
|
|
48
75
|
return null;
|
|
49
76
|
}
|
|
50
77
|
|
|
78
|
+
const showBlockTitle = isSelectionWithinCurrentSection;
|
|
79
|
+
|
|
51
80
|
return (
|
|
52
81
|
<InspectorControls group="list">
|
|
53
|
-
<PanelBody title={
|
|
82
|
+
<PanelBody title={ showBlockTitle ? blockTitle : undefined }>
|
|
54
83
|
{ ! hasChildren && (
|
|
55
84
|
<p className="block-editor-block-inspector__no-blocks">
|
|
56
85
|
{ __( 'No items yet.' ) }
|
|
@@ -74,4 +103,5 @@ export default {
|
|
|
74
103
|
edit: ListViewPanel,
|
|
75
104
|
hasSupport: hasListViewSupport,
|
|
76
105
|
attributeKeys: [],
|
|
106
|
+
supportsPatternEditing: true,
|
|
77
107
|
};
|
package/src/hooks/utils.js
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
useBlockEditContext,
|
|
20
20
|
mayDisplayControlsKey,
|
|
21
21
|
mayDisplayParentControlsKey,
|
|
22
|
+
mayDisplayPatternEditingControlsKey,
|
|
22
23
|
} from '../components/block-edit/context';
|
|
23
24
|
import { useSettings } from '../components';
|
|
24
25
|
import { useSettingsForBlockElement } from '../components/global-styles/hooks';
|
|
@@ -534,8 +535,11 @@ export function createBlockEditFilter( features ) {
|
|
|
534
535
|
hasSupport,
|
|
535
536
|
attributeKeys = [],
|
|
536
537
|
shareWithChildBlocks,
|
|
538
|
+
supportsPatternEditing,
|
|
537
539
|
} = feature;
|
|
538
540
|
const shouldDisplayControls =
|
|
541
|
+
( supportsPatternEditing &&
|
|
542
|
+
context[ mayDisplayPatternEditingControlsKey ] ) ||
|
|
539
543
|
context[ mayDisplayControlsKey ] ||
|
|
540
544
|
( context[ mayDisplayParentControlsKey ] &&
|
|
541
545
|
shareWithChildBlocks );
|
package/src/layouts/flex.js
CHANGED
|
@@ -71,8 +71,11 @@ export default {
|
|
|
71
71
|
onChange,
|
|
72
72
|
layoutBlockSupport = {},
|
|
73
73
|
} ) {
|
|
74
|
-
const {
|
|
75
|
-
|
|
74
|
+
const {
|
|
75
|
+
allowOrientation = true,
|
|
76
|
+
allowJustification = true,
|
|
77
|
+
allowWrap = true,
|
|
78
|
+
} = layoutBlockSupport;
|
|
76
79
|
return (
|
|
77
80
|
<>
|
|
78
81
|
<Flex>
|
|
@@ -93,7 +96,9 @@ export default {
|
|
|
93
96
|
</FlexItem>
|
|
94
97
|
) }
|
|
95
98
|
</Flex>
|
|
96
|
-
|
|
99
|
+
{ allowWrap && (
|
|
100
|
+
<FlexWrapControl layout={ layout } onChange={ onChange } />
|
|
101
|
+
) }
|
|
97
102
|
</>
|
|
98
103
|
);
|
|
99
104
|
},
|
package/src/layouts/test/flex.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Internal dependencies
|
|
3
8
|
*/
|
|
4
9
|
import flex from '../flex';
|
|
5
10
|
|
|
11
|
+
const FlexLayoutInspectorControls = flex.inspectorControls;
|
|
12
|
+
|
|
6
13
|
describe( 'getLayoutStyle', () => {
|
|
7
14
|
it( 'should return an empty string if no non-default params are provided', () => {
|
|
8
15
|
const expected = '';
|
|
@@ -19,3 +26,49 @@ describe( 'getLayoutStyle', () => {
|
|
|
19
26
|
expect( result ).toBe( expected );
|
|
20
27
|
} );
|
|
21
28
|
} );
|
|
29
|
+
|
|
30
|
+
describe( 'FlexLayoutInspectorControls', () => {
|
|
31
|
+
it( 'should render the wrap toggle by default', () => {
|
|
32
|
+
render(
|
|
33
|
+
<FlexLayoutInspectorControls layout={ {} } onChange={ jest.fn() } />
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(
|
|
37
|
+
screen.getByRole( 'checkbox', {
|
|
38
|
+
name: 'Allow to wrap to multiple lines',
|
|
39
|
+
} )
|
|
40
|
+
).toBeInTheDocument();
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
it( 'should render the wrap toggle when allowWrap is true', () => {
|
|
44
|
+
render(
|
|
45
|
+
<FlexLayoutInspectorControls
|
|
46
|
+
layout={ {} }
|
|
47
|
+
onChange={ jest.fn() }
|
|
48
|
+
layoutBlockSupport={ { allowWrap: true } }
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(
|
|
53
|
+
screen.getByRole( 'checkbox', {
|
|
54
|
+
name: 'Allow to wrap to multiple lines',
|
|
55
|
+
} )
|
|
56
|
+
).toBeInTheDocument();
|
|
57
|
+
} );
|
|
58
|
+
|
|
59
|
+
it( 'should not render the wrap toggle when allowWrap is false', () => {
|
|
60
|
+
render(
|
|
61
|
+
<FlexLayoutInspectorControls
|
|
62
|
+
layout={ {} }
|
|
63
|
+
onChange={ jest.fn() }
|
|
64
|
+
layoutBlockSupport={ { allowWrap: false } }
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(
|
|
69
|
+
screen.queryByRole( 'checkbox', {
|
|
70
|
+
name: 'Allow to wrap to multiple lines',
|
|
71
|
+
} )
|
|
72
|
+
).not.toBeInTheDocument();
|
|
73
|
+
} );
|
|
74
|
+
} );
|
|
@@ -38,6 +38,10 @@ import {
|
|
|
38
38
|
isIsolatedEditorKey,
|
|
39
39
|
deviceTypeKey,
|
|
40
40
|
} from './private-keys';
|
|
41
|
+
import {
|
|
42
|
+
BLOCK_VISIBILITY_VIEWPORT_ENTRIES,
|
|
43
|
+
BLOCK_VISIBILITY_VIEWPORTS,
|
|
44
|
+
} from '../components/block-visibility/constants';
|
|
41
45
|
|
|
42
46
|
const { isContentBlock } = unlock( blocksPrivateApis );
|
|
43
47
|
|
|
@@ -730,7 +734,8 @@ export const isBlockHidden = ( state, clientId ) => {
|
|
|
730
734
|
// Only apply when a device is explicitly selected.
|
|
731
735
|
if ( typeof blockVisibility === 'object' && blockVisibility !== null ) {
|
|
732
736
|
const settings = getSettings( state );
|
|
733
|
-
const viewportType =
|
|
737
|
+
const viewportType =
|
|
738
|
+
settings[ deviceTypeKey ] ?? BLOCK_VISIBILITY_VIEWPORTS.desktop.key;
|
|
734
739
|
const viewportKey = viewportType.toLowerCase();
|
|
735
740
|
return blockVisibility?.[ viewportKey ] === false;
|
|
736
741
|
}
|
|
@@ -738,6 +743,64 @@ export const isBlockHidden = ( state, clientId ) => {
|
|
|
738
743
|
return false;
|
|
739
744
|
};
|
|
740
745
|
|
|
746
|
+
/**
|
|
747
|
+
* Returns true if any of the provided blocks are hidden.
|
|
748
|
+
*
|
|
749
|
+
* @param {Object} state Global application state.
|
|
750
|
+
* @param {Array} clientIds Array of block client IDs to check.
|
|
751
|
+
* @return {boolean} Whether any block is hidden.
|
|
752
|
+
*/
|
|
753
|
+
export const areBlocksHidden = ( state, clientIds ) => {
|
|
754
|
+
if ( ! clientIds || clientIds.length === 0 ) {
|
|
755
|
+
return false;
|
|
756
|
+
}
|
|
757
|
+
return clientIds.some( ( clientId ) => isBlockHidden( state, clientId ) );
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Checks if at least one block in an array is hidden according to viewport visibility metadata.
|
|
762
|
+
*
|
|
763
|
+
* This is typically used to determine if the block visibility button should be shown in the toolbar.
|
|
764
|
+
* TODO: This is temporary for now. Later the UI will
|
|
765
|
+
* want to know where exactly the block is hidden, e.g., to display icons or other things.
|
|
766
|
+
*
|
|
767
|
+
* A block is considered hidden if:
|
|
768
|
+
* - Its `blockVisibility` metadata is `false` (hidden everywhere), or
|
|
769
|
+
* - Any viewport is set to `false`
|
|
770
|
+
*
|
|
771
|
+
* @param {Object} state Global application state.
|
|
772
|
+
* @param {Array} clientIds Array of block client IDs to check.
|
|
773
|
+
* @return {boolean} `true` if at least one block meets the visibility criteria, `false` otherwise.
|
|
774
|
+
*/
|
|
775
|
+
export const areBlocksHiddenAnywhere = ( state, clientIds ) => {
|
|
776
|
+
if ( ! clientIds?.length ) {
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
return clientIds.some( ( clientId ) => {
|
|
780
|
+
if ( ! clientId ) {
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
const attributes = state.blocks.attributes.get( clientId );
|
|
785
|
+
const blockVisibility = attributes?.metadata?.blockVisibility;
|
|
786
|
+
|
|
787
|
+
// If explicitly hidden everywhere (false), return true.
|
|
788
|
+
if ( typeof blockVisibility === 'boolean' ) {
|
|
789
|
+
return blockVisibility === false;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// If not an object, block is not hidden in any viewport.
|
|
793
|
+
if ( 'object' !== typeof blockVisibility ) {
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Check viewport-specific visibility.
|
|
798
|
+
return BLOCK_VISIBILITY_VIEWPORT_ENTRIES.some(
|
|
799
|
+
( [ , { key } ] ) => blockVisibility?.[ key ] === false
|
|
800
|
+
);
|
|
801
|
+
} );
|
|
802
|
+
};
|
|
803
|
+
|
|
741
804
|
/**
|
|
742
805
|
* Returns true if there is a spotlighted block.
|
|
743
806
|
*
|