@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.
Files changed (197) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/build/components/collab-sidebar/format.cjs +83 -0
  3. package/build/components/collab-sidebar/format.cjs.map +7 -0
  4. package/build/components/collab-sidebar/hooks.cjs +117 -16
  5. package/build/components/collab-sidebar/hooks.cjs.map +2 -2
  6. package/build/components/collab-sidebar/index.cjs +18 -2
  7. package/build/components/collab-sidebar/index.cjs.map +2 -2
  8. package/build/components/collab-sidebar/note-highlight-styles.cjs +67 -0
  9. package/build/components/collab-sidebar/note-highlight-styles.cjs.map +7 -0
  10. package/build/components/collab-sidebar/utils.cjs +139 -0
  11. package/build/components/collab-sidebar/utils.cjs.map +2 -2
  12. package/build/components/collaborators-presence/use-collaborator-notifications.cjs +55 -30
  13. package/build/components/collaborators-presence/use-collaborator-notifications.cjs.map +2 -2
  14. package/build/components/commands/index.cjs +99 -3
  15. package/build/components/commands/index.cjs.map +2 -2
  16. package/build/components/document-bar/index.cjs +28 -34
  17. package/build/components/document-bar/index.cjs.map +2 -2
  18. package/build/components/entities-saved-states/index.cjs +1 -4
  19. package/build/components/entities-saved-states/index.cjs.map +2 -2
  20. package/build/components/media-categories/index.cjs +92 -6
  21. package/build/components/media-categories/index.cjs.map +2 -2
  22. package/build/components/page-attributes/parent.cjs +0 -1
  23. package/build/components/page-attributes/parent.cjs.map +2 -2
  24. package/build/components/post-author/combobox.cjs +0 -1
  25. package/build/components/post-author/combobox.cjs.map +2 -2
  26. package/build/components/post-author/select.cjs +0 -1
  27. package/build/components/post-author/select.cjs.map +2 -2
  28. package/build/components/post-preview-button/index.cjs +29 -2
  29. package/build/components/post-preview-button/index.cjs.map +2 -2
  30. package/build/components/post-publish-panel/maybe-upload-media.cjs +15 -26
  31. package/build/components/post-publish-panel/maybe-upload-media.cjs.map +3 -3
  32. package/build/components/post-revisions-preview/revisions-slider.cjs +3 -1
  33. package/build/components/post-revisions-preview/revisions-slider.cjs.map +2 -2
  34. package/build/components/post-taxonomies/flat-term-selector.cjs +0 -1
  35. package/build/components/post-taxonomies/flat-term-selector.cjs.map +2 -2
  36. package/build/components/post-taxonomies/hierarchical-term-selector.cjs +0 -2
  37. package/build/components/post-taxonomies/hierarchical-term-selector.cjs.map +2 -2
  38. package/build/components/post-template/classic-theme.cjs +0 -1
  39. package/build/components/post-template/classic-theme.cjs.map +2 -2
  40. package/build/components/preferences-modal/index.cjs +54 -28
  41. package/build/components/preferences-modal/index.cjs.map +2 -2
  42. package/build/components/preview-dropdown/index.cjs +3 -3
  43. package/build/components/preview-dropdown/index.cjs.map +2 -2
  44. package/build/components/provider/use-block-editor-settings.cjs +23 -3
  45. package/build/components/provider/use-block-editor-settings.cjs.map +3 -3
  46. package/build/components/sidebar/dataform-post-summary.cjs +5 -1
  47. package/build/components/sidebar/dataform-post-summary.cjs.map +3 -3
  48. package/build/components/sidebar/index.cjs +29 -38
  49. package/build/components/sidebar/index.cjs.map +3 -3
  50. package/build/components/sidebar/post-summary.cjs +0 -13
  51. package/build/components/sidebar/post-summary.cjs.map +3 -3
  52. package/build/dataviews/store/private-actions.cjs +24 -19
  53. package/build/dataviews/store/private-actions.cjs.map +2 -2
  54. package/build/store/private-actions.cjs +5 -2
  55. package/build/store/private-actions.cjs.map +2 -2
  56. package/build/utils/media-sideload-from-url/index.cjs +63 -0
  57. package/build/utils/media-sideload-from-url/index.cjs.map +7 -0
  58. package/build-module/components/collab-sidebar/format.mjs +57 -0
  59. package/build-module/components/collab-sidebar/format.mjs.map +7 -0
  60. package/build-module/components/collab-sidebar/hooks.mjs +121 -16
  61. package/build-module/components/collab-sidebar/hooks.mjs.map +2 -2
  62. package/build-module/components/collab-sidebar/index.mjs +21 -5
  63. package/build-module/components/collab-sidebar/index.mjs.map +2 -2
  64. package/build-module/components/collab-sidebar/note-highlight-styles.mjs +41 -0
  65. package/build-module/components/collab-sidebar/note-highlight-styles.mjs.map +7 -0
  66. package/build-module/components/collab-sidebar/utils.mjs +133 -0
  67. package/build-module/components/collab-sidebar/utils.mjs.map +2 -2
  68. package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs +55 -30
  69. package/build-module/components/collaborators-presence/use-collaborator-notifications.mjs.map +2 -2
  70. package/build-module/components/commands/index.mjs +99 -3
  71. package/build-module/components/commands/index.mjs.map +2 -2
  72. package/build-module/components/document-bar/index.mjs +28 -34
  73. package/build-module/components/document-bar/index.mjs.map +2 -2
  74. package/build-module/components/entities-saved-states/index.mjs +1 -4
  75. package/build-module/components/entities-saved-states/index.mjs.map +2 -2
  76. package/build-module/components/media-categories/index.mjs +93 -7
  77. package/build-module/components/media-categories/index.mjs.map +2 -2
  78. package/build-module/components/page-attributes/parent.mjs +0 -1
  79. package/build-module/components/page-attributes/parent.mjs.map +2 -2
  80. package/build-module/components/post-author/combobox.mjs +0 -1
  81. package/build-module/components/post-author/combobox.mjs.map +2 -2
  82. package/build-module/components/post-author/select.mjs +0 -1
  83. package/build-module/components/post-author/select.mjs.map +2 -2
  84. package/build-module/components/post-preview-button/index.mjs +29 -2
  85. package/build-module/components/post-preview-button/index.mjs.map +2 -2
  86. package/build-module/components/post-publish-panel/maybe-upload-media.mjs +19 -27
  87. package/build-module/components/post-publish-panel/maybe-upload-media.mjs.map +2 -2
  88. package/build-module/components/post-revisions-preview/revisions-slider.mjs +3 -1
  89. package/build-module/components/post-revisions-preview/revisions-slider.mjs.map +2 -2
  90. package/build-module/components/post-taxonomies/flat-term-selector.mjs +0 -1
  91. package/build-module/components/post-taxonomies/flat-term-selector.mjs.map +2 -2
  92. package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs +0 -2
  93. package/build-module/components/post-taxonomies/hierarchical-term-selector.mjs.map +2 -2
  94. package/build-module/components/post-template/classic-theme.mjs +0 -1
  95. package/build-module/components/post-template/classic-theme.mjs.map +2 -2
  96. package/build-module/components/preferences-modal/index.mjs +54 -28
  97. package/build-module/components/preferences-modal/index.mjs.map +2 -2
  98. package/build-module/components/preview-dropdown/index.mjs +3 -3
  99. package/build-module/components/preview-dropdown/index.mjs.map +2 -2
  100. package/build-module/components/provider/use-block-editor-settings.mjs +23 -3
  101. package/build-module/components/provider/use-block-editor-settings.mjs.map +2 -2
  102. package/build-module/components/sidebar/dataform-post-summary.mjs +6 -2
  103. package/build-module/components/sidebar/dataform-post-summary.mjs.map +2 -2
  104. package/build-module/components/sidebar/index.mjs +29 -42
  105. package/build-module/components/sidebar/index.mjs.map +2 -2
  106. package/build-module/components/sidebar/post-summary.mjs +0 -13
  107. package/build-module/components/sidebar/post-summary.mjs.map +2 -2
  108. package/build-module/dataviews/store/private-actions.mjs +26 -19
  109. package/build-module/dataviews/store/private-actions.mjs.map +2 -2
  110. package/build-module/store/private-actions.mjs +5 -2
  111. package/build-module/store/private-actions.mjs.map +2 -2
  112. package/build-module/utils/media-sideload-from-url/index.mjs +32 -0
  113. package/build-module/utils/media-sideload-from-url/index.mjs.map +7 -0
  114. package/build-style/style-rtl.css +65 -33
  115. package/build-style/style.css +65 -33
  116. package/build-types/components/collab-sidebar/format.d.ts +17 -0
  117. package/build-types/components/collab-sidebar/format.d.ts.map +1 -0
  118. package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
  119. package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
  120. package/build-types/components/collab-sidebar/note-highlight-styles.d.ts +31 -0
  121. package/build-types/components/collab-sidebar/note-highlight-styles.d.ts.map +1 -0
  122. package/build-types/components/collab-sidebar/utils.d.ts +82 -2
  123. package/build-types/components/collab-sidebar/utils.d.ts.map +1 -1
  124. package/build-types/components/collaborators-presence/use-collaborator-notifications.d.ts.map +1 -1
  125. package/build-types/components/commands/index.d.ts.map +1 -1
  126. package/build-types/components/document-bar/index.d.ts.map +1 -1
  127. package/build-types/components/entities-saved-states/index.d.ts.map +1 -1
  128. package/build-types/components/media-categories/index.d.ts +12 -3
  129. package/build-types/components/media-categories/index.d.ts.map +1 -1
  130. package/build-types/components/page-attributes/parent.d.ts.map +1 -1
  131. package/build-types/components/post-author/combobox.d.ts.map +1 -1
  132. package/build-types/components/post-author/select.d.ts.map +1 -1
  133. package/build-types/components/post-preview-button/index.d.ts.map +1 -1
  134. package/build-types/components/post-publish-panel/maybe-upload-media.d.ts.map +1 -1
  135. package/build-types/components/post-revisions-preview/revisions-slider.d.ts.map +1 -1
  136. package/build-types/components/post-taxonomies/flat-term-selector.d.ts.map +1 -1
  137. package/build-types/components/post-taxonomies/hierarchical-term-selector.d.ts.map +1 -1
  138. package/build-types/components/post-template/classic-theme.d.ts.map +1 -1
  139. package/build-types/components/provider/use-block-editor-settings.d.ts.map +1 -1
  140. package/build-types/components/sidebar/dataform-post-summary.d.ts.map +1 -1
  141. package/build-types/components/sidebar/index.d.ts.map +1 -1
  142. package/build-types/components/sidebar/post-summary.d.ts.map +1 -1
  143. package/build-types/dataviews/store/private-actions.d.ts.map +1 -1
  144. package/build-types/store/private-actions.d.ts.map +1 -1
  145. package/build-types/store/selectors.d.ts.map +1 -1
  146. package/build-types/utils/get-template-part-icon.d.ts.map +1 -1
  147. package/build-types/utils/media-sideload-from-url/index.d.ts +18 -0
  148. package/build-types/utils/media-sideload-from-url/index.d.ts.map +1 -0
  149. package/package.json +48 -46
  150. package/src/components/collab-sidebar/format.js +72 -0
  151. package/src/components/collab-sidebar/hooks.js +203 -22
  152. package/src/components/collab-sidebar/index.js +19 -5
  153. package/src/components/collab-sidebar/note-highlight-styles.js +83 -0
  154. package/src/components/collab-sidebar/style.scss +9 -0
  155. package/src/components/collab-sidebar/test/note-highlight-styles.js +106 -0
  156. package/src/components/collab-sidebar/test/utils.js +471 -0
  157. package/src/components/collab-sidebar/utils.js +225 -2
  158. package/src/components/collaborators-presence/test/use-collaborator-notifications.ts +265 -262
  159. package/src/components/collaborators-presence/use-collaborator-notifications.ts +70 -34
  160. package/src/components/commands/index.js +142 -0
  161. package/src/components/document-bar/index.js +0 -9
  162. package/src/components/document-bar/style.scss +0 -17
  163. package/src/components/entities-saved-states/index.js +1 -5
  164. package/src/components/header/style.scss +7 -3
  165. package/src/components/media-categories/index.js +160 -6
  166. package/src/components/media-categories/test/index.js +202 -0
  167. package/src/components/page-attributes/parent.js +0 -1
  168. package/src/components/post-author/combobox.js +0 -1
  169. package/src/components/post-author/select.js +0 -1
  170. package/src/components/post-preview-button/index.js +68 -2
  171. package/src/components/post-publish-panel/maybe-upload-media.js +25 -30
  172. package/src/components/post-publish-panel/style.scss +1 -1
  173. package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +11 -127
  174. package/src/components/post-revisions-preview/revisions-slider.js +4 -1
  175. package/src/components/post-revisions-preview/test/block-diff.js +2 -2
  176. package/src/components/post-taxonomies/flat-term-selector.js +0 -1
  177. package/src/components/post-taxonomies/hierarchical-term-selector.js +0 -2
  178. package/src/components/post-template/classic-theme.js +0 -1
  179. package/src/components/preferences-modal/index.js +40 -22
  180. package/src/components/preferences-modal/test/index.js +83 -0
  181. package/src/components/preview-dropdown/index.js +3 -3
  182. package/src/components/provider/use-block-editor-settings.js +42 -1
  183. package/src/components/sidebar/dataform-post-summary.js +13 -1
  184. package/src/components/sidebar/index.js +32 -47
  185. package/src/components/sidebar/post-summary.js +0 -17
  186. package/src/dataviews/store/private-actions.ts +30 -26
  187. package/src/store/private-actions.js +6 -2
  188. package/src/utils/media-sideload-from-url/index.js +54 -0
  189. package/src/utils/media-sideload-from-url/test/index.js +162 -0
  190. package/build/components/post-publish-panel/media-util.cjs +0 -72
  191. package/build/components/post-publish-panel/media-util.cjs.map +0 -7
  192. package/build-module/components/post-publish-panel/media-util.mjs +0 -46
  193. package/build-module/components/post-publish-panel/media-util.mjs.map +0 -7
  194. package/build-types/components/post-publish-panel/media-util.d.ts +0 -20
  195. package/build-types/components/post-publish-panel/media-util.d.ts.map +0 -1
  196. package/src/components/post-publish-panel/media-util.js +0 -87
  197. 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
