@wordpress/block-library 7.16.0 → 7.17.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 (235) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/build/archives/edit.js +1 -0
  3. package/build/archives/edit.js.map +1 -1
  4. package/build/comment-template/edit.js +40 -32
  5. package/build/comment-template/edit.js.map +1 -1
  6. package/build/comments/edit/placeholder.js +1 -4
  7. package/build/comments/edit/placeholder.js.map +1 -1
  8. package/build/comments/index.js +5 -1
  9. package/build/comments/index.js.map +1 -1
  10. package/build/comments-title/edit.js +18 -1
  11. package/build/comments-title/edit.js.map +1 -1
  12. package/build/cover/edit/index.js +2 -2
  13. package/build/cover/edit/index.js.map +1 -1
  14. package/build/cover/edit/use-cover-is-dark.js +8 -7
  15. package/build/cover/edit/use-cover-is-dark.js.map +1 -1
  16. package/build/embed/variations.js +1 -1
  17. package/build/embed/variations.js.map +1 -1
  18. package/build/gallery/transforms.js +3 -3
  19. package/build/gallery/transforms.js.map +1 -1
  20. package/build/gallery/v1/edit.js +1 -1
  21. package/build/gallery/v1/edit.js.map +1 -1
  22. package/build/image/image.js +34 -10
  23. package/build/image/image.js.map +1 -1
  24. package/build/image/transforms.js +1 -7
  25. package/build/image/transforms.js.map +1 -1
  26. package/build/list/transforms.js +9 -1
  27. package/build/list/transforms.js.map +1 -1
  28. package/build/list-item/edit.js +3 -2
  29. package/build/list-item/edit.js.map +1 -1
  30. package/build/list-item/edit.native.js +3 -2
  31. package/build/list-item/edit.native.js.map +1 -1
  32. package/build/list-item/hooks/use-merge.js +19 -22
  33. package/build/list-item/hooks/use-merge.js.map +1 -1
  34. package/build/list-item/hooks/use-outdent-list-item.js +19 -3
  35. package/build/list-item/hooks/use-outdent-list-item.js.map +1 -1
  36. package/build/list-item/index.js +14 -1
  37. package/build/list-item/index.js.map +1 -1
  38. package/build/list-item/utils.js +14 -1
  39. package/build/list-item/utils.js.map +1 -1
  40. package/build/navigation/edit/index.js +35 -22
  41. package/build/navigation/edit/index.js.map +1 -1
  42. package/build/navigation/edit/inner-blocks.js +3 -5
  43. package/build/navigation/edit/inner-blocks.js.map +1 -1
  44. package/build/navigation/edit/use-convert-classic-menu-to-block-menu.js +25 -8
  45. package/build/navigation/edit/use-convert-classic-menu-to-block-menu.js.map +1 -1
  46. package/build/navigation/edit/use-create-navigation-menu.js +1 -1
  47. package/build/navigation/edit/use-create-navigation-menu.js.map +1 -1
  48. package/build/navigation/index.js +4 -1
  49. package/build/navigation/index.js.map +1 -1
  50. package/build/navigation-link/edit.js +1 -1
  51. package/build/navigation-link/edit.js.map +1 -1
  52. package/build/page-list/index.js +1 -5
  53. package/build/page-list/index.js.map +1 -1
  54. package/build/paragraph/edit.js +3 -11
  55. package/build/paragraph/edit.js.map +1 -1
  56. package/build/pattern/edit.js +11 -4
  57. package/build/pattern/edit.js.map +1 -1
  58. package/build/post-comments-form/form.js +1 -2
  59. package/build/post-comments-form/form.js.map +1 -1
  60. package/build/query/edit/inspector-controls/index.js +2 -2
  61. package/build/query/edit/inspector-controls/index.js.map +1 -1
  62. package/build/query/edit/inspector-controls/taxonomy-controls.js +79 -104
  63. package/build/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  64. package/build/search/edit.js +2 -1
  65. package/build/search/edit.js.map +1 -1
  66. package/build/site-logo/edit.js +6 -9
  67. package/build/site-logo/edit.js.map +1 -1
  68. package/build/table/state.js +1 -1
  69. package/build/table/state.js.map +1 -1
  70. package/build/table-of-contents/edit.js +1 -4
  71. package/build/table-of-contents/edit.js.map +1 -1
  72. package/build/tag-cloud/edit.js +1 -1
  73. package/build/tag-cloud/edit.js.map +1 -1
  74. package/build/tag-cloud/index.js +8 -0
  75. package/build/tag-cloud/index.js.map +1 -1
  76. package/build-module/archives/edit.js +1 -0
  77. package/build-module/archives/edit.js.map +1 -1
  78. package/build-module/comment-template/edit.js +38 -30
  79. package/build-module/comment-template/edit.js.map +1 -1
  80. package/build-module/comments/edit/placeholder.js +1 -3
  81. package/build-module/comments/edit/placeholder.js.map +1 -1
  82. package/build-module/comments/index.js +5 -1
  83. package/build-module/comments/index.js.map +1 -1
  84. package/build-module/comments-title/edit.js +18 -2
  85. package/build-module/comments-title/edit.js.map +1 -1
  86. package/build-module/cover/edit/index.js +2 -2
  87. package/build-module/cover/edit/index.js.map +1 -1
  88. package/build-module/cover/edit/use-cover-is-dark.js +7 -7
  89. package/build-module/cover/edit/use-cover-is-dark.js.map +1 -1
  90. package/build-module/embed/variations.js +1 -1
  91. package/build-module/embed/variations.js.map +1 -1
  92. package/build-module/gallery/transforms.js +4 -4
  93. package/build-module/gallery/transforms.js.map +1 -1
  94. package/build-module/gallery/v1/edit.js +2 -2
  95. package/build-module/gallery/v1/edit.js.map +1 -1
  96. package/build-module/image/image.js +35 -11
  97. package/build-module/image/image.js.map +1 -1
  98. package/build-module/image/transforms.js +1 -6
  99. package/build-module/image/transforms.js.map +1 -1
  100. package/build-module/list/transforms.js +9 -1
  101. package/build-module/list/transforms.js.map +1 -1
  102. package/build-module/list-item/edit.js +3 -2
  103. package/build-module/list-item/edit.js.map +1 -1
  104. package/build-module/list-item/edit.native.js +3 -2
  105. package/build-module/list-item/edit.native.js.map +1 -1
  106. package/build-module/list-item/hooks/use-merge.js +19 -21
  107. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  108. package/build-module/list-item/hooks/use-outdent-list-item.js +19 -3
  109. package/build-module/list-item/hooks/use-outdent-list-item.js.map +1 -1
  110. package/build-module/list-item/index.js +14 -1
  111. package/build-module/list-item/index.js.map +1 -1
  112. package/build-module/list-item/utils.js +14 -1
  113. package/build-module/list-item/utils.js.map +1 -1
  114. package/build-module/navigation/edit/index.js +35 -22
  115. package/build-module/navigation/edit/index.js.map +1 -1
  116. package/build-module/navigation/edit/inner-blocks.js +3 -5
  117. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  118. package/build-module/navigation/edit/use-convert-classic-menu-to-block-menu.js +25 -8
  119. package/build-module/navigation/edit/use-convert-classic-menu-to-block-menu.js.map +1 -1
  120. package/build-module/navigation/edit/use-create-navigation-menu.js +1 -1
  121. package/build-module/navigation/edit/use-create-navigation-menu.js.map +1 -1
  122. package/build-module/navigation/index.js +4 -1
  123. package/build-module/navigation/index.js.map +1 -1
  124. package/build-module/navigation-link/edit.js +1 -1
  125. package/build-module/navigation-link/edit.js.map +1 -1
  126. package/build-module/page-list/index.js +1 -5
  127. package/build-module/page-list/index.js.map +1 -1
  128. package/build-module/paragraph/edit.js +3 -10
  129. package/build-module/paragraph/edit.js.map +1 -1
  130. package/build-module/pattern/edit.js +10 -3
  131. package/build-module/pattern/edit.js.map +1 -1
  132. package/build-module/post-comments-form/form.js +2 -3
  133. package/build-module/post-comments-form/form.js.map +1 -1
  134. package/build-module/query/edit/inspector-controls/index.js +4 -4
  135. package/build-module/query/edit/inspector-controls/index.js.map +1 -1
  136. package/build-module/query/edit/inspector-controls/taxonomy-controls.js +81 -102
  137. package/build-module/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  138. package/build-module/search/edit.js +3 -2
  139. package/build-module/search/edit.js.map +1 -1
  140. package/build-module/site-logo/edit.js +6 -9
  141. package/build-module/site-logo/edit.js.map +1 -1
  142. package/build-module/table/state.js +2 -2
  143. package/build-module/table/state.js.map +1 -1
  144. package/build-module/table-of-contents/edit.js +1 -3
  145. package/build-module/table-of-contents/edit.js.map +1 -1
  146. package/build-module/tag-cloud/edit.js +1 -1
  147. package/build-module/tag-cloud/edit.js.map +1 -1
  148. package/build-module/tag-cloud/index.js +8 -0
  149. package/build-module/tag-cloud/index.js.map +1 -1
  150. package/build-style/archives/style-rtl.css +4 -0
  151. package/build-style/archives/style.css +4 -0
  152. package/build-style/comments/editor-rtl.css +1 -0
  153. package/build-style/comments/editor.css +1 -0
  154. package/build-style/comments/style-rtl.css +1 -0
  155. package/build-style/comments/style.css +1 -0
  156. package/build-style/cover/editor-rtl.css +4 -0
  157. package/build-style/cover/editor.css +4 -0
  158. package/build-style/editor-rtl.css +9 -17
  159. package/build-style/editor.css +9 -17
  160. package/build-style/group/editor-rtl.css +1 -0
  161. package/build-style/group/editor.css +1 -0
  162. package/build-style/image/editor-rtl.css +1 -1
  163. package/build-style/image/editor.css +1 -1
  164. package/build-style/navigation/editor-rtl.css +1 -0
  165. package/build-style/navigation/editor.css +1 -0
  166. package/build-style/paragraph/editor-rtl.css +0 -16
  167. package/build-style/paragraph/editor.css +0 -16
  168. package/build-style/site-logo/editor-rtl.css +1 -0
  169. package/build-style/site-logo/editor.css +1 -0
  170. package/build-style/style-rtl.css +8 -0
  171. package/build-style/style.css +8 -0
  172. package/build-style/tag-cloud/style-rtl.css +3 -0
  173. package/build-style/tag-cloud/style.css +3 -0
  174. package/package.json +28 -28
  175. package/src/archives/edit.js +1 -0
  176. package/src/archives/style.scss +5 -0
  177. package/src/avatar/index.php +1 -1
  178. package/src/code/test/__snapshots__/edit.native.js.snap +13 -0
  179. package/src/code/test/edit.native.js +46 -32
  180. package/src/comment-template/edit.js +47 -34
  181. package/src/comments/block.json +5 -1
  182. package/src/comments/edit/placeholder.js +1 -7
  183. package/src/comments/style.scss +2 -0
  184. package/src/comments-title/edit.js +24 -1
  185. package/src/cover/edit/index.js +2 -7
  186. package/src/cover/edit/use-cover-is-dark.js +11 -11
  187. package/src/cover/editor.scss +7 -0
  188. package/src/embed/variations.js +1 -1
  189. package/src/gallery/transforms.js +8 -5
  190. package/src/gallery/v1/edit.js +2 -2
  191. package/src/group/editor.scss +1 -0
  192. package/src/image/editor.scss +4 -1
  193. package/src/image/image.js +59 -29
  194. package/src/image/transforms.js +1 -7
  195. package/src/list/test/edit.native.js +102 -3
  196. package/src/list/transforms.js +11 -0
  197. package/src/list-item/block.json +14 -1
  198. package/src/list-item/edit.js +2 -1
  199. package/src/list-item/edit.native.js +2 -1
  200. package/src/list-item/hooks/use-merge.js +4 -23
  201. package/src/list-item/hooks/use-outdent-list-item.js +6 -2
  202. package/src/navigation/block.json +4 -1
  203. package/src/navigation/edit/index.js +49 -23
  204. package/src/navigation/edit/inner-blocks.js +2 -5
  205. package/src/navigation/edit/use-convert-classic-menu-to-block-menu.js +32 -5
  206. package/src/navigation/edit/use-create-navigation-menu.js +2 -5
  207. package/src/navigation/editor.scss +1 -0
  208. package/src/navigation/index.php +103 -6
  209. package/src/navigation-link/edit.js +1 -1
  210. package/src/navigation-link/index.php +8 -1
  211. package/src/navigation-submenu/index.php +8 -1
  212. package/src/page-list/block.json +1 -5
  213. package/src/page-list/index.php +8 -6
  214. package/src/paragraph/edit.js +1 -14
  215. package/src/paragraph/editor.scss +0 -20
  216. package/src/pattern/edit.js +10 -3
  217. package/src/post-comments-form/form.js +2 -3
  218. package/src/query/edit/inspector-controls/index.js +4 -3
  219. package/src/query/edit/inspector-controls/taxonomy-controls.js +82 -87
  220. package/src/rss/index.php +3 -3
  221. package/src/search/edit.js +6 -1
  222. package/src/search/index.php +21 -13
  223. package/src/site-logo/edit.js +10 -8
  224. package/src/site-logo/editor.scss +1 -0
  225. package/src/table/state.js +2 -2
  226. package/src/table-of-contents/edit.js +1 -3
  227. package/src/tag-cloud/block.json +8 -0
  228. package/src/tag-cloud/edit.js +1 -1
  229. package/src/tag-cloud/style.scss +3 -0
  230. package/src/template-part/index.php +4 -0
  231. package/build/paragraph/drop-zone.js +0 -99
  232. package/build/paragraph/drop-zone.js.map +0 -1
  233. package/build-module/paragraph/drop-zone.js +0 -88
  234. package/build-module/paragraph/drop-zone.js.map +0 -1
  235. package/src/paragraph/drop-zone.js +0 -105
