@wordpress/block-library 9.46.0 → 9.48.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 +8 -0
- package/build/button/edit.cjs +7 -4
- package/build/button/edit.cjs.map +3 -3
- package/build/columns/edit.cjs +4 -10
- package/build/columns/edit.cjs.map +2 -2
- package/build/cover/edit/inspector-controls.cjs +20 -6
- package/build/cover/edit/inspector-controls.cjs.map +2 -2
- package/build/freeform/migration-notice.cjs +1 -1
- package/build/freeform/migration-notice.cjs.map +1 -1
- package/build/home-link/block.json +7 -0
- package/build/home-link/edit.cjs +167 -24
- package/build/home-link/edit.cjs.map +3 -3
- package/build/html/edit.cjs +2 -4
- package/build/html/edit.cjs.map +2 -2
- package/build/html/modal.cjs +0 -4
- package/build/html/modal.cjs.map +2 -2
- package/build/image/block.json +4 -0
- package/build/image/deprecated.cjs +202 -4
- package/build/image/deprecated.cjs.map +3 -3
- package/build/image/image.cjs +94 -30
- package/build/image/image.cjs.map +2 -2
- package/build/image/index.cjs +23 -4
- package/build/image/index.cjs.map +2 -2
- package/build/image/save.cjs +25 -10
- package/build/image/save.cjs.map +2 -2
- package/build/image/transforms.cjs +15 -3
- package/build/image/transforms.cjs.map +2 -2
- package/build/image/use-open-image-media-editor-modal.cjs +37 -14
- package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
- package/build/list-item/hooks/use-enter.cjs +8 -4
- package/build/list-item/hooks/use-enter.cjs.map +3 -3
- package/build/list-item/hooks/use-space.cjs +8 -4
- package/build/list-item/hooks/use-space.cjs.map +3 -3
- package/build/navigation-link/edit.cjs +2 -1
- package/build/navigation-link/edit.cjs.map +2 -2
- package/build/navigation-link/shared/use-handle-link-change.cjs +19 -3
- package/build/navigation-link/shared/use-handle-link-change.cjs.map +3 -3
- package/build/navigation-submenu/edit.cjs +8 -22
- package/build/navigation-submenu/edit.cjs.map +2 -2
- package/build/paragraph/use-enter.cjs +8 -4
- package/build/paragraph/use-enter.cjs.map +3 -3
- package/build/post-date/edit.cjs +9 -1
- package/build/post-date/edit.cjs.map +2 -2
- package/build/post-featured-image/edit.cjs +6 -5
- package/build/post-featured-image/edit.cjs.map +2 -2
- package/build/site-logo/edit.cjs +5 -2
- package/build/site-logo/edit.cjs.map +2 -2
- package/build/social-link/edit.cjs.map +3 -3
- package/build/tab-list/edit.cjs +2 -0
- package/build/tab-list/edit.cjs.map +2 -2
- package/build/tab-panels/edit.cjs +5 -1
- package/build/tab-panels/edit.cjs.map +2 -2
- package/build/table/edit.cjs +1 -0
- package/build/table/edit.cjs.map +2 -2
- package/build/tabs/edit.cjs +1 -36
- package/build/tabs/edit.cjs.map +2 -2
- package/build-module/button/edit.mjs +12 -5
- package/build-module/button/edit.mjs.map +2 -2
- package/build-module/columns/edit.mjs +4 -10
- package/build-module/columns/edit.mjs.map +2 -2
- package/build-module/cover/edit/inspector-controls.mjs +20 -7
- package/build-module/cover/edit/inspector-controls.mjs.map +2 -2
- package/build-module/freeform/migration-notice.mjs +1 -1
- package/build-module/freeform/migration-notice.mjs.map +1 -1
- package/build-module/home-link/block.json +7 -0
- package/build-module/home-link/edit.mjs +181 -26
- package/build-module/home-link/edit.mjs.map +2 -2
- package/build-module/html/edit.mjs +2 -4
- package/build-module/html/edit.mjs.map +2 -2
- package/build-module/html/modal.mjs +0 -4
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/image/block.json +4 -0
- package/build-module/image/deprecated.mjs +204 -5
- package/build-module/image/deprecated.mjs.map +2 -2
- package/build-module/image/image.mjs +96 -30
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/image/index.mjs +23 -4
- package/build-module/image/index.mjs.map +2 -2
- package/build-module/image/save.mjs +25 -10
- package/build-module/image/save.mjs.map +2 -2
- package/build-module/image/transforms.mjs +15 -3
- package/build-module/image/transforms.mjs.map +2 -2
- package/build-module/image/use-open-image-media-editor-modal.mjs +37 -14
- package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
- package/build-module/list-item/hooks/use-enter.mjs +12 -5
- package/build-module/list-item/hooks/use-enter.mjs.map +2 -2
- package/build-module/list-item/hooks/use-space.mjs +12 -5
- package/build-module/list-item/hooks/use-space.mjs.map +2 -2
- package/build-module/navigation-link/edit.mjs +2 -1
- package/build-module/navigation-link/edit.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-handle-link-change.mjs +19 -3
- package/build-module/navigation-link/shared/use-handle-link-change.mjs.map +2 -2
- package/build-module/navigation-submenu/edit.mjs +9 -23
- package/build-module/navigation-submenu/edit.mjs.map +2 -2
- package/build-module/paragraph/use-enter.mjs +12 -5
- package/build-module/paragraph/use-enter.mjs.map +2 -2
- package/build-module/post-date/edit.mjs +9 -1
- package/build-module/post-date/edit.mjs.map +2 -2
- package/build-module/post-featured-image/edit.mjs +6 -5
- package/build-module/post-featured-image/edit.mjs.map +2 -2
- package/build-module/site-logo/edit.mjs +6 -2
- package/build-module/site-logo/edit.mjs.map +2 -2
- package/build-module/social-link/edit.mjs +2 -2
- package/build-module/social-link/edit.mjs.map +2 -2
- package/build-module/tab-list/edit.mjs +2 -0
- package/build-module/tab-list/edit.mjs.map +2 -2
- package/build-module/tab-panels/edit.mjs +5 -1
- package/build-module/tab-panels/edit.mjs.map +2 -2
- package/build-module/table/edit.mjs +1 -0
- package/build-module/table/edit.mjs.map +2 -2
- package/build-module/tabs/edit.mjs +2 -37
- package/build-module/tabs/edit.mjs.map +2 -2
- package/build-style/breadcrumbs/style-rtl.css +1 -1
- package/build-style/breadcrumbs/style.css +1 -1
- package/build-style/editor-rtl.css +0 -11
- package/build-style/editor.css +0 -11
- package/build-style/gallery/editor-rtl.css +0 -11
- package/build-style/gallery/editor.css +0 -11
- package/build-style/style-rtl.css +1 -1
- package/build-style/style.css +1 -1
- package/package.json +40 -40
- package/src/block/edit-title.native.js +3 -3
- package/src/block/edit.native.js +2 -2
- package/src/breadcrumbs/style.scss +1 -1
- package/src/button/edit.js +14 -5
- package/src/columns/edit.js +3 -9
- package/src/cover/controls.native.js +2 -2
- package/src/cover/edit/inspector-controls.js +69 -52
- package/src/cover/edit.native.js +6 -4
- package/src/cover/focal-point-settings-button.native.js +2 -2
- package/src/cover/test/edit.js +70 -31
- package/src/embed/embed-no-preview.native.js +7 -3
- package/src/embed/embed-placeholder.native.js +2 -2
- package/src/file/edit.native.js +2 -2
- package/src/freeform/migration-notice.js +1 -1
- package/src/gallery/editor.scss +0 -14
- package/src/home-link/block.json +7 -0
- package/src/home-link/edit.js +185 -22
- package/src/home-link/index.php +14 -2
- package/src/html/edit.js +14 -12
- package/src/html/modal.js +0 -5
- package/src/image/block.json +4 -0
- package/src/image/deprecated.js +236 -4
- package/src/image/edit.native.js +2 -2
- package/src/image/image.js +166 -76
- package/src/image/index.js +20 -1
- package/src/image/index.php +1 -1
- package/src/image/save.js +39 -12
- package/src/image/test/use-open-image-media-editor-modal.js +101 -0
- package/src/image/transforms.js +21 -5
- package/src/image/use-open-image-media-editor-modal.js +41 -17
- package/src/latest-posts/edit.native.js +2 -2
- package/src/list-item/hooks/use-enter.js +15 -5
- package/src/list-item/hooks/use-space.js +15 -5
- package/src/list-item/list-style-type.native.js +2 -2
- package/src/media-text/media-container.native.js +7 -3
- package/src/missing/edit.native.js +4 -4
- package/src/missing/test/edit.native.js +3 -3
- package/src/navigation/test/use-navigation-menu.js +8 -2
- package/src/navigation-link/edit.js +1 -0
- package/src/navigation-link/shared/test/use-handle-link-change.test.js +212 -0
- package/src/navigation-link/shared/use-handle-link-change.js +36 -9
- package/src/navigation-submenu/edit.js +11 -28
- package/src/navigation-submenu/index.php +13 -0
- package/src/paragraph/use-enter.js +19 -5
- package/src/post-date/edit.js +7 -3
- package/src/post-featured-image/edit.js +15 -11
- package/src/search/edit.native.js +2 -2
- package/src/search/test/edit.native.js +2 -2
- package/src/site-logo/edit.js +7 -1
- package/src/social-link/edit.js +2 -2
- package/src/tab-list/edit.js +3 -0
- package/src/tab-panels/edit.js +10 -1
- package/src/table/edit.js +1 -0
- package/src/tabs/edit.js +14 -42
- package/src/video/edit.native.js +3 -3
package/src/image/save.js
CHANGED
|
@@ -37,6 +37,7 @@ export default function save( { attributes } ) {
|
|
|
37
37
|
linkTarget,
|
|
38
38
|
sizeSlug,
|
|
39
39
|
title,
|
|
40
|
+
isDecorative,
|
|
40
41
|
metadata: { bindings = {} } = {},
|
|
41
42
|
} = attributes;
|
|
42
43
|
|
|
@@ -65,19 +66,45 @@ export default function save( { attributes } ) {
|
|
|
65
66
|
src={ url }
|
|
66
67
|
alt={ alt }
|
|
67
68
|
className={ imageClasses || undefined }
|
|
68
|
-
style={ {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
style={ ( () => {
|
|
70
|
+
const style = {
|
|
71
|
+
...borderProps.style,
|
|
72
|
+
...shadowProps.style,
|
|
73
|
+
aspectRatio,
|
|
74
|
+
objectFit: scale,
|
|
75
|
+
objectPosition:
|
|
76
|
+
focalPoint && scale
|
|
77
|
+
? mediaPosition( focalPoint )
|
|
78
|
+
: undefined,
|
|
79
|
+
};
|
|
80
|
+
// Only apply dimension styles when a width or height is provided.
|
|
81
|
+
if ( width !== undefined || height !== undefined ) {
|
|
82
|
+
// Only apply width when explicitly provided.
|
|
83
|
+
if ( width === 'auto' ) {
|
|
84
|
+
style.width = 'auto';
|
|
85
|
+
} else if ( width !== undefined && width !== null ) {
|
|
86
|
+
style.width =
|
|
87
|
+
typeof width === 'number' ? `${ width }px` : width;
|
|
88
|
+
}
|
|
89
|
+
// Force height to auto when unspecified to prevent
|
|
90
|
+
// theme CSS from squishing the image.
|
|
91
|
+
if (
|
|
92
|
+
height === 'auto' ||
|
|
93
|
+
height === undefined ||
|
|
94
|
+
height === null
|
|
95
|
+
) {
|
|
96
|
+
style.height = 'auto';
|
|
97
|
+
} else {
|
|
98
|
+
style.height =
|
|
99
|
+
typeof height === 'number'
|
|
100
|
+
? `${ height }px`
|
|
101
|
+
: height;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return style;
|
|
105
|
+
} )() }
|
|
80
106
|
title={ title }
|
|
107
|
+
role={ isDecorative ? 'none' : undefined }
|
|
81
108
|
/>
|
|
82
109
|
);
|
|
83
110
|
|
|
@@ -111,6 +111,45 @@ describe( 'useOpenImageMediaEditorModal', () => {
|
|
|
111
111
|
jest.clearAllMocks();
|
|
112
112
|
} );
|
|
113
113
|
|
|
114
|
+
it( 'passes an onClose handler for returning focus when the media editor closes', async () => {
|
|
115
|
+
const cropButton = document.createElement( 'button' );
|
|
116
|
+
const otherButton = document.createElement( 'button' );
|
|
117
|
+
document.body.append( cropButton, otherButton );
|
|
118
|
+
const registry = createRegistry();
|
|
119
|
+
useRegistry.mockReturnValue( registry );
|
|
120
|
+
const setAttributes = jest.fn();
|
|
121
|
+
const openMediaEditorModal = jest.fn();
|
|
122
|
+
mockMediaEditorModalSetting( openMediaEditorModal );
|
|
123
|
+
const onClose = () => cropButton.focus();
|
|
124
|
+
const { result } = renderHook( () =>
|
|
125
|
+
useOpenImageMediaEditorModal( {
|
|
126
|
+
attributes: {
|
|
127
|
+
id: 1,
|
|
128
|
+
url: 'original.jpg',
|
|
129
|
+
alt: '',
|
|
130
|
+
caption: '',
|
|
131
|
+
},
|
|
132
|
+
setAttributes,
|
|
133
|
+
onClose,
|
|
134
|
+
} )
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
await act( async () => {
|
|
139
|
+
await result.current();
|
|
140
|
+
} );
|
|
141
|
+
otherButton.focus();
|
|
142
|
+
expect( otherButton ).toHaveFocus();
|
|
143
|
+
|
|
144
|
+
openMediaEditorModal.mock.calls[ 0 ][ 0 ].onClose();
|
|
145
|
+
|
|
146
|
+
expect( cropButton ).toHaveFocus();
|
|
147
|
+
} finally {
|
|
148
|
+
cropButton.remove();
|
|
149
|
+
otherButton.remove();
|
|
150
|
+
}
|
|
151
|
+
} );
|
|
152
|
+
|
|
114
153
|
it( 'resolves fresh attachment metadata when the same attachment id has a stale cache', async () => {
|
|
115
154
|
const originalAttachment = {
|
|
116
155
|
id: 1,
|
|
@@ -187,6 +226,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
|
|
|
187
226
|
expect( openMediaEditorModal ).toHaveBeenCalledWith( {
|
|
188
227
|
id: 1,
|
|
189
228
|
onUpdate: expect.any( Function ),
|
|
229
|
+
onClose: undefined,
|
|
190
230
|
} );
|
|
191
231
|
expect( setAttributes ).toHaveBeenCalledWith( {
|
|
192
232
|
alt: 'Updated alt',
|
|
@@ -229,6 +269,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
|
|
|
229
269
|
expect( openMediaEditorModal ).toHaveBeenCalledWith( {
|
|
230
270
|
id: 1,
|
|
231
271
|
onUpdate: expect.any( Function ),
|
|
272
|
+
onClose: undefined,
|
|
232
273
|
} );
|
|
233
274
|
expect( setAttributes ).toHaveBeenCalledWith( {
|
|
234
275
|
caption: 'Updated attachment caption',
|
|
@@ -317,6 +358,66 @@ describe( 'useOpenImageMediaEditorModal', () => {
|
|
|
317
358
|
} );
|
|
318
359
|
} );
|
|
319
360
|
|
|
361
|
+
it( 'updates back to the previous attachment from the original modal callback', async () => {
|
|
362
|
+
const originalAttachment = {
|
|
363
|
+
id: 1,
|
|
364
|
+
alt_text: '',
|
|
365
|
+
caption: { raw: '' },
|
|
366
|
+
};
|
|
367
|
+
const croppedAttachment = {
|
|
368
|
+
id: 2,
|
|
369
|
+
alt_text: '',
|
|
370
|
+
caption: { raw: '' },
|
|
371
|
+
};
|
|
372
|
+
const deferredAttachment = createDeferred();
|
|
373
|
+
const registry = createRegistry( {
|
|
374
|
+
getEntityRecord: ( kind, name, attachmentId ) =>
|
|
375
|
+
attachmentId === 1 ? originalAttachment : undefined,
|
|
376
|
+
resolveGetEntityRecord: ( kind, name, attachmentId ) =>
|
|
377
|
+
attachmentId === 2 ? deferredAttachment.promise : undefined,
|
|
378
|
+
} );
|
|
379
|
+
useRegistry.mockReturnValue( registry );
|
|
380
|
+
const setAttributes = jest.fn();
|
|
381
|
+
const openMediaEditorModal = jest.fn();
|
|
382
|
+
mockMediaEditorModalSetting( openMediaEditorModal );
|
|
383
|
+
const { result } = renderHook(
|
|
384
|
+
( { attributes } ) =>
|
|
385
|
+
useOpenImageMediaEditorModal( { attributes, setAttributes } ),
|
|
386
|
+
{
|
|
387
|
+
initialProps: {
|
|
388
|
+
attributes: {
|
|
389
|
+
id: 1,
|
|
390
|
+
url: 'original.jpg',
|
|
391
|
+
alt: '',
|
|
392
|
+
caption: '',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
await act( async () => {
|
|
399
|
+
await result.current();
|
|
400
|
+
} );
|
|
401
|
+
const onUpdate = openMediaEditorModal.mock.calls[ 0 ][ 0 ].onUpdate;
|
|
402
|
+
let updatePromise;
|
|
403
|
+
await act( async () => {
|
|
404
|
+
updatePromise = onUpdate( { id: 2, url: 'cropped.jpg' } );
|
|
405
|
+
} );
|
|
406
|
+
await act( async () => {
|
|
407
|
+
await onUpdate( { id: 1, url: 'original.jpg' } );
|
|
408
|
+
} );
|
|
409
|
+
await act( async () => {
|
|
410
|
+
deferredAttachment.resolve( croppedAttachment );
|
|
411
|
+
await updatePromise;
|
|
412
|
+
} );
|
|
413
|
+
|
|
414
|
+
expect( setAttributes ).toHaveBeenCalledTimes( 1 );
|
|
415
|
+
expect( setAttributes ).toHaveBeenCalledWith( {
|
|
416
|
+
id: 1,
|
|
417
|
+
url: 'original.jpg',
|
|
418
|
+
} );
|
|
419
|
+
} );
|
|
420
|
+
|
|
320
421
|
it( 'resolves fresh metadata when the new attachment id has an incomplete cached record', async () => {
|
|
321
422
|
const originalAttachment = {
|
|
322
423
|
id: 1,
|
package/src/image/transforms.js
CHANGED
|
@@ -41,7 +41,7 @@ function getFirstAnchorAttributeFormHTML( html, attributeName ) {
|
|
|
41
41
|
|
|
42
42
|
const imageSchema = {
|
|
43
43
|
img: {
|
|
44
|
-
attributes: [ 'src', 'alt', 'title' ],
|
|
44
|
+
attributes: [ 'src', 'alt', 'title', 'width', 'height' ],
|
|
45
45
|
classes: [
|
|
46
46
|
'alignleft',
|
|
47
47
|
'aligncenter',
|
|
@@ -52,6 +52,14 @@ const imageSchema = {
|
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
+
// Read a pixel dimension from an `<img>` HTML attribute and normalise it to
|
|
56
|
+
// the `<value>px` form the Image block stores in its `width` / `height`
|
|
57
|
+
// attributes. Non-integer values (e.g. `50%`) are dropped because the block
|
|
58
|
+
// attribute round-trips through inline styles that expect pixel units.
|
|
59
|
+
function parsePixelDimension( value ) {
|
|
60
|
+
return value && /^\d+$/.test( value ) ? `${ value }px` : undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
const schema = ( { phrasingContentSchema } ) => ( {
|
|
56
64
|
figure: {
|
|
57
65
|
require: [ 'img' ],
|
|
@@ -77,12 +85,10 @@ const transforms = {
|
|
|
77
85
|
node.nodeName === 'FIGURE' && !! node.querySelector( 'img' ),
|
|
78
86
|
schema,
|
|
79
87
|
transform: ( node ) => {
|
|
88
|
+
const img = node.querySelector( 'img' );
|
|
80
89
|
// Search both figure and image classes. Alignment could be
|
|
81
90
|
// set on either. ID is set on the image.
|
|
82
|
-
const className =
|
|
83
|
-
node.className +
|
|
84
|
-
' ' +
|
|
85
|
-
node.querySelector( 'img' ).className;
|
|
91
|
+
const className = node.className + ' ' + img.className;
|
|
86
92
|
const alignMatches =
|
|
87
93
|
/(?:^|\s)align(left|center|right)(?:$|\s)/.exec(
|
|
88
94
|
className
|
|
@@ -108,6 +114,14 @@ const transforms = {
|
|
|
108
114
|
anchorElement && anchorElement.className
|
|
109
115
|
? anchorElement.className
|
|
110
116
|
: undefined;
|
|
117
|
+
// Preserve explicit pixel dimensions set on the source `<img>`
|
|
118
|
+
// (e.g. legacy "Add Media" output: `<img width="77" height="77">`).
|
|
119
|
+
const width = parsePixelDimension(
|
|
120
|
+
img.getAttribute( 'width' )
|
|
121
|
+
);
|
|
122
|
+
const height = parsePixelDimension(
|
|
123
|
+
img.getAttribute( 'height' )
|
|
124
|
+
);
|
|
111
125
|
const attributes = getBlockAttributes(
|
|
112
126
|
'core/image',
|
|
113
127
|
node.outerHTML,
|
|
@@ -119,6 +133,8 @@ const transforms = {
|
|
|
119
133
|
rel,
|
|
120
134
|
linkClass,
|
|
121
135
|
anchor,
|
|
136
|
+
width,
|
|
137
|
+
height,
|
|
122
138
|
}
|
|
123
139
|
);
|
|
124
140
|
|
|
@@ -136,7 +136,11 @@ function hasKnownAttachmentMetadata( attachment ) {
|
|
|
136
136
|
return hasKnownAlt && hasKnownCaption;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
export function useOpenImageMediaEditorModal( {
|
|
139
|
+
export function useOpenImageMediaEditorModal( {
|
|
140
|
+
attributes,
|
|
141
|
+
setAttributes,
|
|
142
|
+
onClose,
|
|
143
|
+
} ) {
|
|
140
144
|
// Keep this hook private to the Image block and pass the block attributes
|
|
141
145
|
// object so the callsite stays compact. Destructure only the attributes
|
|
142
146
|
// currently used for metadata sync; add more here if the sync policy grows.
|
|
@@ -147,11 +151,16 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
147
151
|
select( blockEditorStore ).getSettings()[ openMediaEditorModalKey ],
|
|
148
152
|
[]
|
|
149
153
|
);
|
|
150
|
-
// Track the block's current
|
|
151
|
-
// can read the latest values without being listed as
|
|
152
|
-
// would recreate the callback and re-register the
|
|
153
|
-
//
|
|
154
|
-
const
|
|
154
|
+
// Track the block's current attachment and metadata in a ref so
|
|
155
|
+
// handleMediaUpdate can read the latest values without being listed as
|
|
156
|
+
// dependencies (which would recreate the callback and re-register the
|
|
157
|
+
// onUpdate handler on every block change while the modal is open).
|
|
158
|
+
const blockAttributesRef = useRef( {
|
|
159
|
+
id,
|
|
160
|
+
url,
|
|
161
|
+
alt,
|
|
162
|
+
caption: caption?.toString(),
|
|
163
|
+
} );
|
|
155
164
|
// Snapshot of the attachment's metadata taken just before the modal opens,
|
|
156
165
|
// used as the baseline for detecting what changed during the editing session.
|
|
157
166
|
const mediaEditorMetadataBaselineRef = useRef();
|
|
@@ -160,8 +169,13 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
160
169
|
const mediaEditorMetadataSyncRequestRef = useRef( 0 );
|
|
161
170
|
|
|
162
171
|
useEffect( () => {
|
|
163
|
-
|
|
164
|
-
|
|
172
|
+
blockAttributesRef.current = {
|
|
173
|
+
id,
|
|
174
|
+
url,
|
|
175
|
+
alt,
|
|
176
|
+
caption: caption?.toString(),
|
|
177
|
+
};
|
|
178
|
+
}, [ alt, caption, id, url ] );
|
|
165
179
|
|
|
166
180
|
const getCachedAttachmentRecord = useCallback(
|
|
167
181
|
( attachmentId ) => {
|
|
@@ -245,9 +259,16 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
245
259
|
const syncRequest = ++mediaEditorMetadataSyncRequestRef.current;
|
|
246
260
|
const nextAttributes = {};
|
|
247
261
|
|
|
248
|
-
|
|
262
|
+
const currentBlockAttributes = blockAttributesRef.current;
|
|
263
|
+
|
|
264
|
+
if ( newId !== currentBlockAttributes.id ) {
|
|
249
265
|
nextAttributes.id = newId;
|
|
250
|
-
nextAttributes.url = newUrl ?? url;
|
|
266
|
+
nextAttributes.url = newUrl ?? currentBlockAttributes.url;
|
|
267
|
+
blockAttributesRef.current = {
|
|
268
|
+
...blockAttributesRef.current,
|
|
269
|
+
id: nextAttributes.id,
|
|
270
|
+
url: nextAttributes.url,
|
|
271
|
+
};
|
|
251
272
|
}
|
|
252
273
|
|
|
253
274
|
if ( originalAttachment ) {
|
|
@@ -270,27 +291,28 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
270
291
|
// has independently customised on the block (i.e. values
|
|
271
292
|
// that don't match the pre-session attachment metadata)
|
|
272
293
|
// are left untouched.
|
|
294
|
+
const latestBlockAttributes = blockAttributesRef.current;
|
|
273
295
|
const resolvedMetadataAttributes =
|
|
274
296
|
getSyncedImageBlockAttributes(
|
|
275
|
-
|
|
297
|
+
latestBlockAttributes,
|
|
276
298
|
originalAttachment,
|
|
277
299
|
resolvedAttachment
|
|
278
300
|
);
|
|
279
301
|
|
|
280
302
|
if ( Object.keys( resolvedMetadataAttributes ).length ) {
|
|
281
303
|
Object.assign( nextAttributes, resolvedMetadataAttributes );
|
|
282
|
-
blockMetadataRef.current = {
|
|
283
|
-
...blockMetadataRef.current,
|
|
284
|
-
...resolvedMetadataAttributes,
|
|
285
|
-
};
|
|
286
304
|
}
|
|
287
305
|
}
|
|
288
306
|
|
|
289
307
|
if ( Object.keys( nextAttributes ).length ) {
|
|
308
|
+
blockAttributesRef.current = {
|
|
309
|
+
...blockAttributesRef.current,
|
|
310
|
+
...nextAttributes,
|
|
311
|
+
};
|
|
290
312
|
setAttributes( nextAttributes );
|
|
291
313
|
}
|
|
292
314
|
},
|
|
293
|
-
[
|
|
315
|
+
[ resolveFreshAttachmentRecord, setAttributes ]
|
|
294
316
|
);
|
|
295
317
|
|
|
296
318
|
const openImageMediaEditorModal = useCallback( async () => {
|
|
@@ -306,7 +328,7 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
306
328
|
const cachedAttachmentRecord = getCachedAttachmentRecord( id );
|
|
307
329
|
const fallbackAttachmentRecord =
|
|
308
330
|
getAttachmentFallbackForEmptyBlockMetadata(
|
|
309
|
-
|
|
331
|
+
blockAttributesRef.current
|
|
310
332
|
);
|
|
311
333
|
const resolvedAttachmentRecord = hasKnownAttachmentMetadata(
|
|
312
334
|
cachedAttachmentRecord
|
|
@@ -324,11 +346,13 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
|
|
|
324
346
|
openMediaEditorModal( {
|
|
325
347
|
id,
|
|
326
348
|
onUpdate: handleMediaUpdate,
|
|
349
|
+
onClose,
|
|
327
350
|
} );
|
|
328
351
|
}, [
|
|
329
352
|
getCachedAttachmentRecord,
|
|
330
353
|
handleMediaUpdate,
|
|
331
354
|
id,
|
|
355
|
+
onClose,
|
|
332
356
|
openMediaEditorModal,
|
|
333
357
|
resolveAttachmentRecord,
|
|
334
358
|
] );
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from '@wordpress/block-editor';
|
|
18
18
|
import apiFetch from '@wordpress/api-fetch';
|
|
19
19
|
import {
|
|
20
|
-
Icon,
|
|
20
|
+
Icon as WCIcon,
|
|
21
21
|
PanelBody,
|
|
22
22
|
ToggleControl,
|
|
23
23
|
RangeControl,
|
|
@@ -265,7 +265,7 @@ class LatestPostsEdit extends Component {
|
|
|
265
265
|
>
|
|
266
266
|
<View style={ blockStyle }>
|
|
267
267
|
{ isSelected && this.getInspectorControls() }
|
|
268
|
-
<
|
|
268
|
+
<WCIcon icon={ icon } { ...iconStyle } />
|
|
269
269
|
<Text style={ titleStyle }>{ blockTitle }</Text>
|
|
270
270
|
<Text style={ styles.latestPostBlockSubtitle }>
|
|
271
271
|
{ __( 'CUSTOMIZE' ) }
|
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
cloneBlock,
|
|
8
8
|
} from '@wordpress/blocks';
|
|
9
9
|
import { useRef } from '@wordpress/element';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
useRefEffect,
|
|
12
|
+
privateApis as composePrivateApis,
|
|
13
|
+
} from '@wordpress/compose';
|
|
11
14
|
import { ENTER } from '@wordpress/keycodes';
|
|
12
15
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
13
16
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
@@ -16,6 +19,9 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
|
16
19
|
* Internal dependencies
|
|
17
20
|
*/
|
|
18
21
|
import useOutdentListItem from './use-outdent-list-item';
|
|
22
|
+
import { unlock } from '../../lock-unlock';
|
|
23
|
+
|
|
24
|
+
const { subscribeDelegatedListener } = unlock( composePrivateApis );
|
|
19
25
|
|
|
20
26
|
export default function useEnter( props ) {
|
|
21
27
|
const { replaceBlocks, selectionChange } = useDispatch( blockEditorStore );
|
|
@@ -82,9 +88,13 @@ export default function useEnter( props ) {
|
|
|
82
88
|
selectionChange( middle.clientId );
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
// Capture phase so we run before writing-flow's ancestor-bubble
|
|
92
|
+
// keydown handlers that gate on `event.defaultPrevented`.
|
|
93
|
+
return subscribeDelegatedListener(
|
|
94
|
+
element,
|
|
95
|
+
'keydown',
|
|
96
|
+
onKeyDown,
|
|
97
|
+
true
|
|
98
|
+
);
|
|
89
99
|
}, [] );
|
|
90
100
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useRefEffect,
|
|
6
|
+
privateApis as composePrivateApis,
|
|
7
|
+
} from '@wordpress/compose';
|
|
5
8
|
import { SPACE, TAB } from '@wordpress/keycodes';
|
|
6
9
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
10
|
import { useSelect } from '@wordpress/data';
|
|
@@ -11,6 +14,9 @@ import { useSelect } from '@wordpress/data';
|
|
|
11
14
|
*/
|
|
12
15
|
import useIndentListItem from './use-indent-list-item';
|
|
13
16
|
import useOutdentListItem from './use-outdent-list-item';
|
|
17
|
+
import { unlock } from '../../lock-unlock';
|
|
18
|
+
|
|
19
|
+
const { subscribeDelegatedListener } = unlock( composePrivateApis );
|
|
14
20
|
|
|
15
21
|
export default function useSpace( clientId ) {
|
|
16
22
|
const { getSelectionStart, getSelectionEnd, getBlockIndex } =
|
|
@@ -55,10 +61,14 @@ export default function useSpace( clientId ) {
|
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
// Capture phase so we run before writing-flow's ancestor-bubble
|
|
65
|
+
// keydown handlers that gate on `event.defaultPrevented`.
|
|
66
|
+
return subscribeDelegatedListener(
|
|
67
|
+
element,
|
|
68
|
+
'keydown',
|
|
69
|
+
onKeyDown,
|
|
70
|
+
true
|
|
71
|
+
);
|
|
62
72
|
},
|
|
63
73
|
[ clientId, indentListItem ]
|
|
64
74
|
);
|
|
@@ -6,7 +6,7 @@ import { View, Text } from 'react-native';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import { Icon } from '@wordpress/components';
|
|
9
|
+
import { Icon as WCIcon } from '@wordpress/components';
|
|
10
10
|
import { Platform } from '@wordpress/element';
|
|
11
11
|
import { usePreferredColorSchemeStyle } from '@wordpress/compose';
|
|
12
12
|
|
|
@@ -85,7 +85,7 @@ function IconList( { fontSize, color, defaultFontSize, indentationLevel } ) {
|
|
|
85
85
|
|
|
86
86
|
return (
|
|
87
87
|
<View style={ listStyles }>
|
|
88
|
-
<
|
|
88
|
+
<WCIcon icon={ listIcon } size={ iconSize } />
|
|
89
89
|
</View>
|
|
90
90
|
);
|
|
91
91
|
}
|
|
@@ -12,7 +12,11 @@ import {
|
|
|
12
12
|
requestImageUploadCancelDialog,
|
|
13
13
|
requestImageFullscreenPreview,
|
|
14
14
|
} from '@wordpress/react-native-bridge';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
Icon as WCIcon,
|
|
17
|
+
Image,
|
|
18
|
+
IMAGE_DEFAULT_FOCAL_POINT,
|
|
19
|
+
} from '@wordpress/components';
|
|
16
20
|
import {
|
|
17
21
|
MEDIA_TYPE_IMAGE,
|
|
18
22
|
MEDIA_TYPE_VIDEO,
|
|
@@ -117,7 +121,7 @@ class MediaContainer extends Component {
|
|
|
117
121
|
styles.iconRetryVideoDark
|
|
118
122
|
);
|
|
119
123
|
|
|
120
|
-
return <
|
|
124
|
+
return <WCIcon icon={ SvgIconRetry } { ...iconStyle } />;
|
|
121
125
|
case ICON_TYPE.PLACEHOLDER:
|
|
122
126
|
iconStyle = getStylesFromColorScheme(
|
|
123
127
|
styles.iconPlaceholder,
|
|
@@ -125,7 +129,7 @@ class MediaContainer extends Component {
|
|
|
125
129
|
);
|
|
126
130
|
break;
|
|
127
131
|
}
|
|
128
|
-
return <
|
|
132
|
+
return <WCIcon icon={ icon } { ...iconStyle } />;
|
|
129
133
|
}
|
|
130
134
|
|
|
131
135
|
updateMediaProgress( payload ) {
|
|
@@ -6,9 +6,8 @@ import { View, Text, TouchableOpacity } from 'react-native';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import { Icon } from '@wordpress/components';
|
|
9
|
+
import { Icon as WCIcon } from '@wordpress/components';
|
|
10
10
|
import { compose, withPreferredColorScheme } from '@wordpress/compose';
|
|
11
|
-
import { coreBlocks } from '@wordpress/block-library';
|
|
12
11
|
import { normalizeIconObject, rawHandler, serialize } from '@wordpress/blocks';
|
|
13
12
|
import { Component } from '@wordpress/element';
|
|
14
13
|
import { __, _x, sprintf } from '@wordpress/i18n';
|
|
@@ -21,6 +20,7 @@ import {
|
|
|
21
20
|
} from '@wordpress/block-editor';
|
|
22
21
|
import { store as noticesStore } from '@wordpress/notices';
|
|
23
22
|
import { requestUnsupportedBlockFallback } from '@wordpress/react-native-bridge';
|
|
23
|
+
import { coreBlocks } from '@wordpress/block-library';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Internal dependencies
|
|
@@ -116,7 +116,7 @@ export class UnsupportedBlockEdit extends Component {
|
|
|
116
116
|
accessibilityRole="button"
|
|
117
117
|
accessibilityHint={ __( 'Tap here to show help' ) }
|
|
118
118
|
>
|
|
119
|
-
<
|
|
119
|
+
<WCIcon
|
|
120
120
|
className="unsupported-icon-help"
|
|
121
121
|
label={ __( 'Help icon' ) }
|
|
122
122
|
icon={ help }
|
|
@@ -245,7 +245,7 @@ export class UnsupportedBlockEdit extends Component {
|
|
|
245
245
|
{ ! this.canEditUnsupportedBlock() &&
|
|
246
246
|
this.renderHelpIcon() }
|
|
247
247
|
<View style={ styles.unsupportedBlockHeader }>
|
|
248
|
-
<
|
|
248
|
+
<WCIcon
|
|
249
249
|
className={ iconClassName }
|
|
250
250
|
icon={ icon && icon.src ? icon.src : icon }
|
|
251
251
|
fill={ iconStyle.color }
|
|
@@ -7,7 +7,7 @@ import { Text } from 'react-native';
|
|
|
7
7
|
/**
|
|
8
8
|
* WordPress dependencies
|
|
9
9
|
*/
|
|
10
|
-
import { BottomSheet, Icon } from '@wordpress/components';
|
|
10
|
+
import { BottomSheet, Icon as WCIcon } from '@wordpress/components';
|
|
11
11
|
import { help, plugins } from '@wordpress/icons';
|
|
12
12
|
import { storeConfig } from '@wordpress/block-editor';
|
|
13
13
|
jest.mock( '@wordpress/block-editor/src/store/selectors' );
|
|
@@ -39,7 +39,7 @@ describe( 'Missing block', () => {
|
|
|
39
39
|
describe( 'help modal', () => {
|
|
40
40
|
it( 'renders help icon', () => {
|
|
41
41
|
const testInstance = getTestComponentWithContent();
|
|
42
|
-
const icons = testInstance.UNSAFE_getAllByType(
|
|
42
|
+
const icons = testInstance.UNSAFE_getAllByType( WCIcon );
|
|
43
43
|
expect( icons.length ).toBe( 2 );
|
|
44
44
|
expect( icons[ 0 ].props.icon ).toBe( help );
|
|
45
45
|
} );
|
|
@@ -66,7 +66,7 @@ describe( 'Missing block', () => {
|
|
|
66
66
|
|
|
67
67
|
it( 'renders admin plugins icon', () => {
|
|
68
68
|
const testInstance = getTestComponentWithContent();
|
|
69
|
-
const icons = testInstance.UNSAFE_getAllByType(
|
|
69
|
+
const icons = testInstance.UNSAFE_getAllByType( WCIcon );
|
|
70
70
|
expect( icons.length ).toBe( 2 );
|
|
71
71
|
expect( icons[ 1 ].props.icon ).toBe( plugins );
|
|
72
72
|
} );
|
|
@@ -70,8 +70,14 @@ function resolveRecords( registry, menus ) {
|
|
|
70
70
|
function resolveReadPermission( registry, allowed ) {
|
|
71
71
|
const dispatch = registry.dispatch( coreStore );
|
|
72
72
|
dispatch.receiveUserPermission( 'read/postType/wp_navigation', allowed );
|
|
73
|
-
dispatch.startResolution( 'canUser', [
|
|
74
|
-
|
|
73
|
+
dispatch.startResolution( 'canUser', [
|
|
74
|
+
'read',
|
|
75
|
+
{ kind: 'postType', name: 'wp_navigation' },
|
|
76
|
+
] );
|
|
77
|
+
dispatch.finishResolution( 'canUser', [
|
|
78
|
+
'read',
|
|
79
|
+
{ kind: 'postType', name: 'wp_navigation' },
|
|
80
|
+
] );
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
function resolveReadRecordPermission( registry, ref, allowed ) {
|