@wordpress/block-library 6.0.10 → 6.0.14

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 (145) hide show
  1. package/build/cover/edit.js +1 -0
  2. package/build/cover/edit.js.map +1 -1
  3. package/build/gallery/deprecated.js +314 -26
  4. package/build/gallery/deprecated.js.map +1 -1
  5. package/build/gallery/edit-wrapper.js +10 -27
  6. package/build/gallery/edit-wrapper.js.map +1 -1
  7. package/build/gallery/edit.js +10 -12
  8. package/build/gallery/edit.js.map +1 -1
  9. package/build/gallery/save.js +3 -3
  10. package/build/gallery/save.js.map +1 -1
  11. package/build/gallery/shared.js +24 -0
  12. package/build/gallery/shared.js.map +1 -1
  13. package/build/gallery/transforms.js +8 -22
  14. package/build/gallery/transforms.js.map +1 -1
  15. package/build/gallery/use-mobile-warning.js +1 -1
  16. package/build/gallery/use-mobile-warning.js.map +1 -1
  17. package/build/gallery/v1/edit.js +2 -21
  18. package/build/gallery/v1/edit.js.map +1 -1
  19. package/build/image/image.js +30 -6
  20. package/build/image/image.js.map +1 -1
  21. package/build/navigation/deprecated.js +9 -7
  22. package/build/navigation/deprecated.js.map +1 -1
  23. package/build/navigation/edit/index.js +12 -1
  24. package/build/navigation/edit/index.js.map +1 -1
  25. package/build/navigation/edit/inner-blocks.js +0 -4
  26. package/build/navigation/edit/inner-blocks.js.map +1 -1
  27. package/build/navigation/edit/navigation-menu-selector.js +7 -1
  28. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  29. package/build/navigation/menu-items-to-blocks.js +4 -1
  30. package/build/navigation/menu-items-to-blocks.js.map +1 -1
  31. package/build/navigation/view.js +2 -2
  32. package/build/navigation/view.js.map +1 -1
  33. package/build/navigation-submenu/edit.js +5 -1
  34. package/build/navigation-submenu/edit.js.map +1 -1
  35. package/build/post-comments/index.js +1 -1
  36. package/build/query-pagination/index.js +1 -1
  37. package/build/query-pagination-next/index.js +2 -2
  38. package/build/query-pagination-numbers/index.js +1 -1
  39. package/build/query-pagination-previous/index.js +2 -2
  40. package/build/separator/separator-settings.js +1 -0
  41. package/build/separator/separator-settings.js.map +1 -1
  42. package/build/social-links/edit.js +1 -0
  43. package/build/social-links/edit.js.map +1 -1
  44. package/build-module/cover/edit.js +1 -0
  45. package/build-module/cover/edit.js.map +1 -1
  46. package/build-module/gallery/deprecated.js +309 -27
  47. package/build-module/gallery/deprecated.js.map +1 -1
  48. package/build-module/gallery/edit-wrapper.js +7 -27
  49. package/build-module/gallery/edit-wrapper.js.map +1 -1
  50. package/build-module/gallery/edit.js +10 -12
  51. package/build-module/gallery/edit.js.map +1 -1
  52. package/build-module/gallery/save.js +2 -3
  53. package/build-module/gallery/save.js.map +1 -1
  54. package/build-module/gallery/shared.js +22 -0
  55. package/build-module/gallery/shared.js.map +1 -1
  56. package/build-module/gallery/transforms.js +9 -21
  57. package/build-module/gallery/transforms.js.map +1 -1
  58. package/build-module/gallery/use-mobile-warning.js +1 -1
  59. package/build-module/gallery/use-mobile-warning.js.map +1 -1
  60. package/build-module/gallery/v1/edit.js +4 -22
  61. package/build-module/gallery/v1/edit.js.map +1 -1
  62. package/build-module/image/image.js +31 -7
  63. package/build-module/image/image.js.map +1 -1
  64. package/build-module/navigation/deprecated.js +9 -7
  65. package/build-module/navigation/deprecated.js.map +1 -1
  66. package/build-module/navigation/edit/index.js +11 -1
  67. package/build-module/navigation/edit/index.js.map +1 -1
  68. package/build-module/navigation/edit/inner-blocks.js +0 -4
  69. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  70. package/build-module/navigation/edit/navigation-menu-selector.js +6 -1
  71. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  72. package/build-module/navigation/menu-items-to-blocks.js +3 -1
  73. package/build-module/navigation/menu-items-to-blocks.js.map +1 -1
  74. package/build-module/navigation/view.js +2 -2
  75. package/build-module/navigation/view.js.map +1 -1
  76. package/build-module/navigation-submenu/edit.js +5 -1
  77. package/build-module/navigation-submenu/edit.js.map +1 -1
  78. package/build-module/post-comments/index.js +1 -1
  79. package/build-module/query-pagination/index.js +1 -1
  80. package/build-module/query-pagination-next/index.js +2 -2
  81. package/build-module/query-pagination-numbers/index.js +1 -1
  82. package/build-module/query-pagination-previous/index.js +2 -2
  83. package/build-module/separator/separator-settings.js +1 -0
  84. package/build-module/separator/separator-settings.js.map +1 -1
  85. package/build-module/social-links/edit.js +1 -0
  86. package/build-module/social-links/edit.js.map +1 -1
  87. package/build-style/columns/editor-rtl.css +1 -1
  88. package/build-style/columns/editor.css +1 -1
  89. package/build-style/editor-rtl.css +26 -1
  90. package/build-style/editor.css +26 -1
  91. package/build-style/image/editor-rtl.css +16 -0
  92. package/build-style/image/editor.css +16 -0
  93. package/build-style/navigation/editor-rtl.css +9 -0
  94. package/build-style/navigation/editor.css +9 -0
  95. package/build-style/navigation/style-rtl.css +5 -1
  96. package/build-style/navigation/style.css +5 -1
  97. package/build-style/post-comments/style-rtl.css +3 -1
  98. package/build-style/post-comments/style.css +3 -1
  99. package/build-style/post-comments-form/style-rtl.css +2 -2
  100. package/build-style/post-comments-form/style.css +2 -2
  101. package/build-style/style-rtl.css +10 -4
  102. package/build-style/style.css +10 -4
  103. package/package.json +8 -8
  104. package/src/columns/editor.scss +3 -2
  105. package/src/cover/edit.js +1 -0
  106. package/src/gallery/deprecated.js +831 -559
  107. package/src/gallery/edit-wrapper.js +7 -27
  108. package/src/gallery/edit.js +10 -12
  109. package/src/gallery/index.php +7 -8
  110. package/src/gallery/save.js +2 -1
  111. package/src/gallery/shared.js +24 -0
  112. package/src/gallery/transforms.js +9 -27
  113. package/src/gallery/use-mobile-warning.js +1 -1
  114. package/src/gallery/v1/edit.js +1 -28
  115. package/src/image/editor.scss +18 -0
  116. package/src/image/image.js +32 -8
  117. package/src/image/index.php +1 -1
  118. package/src/navigation/deprecated.js +10 -9
  119. package/src/navigation/edit/index.js +15 -6
  120. package/src/navigation/edit/inner-blocks.js +0 -5
  121. package/src/navigation/edit/navigation-menu-selector.js +8 -0
  122. package/src/navigation/editor.scss +12 -0
  123. package/src/navigation/index.php +149 -26
  124. package/src/navigation/menu-items-to-blocks.js +7 -1
  125. package/src/navigation/style.scss +5 -1
  126. package/src/navigation/view.js +2 -2
  127. package/src/navigation-submenu/edit.js +7 -1
  128. package/src/navigation-submenu/index.php +30 -45
  129. package/src/page-list/index.php +5 -9
  130. package/src/post-comments/block.json +5 -1
  131. package/src/post-comments/index.php +15 -0
  132. package/src/post-comments/style.scss +7 -3
  133. package/src/post-comments-form/style.scss +7 -5
  134. package/src/query-pagination/block.json +1 -1
  135. package/src/query-pagination-next/block.json +2 -2
  136. package/src/query-pagination-numbers/block.json +1 -1
  137. package/src/query-pagination-previous/block.json +2 -2
  138. package/src/separator/separator-settings.js +1 -0
  139. package/src/social-links/edit.js +1 -0
  140. package/src/template-part/index.php +36 -0
  141. package/build/gallery/v1/update-gallery-modal.js +0 -114
  142. package/build/gallery/v1/update-gallery-modal.js.map +0 -1
  143. package/build-module/gallery/v1/update-gallery-modal.js +0 -97
  144. package/build-module/gallery/v1/update-gallery-modal.js.map +0 -1
  145. package/src/gallery/v1/update-gallery-modal.js +0 -97