@@ -248,6 +248,99 @@ function block_core_navigation_render_submenu_icon() {
248
248
  return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
249
249
  }
250
250
 
251
+ /**
252
+ * Get the classic navigation menu to use as a fallback.
253
+ *
254
+ * @return object WP_Term The classic navigation.
255
+ */
256
+ function block_core_navigation_get_classic_menu_fallback() {
257
+ $classic_nav_menus = wp_get_nav_menus();
258
+
259
+ // If menus exist.
260
+ if ( $classic_nav_menus && ! is_wp_error( $classic_nav_menus ) && count( $classic_nav_menus ) === 1 ) {
261
+ // Use the first classic menu only. Handles simple use case where user has a single
262
+ // classic menu and switches to a block theme. In future this maybe expanded to
263
+ // determine the most appropriate classic menu to be used based on location.
264
+ return $classic_nav_menus[0];
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Converts a classic navigation to blocks.
270
+ *
271
+ * @param object $classic_nav_menu WP_Term The classic navigation object to convert.
272
+ * @return array the normalized parsed blocks.
273
+ */
274
+ function block_core_navigation_get_classic_menu_fallback_blocks( $classic_nav_menu ) {
275
+ // BEGIN: Code that already exists in wp_nav_menu().
276
+ $menu_items = wp_get_nav_menu_items( $classic_nav_menu->term_id, array( 'update_post_term_cache' => false ) );
277
+
278
+ // Set up the $menu_item variables.
279
+ _wp_menu_item_classes_by_context( $menu_items );
280
+
281
+ $sorted_menu_items = array();
282
+ foreach ( (array) $menu_items as $menu_item ) {
283
+ $sorted_menu_items[ $menu_item->menu_order ] = $menu_item;
284
+ }
285
+
286
+ unset( $menu_items, $menu_item );
287
+
288
+ // END: Code that already exists in wp_nav_menu().
289
+
290
+ $menu_items_by_parent_id = array();
291
+ foreach ( $sorted_menu_items as $menu_item ) {
292
+ $menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item;
293
+ }
294
+
295
+ $inner_blocks = block_core_navigation_parse_blocks_from_menu_items(
296
+ isset( $menu_items_by_parent_id[0] )
297
+ ? $menu_items_by_parent_id[0]
298
+ : array(),
299
+ $menu_items_by_parent_id
300
+ );
301
+
302
+ return serialize_blocks( $inner_blocks );
303
+ }
304
+
305
+ /**
306
+ * If there's a the classic menu then use it as a fallback.
307
+ *
308
+ * @return array the normalized parsed blocks.
309
+ */
310
+ function block_core_navigation_maybe_use_classic_menu_fallback() {
311
+ // See if we have a classic menu.
312
+ $classic_nav_menu = block_core_navigation_get_classic_menu_fallback();
313
+
314
+ if ( ! $classic_nav_menu ) {
315
+ return;
316
+ }
317
+
318
+ // If we have a classic menu then convert it to blocks.
319
+ $classic_nav_menu_blocks = block_core_navigation_get_classic_menu_fallback_blocks( $classic_nav_menu );
320
+
321
+ if ( empty( $classic_nav_menu_blocks ) ) {
322
+ return;
323
+ }
324
+
325
+ // Create a new navigation menu from the classic menu.
326
+ $wp_insert_post_result = wp_insert_post(
327
+ array(
328
+ 'post_content' => $classic_nav_menu_blocks,
329
+ 'post_title' => $classic_nav_menu->slug,
330
+ 'post_name' => $classic_nav_menu->slug,
331
+ 'post_status' => 'publish',
332
+ 'post_type' => 'wp_navigation',
333
+ ),
334
+ true // So that we can check whether the result is an error.
335
+ );
336
+
337
+ if ( is_wp_error( $wp_insert_post_result ) ) {
338
+ return;
339
+ }
340
+
341
+ // Fetch the most recently published navigation which will be the classic one created above.
342
+ return block_core_navigation_get_most_recently_published_navigation();
343
+ }
251
344
 
252
345
  /**
253
346
  * Finds the most recently published `wp_navigation` Post.
@@ -255,7 +348,8 @@ function block_core_navigation_render_submenu_icon() {
255
348
  * @return WP_Post|null the first non-empty Navigation or null.
256
349
  */
257
350
  function block_core_navigation_get_most_recently_published_navigation() {
258
- // We default to the most recently created menu.
351
+
352
+ // Default to the most recently created menu.
259
353
  $parsed_args = array(
260
354
  'post_type' => 'wp_navigation',
261
355
  'no_found_rows' => true,
@@ -307,9 +401,6 @@ function block_core_navigation_get_fallback_blocks() {
307
401
  $page_list_fallback = array(
308
402
  array(
309
403
  'blockName' => 'core/page-list',
310
- 'attrs' => array(
311
- '__unstableMaxPages' => 4,
312
- ),
313
404
  ),
314
405
  );
315
406
 
@@ -322,7 +413,13 @@ function block_core_navigation_get_fallback_blocks() {
322
413
 
323
414
  $navigation_post = block_core_navigation_get_most_recently_published_navigation();
324
415
 
325
- // Prefer using the first non-empty Navigation as fallback if available.
416
+ // If there are no navigation posts then try to find a classic menu
417
+ // and convert it into a block based navigation menu.
418
+ if ( ! $navigation_post ) {
419
+ $navigation_post = block_core_navigation_maybe_use_classic_menu_fallback();
420
+ }
421
+
422
+ // Use the first non-empty Navigation as fallback if available.
326
423
  if ( $navigation_post ) {
327
424
  $maybe_fallback = block_core_navigation_filter_out_empty_blocks( parse_blocks( $navigation_post->post_content ) );
328
425
 
@@ -649,7 +746,7 @@ function render_block_core_navigation( $attributes, $content, $block ) {
649
746
  $toggle_aria_label_close,
650
747
  esc_attr( implode( ' ', $responsive_container_classes ) ),
651
748
  esc_attr( implode( ' ', $open_button_classes ) ),
652
- safecss_filter_attr( $colors['overlay_inline_styles'] ),
749
+ esc_attr( safecss_filter_attr( $colors['overlay_inline_styles'] ) ),
653
750
  __( 'Menu' ),
654
751
  $toggle_button_content,
655
752
  $toggle_close_button_content
@@ -467,7 +467,7 @@ export default function NavigationLinkEdit( {
467
467
  const [ popoverAnchor, setPopoverAnchor ] = useState( null );
468
468
  const listItemRef = useRef( null );
469
469
  const isDraggingWithin = useIsDraggingWithin( listItemRef );
470
- const itemLabelPlaceholder = __( 'Add link…' );
470
+ const itemLabelPlaceholder = __( 'Add label…' );
471
471
  const ref = useRef();
472
472
 
473
473
  const pagesPermissions = useResourcePermissions( 'pages' );
@@ -98,7 +98,14 @@ function block_core_navigation_link_build_css_font_sizes( $context ) {
98
98
  $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
99
99
  } elseif ( $has_custom_font_size ) {
100
100
  // Add the custom font size inline style.
101
- $font_sizes['inline_styles'] = sprintf( 'font-size: %s;', $context['style']['typography']['fontSize'] );
101
+ $font_sizes['inline_styles'] = sprintf(
102
+ 'font-size: %s;',
103
+ wp_get_typography_font_size_value(
104
+ array(
105
+ 'size' => $context['style']['typography']['fontSize'],
106
+ )
107
+ )
108
+ );
102
109
  }
103
110
 
104
111
  return $font_sizes;
@@ -98,7 +98,14 @@ function block_core_navigation_submenu_build_css_font_sizes( $context ) {
98
98
  $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
99
99
  } elseif ( $has_custom_font_size ) {
100
100
  // Add the custom font size inline style.
101
- $font_sizes['inline_styles'] = sprintf( 'font-size: %s;', $context['style']['typography']['fontSize'] );
101
+ $font_sizes['inline_styles'] = sprintf(
102
+ 'font-size: %s;',
103
+ wp_get_typography_font_size_value(
104
+ array(
105
+ 'size' => $context['style']['typography']['fontSize'],
106
+ )
107
+ )
108
+ );
102
109
  }
103
110
 
104
111
  return $font_sizes;
@@ -7,11 +7,7 @@
7
7
  "description": "Display a list of all pages.",
8
8
  "keywords": [ "menu", "navigation" ],
9
9
  "textdomain": "default",
10
- "attributes": {
11
- "__unstableMaxPages": {
12
- "type": "number"
13
- }
14
- },
10
+ "attributes": {},
15
11
  "usesContext": [
16
12
  "textColor",
17
13
  "customTextColor",
@@ -119,7 +119,14 @@ function block_core_page_list_build_css_font_sizes( $context ) {
119
119
  $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
120
120
  } elseif ( $has_custom_font_size ) {
121
121
  // Add the custom font size inline style.
122
- $font_sizes['inline_styles'] = sprintf( 'font-size: %s;', $context['style']['typography']['fontSize'] );
122
+ $font_sizes['inline_styles'] = sprintf(
123
+ 'font-size: %s;',
124
+ wp_get_typography_font_size_value(
125
+ array(
126
+ 'size' => $context['style']['typography']['fontSize'],
127
+ )
128
+ )
129
+ );
123
130
  }
124
131
 
125
132
  return $font_sizes;
@@ -299,11 +306,6 @@ function render_block_core_page_list( $attributes, $content, $block ) {
299
306
 
300
307
  $nested_pages = block_core_page_list_nest_pages( $top_level_pages, $pages_with_children );
301
308
 
302
- // Limit the number of items to be visually displayed.
303
- if ( ! empty( $attributes['__unstableMaxPages'] ) ) {
304
- $nested_pages = array_slice( $nested_pages, 0, $attributes['__unstableMaxPages'] );
305
- }
306
-
307
309
  $is_navigation_child = array_key_exists( 'showSubmenuIcon', $block->context );
308
310
 
309
311
  $open_submenus_on_click = array_key_exists( 'openSubmenusOnClick', $block->context ) ? $block->context['openSubmenusOnClick'] : false;
@@ -6,7 +6,6 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { useState } from '@wordpress/element';
10
9
  import { __, _x, isRTL } from '@wordpress/i18n';
11
10
  import {
12
11
  ToolbarButton,
@@ -21,7 +20,6 @@ import {
21
20
  useBlockProps,
22
21
  useSetting,
23
22
  } from '@wordpress/block-editor';
24
- import { useMergeRefs } from '@wordpress/compose';
25
23
  import { createBlock } from '@wordpress/blocks';
26
24
  import { formatLtr } from '@wordpress/icons';
27
25
 
@@ -29,7 +27,6 @@ import { formatLtr } from '@wordpress/icons';
29
27
  * Internal dependencies
30
28
  */
31
29
  import { useOnEnter } from './use-enter';
32
- import DropZone from './drop-zone';
33
30
 
34
31
  const name = 'core/paragraph';
35
32
 
@@ -62,12 +59,8 @@ function ParagraphBlock( {
62
59
  } ) {
63
60
  const { align, content, direction, dropCap, placeholder } = attributes;
64
61
  const isDropCapFeatureEnabled = useSetting( 'typography.dropCap' );
65
- const [ paragraphElement, setParagraphElement ] = useState( null );
66
62
  const blockProps = useBlockProps( {
67
- ref: useMergeRefs( [
68
- useOnEnter( { clientId, content } ),
69
- setParagraphElement,
70
- ] ),
63
+ ref: useOnEnter( { clientId, content } ),
71
64
  className: classnames( {
72
65
  'has-drop-cap': hasDropCapDisabled( align ) ? false : dropCap,
73
66
  [ `has-text-align-${ align }` ]: align,
@@ -130,12 +123,6 @@ function ParagraphBlock( {
130
123
  </ToolsPanelItem>
131
124
  </InspectorControls>
132
125
  ) }
133
- { ! content && (
134
- <DropZone
135
- clientId={ clientId }
136
- paragraphElement={ paragraphElement }
137
- />
138
- ) }
139
126
  <RichText
140
127
  identifier="content"
141
128
  tagName="p"
@@ -17,23 +17,3 @@
17
17
  }
18
18
  }
19
19
  }
20
-
21
- .components-popover.wp-block-paragraph__drop-zone {
22
- .components-popover__content {
23
- border: none;
24
- outline: none;
25
- box-shadow: none;
26
- }
27
-
28
- .wp-block-paragraph__drop-zone-backdrop {
29
- position: absolute;
30
- }
31
-
32
- .wp-block-paragraph__drop-zone-foreground {
33
- position: absolute;
34
- inset: 0;
35
- pointer-events: none;
36
- background-color: var(--wp-admin-theme-color);
37
- border-radius: 2px;
38
- }
39
- }
@@ -26,10 +26,17 @@ const PatternEdit = ( { attributes, clientId } ) => {
26
26
  // It will continue to pull from the pattern file unless changes are made to its respective template part.
27
27
  useEffect( () => {
28
28
  if ( selectedPattern?.blocks ) {
29
- __unstableMarkNextChangeAsNotPersistent();
30
- replaceBlocks( clientId, selectedPattern.blocks );
29
+ // We batch updates to block list settings to avoid triggering cascading renders
30
+ // for each container block included in a tree and optimize initial render.
31
+ // Since the above uses microtasks, we need to use a microtask here as well,
32
+ // because nested pattern blocks cannot be inserted if the parent block supports
33
+ // inner blocks but doesn't have blockSettings in the state.
34
+ window.queueMicrotask( () => {
35
+ __unstableMarkNextChangeAsNotPersistent();
36
+ replaceBlocks( clientId, selectedPattern.blocks );
37
+ } );
31
38
  }
32
- }, [ selectedPattern?.blocks ] );
39
+ }, [ clientId, selectedPattern?.blocks ] );
33
40
 
34
41
  const props = useBlockProps();
35
42
 
@@ -13,18 +13,17 @@ import {
13
13
  __experimentalGetElementClassName,
14
14
  } from '@wordpress/block-editor';
15
15
  import { Button } from '@wordpress/components';
16
- import { useDisabled, useInstanceId } from '@wordpress/compose';
16
+ import { useInstanceId } from '@wordpress/compose';
17
17
  import { useEntityProp, store as coreStore } from '@wordpress/core-data';
18
18
  import { useSelect } from '@wordpress/data';
19
19
 
20
20
  const CommentsFormPlaceholder = () => {
21
- const disabledFormRef = useDisabled();
22
21
  const instanceId = useInstanceId( CommentsFormPlaceholder );
23
22
 
24
23
  return (
25
24
  <div className="comment-respond">
26
25
  <h3 className="comment-reply-title">{ __( 'Leave a Reply' ) }</h3>
27
- <form noValidate className="comment-form" ref={ disabledFormRef }>
26
+ <form noValidate className="comment-form" inert="true">
28
27
  <p>
29
28
  <label htmlFor={ `comment-${ instanceId }` }>
30
29
  { __( 'Comment' ) }
@@ -22,13 +22,14 @@ import { useEffect, useState, useCallback } from '@wordpress/element';
22
22
  import OrderControl from './order-control';
23
23
  import AuthorControl from './author-control';
24
24
  import ParentControl from './parent-control';
25
- import { TaxonomyControls, useTaxonomiesInfo } from './taxonomy-controls';
25
+ import { TaxonomyControls } from './taxonomy-controls';
26
26
  import StickyControl from './sticky-control';
27
27
  import {
28
28
  usePostTypes,
29
29
  useIsPostTypeHierarchical,
30
30
  useAllowedControls,
31
31
  isControlAllowed,
32
+ useTaxonomies,
32
33
  } from '../../utils';
33
34
 
34
35
  export default function QueryInspectorControls( {
@@ -50,7 +51,7 @@ export default function QueryInspectorControls( {
50
51
  const allowedControls = useAllowedControls( attributes );
51
52
  const [ showSticky, setShowSticky ] = useState( postType === 'post' );
52
53
  const { postTypesTaxonomiesMap, postTypesSelectOptions } = usePostTypes();
53
- const taxonomiesInfo = useTaxonomiesInfo( postType );
54
+ const taxonomies = useTaxonomies( postType );
54
55
  const isPostTypeHierarchical = useIsPostTypeHierarchical( postType );
55
56
  useEffect( () => {
56
57
  setShowSticky( postType === 'post' );
@@ -192,7 +193,7 @@ export default function QueryInspectorControls( {
192
193
  setQuerySearch( '' );
193
194
  } }
194
195
  >
195
- { !! taxonomiesInfo?.length &&
196
+ { !! taxonomies?.length &&
196
197
  isControlAllowed( allowedControls, 'taxQuery' ) && (
197
198
  <ToolsPanelItem
198
199
  label={ __( 'Taxonomies' ) }
@@ -8,14 +8,18 @@ import { store as coreStore } from '@wordpress/core-data';
8
8
  /**
9
9
  * Internal dependencies
10
10
  */
11
- import { getEntitiesInfo, useTaxonomies } from '../../utils';
11
+ import { useTaxonomies } from '../../utils';
12
12
  import { MAX_FETCHED_TERMS } from '../../constants';
13
13
 
14
14
  // Helper function to get the term id based on user input in terms `FormTokenField`.
15
- const getTermIdByTermValue = ( termsMappedByName, termValue ) => {
15
+ const getTermIdByTermValue = ( terms, termValue ) => {
16
16
  // First we check for exact match by `term.id` or case sensitive `term.name` match.
17
- const termId = termValue?.id || termsMappedByName[ termValue ]?.id;
18
- if ( termId ) return termId;
17
+ const termId =
18
+ termValue?.id || terms.find( ( term ) => term.name === termValue )?.id;
19
+ if ( termId ) {
20
+ return termId;
21
+ }
22
+
19
23
  /**
20
24
  * Here we make an extra check for entered terms in a non case sensitive way,
21
25
  * to match user expectations, due to `FormTokenField` behaviour that shows
@@ -26,101 +30,92 @@ const getTermIdByTermValue = ( termsMappedByName, termValue ) => {
26
30
  * In this edge case we always apply the first match from the terms list.
27
31
  */
28
32
  const termValueLower = termValue.toLocaleLowerCase();
29
- for ( const term in termsMappedByName ) {
30
- if ( term.toLocaleLowerCase() === termValueLower ) {
31
- return termsMappedByName[ term ].id;
32
- }
33
- }
33
+ return terms.find(
34
+ ( term ) => term.name.toLocaleLowerCase() === termValueLower
35
+ )?.id;
34
36
  };
35
37
 
36
- export const useTaxonomiesInfo = ( postType ) => {
37
- const taxonomies = useTaxonomies( postType );
38
- const taxonomiesInfo = useSelect(
38
+ const useTaxonomyTerms = ( slug ) => {
39
+ return useSelect(
39
40
  ( select ) => {
40
- const { getEntityRecords } = select( coreStore );
41
- const termsQuery = { context: 'view', per_page: MAX_FETCHED_TERMS };
42
- const _taxonomiesInfo = taxonomies?.map( ( { slug, name } ) => {
43
- const _terms = getEntityRecords( 'taxonomy', slug, termsQuery );
44
- return {
45
- slug,
46
- name,
47
- terms: getEntitiesInfo( _terms ),
48
- };
49
- } );
50
- return _taxonomiesInfo;
41
+ const terms = select( coreStore ).getEntityRecords(
42
+ 'taxonomy',
43
+ slug,
44
+ { context: 'view', per_page: MAX_FETCHED_TERMS }
45
+ );
46
+ return { terms };
51
47
  },
52
- [ taxonomies ]
48
+ [ slug ]
53
49
  );
54
- return taxonomiesInfo;
55
50
  };
56
51
 
57
52
  export function TaxonomyControls( { onChange, query } ) {
58
- const taxonomiesInfo = useTaxonomiesInfo( query.postType );
59
- const onTermsChange = ( taxonomySlug ) => ( newTermValues ) => {
60
- const taxonomyInfo = taxonomiesInfo.find(
61
- ( { slug } ) => slug === taxonomySlug
62
- );
63
- if ( ! taxonomyInfo ) return;
64
- const termIds = Array.from(
65
- newTermValues.reduce( ( accumulator, termValue ) => {
66
- const termId = getTermIdByTermValue(
67
- taxonomyInfo.terms.mapByName,
68
- termValue
53
+ const { postType, taxQuery } = query;
54
+
55
+ const taxonomies = useTaxonomies( postType );
56
+ if ( ! taxonomies || taxonomies.length === 0 ) {
57
+ return null;
58
+ }
59
+
60
+ return (
61
+ <>
62
+ { taxonomies.map( ( taxonomy ) => {
63
+ const value = taxQuery?.[ taxonomy.slug ] || [];
64
+ const handleChange = ( newTermIds ) =>
65
+ onChange( {
66
+ taxQuery: {
67
+ ...taxQuery,
68
+ [ taxonomy.slug ]: newTermIds,
69
+ },
70
+ } );
71
+
72
+ return (
73
+ <TaxonomyItem
74
+ key={ taxonomy.slug }
75
+ taxonomy={ taxonomy }
76
+ value={ value }
77
+ onChange={ handleChange }
78
+ />
69
79
  );
70
- if ( termId ) accumulator.add( termId );
71
- return accumulator;
72
- }, new Set() )
73
- );
74
- const newTaxQuery = {
75
- ...query.taxQuery,
76
- [ taxonomySlug ]: termIds,
77
- };
78
- onChange( { taxQuery: newTaxQuery } );
80
+ } ) }
81
+ </>
82
+ );
83
+ }
84
+ function TaxonomyItem( { taxonomy, value, onChange } ) {
85
+ const { terms } = useTaxonomyTerms( taxonomy.slug );
86
+ if ( ! terms?.length ) {
87
+ return null;
88
+ }
89
+
90
+ const onTermsChange = ( newTermValues ) => {
91
+ const termIds = new Set();
92
+ for ( const termValue of newTermValues ) {
93
+ const termId = getTermIdByTermValue( terms, termValue );
94
+ if ( termId ) {
95
+ termIds.add( termId );
96
+ }
97
+ }
98
+
99
+ onChange( Array.from( termIds ) );
79
100
  };
80
- // Returns only the existing term ids in proper format to be
101
+
102
+ // Selects only the existing term ids in proper format to be
81
103
  // used in `FormTokenField`. This prevents the component from
82
104
  // crashing in the editor, when non existing term ids were provided.
83
- const getExistingTaxQueryValue = ( taxonomySlug ) => {
84
- const taxonomyInfo = taxonomiesInfo.find(
85
- ( { slug } ) => slug === taxonomySlug
86
- );
87
- if ( ! taxonomyInfo ) return [];
88
- return ( query.taxQuery?.[ taxonomySlug ] || [] ).reduce(
89
- ( accumulator, termId ) => {
90
- const term = taxonomyInfo.terms.mapById[ termId ];
91
- if ( term ) {
92
- accumulator.push( {
93
- id: termId,
94
- value: term.name,
95
- } );
96
- }
97
- return accumulator;
98
- },
99
- []
100
- );
101
- };
105
+ const taxQueryValue = value
106
+ .map( ( termId ) => terms.find( ( t ) => t.id === termId ) )
107
+ .filter( Boolean )
108
+ .map( ( term ) => ( { id: term.id, value: term.name } ) );
109
+
102
110
  return (
103
- <>
104
- { !! taxonomiesInfo?.length &&
105
- taxonomiesInfo.map( ( { slug, name, terms } ) => {
106
- if ( ! terms?.names?.length ) {
107
- return null;
108
- }
109
- return (
110
- <div
111
- key={ slug }
112
- className="block-library-query-inspector__taxonomy-control"
113
- >
114
- <FormTokenField
115
- label={ name }
116
- value={ getExistingTaxQueryValue( slug ) }
117
- suggestions={ terms.names }
118
- onChange={ onTermsChange( slug ) }
119
- __experimentalShowHowTo={ false }
120
- />
121
- </div>
122
- );
123
- } ) }
124
- </>
111
+ <div className="block-library-query-inspector__taxonomy-control">
112
+ <FormTokenField
113
+ label={ taxonomy.name }
114
+ value={ taxQueryValue }
115
+ suggestions={ terms.map( ( t ) => t.name ) }
116
+ onChange={ onTermsChange }
117
+ __experimentalShowHowTo={ false }
118
+ />
119
+ </div>
125
120
  );
126
121
  }
package/src/rss/index.php CHANGED
@@ -20,7 +20,7 @@ function render_block_core_rss( $attributes ) {
20
20
  $rss = fetch_feed( $attributes['feedURL'] );
21
21
 
22
22
  if ( is_wp_error( $rss ) ) {
23
- return '<div class="components-placeholder"><div class="notice notice-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . $rss->get_error_message() . '</div></div>';
23
+ return '<div class="components-placeholder"><div class="notice notice-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . esc_html( $rss->get_error_message() ) . '</div></div>';
24
24
  }
25
25
 
26
26
  if ( ! $rss->get_item_quantity() ) {
@@ -48,8 +48,8 @@ function render_block_core_rss( $attributes ) {
48
48
  if ( $date ) {
49
49
  $date = sprintf(
50
50
  '<time datetime="%1$s" class="wp-block-rss__item-publish-date">%2$s</time> ',
51
- date_i18n( get_option( 'c' ), $date ),
52
- date_i18n( get_option( 'date_format' ), $date )
51
+ esc_attr( date_i18n( get_option( 'c' ), $date ) ),
52
+ esc_attr( date_i18n( get_option( 'date_format' ), $date ) )
53
53
  );
54
54
  }
55
55
  }
@@ -16,6 +16,7 @@ import {
16
16
  getTypographyClassesAndStyles as useTypographyProps,
17
17
  store as blockEditorStore,
18
18
  __experimentalGetElementClassName,
19
+ useSetting,
19
20
  } from '@wordpress/block-editor';
20
21
  import { useDispatch, useSelect } from '@wordpress/data';
21
22
  import { useEffect } from '@wordpress/element';
@@ -113,7 +114,11 @@ export default function SearchEdit( {
113
114
  }
114
115
 
115
116
  const colorProps = useColorProps( attributes );
116
- const typographyProps = useTypographyProps( attributes );
117
+ const fluidTypographyEnabled = useSetting( 'typography.fluid' );
118
+ const typographyProps = useTypographyProps(
119
+ attributes,
120
+ fluidTypographyEnabled
121
+ );
117
122
  const unitControlInstanceId = useInstanceId( UnitControl );
118
123
  const unitControlInputId = `wp-block-search__width-${ unitControlInstanceId }`;
119
124
  const isButtonPositionInside = 'button-inside' === buttonPosition;