@wordpress/block-library 6.0.8 → 6.0.12

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 (214) hide show
  1. package/build/cover/edit.js +9 -3
  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 +11 -13
  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/index.js +4 -3
  20. package/build/index.js.map +1 -1
  21. package/build/navigation/deprecated.js +127 -19
  22. package/build/navigation/deprecated.js.map +1 -1
  23. package/build/navigation/edit/index.js +46 -31
  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 +2 -2
  28. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  29. package/build/navigation/edit/placeholder/index.js +16 -48
  30. package/build/navigation/edit/placeholder/index.js.map +1 -1
  31. package/build/navigation/edit/unsaved-inner-blocks.js +4 -35
  32. package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  33. package/build/navigation/edit/use-create-navigation-menu.js +50 -0
  34. package/build/navigation/edit/use-create-navigation-menu.js.map +1 -0
  35. package/build/navigation/edit/use-generate-default-navigation-title.js +73 -0
  36. package/build/navigation/edit/use-generate-default-navigation-title.js.map +1 -0
  37. package/build/navigation/index.js +1 -1
  38. package/build/navigation/save.js +2 -2
  39. package/build/navigation/save.js.map +1 -1
  40. package/build/navigation/use-navigation-menu.js +19 -8
  41. package/build/navigation/use-navigation-menu.js.map +1 -1
  42. package/build/navigation-area/edit.js +5 -0
  43. package/build/navigation-area/edit.js.map +1 -1
  44. package/build/navigation-submenu/edit.js +4 -0
  45. package/build/navigation-submenu/edit.js.map +1 -1
  46. package/build/pattern/index.js +1 -1
  47. package/build/post-featured-image/edit.js +2 -3
  48. package/build/post-featured-image/edit.js.map +1 -1
  49. package/build/post-terms/index.js +1 -1
  50. package/build/post-title/edit.js +2 -2
  51. package/build/post-title/edit.js.map +1 -1
  52. package/build/query-pagination/index.js +1 -1
  53. package/build/query-pagination-next/index.js +2 -2
  54. package/build/query-pagination-numbers/index.js +1 -1
  55. package/build/query-pagination-previous/index.js +2 -2
  56. package/build/query-title/index.js +1 -1
  57. package/build/separator/separator-settings.js +1 -0
  58. package/build/separator/separator-settings.js.map +1 -1
  59. package/build/site-logo/index.js +1 -1
  60. package/build/site-tagline/index.js +1 -1
  61. package/build/site-title/index.js +1 -1
  62. package/build/social-links/edit.js +1 -0
  63. package/build/social-links/edit.js.map +1 -1
  64. package/build/template-part/edit/placeholder/index.js +1 -1
  65. package/build/template-part/edit/placeholder/index.js.map +1 -1
  66. package/build/template-part/index.js +2 -1
  67. package/build/template-part/index.js.map +1 -1
  68. package/build-module/cover/edit.js +9 -3
  69. package/build-module/cover/edit.js.map +1 -1
  70. package/build-module/gallery/deprecated.js +309 -27
  71. package/build-module/gallery/deprecated.js.map +1 -1
  72. package/build-module/gallery/edit-wrapper.js +7 -27
  73. package/build-module/gallery/edit-wrapper.js.map +1 -1
  74. package/build-module/gallery/edit.js +11 -13
  75. package/build-module/gallery/edit.js.map +1 -1
  76. package/build-module/gallery/save.js +2 -3
  77. package/build-module/gallery/save.js.map +1 -1
  78. package/build-module/gallery/shared.js +22 -0
  79. package/build-module/gallery/shared.js.map +1 -1
  80. package/build-module/gallery/transforms.js +9 -21
  81. package/build-module/gallery/transforms.js.map +1 -1
  82. package/build-module/gallery/use-mobile-warning.js +1 -1
  83. package/build-module/gallery/use-mobile-warning.js.map +1 -1
  84. package/build-module/gallery/v1/edit.js +4 -22
  85. package/build-module/gallery/v1/edit.js.map +1 -1
  86. package/build-module/index.js +4 -3
  87. package/build-module/index.js.map +1 -1
  88. package/build-module/navigation/deprecated.js +127 -19
  89. package/build-module/navigation/deprecated.js.map +1 -1
  90. package/build-module/navigation/edit/index.js +47 -31
  91. package/build-module/navigation/edit/index.js.map +1 -1
  92. package/build-module/navigation/edit/inner-blocks.js +0 -4
  93. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  94. package/build-module/navigation/edit/navigation-menu-selector.js +2 -2
  95. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  96. package/build-module/navigation/edit/placeholder/index.js +15 -45
  97. package/build-module/navigation/edit/placeholder/index.js.map +1 -1
  98. package/build-module/navigation/edit/unsaved-inner-blocks.js +6 -35
  99. package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  100. package/build-module/navigation/edit/use-create-navigation-menu.js +36 -0
  101. package/build-module/navigation/edit/use-create-navigation-menu.js.map +1 -0
  102. package/build-module/navigation/edit/use-generate-default-navigation-title.js +57 -0
  103. package/build-module/navigation/edit/use-generate-default-navigation-title.js.map +1 -0
  104. package/build-module/navigation/index.js +1 -1
  105. package/build-module/navigation/save.js +2 -2
  106. package/build-module/navigation/save.js.map +1 -1
  107. package/build-module/navigation/use-navigation-menu.js +19 -8
  108. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  109. package/build-module/navigation-area/edit.js +4 -0
  110. package/build-module/navigation-area/edit.js.map +1 -1
  111. package/build-module/navigation-submenu/edit.js +4 -0
  112. package/build-module/navigation-submenu/edit.js.map +1 -1
  113. package/build-module/pattern/index.js +1 -1
  114. package/build-module/post-featured-image/edit.js +2 -3
  115. package/build-module/post-featured-image/edit.js.map +1 -1
  116. package/build-module/post-terms/index.js +1 -1
  117. package/build-module/post-title/edit.js +2 -2
  118. package/build-module/post-title/edit.js.map +1 -1
  119. package/build-module/query-pagination/index.js +1 -1
  120. package/build-module/query-pagination-next/index.js +2 -2
  121. package/build-module/query-pagination-numbers/index.js +1 -1
  122. package/build-module/query-pagination-previous/index.js +2 -2
  123. package/build-module/query-title/index.js +1 -1
  124. package/build-module/separator/separator-settings.js +1 -0
  125. package/build-module/separator/separator-settings.js.map +1 -1
  126. package/build-module/site-logo/index.js +1 -1
  127. package/build-module/site-tagline/index.js +1 -1
  128. package/build-module/site-title/index.js +1 -1
  129. package/build-module/social-links/edit.js +1 -0
  130. package/build-module/social-links/edit.js.map +1 -1
  131. package/build-module/template-part/edit/placeholder/index.js +2 -2
  132. package/build-module/template-part/edit/placeholder/index.js.map +1 -1
  133. package/build-module/template-part/index.js +2 -1
  134. package/build-module/template-part/index.js.map +1 -1
  135. package/build-style/columns/editor-rtl.css +1 -1
  136. package/build-style/columns/editor.css +1 -1
  137. package/build-style/editor-rtl.css +6 -5
  138. package/build-style/editor.css +6 -5
  139. package/build-style/gallery/editor-rtl.css +1 -0
  140. package/build-style/gallery/editor.css +1 -0
  141. package/build-style/navigation/style-rtl.css +12 -3
  142. package/build-style/navigation/style.css +12 -3
  143. package/build-style/post-featured-image/editor-rtl.css +2 -2
  144. package/build-style/post-featured-image/editor.css +2 -2
  145. package/build-style/site-logo/editor-rtl.css +2 -2
  146. package/build-style/site-logo/editor.css +2 -2
  147. package/build-style/style-rtl.css +12 -3
  148. package/build-style/style.css +12 -3
  149. package/package.json +9 -9
  150. package/src/calendar/index.php +2 -2
  151. package/src/columns/editor.scss +3 -2
  152. package/src/cover/edit.js +9 -1
  153. package/src/gallery/deprecated.js +831 -559
  154. package/src/gallery/edit-wrapper.js +7 -27
  155. package/src/gallery/edit.js +11 -13
  156. package/src/gallery/editor.scss +1 -0
  157. package/src/gallery/save.js +2 -1
  158. package/src/gallery/shared.js +24 -0
  159. package/src/gallery/transforms.js +9 -27
  160. package/src/gallery/use-mobile-warning.js +1 -1
  161. package/src/gallery/v1/edit.js +1 -28
  162. package/src/index.js +28 -26
  163. package/src/navigation/block.json +1 -1
  164. package/src/navigation/deprecated.js +115 -13
  165. package/src/navigation/edit/index.js +44 -36
  166. package/src/navigation/edit/inner-blocks.js +0 -5
  167. package/src/navigation/edit/navigation-menu-selector.js +2 -2
  168. package/src/navigation/edit/placeholder/index.js +16 -62
  169. package/src/navigation/edit/unsaved-inner-blocks.js +6 -57
  170. package/src/navigation/edit/use-create-navigation-menu.js +39 -0
  171. package/src/navigation/edit/use-generate-default-navigation-title.js +79 -0
  172. package/src/navigation/index.php +263 -26
  173. package/src/navigation/save.js +2 -2
  174. package/src/navigation/style.scss +15 -4
  175. package/src/navigation/use-navigation-menu.js +20 -9
  176. package/src/navigation-area/edit.js +5 -0
  177. package/src/navigation-area/index.php +1 -0
  178. package/src/navigation-submenu/edit.js +6 -0
  179. package/src/navigation-submenu/index.php +30 -45
  180. package/src/page-list/index.php +14 -13
  181. package/src/pattern/block.json +1 -1
  182. package/src/post-featured-image/edit.js +2 -5
  183. package/src/post-featured-image/editor.scss +2 -2
  184. package/src/post-terms/block.json +1 -1
  185. package/src/post-title/edit.js +2 -2
  186. package/src/query-pagination/block.json +1 -1
  187. package/src/query-pagination-next/block.json +2 -2
  188. package/src/query-pagination-numbers/block.json +1 -1
  189. package/src/query-pagination-previous/block.json +2 -2
  190. package/src/query-title/block.json +1 -1
  191. package/src/separator/separator-settings.js +1 -0
  192. package/src/site-logo/block.json +1 -1
  193. package/src/site-logo/editor.scss +2 -2
  194. package/src/site-tagline/block.json +1 -1
  195. package/src/site-title/block.json +1 -1
  196. package/src/social-links/edit.js +1 -0
  197. package/src/template-part/block.json +2 -1
  198. package/src/template-part/edit/placeholder/index.js +2 -2
  199. package/src/template-part/index.php +38 -1
  200. package/build/gallery/v1/update-gallery-modal.js +0 -114
  201. package/build/gallery/v1/update-gallery-modal.js.map +0 -1
  202. package/build/navigation/edit/navigation-menu-name-modal.js +0 -55
  203. package/build/navigation/edit/navigation-menu-name-modal.js.map +0 -1
  204. package/build/navigation/edit/navigation-menu-publish-button.js +0 -53
  205. package/build/navigation/edit/navigation-menu-publish-button.js.map +0 -1
  206. package/build-module/gallery/v1/update-gallery-modal.js +0 -97
  207. package/build-module/gallery/v1/update-gallery-modal.js.map +0 -1
  208. package/build-module/navigation/edit/navigation-menu-name-modal.js +0 -47
  209. package/build-module/navigation/edit/navigation-menu-name-modal.js.map +0 -1
  210. package/build-module/navigation/edit/navigation-menu-publish-button.js +0 -40
  211. package/build-module/navigation/edit/navigation-menu-publish-button.js.map +0 -1
  212. package/src/gallery/v1/update-gallery-modal.js +0 -97
  213. package/src/navigation/edit/navigation-menu-name-modal.js +0 -69
  214. package/src/navigation/edit/navigation-menu-publish-button.js +0 -57