@@ -1,47 +1,27 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { store as blockEditorStore } from '@wordpress/block-editor';
5
- import { useSelect } from '@wordpress/data';
4
+ import { compose } from '@wordpress/compose';
5
+ import { withNotices } from '@wordpress/components';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
10
  import EditWithInnerBlocks from './edit';
11
11
  import EditWithoutInnerBlocks from './v1/edit';
12
+ import { isGalleryV2Enabled } from './shared';
12
13
 
13
14
  /*
14
15
  * Using a wrapper around the logic to load the edit for v1 of Gallery block
15
16
  * or the refactored version with InnerBlocks. This is to prevent conditional
16
17
  * use of hooks lint errors if adding this logic to the top of the edit component.
17
18
  */
18
- export default function GalleryEditWrapper( props ) {
19
- const { attributes, clientId } = props;
20
-
21
- const innerBlockImages = useSelect(
22
- ( select ) => {
23
- return select( blockEditorStore ).getBlock( clientId )?.innerBlocks;
24
- },
25
- [ clientId ]
26
- );
27
-
28
- const __unstableGalleryWithImageBlocks = useSelect( ( select ) => {
29
- const settings = select( blockEditorStore ).getSettings();
30
- return settings.__unstableGalleryWithImageBlocks;
31
- }, [] );
32
-
33
- // This logic is used to infer version information from content with higher
34
- // precedence than the flag. New galleries (and existing empty galleries) will
35
- // honor the flag.
36
- const hasNewVersionContent = !! innerBlockImages?.length;
37
- const hasOldVersionContent =
38
- 0 < attributes?.ids?.length || 0 < attributes?.images?.length;
39
- if (
40
- hasOldVersionContent ||
41
- ( ! hasNewVersionContent && ! __unstableGalleryWithImageBlocks )
42
- ) {
19
+ function GalleryEditWrapper( props ) {
20
+ if ( ! isGalleryV2Enabled() ) {
43
21
  return <EditWithoutInnerBlocks { ...props } />;
44
22
  }
45
23
 
46
24
  return <EditWithInnerBlocks { ...props } />;
47
25
  }
26
+
27
+ export default compose( [ withNotices ] )( GalleryEditWrapper );
@@ -144,7 +144,7 @@ function GalleryEdit( props ) {
144
144
  useEffect( () => {
145
145
  newImages?.forEach( ( newImage ) => {
146
146
  updateBlockAttributes( newImage.clientId, {
147
- ...buildImageAttributes( false, newImage.attributes ),
147
+ ...buildImageAttributes( newImage.attributes ),
148
148
  id: newImage.id,
149
149
  align: undefined,
150
150
  } );
@@ -176,26 +176,24 @@ function GalleryEdit( props ) {
176
176
  * it already existed in the gallery. If the image is in fact new, we need
177
177
  * to apply the gallery's current settings to the image.
178
178
  *
179
- * @param {Object} existingBlock Existing Image block that still exists after gallery update.
180
- * @param {Object} image Media object for the actual image.
181
- * @return {Object} Attributes to set on the new image block.
179
+ * @param {Object} imageAttributes Media object for the actual image.
180
+ * @return {Object} Attributes to set on the new image block.
182
181
  */
183
- function buildImageAttributes( existingBlock, image ) {
184
- if ( existingBlock ) {
185
- return existingBlock.attributes;
186
- }
182
+ function buildImageAttributes( imageAttributes ) {
183
+ const image = imageAttributes.id
184
+ ? find( imageData, { id: imageAttributes.id } )
185
+ : null;
187
186
 
188
187
  let newClassName;
189
- if ( image.className && image.className !== '' ) {
190
- newClassName = image.className;
188
+ if ( imageAttributes.className && imageAttributes.className !== '' ) {
189
+ newClassName = imageAttributes.className;
191
190
  } else {
192
191
  newClassName = preferredStyle
193
192
  ? `is-style-${ preferredStyle }`
194
193
  : undefined;
195
194
  }
196
-
197
195
  return {
198
- ...pickRelevantMediaFiles( image, sizeSlug ),
196
+ ...pickRelevantMediaFiles( imageAttributes, sizeSlug ),
199
197
  ...getHrefAndDestination( image, linkTo ),
200
198
  ...getUpdatedLinkTargetSettings( linkTarget, attributes ),
201
199
  className: newClassName,
@@ -1,6 +1,6 @@
1
1
  <?php
2
2
  /**
3
- * Server-side rendering of the `core/image` block.
3
+ * Server-side rendering of the `core/gallery` block.
4
4
  *
5
5
  * @package WordPress
6
6
  */
@@ -13,11 +13,10 @@
13
13
  * we add a custom `data-id` attribute before rendering the gallery
14
14
  * so that the Image Block can pick it up in its render_callback.
15
15
  *
16
- * @param array $parsed_block A single parsed block object.
17
- *
18
- * @return array The migrated block object.
16
+ * @param array $parsed_block The block being rendered.
17
+ * @return array The migrated block object.
19
18
  */
20
- function render_block_core_gallery_data( $parsed_block ) {
19
+ function block_core_gallery_data_id_backcompatibility( $parsed_block ) {
21
20
  if ( 'core/gallery' === $parsed_block['blockName'] ) {
22
21
  foreach ( $parsed_block['innerBlocks'] as $key => $inner_block ) {
23
22
  if ( 'core/image' === $inner_block['blockName'] ) {
@@ -31,14 +30,14 @@ function render_block_core_gallery_data( $parsed_block ) {
31
30
  return $parsed_block;
32
31
  }
33
32
 
34
- add_filter( 'render_block_data', 'render_block_core_gallery_data' );
33
+ add_filter( 'render_block_data', 'block_core_gallery_data_id_backcompatibility' );
35
34
 
36
35
  /**
37
36
  * Registers the `core/gallery` block on server.
38
37
  * This render callback needs to be here
39
38
  * so that the gallery styles are loaded in block-based themes.
40
39
  */
41
- function gutenberg_register_block_core_gallery() {
40
+ function register_block_core_gallery() {
42
41
  register_block_type_from_metadata(
43
42
  __DIR__ . '/gallery',
44
43
  array(
@@ -49,4 +48,4 @@ function gutenberg_register_block_core_gallery() {
49
48
  );
50
49
  }
51
50
 
52
- add_action( 'init', 'gutenberg_register_block_core_gallery', 20 );
51
+ add_action( 'init', 'register_block_core_gallery', 20 );
@@ -16,9 +16,10 @@ import {
16
16
  * Internal dependencies
17
17
  */
18
18
  import saveWithoutInnerBlocks from './v1/save';
19
+ import { isGalleryV2Enabled } from './shared';
19
20
 
20
21
  export default function saveWithInnerBlocks( { attributes } ) {
21
- if ( attributes?.ids?.length > 0 || attributes?.images?.length > 0 ) {
22
+ if ( ! isGalleryV2Enabled() ) {
22
23
  return saveWithoutInnerBlocks( { attributes } );
23
24
  }
24
25
 
@@ -21,3 +21,27 @@ export const pickRelevantMediaFiles = ( image, sizeSlug = 'large' ) => {
21
21
  }
22
22
  return imageProps;
23
23
  };
24
+
25
+ /**
26
+ * The new gallery block format is not compatible with the use_BalanceTags option
27
+ * in WP versions <= 5.8 https://core.trac.wordpress.org/ticket/54130. The
28
+ * window.wp.galleryBlockV2Enabled flag is set in lib/compat.php. This method
29
+ * can be removed when minimum supported WP version >=5.9.
30
+ */
31
+ export function isGalleryV2Enabled() {
32
+ // Only run the Gallery version compat check if the plugin is running, otherwise
33
+ // assume we are in 5.9 core and enable by default.
34
+ if ( process.env.GUTENBERG_PHASE === 2 ) {
35
+ // We want to fail early here, at least during beta testing phase, to ensure
36
+ // there aren't instances where undefined values cause false negatives.
37
+ if (
38
+ ! window.wp ||
39
+ typeof window.wp.galleryBlockV2Enabled !== 'boolean'
40
+ ) {
41
+ throw 'window.wp.galleryBlockV2Enabled is not defined';
42
+ }
43
+ return window.wp.galleryBlockV2Enabled;
44
+ }
45
+
46
+ return true;
47
+ }
@@ -8,8 +8,6 @@ import { filter, every, toString } from 'lodash';
8
8
  */
9
9
  import { createBlock } from '@wordpress/blocks';
10
10
  import { createBlobURL } from '@wordpress/blob';
11
- import { select } from '@wordpress/data';
12
- import { store as blockEditorStore } from '@wordpress/block-editor';
13
11
  import { addFilter } from '@wordpress/hooks';
14
12
 
15
13
  /**
@@ -24,7 +22,7 @@ import {
24
22
  LINK_DESTINATION_ATTACHMENT as DEPRECATED_LINK_DESTINATION_ATTACHMENT,
25
23
  LINK_DESTINATION_MEDIA as DEPRECATED_LINK_DESTINATION_MEDIA,
26
24
  } from './v1/constants';
27
- import { pickRelevantMediaFiles } from './shared';
25
+ import { pickRelevantMediaFiles, isGalleryV2Enabled } from './shared';
28
26
 
29
27
  const parseShortcodeIds = ( ids ) => {
30
28
  if ( ! ids ) {
@@ -49,9 +47,8 @@ const parseShortcodeIds = ( ids ) => {
49
47
  * @return {Block} The transformed block.
50
48
  */
51
49
  function updateThirdPartyTransformToGallery( block ) {
52
- const settings = select( blockEditorStore ).getSettings();
53
50
  if (
54
- settings.__unstableGalleryWithImageBlocks &&
51
+ isGalleryV2Enabled() &&
55
52
  block.name === 'core/gallery' &&
56
53
  block.attributes?.images.length > 0
57
54
  ) {
@@ -145,8 +142,7 @@ const transforms = {
145
142
 
146
143
  const validImages = filter( attributes, ( { url } ) => url );
147
144
 
148
- const settings = select( blockEditorStore ).getSettings();
149
- if ( settings.__unstableGalleryWithImageBlocks ) {
145
+ if ( isGalleryV2Enabled() ) {
150
146
  const innerBlocks = validImages.map( ( image ) => {
151
147
  return createBlock( 'core/image', image );
152
148
  } );
@@ -184,10 +180,7 @@ const transforms = {
184
180
  images: {
185
181
  type: 'array',
186
182
  shortcode: ( { named: { ids } } ) => {
187
- const settings = select(
188
- blockEditorStore
189
- ).getSettings();
190
- if ( ! settings.__unstableGalleryWithImageBlocks ) {
183
+ if ( ! isGalleryV2Enabled() ) {
191
184
  return parseShortcodeIds( ids ).map( ( id ) => ( {
192
185
  id: toString( id ),
193
186
  } ) );
@@ -197,10 +190,7 @@ const transforms = {
197
190
  ids: {
198
191
  type: 'array',
199
192
  shortcode: ( { named: { ids } } ) => {
200
- const settings = select(
201
- blockEditorStore
202
- ).getSettings();
203
- if ( ! settings.__unstableGalleryWithImageBlocks ) {
193
+ if ( ! isGalleryV2Enabled() ) {
204
194
  return parseShortcodeIds( ids );
205
195
  }
206
196
  },
@@ -208,10 +198,7 @@ const transforms = {
208
198
  shortCodeTransforms: {
209
199
  type: 'array',
210
200
  shortcode: ( { named: { ids } } ) => {
211
- const settings = select(
212
- blockEditorStore
213
- ).getSettings();
214
- if ( settings.__unstableGalleryWithImageBlocks ) {
201
+ if ( isGalleryV2Enabled() ) {
215
202
  return parseShortcodeIds( ids ).map( ( id ) => ( {
216
203
  id: parseInt( id ),
217
204
  } ) );
@@ -227,10 +214,7 @@ const transforms = {
227
214
  linkTo: {
228
215
  type: 'string',
229
216
  shortcode: ( { named: { link } } ) => {
230
- const settings = select(
231
- blockEditorStore
232
- ).getSettings();
233
- if ( ! settings.__unstableGalleryWithImageBlocks ) {
217
+ if ( ! isGalleryV2Enabled() ) {
234
218
  switch ( link ) {
235
219
  case 'post':
236
220
  return DEPRECATED_LINK_DESTINATION_ATTACHMENT;
@@ -273,8 +257,7 @@ const transforms = {
273
257
  );
274
258
  },
275
259
  transform( files ) {
276
- const settings = select( blockEditorStore ).getSettings();
277
- if ( settings.__unstableGalleryWithImageBlocks ) {
260
+ if ( isGalleryV2Enabled() ) {
278
261
  const innerBlocks = files.map( ( file ) =>
279
262
  createBlock( 'core/image', {
280
263
  url: createBlobURL( file ),
@@ -299,8 +282,7 @@ const transforms = {
299
282
  type: 'block',
300
283
  blocks: [ 'core/image' ],
301
284
  transform: ( { align, images, ids, sizeSlug }, innerBlocks ) => {
302
- const settings = select( blockEditorStore ).getSettings();
303
- if ( settings.__unstableGalleryWithImageBlocks ) {
285
+ if ( isGalleryV2Enabled() ) {
304
286
  if ( innerBlocks.length > 0 ) {
305
287
  return innerBlocks.map(
306
288
  ( {
@@ -20,7 +20,7 @@ export default function useMobileWarning( newImages ) {
20
20
 
21
21
  createWarningNotice(
22
22
  __(
23
- 'Editing this Gallery in the WordPress mobile app requires version 18.2 or higher.'
23
+ 'If you want to edit the gallery you just added in the mobile app, to avoid losing any data please make sure you use version 18.2 of the app or above.'
24
24
  ),
25
25
  { type: 'snackbar', explicitDismiss: true }
26
26
  );
@@ -24,10 +24,8 @@ import {
24
24
  ToggleControl,
25
25
  withNotices,
26
26
  RangeControl,
27
- ToolbarButton,
28
27
  } from '@wordpress/components';
29
28
  import {
30
- BlockControls,
31
29
  MediaPlaceholder,
32
30
  InspectorControls,
33
31
  useBlockProps,
@@ -53,7 +51,6 @@ import {
53
51
  LINK_DESTINATION_MEDIA,
54
52
  LINK_DESTINATION_NONE,
55
53
  } from './constants';
56
- import UpdateGalleryModal from './update-gallery-modal';
57
54
 
58
55
  const MAX_COLUMNS = 8;
59
56
  const linkOptions = [
@@ -102,13 +99,10 @@ function GalleryEdit( props ) {
102
99
  mediaUpload,
103
100
  getMedia,
104
101
  wasBlockJustInserted,
105
- __unstableGalleryWithImageBlocks,
106
102
  } = useSelect( ( select ) => {
107
103
  const settings = select( blockEditorStore ).getSettings();
108
104
 
109
105
  return {
110
- __unstableGalleryWithImageBlocks:
111
- settings.__unstableGalleryWithImageBlocks,
112
106
  imageSizes: settings.imageSizes,
113
107
  mediaUpload: settings.mediaUpload,
114
108
  getMedia: select( coreStore ).getMedia,
@@ -414,10 +408,6 @@ function GalleryEdit( props ) {
414
408
  />
415
409
  );
416
410
 
417
- const [ isUpdateOpen, setUpdateOpen ] = useState( false );
418
- const openUpdateModal = () => setUpdateOpen( true );
419
- const closeUpdateModal = () => setUpdateOpen( false );
420
-
421
411
  const blockProps = useBlockProps();
422
412
 
423
413
  if ( ! hasImages ) {
@@ -466,24 +456,7 @@ function GalleryEdit( props ) {
466
456
  ) }
467
457
  </PanelBody>
468
458
  </InspectorControls>
469
- { /* TODO: Remove platform condition when native conversion is ready */ }
470
- { Platform.isWeb && __unstableGalleryWithImageBlocks && (
471
- <BlockControls group="other">
472
- <ToolbarButton
473
- onClick={ openUpdateModal }
474
- title={ __( 'Update' ) }
475
- label={ __( 'Update to the new gallery format' ) }
476
- >
477
- { __( 'Update' ) }
478
- </ToolbarButton>
479
- </BlockControls>
480
- ) }
481
- { Platform.isWeb && isUpdateOpen && (
482
- <UpdateGalleryModal
483
- onClose={ closeUpdateModal }
484
- clientId={ clientId }
485
- />
486
- ) }
459
+
487
460
  { noticeUI }
488
461
  <Gallery
489
462
  { ...props }
@@ -70,6 +70,24 @@ figure.wp-block-image:not(.wp-block) {
70
70
  }
71
71
  }
72
72
 
73
+ *:not([data-align]) {
74
+ > .wp-block-image {
75
+ display: grid;
76
+ grid-template-columns: [image] minmax(0, max-content) [placeholder] auto;
77
+ .components-placeholder {
78
+ grid-column: placeholder;
79
+ }
80
+ > div:not(.components-placeholder) {
81
+ grid-column: image;
82
+ }
83
+ > figcaption {
84
+ grid-column: image;
85
+ display: table-caption;
86
+ caption-side: bottom;
87
+ }
88
+ }
89
+ }
90
+
73
91
  .wp-block[data-align="left"] > .wp-block-image {
74
92
  margin-right: 1em;
75
93
  margin-left: 0;
@@ -30,7 +30,7 @@ import {
30
30
  __experimentalImageEditor as ImageEditor,
31
31
  __experimentalImageEditingProvider as ImageEditingProvider,
32
32
  } from '@wordpress/block-editor';
33
- import { useEffect, useState, useRef } from '@wordpress/element';
33
+ import { useEffect, useMemo, useState, useRef } from '@wordpress/element';
34
34
  import { __, sprintf, isRTL } from '@wordpress/i18n';
35
35
  import { getFilename } from '@wordpress/url';
36
36
  import { createBlock, switchToBlockType } from '@wordpress/blocks';
@@ -79,6 +79,7 @@ export default function Image( {
79
79
  context,
80
80
  clientId,
81
81
  } ) {
82
+ const imageRef = useRef();
82
83
  const captionRef = useRef();
83
84
  const prevUrl = usePrevious( url );
84
85
  const { allowResize = true } = context;
@@ -141,7 +142,10 @@ export default function Image( {
141
142
  );
142
143
  const isLargeViewport = useViewportMatch( 'medium' );
143
144
  const isWideAligned = includes( [ 'wide', 'full' ], align );
144
- const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} );
145
+ const [
146
+ { loadedNaturalWidth, loadedNaturalHeight },
147
+ setLoadedNaturalSize,
148
+ ] = useState( {} );
145
149
  const [ isEditingImage, setIsEditingImage ] = useState( false );
146
150
  const [ externalBlob, setExternalBlob ] = useState();
147
151
  const clientWidth = useClientWidth( containerRef, [ align ] );
@@ -179,6 +183,27 @@ export default function Image( {
179
183
  }
180
184
  }, [ url, prevUrl ] );
181
185
 
186
+ // Get naturalWidth and naturalHeight from image ref, and fall back to loaded natural
187
+ // width and height. This resolves an issue in Safari where the loaded natural
188
+ // witdth and height is otherwise lost when switching between alignments.
189
+ // See: https://github.com/WordPress/gutenberg/pull/37210.
190
+ const { naturalWidth, naturalHeight } = useMemo( () => {
191
+ return {
192
+ naturalWidth:
193
+ imageRef.current?.naturalWidth ||
194
+ loadedNaturalWidth ||
195
+ undefined,
196
+ naturalHeight:
197
+ imageRef.current?.naturalHeight ||
198
+ loadedNaturalHeight ||
199
+ undefined,
200
+ };
201
+ }, [
202
+ loadedNaturalWidth,
203
+ loadedNaturalHeight,
204
+ imageRef.current?.complete,
205
+ ] );
206
+
182
207
  function onResizeStart() {
183
208
  toggleSelection( false );
184
209
  }
@@ -411,13 +436,12 @@ export default function Image( {
411
436
  alt={ defaultedAlt }
412
437
  onError={ () => onImageError() }
413
438
  onLoad={ ( event ) => {
414
- setNaturalSize(
415
- pick( event.target, [
416
- 'naturalWidth',
417
- 'naturalHeight',
418
- ] )
419
- );
439
+ setLoadedNaturalSize( {
440
+ loadedNaturalWidth: event.target?.naturalWidth,
441
+ loadedNaturalHeight: event.target?.naturalHeight,
442
+ } );
420
443
  } }
444
+ ref={ imageRef }
421
445
  />
422
446
  { temporaryURL && <Spinner /> }
423
447
  </>
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @param array $attributes The block attributes.
13
13
  * @param array $content The block content.
14
- * @return string Returns the block content with the data-id attribute added.
14
+ * @return string Returns the block content with the data-id attribute added.
15
15
  */
16
16
  function render_block_core_image( $attributes, $content ) {
17
17
  if ( isset( $attributes['data-id'] ) ) {
@@ -33,22 +33,23 @@ const migrateWithLayout = ( attributes ) => {
33
33
  return attributes;
34
34
  }
35
35
 
36
- const { itemsJustification, orientation } = attributes;
37
-
38
- const updatedAttributes = {
39
- ...attributes,
40
- };
36
+ const {
37
+ itemsJustification,
38
+ orientation,
39
+ ...updatedAttributes
40
+ } = attributes;
41
41
 
42
42
  if ( itemsJustification || orientation ) {
43
43
  Object.assign( updatedAttributes, {
44
44
  layout: {
45
45
  type: 'flex',
46
- justifyContent: itemsJustification || 'left',
47
- orientation: orientation || 'horizontal',
46
+ setCascadingProperties: 'true',
47
+ ...( itemsJustification && {
48
+ justifyContent: itemsJustification,
49
+ } ),
50
+ ...( orientation && { orientation } ),
48
51
  },
49
52
  } );
50
- delete updatedAttributes.itemsJustification;
51
- delete updatedAttributes.orientation;
52
53
  }
53
54
 
54
55
  return updatedAttributes;
@@ -2,6 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  import classnames from 'classnames';
5
+ import noop from 'lodash';
5
6
 
6
7
  /**
7
8
  * WordPress dependencies
@@ -109,12 +110,19 @@ function Navigation( {
109
110
  layout: { justifyContent, orientation = 'horizontal' } = {},
110
111
  } = attributes;
111
112
 
112
- const [ areaMenu, setAreaMenu ] = useEntityProp(
113
- 'root',
114
- 'navigationArea',
115
- 'navigation',
116
- navigationArea
117
- );
113
+ let areaMenu,
114
+ setAreaMenu = noop;
115
+ // Navigation areas are deprecated and on their way out. Let's not perform
116
+ // the request unless we're in an environment where the endpoint exists.
117
+ if ( process.env.GUTENBERG_PHASE === 2 ) {
118
+ // eslint-disable-next-line react-hooks/rules-of-hooks
119
+ [ areaMenu, setAreaMenu ] = useEntityProp(
120
+ 'root',
121
+ 'navigationArea',
122
+ 'navigation',
123
+ navigationArea
124
+ );
125
+ }
118
126
 
119
127
  const navigationAreaMenu = areaMenu === 0 ? undefined : areaMenu;
120
128
 
@@ -437,6 +445,7 @@ function Navigation( {
437
445
  { hasColorSettings && (
438
446
  <PanelColorSettings
439
447
  __experimentalHasMultipleOrigins
448
+ __experimentalIsRenderedInSidebar
440
449
  title={ __( 'Color' ) }
441
450
  initialOpen={ false }
442
451
  colorSettings={ [
@@ -110,11 +110,6 @@ export default function NavigationInnerBlocks( {
110
110
  __experimentalDirectInsert: shouldDirectInsert,
111
111
  orientation,
112
112
  renderAppender: CustomAppender || appender,
113
-
114
- // Ensure block toolbar is not too far removed from item
115
- // being edited when in vertical mode.
116
- // see: https://github.com/WordPress/gutenberg/pull/34615.
117
- __experimentalCaptureToolbars: orientation !== 'vertical',
118
113
  // Template lock set to false here so that the Nav
119
114
  // Block on the experimental menus screen does not
120
115
  // inherit templateLock={ 'all' }.
@@ -5,6 +5,7 @@ import { MenuGroup, MenuItem, MenuItemsChoice } from '@wordpress/components';
5
5
  import { useEntityId } from '@wordpress/core-data';
6
6
  import { __, sprintf } from '@wordpress/i18n';
7
7
  import { decodeEntities } from '@wordpress/html-entities';
8
+ import { addQueryArgs } from '@wordpress/url';
8
9
 
9
10
  /**
10
11
  * Internal dependencies
@@ -45,6 +46,13 @@ export default function NavigationMenuSelector( { onSelect, onCreateNew } ) {
45
46
  <MenuItem onClick={ onCreateNew }>
46
47
  { __( 'Create new menu' ) }
47
48
  </MenuItem>
49
+ <MenuItem
50
+ href={ addQueryArgs( 'edit.php', {
51
+ post_type: 'wp_navigation',
52
+ } ) }
53
+ >
54
+ { __( 'Manage menus' ) }
55
+ </MenuItem>
48
56
  </MenuGroup>
49
57
  </>
50
58
  );
@@ -96,6 +96,18 @@
96
96
  }
97
97
  }
98
98
 
99
+ // Show even when a child is selected. This is an edgecase just for navigation submenus.
100
+ .is-editing > .wp-block-navigation__submenu-container > .block-list-appender {
101
+ display: block;
102
+ position: static;
103
+ }
104
+
105
+ // Hide when hovering.
106
+ .wp-block-navigation__submenu-container .block-list-appender {
107
+ display: none;
108
+ }
109
+
110
+
99
111
  /**
100
112
  * Colors Selector component
101
113
  */