+ } );
@@ -195,7 +195,6 @@ export function PageAttributesParent() {
195
195
 
196
196
  return (
197
197
  <ComboboxControl
198
- __next40pxDefaultSize
199
198
  className="editor-page-attributes__parent"
200
199
  label={ __( 'Parent' ) }
201
200
  help={ __( 'Choose a parent page.' ) }
@@ -34,7 +34,6 @@ export default function PostAuthorCombobox() {
34
34
 
35
35
  return (
36
36
  <ComboboxControl
37
- __next40pxDefaultSize
38
37
  label={ __( 'Author' ) }
39
38
  options={ authorOptions }
40
39
  value={ authorId }
@@ -22,7 +22,6 @@ export default function PostAuthorSelect() {
22
22
 
23
23
  return (
24
24
  <SelectControl
25
- __next40pxDefaultSize
26
25
  className="post-author-selector"
27
26
  label={ __( 'Author' ) }
28
27
  options={ authorOptions }
@@ -14,7 +14,7 @@ import { VisuallyHidden } from '@wordpress/ui';
14
14
  */
15
15
  import { store as editorStore } from '../../store';
16
16
 
17
- function writeInterstitialMessage( targetDocument ) {
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
- writeInterstitialMessage( previewWindow.document );
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 { store as blockEditorStore } from '@wordpress/block-editor';
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 { fetchMedia } from './media-util';
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, mediaUpload } = useSelect(
120
+ const { editorBlocks, mediaSideloadFromUrl } = useSelect(
117
121
  ( select ) => ( {
118
122
  editorBlocks: select( blockEditorStore ).getBlocks(),
119
- mediaUpload: select( blockEditorStore ).getSettings().mediaUpload,
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 ( ! mediaUpload || ! blocksWithExternalMedia.length ) {
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
- Object.entries( fetchMedia( [ ...mediaUrls ] ) ).map(
184
- ( [ url, filePromise ] ) => {
185
- const uploadPromise = filePromise.then(
186
- ( blob ) =>
187
- new Promise( ( resolve, reject ) => {
188
- mediaUpload( {
189
- filesList: [ blob ],
190
- onFileChange: ( [ media ] ) => {
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
- return [ url, uploadPromise ];
205
- }
206
- )
200
+ return [ url, uploadPromise ];
201
+ } )
207
202
  );
208
203
 
209
204
  // Wait for all blocks to be updated with library media.
@@ -226,7 +226,7 @@
226
226
  }
227
227
 
228
228
  body.is-fullscreen-mode & {
229
- top: 0;
229
+ top: var(--wp-admin--admin-bar--height, 0);
230
230
  }
231
231
 
232
232
  // Keep it open on focus to avoid conflict with navigate-regions animation.
@@ -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 emotion-10 emotion-11"
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 emotion-10 emotion-11"
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 emotion-4 emotion-5"
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 emotion-4 emotion-5"
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 emotion-10 emotion-11"
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
- __next40pxDefaultSize
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/src/paragraph';
13
- import * as groupBlock from '@wordpress/block-library/src/group';
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