@@ -5,11 +5,126 @@
5
5
  * @package WordPress
6
6
  */
7
7
 
8
+ // These functions are used for the __unstableLocation feature and only active
9
+ // when the gutenberg plugin is active.
10
+ if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
11
+ /**
12
+ * Returns the menu items for a WordPress menu location.
13
+ *
14
+ * @param string $location The menu location.
15
+ * @return array Menu items for the location.
16
+ */
17
+ function block_core_navigation_get_menu_items_at_location( $location ) {
18
+ if ( empty( $location ) ) {
19
+ return;
20
+ }
21
+
22
+ // Build menu data. The following approximates the code in
23
+ // `wp_nav_menu()` and `gutenberg_output_block_nav_menu`.
24
+
25
+ // Find the location in the list of locations, returning early if the
26
+ // location can't be found.
27
+ $locations = get_nav_menu_locations();
28
+ if ( ! isset( $locations[ $location ] ) ) {
29
+ return;
30
+ }
31
+
32
+ // Get the menu from the location, returning early if there is no
33
+ // menu or there was an error.
34
+ $menu = wp_get_nav_menu_object( $locations[ $location ] );
35
+ if ( ! $menu || is_wp_error( $menu ) ) {
36
+ return;
37
+ }
38
+
39
+ $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
40
+ _wp_menu_item_classes_by_context( $menu_items );
41
+
42
+ return $menu_items;
43
+ }
44
+
45
+
46
+ /**
47
+ * Sorts a standard array of menu items into a nested structure keyed by the
48
+ * id of the parent menu.
49
+ *
50
+ * @param array $menu_items Menu items to sort.
51
+ * @return array An array keyed by the id of the parent menu where each element
52
+ * is an array of menu items that belong to that parent.
53
+ */
54
+ function block_core_navigation_sort_menu_items_by_parent_id( $menu_items ) {
55
+ $sorted_menu_items = array();
56
+ foreach ( (array) $menu_items as $menu_item ) {
57
+ $sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
58
+ }
59
+ unset( $menu_items, $menu_item );
60
+
61
+ $menu_items_by_parent_id = array();
62
+ foreach ( $sorted_menu_items as $menu_item ) {
63
+ $menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item;
64
+ }
65
+
66
+ return $menu_items_by_parent_id;
67
+ }
68
+
69
+ /**
70
+ * Turns menu item data into a nested array of parsed blocks
71
+ *
72
+ * @param array $menu_items An array of menu items that represent
73
+ * an individual level of a menu.
74
+ * @param array $menu_items_by_parent_id An array keyed by the id of the
75
+ * parent menu where each element is an
76
+ * array of menu items that belong to
77
+ * that parent.
78
+ * @return array An array of parsed block data.
79
+ */
80
+ function block_core_navigation_parse_blocks_from_menu_items( $menu_items, $menu_items_by_parent_id ) {
81
+ if ( empty( $menu_items ) ) {
82
+ return array();
83
+ }
84
+
85
+ $blocks = array();
86
+
87
+ foreach ( $menu_items as $menu_item ) {
88
+ $class_name = ! empty( $menu_item->classes ) ? implode( ' ', (array) $menu_item->classes ) : null;
89
+ $id = ( null !== $menu_item->object_id && 'custom' !== $menu_item->object ) ? $menu_item->object_id : null;
90
+ $opens_in_new_tab = null !== $menu_item->target && '_blank' === $menu_item->target;
91
+ $rel = ( null !== $menu_item->xfn && '' !== $menu_item->xfn ) ? $menu_item->xfn : null;
92
+ $kind = null !== $menu_item->type ? str_replace( '_', '-', $menu_item->type ) : 'custom';
93
+
94
+ $block = array(
95
+ 'blockName' => isset( $menu_items_by_parent_id[ $menu_item->ID ] ) ? 'core/navigation-submenu' : 'core/navigation-link',
96
+ 'attrs' => array(
97
+ 'className' => $class_name,
98
+ 'description' => $menu_item->description,
99
+ 'id' => $id,
100
+ 'kind' => $kind,
101
+ 'label' => $menu_item->title,
102
+ 'opensInNewTab' => $opens_in_new_tab,
103
+ 'rel' => $rel,
104
+ 'title' => $menu_item->attr_title,
105
+ 'type' => $menu_item->object,
106
+ 'url' => $menu_item->url,
107
+ ),
108
+ );
109
+
110
+ $block['innerBlocks'] = isset( $menu_items_by_parent_id[ $menu_item->ID ] )
111
+ ? block_core_navigation_parse_blocks_from_menu_items( $menu_items_by_parent_id[ $menu_item->ID ], $menu_items_by_parent_id )
112
+ : array();
113
+ $block['innerContent'] = array_map( 'serialize_block', $block['innerBlocks'] );
114
+
115
+ $blocks[] = $block;
116
+ }
117
+
118
+ return $blocks;
119
+ }
120
+ }
121
+
8
122
  /**
9
123
  * Build an array with CSS classes and inline styles defining the colors
10
124
  * which will be applied to the navigation markup in the front-end.
11
125
  *
12
- * @param array $attributes Navigation block attributes.
126
+ * @param array $attributes Navigation block attributes.
127
+ *
13
128
  * @return array Colors CSS classes and inline styles.
14
129
  */
