@wordpress/editor 14.50.0 → 14.51.1-next.v.202607070741.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 +10 -0
- package/build/components/collab-sidebar/format.cjs +83 -0
- package/build/components/collab-sidebar/format.cjs.map +7 -0
- package/build/components/collab-sidebar/hooks.cjs +117 -16
- package/build/components/collab-sidebar/hooks.cjs.map +2 -2
- package/build/components/collab-sidebar/index.cjs +18 -2
- package/build/components/collab-sidebar/index.cjs.map +2 -2
- package/build/components/collab-sidebar/note-highlight-styles.cjs +67 -0
- package/build/components/collab-sidebar/note-highlight-styles.cjs.map +7 -0
- package/build/components/collab-sidebar/utils.cjs +139 -0
- package/build/components/collab-sidebar/utils.cjs.map +2 -2
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs +55 -30
- package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +2 -2
- package/build/components/commands/index.cjs +99 -3
- package/build/components/commands/index.cjs.map +2 -2
- package/build/components/document-bar/index.cjs +28 -34
- package/build/components/document-bar/index.cjs.map +2 -2
- package/build/components/entities-saved-states/index.cjs +1 -4
- package/build/components/entities-saved-states/index.cjs.map +2 -2
- package/build/components/media-categories/index.cjs +92 -6
- package/build/components/media-categories/index.cjs.map +2 -2
- package/build/components/page-attributes/parent.cjs +0 -1
- package/build/components/page-attributes/parent.cjs.map +2 -2
- package/build/components/post-author/combobox.cjs +0 -1
- package/build/components/post-author/combobox.cjs.map +2 -2
- package/build/components/post-author/select.cjs +0 -1
- package/build/components/post-author/select.cjs.map +2 -2
- package/build/components/post-preview-button/index.cjs +29 -2
- package/build/components/post-preview-button/index.cjs.map +2 -2
- package/build/components/post-publish-panel/maybe-upload-media.cjs +15 -26
- package/build/components/post-publish-panel/maybe-upload-media.cjs.map +3 -3
- package/build/components/post-revisions-preview/revisions-slider.cjs +3 -1
- package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
- package/build/components/post-taxonomies/flat-term-selector.cjs +0 -1
- package/build/components/post-taxonomies/flat-term-selector.cjs.map +2 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs +0 -2
- package/build/components/post-taxonomies/hierarchical-term-selector.cjs.map +2 -2
- package/build/components/post-template/classic-theme.cjs +0 -1
- package/build/components/post-template/classic-theme.cjs.map +2 -2
- package/build/components/preferences-modal/index.cjs +54 -28
- package/build/components/preferences-modal/index.cjs.map +2 -2
- package/build/components/preview-dropdown/index.cjs +3 -3
- package/build/components/preview-dropdown/index.cjs.map +2 -2
- package/build/components/provider/use-block-editor-settings.cjs +23 -3
- package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
- package/build/components/sidebar/dataform-post-summary.cjs +5 -1
- package/build/components/sidebar/dataform-post-summary.cjs.map +3 -3
- package/build/components/sidebar/index.cjs +29 -38
- package/build/components/sidebar/index.cjs.map +3 -3
- package/build/components/sidebar/post-summary.cjs +0 -13
- package/build/components/sidebar/post-summary.cjs.map +3 -3
- package/build/dataviews/store/private-actions.cjs +24 -19
- package/build/dataviews/store/private-actions.cjs.map +2 -2
- package/build/store/private-actions.cjs +5 -2
- package/build/store/private-actions.cjs.map +2 -2
- package/build/utils/media-sideload-from-url/index.cjs +63 -0
- package/build/utils/media-sideload-from-url/index.cjs.map +7 -0
- package/build-module/components/collab-sidebar/format.mjs +57 -0
- package/build-module/components/collab-sidebar/format.mjs.map +7 -0
- package/build-module/components/collab-sidebar/hooks.mjs +121 -16
- package/build-module/components/collab-sidebar/hooks.mjs.map +2 -2
- package/build-module/components/collab-sidebar/index.mjs +21 -5
- package/build-module/components/collab-sidebar/index.mjs.map +2 -2
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs +41 -0
- package/build-module/components/collab-sidebar/note-highlight-styles.mjs.map +7 -0
- package/build-module/components/collab-sidebar/utils.mjs +133 -0
- package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +55 -30
- package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
- package/build-module/components/commands/index.mjs +99 -3
- package/build-module/components/commands/index.mjs.map +2 -2
- package/build-module/components/document-bar/index.mjs +28 -34
- package/build-module/components/document-bar/index.mjs.map +2 -2
- package/build-module/components/entities-saved-states/index.mjs +1 -4
- package/build-module/components/entities-saved-states/index.mjs.map +2 -2
- package/build-module/components/media-categories/index.mjs +93 -7
- package/build-module/components/media-categories/index.mjs.map +2 -2
- package/build-module/components/page-attributes/parent.mjs +0 -1
- package/build-module/components/page-attributes/parent.mjs.map +2 -2
- package/build-module/components/post-author/combobox.mjs +0 -1
- package/build-module/components/post-author/combobox.mjs.map +2 -2
- package/build-module/components/post-author/select.mjs +0 -1
- package/build-module/components/post-author/select.mjs.map +2 -2
- package/build-module/components/post-preview-button/index.mjs +29 -2
- package/build-module/components/post-preview-button/index.mjs.map +2 -2
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs +19 -27
- package/build-module/components/post-publish-panel/maybe-upload-media.mjs.map +2 -2
- package/build-module/components/post-revisions-preview/revisions-slider.mjs +3 -1
- package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
- package/build-module/components/post-taxonomies/flat-term-selector.mjs +0 -1
- package/build-module/components/post-taxonomies/flat-term-selector.mjs.map +2 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs +0 -2
- package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs.map +2 -2
- package/build-module/components/post-template/classic-theme.mjs +0 -1
- package/build-module/components/post-template/classic-theme.mjs.map +2 -2
- package/build-module/components/preferences-modal/index.mjs +54 -28
- package/build-module/components/preferences-modal/index.mjs.map +2 -2
- package/build-module/components/preview-dropdown/index.mjs +3 -3
- package/build-module/components/preview-dropdown/index.mjs.map +2 -2
- package/build-module/components/provider/use-block-editor-settings.mjs +23 -3
- package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs +6 -2
- package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
- package/build-module/components/sidebar/index.mjs +29 -42
- package/build-module/components/sidebar/index.mjs.map +2 -2
- package/build-module/components/sidebar/post-summary.mjs +0 -13
- package/build-module/components/sidebar/post-summary.mjs.map +2 -2
- package/build-module/dataviews/store/private-actions.mjs +26 -19
- package/build-module/dataviews/store/private-actions.mjs.map +2 -2
- package/build-module/store/private-actions.mjs +5 -2
- package/build-module/store/private-actions.mjs.map +2 -2
- package/build-module/utils/media-sideload-from-url/index.mjs +32 -0
- package/build-module/utils/media-sideload-from-url/index.mjs.map +7 -0
- package/build-style/style-rtl.css +65 -33
- package/build-style/style.css +65 -33
- package/build-types/components/collab-sidebar/format.d.ts +17 -0
- package/build-types/components/collab-sidebar/format.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts +31 -0
- package/build-types/components/collab-sidebar/note-highlight-styles.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/utils.d.ts +82 -2
- package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
- package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
- package/build-types/components/commands/index.d.ts.map +1 -1
- package/build-types/components/document-bar/index.d.ts.map +1 -1
- package/build-types/components/entities-saved-states/index.d.ts.map +1 -1
- package/build-types/components/media-categories/index.d.ts +12 -3
- package/build-types/components/media-categories/index.d.ts.map +1 -1
- package/build-types/components/page-attributes/parent.d.ts.map +1 -1
- package/build-types/components/post-author/combobox.d.ts.map +1 -1
- package/build-types/components/post-author/select.d.ts.map +1 -1
- package/build-types/components/post-preview-button/index.d.ts.map +1 -1
- package/build-types/components/post-publish-panel/maybe-upload-media.d.ts.map +1 -1
- package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/flat-term-selector.d.ts.map +1 -1
- package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts.map +1 -1
- package/build-types/components/post-template/classic-theme.d.ts.map +1 -1
- package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
- package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
- package/build-types/components/sidebar/index.d.ts.map +1 -1
- package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
- package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
- package/build-types/store/private-actions.d.ts.map +1 -1
- package/build-types/store/selectors.d.ts.map +1 -1
- package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
- package/build-types/utils/media-sideload-from-url/index.d.ts +18 -0
- package/build-types/utils/media-sideload-from-url/index.d.ts.map +1 -0
- package/package.json +48 -46
- package/src/components/collab-sidebar/format.js +72 -0
- package/src/components/collab-sidebar/hooks.js +203 -22
- package/src/components/collab-sidebar/index.js +19 -5
- package/src/components/collab-sidebar/note-highlight-styles.js +83 -0
- package/src/components/collab-sidebar/style.scss +9 -0
- package/src/components/collab-sidebar/test/note-highlight-styles.js +106 -0
- package/src/components/collab-sidebar/test/utils.js +471 -0
- package/src/components/collab-sidebar/utils.js +225 -2
- package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +265 -262
- package/src/components/collaborators-presence/use-collaborator-notifications.ts +70 -34
- package/src/components/commands/index.js +142 -0
- package/src/components/document-bar/index.js +0 -9
- package/src/components/document-bar/style.scss +0 -17
- package/src/components/entities-saved-states/index.js +1 -5
- package/src/components/header/style.scss +7 -3
- package/src/components/media-categories/index.js +160 -6
- package/src/components/media-categories/test/index.js +202 -0
- package/src/components/page-attributes/parent.js +0 -1
- package/src/components/post-author/combobox.js +0 -1
- package/src/components/post-author/select.js +0 -1
- package/src/components/post-preview-button/index.js +68 -2
- package/src/components/post-publish-panel/maybe-upload-media.js +25 -30
- package/src/components/post-publish-panel/style.scss +1 -1
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +11 -127
- package/src/components/post-revisions-preview/revisions-slider.js +4 -1
- package/src/components/post-revisions-preview/test/block-diff.js +2 -2
- package/src/components/post-taxonomies/flat-term-selector.js +0 -1
- package/src/components/post-taxonomies/hierarchical-term-selector.js +0 -2
- package/src/components/post-template/classic-theme.js +0 -1
- package/src/components/preferences-modal/index.js +40 -22
- package/src/components/preferences-modal/test/index.js +83 -0
- package/src/components/preview-dropdown/index.js +3 -3
- package/src/components/provider/use-block-editor-settings.js +42 -1
- package/src/components/sidebar/dataform-post-summary.js +13 -1
- package/src/components/sidebar/index.js +32 -47
- package/src/components/sidebar/post-summary.js +0 -17
- package/src/dataviews/store/private-actions.ts +30 -26
- package/src/store/private-actions.js +6 -2
- package/src/utils/media-sideload-from-url/index.js +54 -0
- package/src/utils/media-sideload-from-url/test/index.js +162 -0
- package/build/components/post-publish-panel/media-util.cjs +0 -72
- package/build/components/post-publish-panel/media-util.cjs.map +0 -7
- package/build-module/components/post-publish-panel/media-util.mjs +0 -46
- package/build-module/components/post-publish-panel/media-util.mjs.map +0 -7
- package/build-types/components/post-publish-panel/media-util.d.ts +0 -20
- package/build-types/components/post-publish-panel/media-util.d.ts.map +0 -1
- package/src/components/post-publish-panel/media-util.js +0 -87
- package/src/components/post-publish-panel/test/media-util.js +0 -118
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { dispatch, resolveSelect } from '@wordpress/data';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import getInserterMediaCategories from '..';
|
|
10
|
+
|
|
11
|
+
jest.mock( '@wordpress/data', () => ( {
|
|
12
|
+
dispatch: jest.fn(),
|
|
13
|
+
resolveSelect: jest.fn(),
|
|
14
|
+
} ) );
|
|
15
|
+
|
|
16
|
+
jest.mock( '@wordpress/core-data', () => ( {
|
|
17
|
+
store: 'core',
|
|
18
|
+
} ) );
|
|
19
|
+
|
|
20
|
+
describe( 'getInserterMediaCategories', () => {
|
|
21
|
+
beforeEach( () => {
|
|
22
|
+
jest.clearAllMocks();
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
it( 'does not include attached images for non-numeric post IDs', () => {
|
|
26
|
+
const categories = getInserterMediaCategories(
|
|
27
|
+
'wp_template//theme//home'
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
expect(
|
|
31
|
+
categories.some(
|
|
32
|
+
( category ) => category.name === 'attached-images'
|
|
33
|
+
)
|
|
34
|
+
).toBe( false );
|
|
35
|
+
} );
|
|
36
|
+
|
|
37
|
+
it( 'fetches images attached to the current post', async () => {
|
|
38
|
+
const getEntityRecords = jest.fn().mockResolvedValue( [
|
|
39
|
+
{
|
|
40
|
+
id: 10,
|
|
41
|
+
source_url: 'https://example.com/image.jpg',
|
|
42
|
+
alt_text: 'Alt text',
|
|
43
|
+
media_details: {
|
|
44
|
+
sizes: {
|
|
45
|
+
medium: {
|
|
46
|
+
source_url: 'https://example.com/image-medium.jpg',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
caption: {
|
|
51
|
+
raw: 'Caption',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
] );
|
|
55
|
+
resolveSelect.mockReturnValue( { getEntityRecords } );
|
|
56
|
+
|
|
57
|
+
const [ attachedImagesCategory ] = getInserterMediaCategories(
|
|
58
|
+
42,
|
|
59
|
+
'Post'
|
|
60
|
+
);
|
|
61
|
+
const results = await attachedImagesCategory.fetch( { per_page: 20 } );
|
|
62
|
+
|
|
63
|
+
expect( getEntityRecords ).toHaveBeenCalledWith(
|
|
64
|
+
'postType',
|
|
65
|
+
'attachment',
|
|
66
|
+
{
|
|
67
|
+
per_page: 20,
|
|
68
|
+
media_type: 'image',
|
|
69
|
+
parent: 42,
|
|
70
|
+
orderBy: 'date',
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
expect( results ).toEqual( [
|
|
74
|
+
expect.objectContaining( {
|
|
75
|
+
id: 10,
|
|
76
|
+
url: 'https://example.com/image.jpg',
|
|
77
|
+
previewUrl: 'https://example.com/image-medium.jpg',
|
|
78
|
+
alt: 'Alt text',
|
|
79
|
+
caption: 'Caption',
|
|
80
|
+
} ),
|
|
81
|
+
] );
|
|
82
|
+
} );
|
|
83
|
+
|
|
84
|
+
it( 'attaches and detaches attachment records', async () => {
|
|
85
|
+
const saveEntityRecord = jest.fn().mockResolvedValue( {} );
|
|
86
|
+
dispatch.mockReturnValue( { saveEntityRecord } );
|
|
87
|
+
|
|
88
|
+
const [ attachedImagesCategory ] = getInserterMediaCategories(
|
|
89
|
+
42,
|
|
90
|
+
'Post'
|
|
91
|
+
);
|
|
92
|
+
const attachedCount = await attachedImagesCategory.attach( [
|
|
93
|
+
// Classic media modal items expose `type`.
|
|
94
|
+
{ id: 10, type: 'image' },
|
|
95
|
+
{ id: 11, type: 'image' },
|
|
96
|
+
{ id: 10, type: 'image' },
|
|
97
|
+
// Non-image (e.g. a PDF uploaded via the picker) is skipped.
|
|
98
|
+
{ id: 12, type: 'application' },
|
|
99
|
+
{},
|
|
100
|
+
// DataViews-driven modal items are REST attachments: `type` is the
|
|
101
|
+
// post type ('attachment'), and the media type lives in
|
|
102
|
+
// `media_type`/`mime_type`. These must still gate to images.
|
|
103
|
+
{
|
|
104
|
+
id: 13,
|
|
105
|
+
type: 'attachment',
|
|
106
|
+
media_type: 'image',
|
|
107
|
+
mime_type: 'image/png',
|
|
108
|
+
},
|
|
109
|
+
{ id: 14, type: 'attachment', mime_type: 'image/jpeg' },
|
|
110
|
+
{
|
|
111
|
+
id: 15,
|
|
112
|
+
type: 'attachment',
|
|
113
|
+
media_type: 'file',
|
|
114
|
+
mime_type: 'application/pdf',
|
|
115
|
+
},
|
|
116
|
+
] );
|
|
117
|
+
await attachedImagesCategory.detach( { id: 11 } );
|
|
118
|
+
|
|
119
|
+
expect( attachedCount ).toBe( 4 );
|
|
120
|
+
expect( saveEntityRecord ).toHaveBeenCalledWith(
|
|
121
|
+
'postType',
|
|
122
|
+
'attachment',
|
|
123
|
+
{
|
|
124
|
+
id: 10,
|
|
125
|
+
post: 42,
|
|
126
|
+
},
|
|
127
|
+
{ throwOnError: true }
|
|
128
|
+
);
|
|
129
|
+
expect( saveEntityRecord ).toHaveBeenCalledWith(
|
|
130
|
+
'postType',
|
|
131
|
+
'attachment',
|
|
132
|
+
{
|
|
133
|
+
id: 11,
|
|
134
|
+
post: 42,
|
|
135
|
+
},
|
|
136
|
+
{ throwOnError: true }
|
|
137
|
+
);
|
|
138
|
+
expect( saveEntityRecord ).toHaveBeenCalledWith(
|
|
139
|
+
'postType',
|
|
140
|
+
'attachment',
|
|
141
|
+
{
|
|
142
|
+
id: 11,
|
|
143
|
+
post: 0,
|
|
144
|
+
},
|
|
145
|
+
{ throwOnError: true }
|
|
146
|
+
);
|
|
147
|
+
expect( saveEntityRecord ).toHaveBeenCalledWith(
|
|
148
|
+
'postType',
|
|
149
|
+
'attachment',
|
|
150
|
+
{
|
|
151
|
+
id: 13,
|
|
152
|
+
post: 42,
|
|
153
|
+
},
|
|
154
|
+
{ throwOnError: true }
|
|
155
|
+
);
|
|
156
|
+
expect( saveEntityRecord ).toHaveBeenCalledWith(
|
|
157
|
+
'postType',
|
|
158
|
+
'attachment',
|
|
159
|
+
{
|
|
160
|
+
id: 14,
|
|
161
|
+
post: 42,
|
|
162
|
+
},
|
|
163
|
+
{ throwOnError: true }
|
|
164
|
+
);
|
|
165
|
+
expect( saveEntityRecord ).not.toHaveBeenCalledWith(
|
|
166
|
+
'postType',
|
|
167
|
+
'attachment',
|
|
168
|
+
expect.objectContaining( { id: 12 } ),
|
|
169
|
+
expect.anything()
|
|
170
|
+
);
|
|
171
|
+
expect( saveEntityRecord ).not.toHaveBeenCalledWith(
|
|
172
|
+
'postType',
|
|
173
|
+
'attachment',
|
|
174
|
+
expect.objectContaining( { id: 15 } ),
|
|
175
|
+
expect.anything()
|
|
176
|
+
);
|
|
177
|
+
expect( saveEntityRecord ).toHaveBeenCalledTimes( 5 );
|
|
178
|
+
} );
|
|
179
|
+
|
|
180
|
+
it( 'words the empty state from the post type label', () => {
|
|
181
|
+
const [ attachedImagesCategory ] = getInserterMediaCategories(
|
|
182
|
+
42,
|
|
183
|
+
'Page'
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
expect( attachedImagesCategory.emptyMessage ).toBe(
|
|
187
|
+
'No images attached to this Page.'
|
|
188
|
+
);
|
|
189
|
+
} );
|
|
190
|
+
|
|
191
|
+
it( 'excludes attached images when there is no viewable post type label', () => {
|
|
192
|
+
// The label is empty for non-viewable post types (synced patterns,
|
|
193
|
+
// navigation, templates) and before the record resolves.
|
|
194
|
+
const categories = getInserterMediaCategories( 42, undefined );
|
|
195
|
+
|
|
196
|
+
expect(
|
|
197
|
+
categories.some(
|
|
198
|
+
( category ) => category.name === 'attached-images'
|
|
199
|
+
)
|
|
200
|
+
).toBe( false );
|
|
201
|
+
} );
|
|
202
|
+
} );
|
|
@@ -14,7 +14,7 @@ import { VisuallyHidden } from '@wordpress/ui';
|
|
|
14
14
|
*/
|
|
15
15
|
import { store as editorStore } from '../../store';
|
|
16
16
|
|
|
17
|
-
function
|
|
17
|
+
function buildInterstitialMarkup() {
|
|
18
18
|
let markup = renderToString(
|
|
19
19
|
<div className="editor-post-preview-button__interstitial-message">
|
|
20
20
|
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
|
|
@@ -95,11 +95,77 @@ function writeInterstitialMessage( targetDocument ) {
|
|
|
95
95
|
*/
|
|
96
96
|
markup = applyFilters( 'editor.PostPreview.interstitialMarkup', markup );
|
|
97
97
|
|
|
98
|
+
return markup;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function writeInterstitialMessage( targetDocument, markup ) {
|
|
98
102
|
targetDocument.write( markup );
|
|
99
103
|
targetDocument.title = __( 'Generating preview…' );
|
|
100
104
|
targetDocument.close();
|
|
101
105
|
}
|
|
102
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Resolves the preview window's `document`, working around
|
|
109
|
+
* `Document-Isolation-Policy` (DIP) isolation.
|
|
110
|
+
*
|
|
111
|
+
* The editor screen is served with `Document-Isolation-Policy:
|
|
112
|
+
* isolate-and-credentialless` to enable cross-origin isolation. This places the
|
|
113
|
+
* editor tab and an already-open preview tab in separate agent clusters, so
|
|
114
|
+
* synchronous access to a reused preview tab's `document` throws a
|
|
115
|
+
* `SecurityError`. Navigating the reused tab back to `about:blank` returns it to
|
|
116
|
+
* the opener's agent cluster and restores access. That navigation is
|
|
117
|
+
* asynchronous and we can't attach a cross-isolation `load` listener, so poll
|
|
118
|
+
* the `document` access (the operation that throws) until it succeeds, up to a
|
|
119
|
+
* short timeout.
|
|
120
|
+
*
|
|
121
|
+
* @param {Window} previewWindow The preview window/tab.
|
|
122
|
+
*
|
|
123
|
+
* @return {?Document} The reachable preview document, or `null` if it never
|
|
124
|
+
* becomes reachable within the timeout.
|
|
125
|
+
*/
|
|
126
|
+
async function getPreviewDocument( previewWindow ) {
|
|
127
|
+
// A freshly opened tab is already on `about:blank` and accessible, so this
|
|
128
|
+
// succeeds on the first preview without any reset.
|
|
129
|
+
try {
|
|
130
|
+
return previewWindow.document;
|
|
131
|
+
} catch {
|
|
132
|
+
// The reused preview tab is isolated from the editor; reset it below.
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
previewWindow.location = 'about:blank';
|
|
136
|
+
|
|
137
|
+
const timeoutMs = 1000;
|
|
138
|
+
const intervalMs = 50;
|
|
139
|
+
const deadline = Date.now() + timeoutMs;
|
|
140
|
+
do {
|
|
141
|
+
await new Promise( ( resolve ) => setTimeout( resolve, intervalMs ) );
|
|
142
|
+
try {
|
|
143
|
+
return previewWindow.document;
|
|
144
|
+
} catch {
|
|
145
|
+
// Navigation to `about:blank` hasn't completed yet; keep polling.
|
|
146
|
+
}
|
|
147
|
+
} while ( Date.now() < deadline );
|
|
148
|
+
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Writes the preview interstitial into the preview window, working around
|
|
154
|
+
* `Document-Isolation-Policy` (DIP) isolation.
|
|
155
|
+
*
|
|
156
|
+
* The interstitial is a progressive enhancement: if the document never becomes
|
|
157
|
+
* reachable we simply skip it, and the caller still navigates the preview to the
|
|
158
|
+
* real content.
|
|
159
|
+
*
|
|
160
|
+
* @param {Window} previewWindow The preview window/tab.
|
|
161
|
+
*/
|
|
162
|
+
async function writeInterstitialIntoPreviewWindow( previewWindow ) {
|
|
163
|
+
const previewDocument = await getPreviewDocument( previewWindow );
|
|
164
|
+
if ( previewDocument ) {
|
|
165
|
+
writeInterstitialMessage( previewDocument, buildInterstitialMarkup() );
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
103
169
|
/**
|
|
104
170
|
* Renders a button that opens a new window or tab for the preview,
|
|
105
171
|
* writes the interstitial message to this window, and then navigates
|
|
@@ -168,7 +234,7 @@ export default function PostPreviewButton( {
|
|
|
168
234
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-window-focus
|
|
169
235
|
previewWindow.focus();
|
|
170
236
|
|
|
171
|
-
|
|
237
|
+
await writeInterstitialIntoPreviewWindow( previewWindow );
|
|
172
238
|
|
|
173
239
|
const link = await __unstableSaveForPreview( { forceIsAutosaveable } );
|
|
174
240
|
|
|
@@ -10,14 +10,18 @@ import {
|
|
|
10
10
|
} from '@wordpress/components';
|
|
11
11
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
12
12
|
import { __, _x } from '@wordpress/i18n';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
store as blockEditorStore,
|
|
15
|
+
privateApis as blockEditorPrivateApis,
|
|
16
|
+
} from '@wordpress/block-editor';
|
|
14
17
|
import { useState } from '@wordpress/element';
|
|
15
|
-
import { isBlobURL } from '@wordpress/blob';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Internal dependencies
|
|
19
21
|
*/
|
|
20
|
-
import {
|
|
22
|
+
import { unlock } from '../../lock-unlock';
|
|
23
|
+
|
|
24
|
+
const { mediaSideloadFromUrlKey } = unlock( blockEditorPrivateApis );
|
|
21
25
|
|
|
22
26
|
function flattenBlocks( blocks ) {
|
|
23
27
|
const result = [];
|
|
@@ -113,10 +117,13 @@ export default function MaybeUploadMediaPanel() {
|
|
|
113
117
|
const [ isUploading, setIsUploading ] = useState( false );
|
|
114
118
|
const [ isAnimating, setIsAnimating ] = useState( false );
|
|
115
119
|
const [ hadUploadError, setHadUploadError ] = useState( false );
|
|
116
|
-
const { editorBlocks,
|
|
120
|
+
const { editorBlocks, mediaSideloadFromUrl } = useSelect(
|
|
117
121
|
( select ) => ( {
|
|
118
122
|
editorBlocks: select( blockEditorStore ).getBlocks(),
|
|
119
|
-
|
|
123
|
+
mediaSideloadFromUrl:
|
|
124
|
+
select( blockEditorStore ).getSettings()[
|
|
125
|
+
mediaSideloadFromUrlKey
|
|
126
|
+
],
|
|
120
127
|
} ),
|
|
121
128
|
[]
|
|
122
129
|
);
|
|
@@ -127,7 +134,7 @@ export default function MaybeUploadMediaPanel() {
|
|
|
127
134
|
);
|
|
128
135
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
129
136
|
|
|
130
|
-
if ( !
|
|
137
|
+
if ( ! mediaSideloadFromUrl || ! blocksWithExternalMedia.length ) {
|
|
131
138
|
return null;
|
|
132
139
|
}
|
|
133
140
|
|
|
@@ -178,32 +185,20 @@ export default function MaybeUploadMediaPanel() {
|
|
|
178
185
|
);
|
|
179
186
|
|
|
180
187
|
// Create an upload promise for each URL, that we can wait for in all
|
|
181
|
-
// blocks that make use of that media.
|
|
188
|
+
// blocks that make use of that media. The server sideloads each URL,
|
|
189
|
+
// so this works even when the editor is cross-origin isolated.
|
|
182
190
|
const uploadPromises = Object.fromEntries(
|
|
183
|
-
|
|
184
|
-
(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if ( isBlobURL( media.url ) ) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
resolve( media );
|
|
196
|
-
},
|
|
197
|
-
onError() {
|
|
198
|
-
reject();
|
|
199
|
-
},
|
|
200
|
-
} );
|
|
201
|
-
} )
|
|
202
|
-
);
|
|
191
|
+
[ ...mediaUrls ].map( ( url ) => {
|
|
192
|
+
const uploadPromise = new Promise( ( resolve, reject ) => {
|
|
193
|
+
mediaSideloadFromUrl( {
|
|
194
|
+
url,
|
|
195
|
+
onSuccess: ( media ) => resolve( media ),
|
|
196
|
+
onError: () => reject(),
|
|
197
|
+
} );
|
|
198
|
+
} );
|
|
203
199
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
)
|
|
200
|
+
return [ url, uploadPromise ];
|
|
201
|
+
} )
|
|
207
202
|
);
|
|
208
203
|
|
|
209
204
|
// Wait for all blocks to be updated with library media.
|
|
@@ -27,30 +27,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
27
27
|
padding: 0;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
.emotion-10 {
|
|
31
|
-
display: -webkit-box;
|
|
32
|
-
display: -webkit-flex;
|
|
33
|
-
display: -ms-flexbox;
|
|
34
|
-
display: flex;
|
|
35
|
-
-webkit-align-items: flex-start;
|
|
36
|
-
-webkit-box-align: flex-start;
|
|
37
|
-
-ms-flex-align: flex-start;
|
|
38
|
-
align-items: flex-start;
|
|
39
|
-
-webkit-flex-direction: row;
|
|
40
|
-
-ms-flex-direction: row;
|
|
41
|
-
flex-direction: row;
|
|
42
|
-
gap: 0;
|
|
43
|
-
-webkit-box-pack: start;
|
|
44
|
-
-ms-flex-pack: start;
|
|
45
|
-
-webkit-justify-content: start;
|
|
46
|
-
justify-content: start;
|
|
47
|
-
width: 100%;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.emotion-10>* {
|
|
51
|
-
min-width: 0;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
30
|
<div>
|
|
55
31
|
<div
|
|
56
32
|
class="editor-post-publish-panel"
|
|
@@ -91,7 +67,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
91
67
|
<a
|
|
92
68
|
class="components-external-link"
|
|
93
69
|
href="https://wordpress.local/sample-page/"
|
|
94
|
-
rel="external noopener"
|
|
95
70
|
target="_blank"
|
|
96
71
|
>
|
|
97
72
|
<span
|
|
@@ -163,6 +138,7 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
163
138
|
target="_blank"
|
|
164
139
|
>
|
|
165
140
|
<span
|
|
141
|
+
class="style-visually-hidden"
|
|
166
142
|
data-visually-hidden=""
|
|
167
143
|
>
|
|
168
144
|
(opens in a new tab)
|
|
@@ -199,9 +175,10 @@ exports[`PostPublishPanel should render the post-publish panel if the post is pu
|
|
|
199
175
|
class="components-base-control__field emotion-2 emotion-3"
|
|
200
176
|
>
|
|
201
177
|
<div
|
|
202
|
-
class="components-flex components-h-stack
|
|
178
|
+
class="style-flex style-items-row style-expanded-row components-flex components-h-stack"
|
|
203
179
|
data-wp-c16t="true"
|
|
204
180
|
data-wp-component="HStack"
|
|
181
|
+
style="--wp-components-flex-align: flex-start; --wp-components-flex-direction: row; --wp-components-flex-wrap: nowrap; --wp-components-flex-gap: 0; --wp-components-flex-justify: start;"
|
|
205
182
|
>
|
|
206
183
|
<span
|
|
207
184
|
class="components-checkbox-control__input-container"
|
|
@@ -254,30 +231,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
254
231
|
padding: 0;
|
|
255
232
|
}
|
|
256
233
|
|
|
257
|
-
.emotion-10 {
|
|
258
|
-
display: -webkit-box;
|
|
259
|
-
display: -webkit-flex;
|
|
260
|
-
display: -ms-flexbox;
|
|
261
|
-
display: flex;
|
|
262
|
-
-webkit-align-items: flex-start;
|
|
263
|
-
-webkit-box-align: flex-start;
|
|
264
|
-
-ms-flex-align: flex-start;
|
|
265
|
-
align-items: flex-start;
|
|
266
|
-
-webkit-flex-direction: row;
|
|
267
|
-
-ms-flex-direction: row;
|
|
268
|
-
flex-direction: row;
|
|
269
|
-
gap: 0;
|
|
270
|
-
-webkit-box-pack: start;
|
|
271
|
-
-ms-flex-pack: start;
|
|
272
|
-
-webkit-justify-content: start;
|
|
273
|
-
justify-content: start;
|
|
274
|
-
width: 100%;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.emotion-10>* {
|
|
278
|
-
min-width: 0;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
234
|
<div>
|
|
282
235
|
<div
|
|
283
236
|
class="editor-post-publish-panel"
|
|
@@ -318,7 +271,6 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
318
271
|
<a
|
|
319
272
|
class="components-external-link"
|
|
320
273
|
href="https://wordpress.local/sample-page/"
|
|
321
|
-
rel="external noopener"
|
|
322
274
|
target="_blank"
|
|
323
275
|
>
|
|
324
276
|
<span
|
|
@@ -405,9 +357,10 @@ exports[`PostPublishPanel should render the post-publish panel if the post is sc
|
|
|
405
357
|
class="components-base-control__field emotion-2 emotion-3"
|
|
406
358
|
>
|
|
407
359
|
<div
|
|
408
|
-
class="components-flex components-h-stack
|
|
360
|
+
class="style-flex style-items-row style-expanded-row components-flex components-h-stack"
|
|
409
361
|
data-wp-c16t="true"
|
|
410
362
|
data-wp-component="HStack"
|
|
363
|
+
style="--wp-components-flex-align: flex-start; --wp-components-flex-direction: row; --wp-components-flex-wrap: nowrap; --wp-components-flex-gap: 0; --wp-components-flex-justify: start;"
|
|
411
364
|
>
|
|
412
365
|
<span
|
|
413
366
|
class="components-checkbox-control__input-container"
|
|
@@ -450,30 +403,6 @@ exports[`PostPublishPanel should render the pre-publish panel if post status is
|
|
|
450
403
|
margin-bottom: inherit;
|
|
451
404
|
}
|
|
452
405
|
|
|
453
|
-
.emotion-4 {
|
|
454
|
-
display: -webkit-box;
|
|
455
|
-
display: -webkit-flex;
|
|
456
|
-
display: -ms-flexbox;
|
|
457
|
-
display: flex;
|
|
458
|
-
-webkit-align-items: flex-start;
|
|
459
|
-
-webkit-box-align: flex-start;
|
|
460
|
-
-ms-flex-align: flex-start;
|
|
461
|
-
align-items: flex-start;
|
|
462
|
-
-webkit-flex-direction: row;
|
|
463
|
-
-ms-flex-direction: row;
|
|
464
|
-
flex-direction: row;
|
|
465
|
-
gap: 0;
|
|
466
|
-
-webkit-box-pack: start;
|
|
467
|
-
-ms-flex-pack: start;
|
|
468
|
-
-webkit-justify-content: start;
|
|
469
|
-
justify-content: start;
|
|
470
|
-
width: 100%;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.emotion-4>* {
|
|
474
|
-
min-width: 0;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
406
|
<div>
|
|
478
407
|
<div
|
|
479
408
|
class="editor-post-publish-panel"
|
|
@@ -560,9 +489,10 @@ exports[`PostPublishPanel should render the pre-publish panel if post status is
|
|
|
560
489
|
class="components-base-control__field emotion-2 emotion-3"
|
|
561
490
|
>
|
|
562
491
|
<div
|
|
563
|
-
class="components-flex components-h-stack
|
|
492
|
+
class="style-flex style-items-row style-expanded-row components-flex components-h-stack"
|
|
564
493
|
data-wp-c16t="true"
|
|
565
494
|
data-wp-component="HStack"
|
|
495
|
+
style="--wp-components-flex-align: flex-start; --wp-components-flex-direction: row; --wp-components-flex-wrap: nowrap; --wp-components-flex-gap: 0; --wp-components-flex-justify: start;"
|
|
566
496
|
>
|
|
567
497
|
<span
|
|
568
498
|
class="components-checkbox-control__input-container"
|
|
@@ -605,30 +535,6 @@ exports[`PostPublishPanel should render the pre-publish panel if the post is not
|
|
|
605
535
|
margin-bottom: inherit;
|
|
606
536
|
}
|
|
607
537
|
|
|
608
|
-
.emotion-4 {
|
|
609
|
-
display: -webkit-box;
|
|
610
|
-
display: -webkit-flex;
|
|
611
|
-
display: -ms-flexbox;
|
|
612
|
-
display: flex;
|
|
613
|
-
-webkit-align-items: flex-start;
|
|
614
|
-
-webkit-box-align: flex-start;
|
|
615
|
-
-ms-flex-align: flex-start;
|
|
616
|
-
align-items: flex-start;
|
|
617
|
-
-webkit-flex-direction: row;
|
|
618
|
-
-ms-flex-direction: row;
|
|
619
|
-
flex-direction: row;
|
|
620
|
-
gap: 0;
|
|
621
|
-
-webkit-box-pack: start;
|
|
622
|
-
-ms-flex-pack: start;
|
|
623
|
-
-webkit-justify-content: start;
|
|
624
|
-
justify-content: start;
|
|
625
|
-
width: 100%;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
.emotion-4>* {
|
|
629
|
-
min-width: 0;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
538
|
<div>
|
|
633
539
|
<div
|
|
634
540
|
class="editor-post-publish-panel"
|
|
@@ -715,9 +621,10 @@ exports[`PostPublishPanel should render the pre-publish panel if the post is not
|
|
|
715
621
|
class="components-base-control__field emotion-2 emotion-3"
|
|
716
622
|
>
|
|
717
623
|
<div
|
|
718
|
-
class="components-flex components-h-stack
|
|
624
|
+
class="style-flex style-items-row style-expanded-row components-flex components-h-stack"
|
|
719
625
|
data-wp-c16t="true"
|
|
720
626
|
data-wp-component="HStack"
|
|
627
|
+
style="--wp-components-flex-align: flex-start; --wp-components-flex-direction: row; --wp-components-flex-wrap: nowrap; --wp-components-flex-gap: 0; --wp-components-flex-justify: start;"
|
|
721
628
|
>
|
|
722
629
|
<span
|
|
723
630
|
class="components-checkbox-control__input-container"
|
|
@@ -804,30 +711,6 @@ exports[`PostPublishPanel should render the spinner if the post is being saved 1
|
|
|
804
711
|
margin-bottom: inherit;
|
|
805
712
|
}
|
|
806
713
|
|
|
807
|
-
.emotion-10 {
|
|
808
|
-
display: -webkit-box;
|
|
809
|
-
display: -webkit-flex;
|
|
810
|
-
display: -ms-flexbox;
|
|
811
|
-
display: flex;
|
|
812
|
-
-webkit-align-items: flex-start;
|
|
813
|
-
-webkit-box-align: flex-start;
|
|
814
|
-
-ms-flex-align: flex-start;
|
|
815
|
-
align-items: flex-start;
|
|
816
|
-
-webkit-flex-direction: row;
|
|
817
|
-
-ms-flex-direction: row;
|
|
818
|
-
flex-direction: row;
|
|
819
|
-
gap: 0;
|
|
820
|
-
-webkit-box-pack: start;
|
|
821
|
-
-ms-flex-pack: start;
|
|
822
|
-
-webkit-justify-content: start;
|
|
823
|
-
justify-content: start;
|
|
824
|
-
width: 100%;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
.emotion-10>* {
|
|
828
|
-
min-width: 0;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
714
|
<div>
|
|
832
715
|
<div
|
|
833
716
|
class="editor-post-publish-panel"
|
|
@@ -894,9 +777,10 @@ exports[`PostPublishPanel should render the spinner if the post is being saved 1
|
|
|
894
777
|
class="components-base-control__field emotion-8 emotion-9"
|
|
895
778
|
>
|
|
896
779
|
<div
|
|
897
|
-
class="components-flex components-h-stack
|
|
780
|
+
class="style-flex style-items-row style-expanded-row components-flex components-h-stack"
|
|
898
781
|
data-wp-c16t="true"
|
|
899
782
|
data-wp-component="HStack"
|
|
783
|
+
style="--wp-components-flex-align: flex-start; --wp-components-flex-direction: row; --wp-components-flex-wrap: nowrap; --wp-components-flex-gap: 0; --wp-components-flex-justify: start;"
|
|
900
784
|
>
|
|
901
785
|
<span
|
|
902
786
|
class="components-checkbox-control__input-container"
|
|
@@ -9,6 +9,7 @@ import { dateI18n, getSettings as getDateSettings } from '@wordpress/date';
|
|
|
9
9
|
import { useMemo } from '@wordpress/element';
|
|
10
10
|
import { chevronLeft, chevronRight } from '@wordpress/icons';
|
|
11
11
|
import { Stack } from '@wordpress/ui';
|
|
12
|
+
import { useFocusOnMount } from '@wordpress/compose';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Internal dependencies
|
|
@@ -64,6 +65,8 @@ function RevisionsSlider() {
|
|
|
64
65
|
useDispatch( editorStore )
|
|
65
66
|
);
|
|
66
67
|
|
|
68
|
+
const focusOnMountRef = useFocusOnMount( true );
|
|
69
|
+
|
|
67
70
|
const isLoading = ! rawRevisions;
|
|
68
71
|
const totalPages = Math.ceil( totalRevisions / perPage ) || 1;
|
|
69
72
|
|
|
@@ -132,7 +135,7 @@ function RevisionsSlider() {
|
|
|
132
135
|
<Spinner />
|
|
133
136
|
) : (
|
|
134
137
|
<RangeControl
|
|
135
|
-
|
|
138
|
+
ref={ focusOnMountRef }
|
|
136
139
|
aria-valuetext={ renderTooltipContent( selectedIndex ) }
|
|
137
140
|
className="editor-revisions-header__slider"
|
|
138
141
|
hideLabelFromVision
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
serialize,
|
|
10
10
|
} from '@wordpress/blocks';
|
|
11
11
|
import { RichTextData } from '@wordpress/rich-text';
|
|
12
|
-
import * as paragraphBlock from '@wordpress/block-library/
|
|
13
|
-
import * as groupBlock from '@wordpress/block-library/
|
|
12
|
+
import * as paragraphBlock from '@wordpress/block-library/build-module/paragraph/index.mjs';
|
|
13
|
+
import * as groupBlock from '@wordpress/block-library/build-module/group/index.mjs';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Internal dependencies
|