15
130
  function block_core_navigation_build_css_colors( $attributes ) {
@@ -99,7 +214,8 @@ function block_core_navigation_build_css_colors( $attributes ) {
99
214
  * Build an array with CSS classes and inline styles defining the font sizes
100
215
  * which will be applied to the navigation markup in the front-end.
101
216
  *
102
- * @param array $attributes Navigation block attributes.
217
+ * @param array $attributes Navigation block attributes.
218
+ *
103
219
  * @return array Font size CSS classes and inline styles.
104
220
  */
105
221
  function block_core_navigation_build_css_font_sizes( $attributes ) {
@@ -132,6 +248,106 @@ function block_core_navigation_render_submenu_icon() {
132
248
  return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
133
249
  }
134
250
 
251
+
252
+ /**
253
+ * Finds the first non-empty `wp_navigation` Post.
254
+ *
255
+ * @return WP_Post|null the first non-empty Navigation or null.
256
+ */
257
+ function block_core_navigation_get_first_non_empty_navigation() {
258
+ // Order and orderby args set to mirror those in `wp_get_nav_menus`
259
+ // see:
260
+ // - https://github.com/WordPress/wordpress-develop/blob/ba943e113d3b31b121f77a2d30aebe14b047c69d/src/wp-includes/nav-menu.php#L613-L619.
261
+ // - https://developer.wordpress.org/reference/classes/wp_query/#order-orderby-parameters.
262
+ $parsed_args = array(
263
+ 'post_type' => 'wp_navigation',
264
+ 'no_found_rows' => true,
265
+ 'order' => 'ASC',
266
+ 'orderby' => 'name',
267
+ 'post_status' => 'publish',
268
+ 'posts_per_page' => 20, // Try the first 20 posts.
269
+ );
270
+
271
+ $navigation_posts = new WP_Query( $parsed_args );
272
+ foreach ( $navigation_posts->posts as $navigation_post ) {
273
+ if ( has_blocks( $navigation_post ) ) {
274
+ return $navigation_post;
275
+ }
276
+ }
277
+
278
+ return null;
279
+ }
280
+
281
+ /**
282
+ * Filter out empty "null" blocks from the block list.
283
+ * 'parse_blocks' includes a null block with '\n\n' as the content when
284
+ * it encounters whitespace. This is not a bug but rather how the parser
285
+ * is designed.
286
+ *
287
+ * @param array $parsed_blocks the parsed blocks to be normalized.
288
+ * @return array the normalized parsed blocks.
289
+ */
290
+ function block_core_navigation_filter_out_empty_blocks( $parsed_blocks ) {
291
+ $filtered = array_filter(
292
+ $parsed_blocks,
293
+ function( $block ) {
294
+ return isset( $block['blockName'] );
295
+ }
296
+ );
297
+
298
+ // Reset keys.
299
+ return array_values( $filtered );
300
+ }
301
+
302
+ /**
303
+ * Retrieves the appropriate fallback to be used on the front of the
304
+ * site when there is no menu assigned to the Nav block.
305
+ *
306
+ * This aims to mirror how the fallback mechanic for wp_nav_menu works.
307
+ * See https://developer.wordpress.org/reference/functions/wp_nav_menu/#more-information.
308
+ *
309
+ * @return array the array of blocks to be used as a fallback.
310
+ */
311
+ function block_core_navigation_get_fallback_blocks() {
312
+ $page_list_fallback = array(
313
+ array(
314
+ 'blockName' => 'core/page-list',
315
+ 'attrs' => array(
316
+ '__unstableMaxPages' => 4,
317
+ ),
318
+ ),
319
+ );
320
+
321
+ $registry = WP_Block_Type_Registry::get_instance();
322
+
323
+ // If `core/page-list` is not registered then return empty blocks.
324
+ $fallback_blocks = $registry->is_registered( 'core/page-list' ) ? $page_list_fallback : array();
325
+
326
+ // Default to a list of Pages.
327
+
328
+ $navigation_post = block_core_navigation_get_first_non_empty_navigation();
329
+
330
+ // Prefer using the first non-empty Navigation as fallback if available.
331
+ if ( $navigation_post ) {
332
+ $maybe_fallback = block_core_navigation_filter_out_empty_blocks( parse_blocks( $navigation_post->post_content ) );
333
+
334
+ // Normalizing blocks may result in an empty array of blocks if they were all `null` blocks.
335
+ // In this case default to the (Page List) fallback.
336
+ $fallback_blocks = ! empty( $maybe_fallback ) ? $maybe_fallback : $fallback_blocks;
337
+ }
338
+
339
+ /**
340
+ * Filters the fallback experience for the Navigation block.
341
+ *
342
+ * Returning a falsey value will opt out of the fallback and cause the block not to render.
343
+ * To customise the blocks provided return an array of blocks - these should be valid
344
+ * children of the `core/navigation` block.
345
+ *
346
+ * @param array[] default fallback blocks provided by the default block mechanic.
347
+ */
348
+ return apply_filters( 'block_core_navigation_render_fallback', $fallback_blocks );
349
+ }
350
+
135
351
  /**
136
352
  * Renders the `core/navigation` block on server.
137
353
  *
@@ -142,6 +358,11 @@ function block_core_navigation_render_submenu_icon() {
142
358
  * @return string Returns the post content with the legacy widget added.
143
359
  */
144
360
  function render_block_core_navigation( $attributes, $content, $block ) {
361
+
362
+ // Flag used to indicate whether the rendered output is considered to be
363
+ // a fallback (i.e. the block has no menu associated with it).
364
+ $is_fallback = false;
365
+
145
366
  /**
146
367
  * Deprecated:
147
368
  * The rgbTextColor and rgbBackgroundColor attributes
@@ -171,29 +392,36 @@ function render_block_core_navigation( $attributes, $content, $block ) {
171
392
 
172
393
  $inner_blocks = $block->inner_blocks;
173
394
 
174
- // If `__unstableLocation` is defined, create inner blocks from the classic menu assigned to that location.
175
- if ( empty( $inner_blocks ) && array_key_exists( '__unstableLocation', $attributes ) ) {
176
- $menu_items = gutenberg_get_menu_items_at_location( $attributes['__unstableLocation'] );
395
+ // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
396
+ if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
397
+ $attributes['ref'] = $attributes['navigationMenuId'];
398
+ }
399
+
400
+ // If:
401
+ // - the gutenberg plugin is active
402
+ // - `__unstableLocation` is defined
403
+ // - we have menu items at the defined location
404
+ // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
405
+ // ...then create inner blocks from the classic menu assigned to that location.
406
+ if (
407
+ defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN &&
408
+ array_key_exists( '__unstableLocation', $attributes ) &&
409
+ ! array_key_exists( 'ref', $attributes ) &&
410
+ ! empty( block_core_navigation_get_menu_items_at_location( $attributes['__unstableLocation'] ) )
411
+ ) {
412
+ $menu_items = block_core_navigation_get_menu_items_at_location( $attributes['__unstableLocation'] );
177
413
  if ( empty( $menu_items ) ) {
178
414
  return '';
179
415
  }
180
416
 
181
- $menu_items_by_parent_id = gutenberg_sort_menu_items_by_parent_id( $menu_items );
182
- $parsed_blocks = gutenberg_parse_blocks_from_menu_items( $menu_items_by_parent_id[0], $menu_items_by_parent_id );
417
+ $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id( $menu_items );
418
+ $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items( $menu_items_by_parent_id[0], $menu_items_by_parent_id );
183
419
  $inner_blocks = new WP_Block_List( $parsed_blocks, $attributes );
184
420
  }
185
421
 
186
- if ( ! empty( $block->context['navigationArea'] ) ) {
187
- $area = $block->context['navigationArea'];
188
- $mapping = get_option( 'wp_navigation_areas', array() );
189
- if ( ! empty( $mapping[ $area ] ) ) {
190
- $attributes['navigationMenuId'] = $mapping[ $area ];
191
- }
192
- }
193
-
194
422
  // Load inner blocks from the navigation post.
195
- if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
196
- $navigation_post = get_post( $attributes['navigationMenuId'] );
423
+ if ( array_key_exists( 'ref', $attributes ) ) {
424
+ $navigation_post = get_post( $attributes['ref'] );
197
425
  if ( ! isset( $navigation_post ) ) {
198
426
  return '';
199
427
  }
@@ -202,20 +430,26 @@ function render_block_core_navigation( $attributes, $content, $block ) {
202
430
 
203
431
  // 'parse_blocks' includes a null block with '\n\n' as the content when
204
432
  // it encounters whitespace. This code strips it.
205
- $compacted_blocks = array_filter(
206
- $parsed_blocks,
207
- function( $block ) {
208
- return isset( $block['blockName'] );
209
- }
210
- );
433
+ $compacted_blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks );
211
434
 
212
435
  // TODO - this uses the full navigation block attributes for the
213
436
  // context which could be refined.
214
437
  $inner_blocks = new WP_Block_List( $compacted_blocks, $attributes );
215
438
  }
216
439
 
440
+ // If there are no inner blocks then fallback to rendering an appropriate fallback.
217
441
  if ( empty( $inner_blocks ) ) {
218
- return '';
442
+ $is_fallback = true; // indicate we are rendering the fallback.
443
+
444
+ $fallback_blocks = block_core_navigation_get_fallback_blocks();
445
+
446
+ // Fallback my have been filtered so do basic test for validity.
447
+ if ( empty( $fallback_blocks ) || ! is_array( $fallback_blocks ) ) {
448
+ return '';
449
+ }
450
+
451
+ $inner_blocks = new WP_Block_List( $fallback_blocks, $attributes );
452
+
219
453
  }
220
454
 
221
455
  // Restore legacy classnames for submenu positioning.
@@ -234,7 +468,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
234
468
  $colors['css_classes'],
235
469
  $font_sizes['css_classes'],
236
470
  $is_responsive_menu ? array( 'is-responsive' ) : array(),
237
- $layout_class ? array( $layout_class ) : array()
471
+ $layout_class ? array( $layout_class ) : array(),
472
+ $is_fallback ? array( 'is-fallback' ) : array()
238
473
  );
239
474
 
240
475
  $inner_blocks_html = '';
@@ -323,8 +558,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
323
558
  /**
324
559
  * Register the navigation block.
325
560
  *
326
- * @uses render_block_core_navigation()
327
561
  * @throws WP_Error An WP_Error exception parsing the block definition.
562
+ * @uses render_block_core_navigation()
328
563
  */
329
564
  function register_block_core_navigation() {
330
565
  register_block_type_from_metadata(
@@ -341,6 +576,7 @@ add_action( 'init', 'register_block_core_navigation' );
341
576
  * Filter that changes the parsed attribute values of navigation blocks contain typographic presets to contain the values directly.
342
577
  *
343
578
  * @param array $parsed_block The block being rendered.
579
+ *
344
580
  * @return array The block being rendered without typographic presets.
345
581
  */
346
582
  function block_core_navigation_typographic_presets_backcompatibility( $parsed_block ) {
@@ -364,6 +600,7 @@ function block_core_navigation_typographic_presets_backcompatibility( $parsed_bl
364
600
  }
365
601
  }
366
602
  }
603
+
367
604
  return $parsed_block;
368
605
  }
369
606
 
@@ -4,8 +4,8 @@
4
4
  import { InnerBlocks } from '@wordpress/block-editor';
5
5
 
6
6
  export default function save( { attributes } ) {
7
- if ( attributes.navigationMenuId ) {
8
- // Avoid rendering inner blocks when a navigationMenuId is defined.
7
+ if ( attributes.ref ) {
8
+ // Avoid rendering inner blocks when a ref is defined.
9
9
  // When this id is defined the inner blocks are loaded from the
10
10
  // `wp_navigation` entity rather than the hard-coded block html.
11
11
  return;
@@ -78,10 +78,11 @@
78
78
 
79
79
  // Submenu indicator.
80
80
  .wp-block-navigation__submenu-icon {
81
- align-self: center;
82
- height: inherit;
81
+ align-self: center; // This one affects nested submenu indicators.
83
82
  line-height: 0;
84
- margin-left: 6px;
83
+ display: inline-block;
84
+ vertical-align: middle;
85
+ font-size: inherit;
85
86
 
86
87
  // Affect the button as well.
87
88
  padding: 0;
@@ -89,9 +90,16 @@
89
90
  color: currentColor;
90
91
  border: none;
91
92
 
93
+ // Scale to font size.
94
+ margin-left: 0.25em;
95
+ width: 0.6em;
96
+ height: 0.6em;
97
+
92
98
  svg {
93
99
  display: inline-block;
94
100
  stroke: currentColor;
101
+ width: inherit;
102
+ height: inherit;
95
103
  }
96
104
  }
97
105
  }
@@ -418,7 +426,10 @@ button.wp-block-navigation-item__content {
418
426
  align-items: var(--layout-justification-setting, inherit);
419
427
 
420
428
  // Always align the contents of the menu to the top.
421
- justify-content: flex-start;
429
+ &,
430
+ .wp-block-navigation__container {
431
+ justify-content: flex-start;
432
+ }
422
433
 
423
434
  // Allow menu to scroll.
424
435
  overflow: auto;
@@ -4,10 +4,11 @@
4
4
  import { store as coreStore } from '@wordpress/core-data';
5
5
  import { useSelect } from '@wordpress/data';
6
6
 
7
- export default function useNavigationMenu( navigationMenuId ) {
7
+ export default function useNavigationMenu( ref ) {
8
8
  return useSelect(
9
9
  ( select ) => {
10
10
  const {
11
+ getEntityRecord,
11
12
  getEditedEntityRecord,
12
13
  getEntityRecords,
13
14
  hasFinishedResolution,
@@ -16,12 +17,22 @@ export default function useNavigationMenu( navigationMenuId ) {
16
17
  const navigationMenuSingleArgs = [
17
18
  'postType',
18
19
  'wp_navigation',
19
- navigationMenuId,
20
+ ref,
20
21
  ];
21
- const navigationMenu = navigationMenuId
22
+ const rawNavigationMenu = ref
23
+ ? getEntityRecord( ...navigationMenuSingleArgs )
24
+ : null;
25
+ let navigationMenu = ref
22
26
  ? getEditedEntityRecord( ...navigationMenuSingleArgs )
23
27
  : null;
24
- const hasResolvedNavigationMenu = navigationMenuId
28
+
29
+ // getEditedEntityRecord will return the post regardless of status.
30
+ // Therefore if the found post is not published then we should ignore it.
31
+ if ( navigationMenu?.status !== 'publish' ) {
32
+ navigationMenu = null;
33
+ }
34
+
35
+ const hasResolvedNavigationMenu = ref
25
36
  ? hasFinishedResolution(
26
37
  'getEditedEntityRecord',
27
38
  navigationMenuSingleArgs
@@ -31,21 +42,21 @@ export default function useNavigationMenu( navigationMenuId ) {
31
42
  const navigationMenuMultipleArgs = [
32
43
  'postType',
33
44
  'wp_navigation',
34
- { per_page: -1 },
45
+ { per_page: -1, status: 'publish' },
35
46
  ];
36
47
  const navigationMenus = getEntityRecords(
37
48
  ...navigationMenuMultipleArgs
38
49
  );
39
50
 
40
- const canSwitchNavigationMenu = navigationMenuId
51
+ const canSwitchNavigationMenu = ref
41
52
  ? navigationMenus?.length > 1
42
53
  : navigationMenus?.length > 0;
43
54
 
44
55
  return {
45
56
  isNavigationMenuResolved: hasResolvedNavigationMenu,
46
57
  isNavigationMenuMissing:
47
- ! navigationMenuId ||
48
- ( hasResolvedNavigationMenu && ! navigationMenu ),
58
+ ! ref ||
59
+ ( hasResolvedNavigationMenu && ! rawNavigationMenu ),
49
60
  canSwitchNavigationMenu,
50
61
  hasResolvedNavigationMenus: hasFinishedResolution(
51
62
  'getEntityRecords',
@@ -55,6 +66,6 @@ export default function useNavigationMenu( navigationMenuId ) {
55
66
  navigationMenus,
56
67
  };
57
68
  },
58
- [ navigationMenuId ]
69
+ [ ref ]
59
70
  );
60
71
  }
@@ -2,6 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { __, _x } from '@wordpress/i18n';
5
+ import deprecated from '@wordpress/deprecated';
5
6
  import { store as coreStore } from '@wordpress/core-data';
6
7
  import {
7
8
  MenuGroup,
@@ -51,6 +52,10 @@ function NavigationAreaBlock( { attributes, setAttributes } ) {
51
52
  [ navigationAreas ]
52
53
  );
53
54
 
55
+ deprecated( 'wp.blockLibrary.NavigationArea', {
56
+ since: '5.9',
57
+ } );
58
+
54
59
  return (
55
60
  <>
56
61
  <BlockControls>
@@ -2,6 +2,7 @@
2
2
  /**
3
3
  * Server-side rendering of the `core/navigation-area` block.
4
4
  *
5
+ * @deprecated 5.9.0 See https://github.com/WordPress/gutenberg/issues/36524
5
6
  * @package WordPress
6
7
  */
7
8
 
@@ -508,6 +508,12 @@ export default function NavigationSubmenuEdit( {
508
508
  allowedBlocks: ALLOWED_BLOCKS,
509
509
  __experimentalDefaultBlock: DEFAULT_BLOCK,
510
510
  __experimentalDirectInsert: true,
511
+
512
+ // Ensure block toolbar is not too far removed from item
513
+ // being edited.
514
+ // see: https://github.com/WordPress/gutenberg/pull/34615.
515
+ __experimentalCaptureToolbars: true,
516
+
511
517
  renderAppender:
512
518
  isSelected ||
513
519
  ( isImmediateParentOfSelectedBlock &&
@@ -163,7 +163,32 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
163
163
  'style' => $style_attribute,
164
164
  )
165
165
  );
166
- $html = '<li ' . $wrapper_attributes . '>';
166
+
167
+ $label = '';
168
+
169
+ if ( isset( $attributes['label'] ) ) {
170
+ $label .= wp_kses(
171
+ $attributes['label'],
172
+ array(
173
+ 'code' => array(),
174
+ 'em' => array(),
175
+ 'img' => array(
176
+ 'scale' => array(),
177
+ 'class' => array(),
178
+ 'style' => array(),
179
+ 'src' => array(),
180
+ 'alt' => array(),
181
+ ),
182
+ 's' => array(),
183
+ 'span' => array(
184
+ 'style' => array(),
185
+ ),
186
+ 'strong' => array(),
187
+ )
188
+ );
189
+ }
190
+
191
+ $html = '<li ' . $wrapper_attributes . '>';
167
192
 
168
193
  // If Submenus open on hover, we render an anchor tag with attributes.
169
194
  // If submenu icons are set to show, we also render a submenu button, so the submenu can be opened on click.
@@ -193,27 +218,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
193
218
  $html .= '>';
194
219
  // End appending HTML attributes to anchor tag.
195
220
 
196
- if ( isset( $attributes['label'] ) ) {
197
- $html .= wp_kses(
198
- $attributes['label'],
199
- array(
200
- 'code' => array(),
201
- 'em' => array(),
202
- 'img' => array(
203
- 'scale' => array(),
204
- 'class' => array(),
205
- 'style' => array(),
206
- 'src' => array(),
207
- 'alt' => array(),
208
- ),
209
- 's' => array(),
210
- 'span' => array(
211
- 'style' => array(),
212
- ),
213
- 'strong' => array(),
214
- )
215
- );
216
- }
221
+ $html .= $label;
217
222
 
218
223
  $html .= '</a>';
219
224
  // End anchor tag content.
@@ -221,36 +226,16 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
221
226
  if ( $show_submenu_indicators ) {
222
227
  // The submenu icon is rendered in a button here
223
228
  // so that there's a clickable elment to open the submenu.
224
- $html .= '<button class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
229
+ $html .= '<button aria-label="' . $label . ' ' . __( 'submenu', 'gutenberg' ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
225
230
  }
226
231
  } else {
227
232
  // If menus open on click, we render the parent as a button.
228
- $html .= '<button class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
233
+ $html .= '<button aria-label="' . $label . ' ' . __( 'submenu', 'gutenberg' ) . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
229
234
 
230
235
  // Wrap title with span to isolate it from submenu icon.
231
236
  $html .= '<span class="wp-block-navigation-item__label">';
232
237
 
233
- if ( isset( $attributes['label'] ) ) {
234
- $html .= wp_kses(
235
- $attributes['label'],
236
- array(
237
- 'code' => array(),
238
- 'em' => array(),
239
- 'img' => array(
240
- 'scale' => array(),
241
- 'class' => array(),
242
- 'style' => array(),
243
- 'src' => array(),
244
- 'alt' => array(),
245
- ),
246
- 's' => array(),
247
- 'span' => array(
248
- 'style' => array(),
249
- ),
250
- 'strong' => array(),
251
- )
252
- );
253
- }
238
+ $html .= $label;
254
239
 
255
240
  $html .= '</span>';
256
241