@wordpress/block-library 9.33.1-next.ff1cebbba.0 → 9.33.2-next.36001005c.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 (173) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +1 -1
  3. package/build/breadcrumbs/block.json +8 -2
  4. package/build/breadcrumbs/edit.js +113 -12
  5. package/build/breadcrumbs/edit.js.map +2 -2
  6. package/build/buttons/transforms.js +7 -7
  7. package/build/buttons/transforms.js.map +2 -2
  8. package/build/code/transforms.js +19 -15
  9. package/build/code/transforms.js.map +2 -2
  10. package/build/heading/index.js +1 -3
  11. package/build/heading/index.js.map +3 -3
  12. package/build/heading/transforms.js +22 -20
  13. package/build/heading/transforms.js.map +2 -2
  14. package/build/index.js +5 -3
  15. package/build/index.js.map +2 -2
  16. package/build/math/block.json +21 -0
  17. package/build/math/edit.js +132 -0
  18. package/build/math/edit.js.map +7 -0
  19. package/build/math/index.js +63 -0
  20. package/build/math/index.js.map +7 -0
  21. package/build/math/init.js +35 -0
  22. package/build/math/init.js.map +7 -0
  23. package/build/math/save.js +40 -0
  24. package/build/math/save.js.map +7 -0
  25. package/build/navigation/edit/menu-inspector-controls.js +2 -2
  26. package/build/navigation/edit/menu-inspector-controls.js.map +2 -2
  27. package/build/navigation-link/edit.js +5 -2
  28. package/build/navigation-link/edit.js.map +2 -2
  29. package/build/navigation-link/link-ui/index.js +1 -1
  30. package/build/navigation-link/link-ui/index.js.map +2 -2
  31. package/build/navigation-link/shared/controls.js +39 -16
  32. package/build/navigation-link/shared/controls.js.map +3 -3
  33. package/build/navigation-link/shared/index.js +2 -0
  34. package/build/navigation-link/shared/index.js.map +2 -2
  35. package/build/navigation-link/shared/update-attributes.js +3 -1
  36. package/build/navigation-link/shared/update-attributes.js.map +2 -2
  37. package/build/navigation-link/shared/use-entity-binding.js +46 -13
  38. package/build/navigation-link/shared/use-entity-binding.js.map +2 -2
  39. package/build/navigation-submenu/edit.js +5 -2
  40. package/build/navigation-submenu/edit.js.map +2 -2
  41. package/build/page-list/use-convert-to-navigation-links.js +6 -1
  42. package/build/page-list/use-convert-to-navigation-links.js.map +2 -2
  43. package/build/paragraph/index.js +1 -3
  44. package/build/paragraph/index.js.map +3 -3
  45. package/build/post-date/deprecated.js +98 -2
  46. package/build/post-date/deprecated.js.map +2 -2
  47. package/build/post-date/edit.js +1 -1
  48. package/build/post-date/edit.js.map +1 -1
  49. package/build/post-date/variations.js +4 -4
  50. package/build/post-date/variations.js.map +2 -2
  51. package/build/term-template/block.json +0 -1
  52. package/build/term-template/edit.js +4 -1
  53. package/build/term-template/edit.js.map +2 -2
  54. package/build/terms-query/block.json +0 -1
  55. package/build/utils/get-transformed-attributes.js +82 -0
  56. package/build/utils/get-transformed-attributes.js.map +7 -0
  57. package/build-module/breadcrumbs/block.json +8 -2
  58. package/build-module/breadcrumbs/edit.js +117 -14
  59. package/build-module/breadcrumbs/edit.js.map +2 -2
  60. package/build-module/buttons/transforms.js +7 -7
  61. package/build-module/buttons/transforms.js.map +2 -2
  62. package/build-module/code/transforms.js +19 -15
  63. package/build-module/code/transforms.js.map +2 -2
  64. package/build-module/heading/index.js +1 -3
  65. package/build-module/heading/index.js.map +2 -2
  66. package/build-module/heading/transforms.js +22 -20
  67. package/build-module/heading/transforms.js.map +2 -2
  68. package/build-module/index.js +5 -3
  69. package/build-module/index.js.map +2 -2
  70. package/build-module/math/block.json +21 -0
  71. package/build-module/math/edit.js +110 -0
  72. package/build-module/math/edit.js.map +7 -0
  73. package/build-module/math/index.js +26 -0
  74. package/build-module/math/index.js.map +7 -0
  75. package/build-module/math/init.js +8 -0
  76. package/build-module/math/init.js.map +7 -0
  77. package/build-module/math/save.js +20 -0
  78. package/build-module/math/save.js.map +7 -0
  79. package/build-module/navigation/edit/menu-inspector-controls.js +2 -2
  80. package/build-module/navigation/edit/menu-inspector-controls.js.map +2 -2
  81. package/build-module/navigation-link/edit.js +5 -2
  82. package/build-module/navigation-link/edit.js.map +2 -2
  83. package/build-module/navigation-link/link-ui/index.js +1 -1
  84. package/build-module/navigation-link/link-ui/index.js.map +2 -2
  85. package/build-module/navigation-link/shared/controls.js +40 -17
  86. package/build-module/navigation-link/shared/controls.js.map +2 -2
  87. package/build-module/navigation-link/shared/index.js +5 -1
  88. package/build-module/navigation-link/shared/index.js.map +2 -2
  89. package/build-module/navigation-link/shared/update-attributes.js +3 -1
  90. package/build-module/navigation-link/shared/update-attributes.js.map +2 -2
  91. package/build-module/navigation-link/shared/use-entity-binding.js +45 -13
  92. package/build-module/navigation-link/shared/use-entity-binding.js.map +2 -2
  93. package/build-module/navigation-submenu/edit.js +5 -2
  94. package/build-module/navigation-submenu/edit.js.map +2 -2
  95. package/build-module/page-list/use-convert-to-navigation-links.js +6 -1
  96. package/build-module/page-list/use-convert-to-navigation-links.js.map +2 -2
  97. package/build-module/paragraph/index.js +1 -3
  98. package/build-module/paragraph/index.js.map +2 -2
  99. package/build-module/post-date/deprecated.js +98 -2
  100. package/build-module/post-date/deprecated.js.map +2 -2
  101. package/build-module/post-date/edit.js +1 -1
  102. package/build-module/post-date/edit.js.map +1 -1
  103. package/build-module/post-date/variations.js +4 -4
  104. package/build-module/post-date/variations.js.map +2 -2
  105. package/build-module/term-template/block.json +0 -1
  106. package/build-module/term-template/edit.js +4 -1
  107. package/build-module/term-template/edit.js.map +2 -2
  108. package/build-module/terms-query/block.json +0 -1
  109. package/build-module/utils/get-transformed-attributes.js +58 -0
  110. package/build-module/utils/get-transformed-attributes.js.map +7 -0
  111. package/build-style/editor-rtl.css +2 -2
  112. package/build-style/editor.css +2 -2
  113. package/build-style/navigation-link/editor-rtl.css +1 -1
  114. package/build-style/navigation-link/editor.css +1 -1
  115. package/build-style/video/editor-rtl.css +1 -1
  116. package/build-style/video/editor.css +1 -1
  117. package/package.json +61 -36
  118. package/src/breadcrumbs/block.json +8 -2
  119. package/src/breadcrumbs/edit.js +163 -18
  120. package/src/breadcrumbs/index.php +118 -16
  121. package/src/buttons/transforms.js +6 -6
  122. package/src/code/transforms.js +16 -14
  123. package/src/heading/index.js +0 -2
  124. package/src/heading/transforms.js +25 -24
  125. package/src/index.js +5 -3
  126. package/src/math/block.json +21 -0
  127. package/src/math/edit.js +123 -0
  128. package/src/math/index.js +31 -0
  129. package/src/math/init.js +4 -0
  130. package/src/math/save.js +20 -0
  131. package/src/navigation/edit/menu-inspector-controls.js +7 -6
  132. package/src/navigation-link/edit.js +5 -2
  133. package/src/navigation-link/editor.scss +1 -1
  134. package/src/navigation-link/index.php +4 -18
  135. package/src/navigation-link/link-ui/index.js +4 -2
  136. package/src/navigation-link/shared/controls.js +69 -20
  137. package/src/navigation-link/shared/index.js +4 -1
  138. package/src/navigation-link/shared/test/controls.js +14 -9
  139. package/src/navigation-link/shared/test/update-attributes.test.js +8 -0
  140. package/src/navigation-link/shared/test/use-entity-binding.js +132 -17
  141. package/src/navigation-link/shared/update-attributes.js +1 -0
  142. package/src/navigation-link/shared/use-entity-binding.js +74 -19
  143. package/src/navigation-submenu/edit.js +5 -2
  144. package/src/navigation-submenu/index.php +3 -17
  145. package/src/page-list/test/{convert-to-links-modal.js → convert-to-navigation-links.js} +67 -0
  146. package/src/page-list/use-convert-to-navigation-links.js +11 -1
  147. package/src/paragraph/index.js +0 -2
  148. package/src/post-date/deprecated.js +104 -2
  149. package/src/post-date/edit.js +1 -1
  150. package/src/post-date/index.php +3 -3
  151. package/src/post-date/variations.js +5 -4
  152. package/src/term-template/block.json +0 -1
  153. package/src/term-template/edit.js +4 -1
  154. package/src/term-template/index.php +4 -6
  155. package/src/terms-query/block.json +0 -1
  156. package/src/utils/get-transformed-attributes.js +98 -0
  157. package/src/video/editor.scss +1 -1
  158. package/tsconfig.json +1 -0
  159. package/build/heading/variations.js +0 -48
  160. package/build/heading/variations.js.map +0 -7
  161. package/build/paragraph/variations.js +0 -48
  162. package/build/paragraph/variations.js.map +0 -7
  163. package/build/utils/get-transformed-metadata.js +0 -65
  164. package/build/utils/get-transformed-metadata.js.map +0 -7
  165. package/build-module/heading/variations.js +0 -28
  166. package/build-module/heading/variations.js.map +0 -7
  167. package/build-module/paragraph/variations.js +0 -28
  168. package/build-module/paragraph/variations.js.map +0 -7
  169. package/build-module/utils/get-transformed-metadata.js +0 -41
  170. package/build-module/utils/get-transformed-metadata.js.map +0 -7
  171. package/src/heading/variations.js +0 -29
  172. package/src/paragraph/variations.js +0 -29
  173. package/src/utils/get-transformed-metadata.js +0 -69
@@ -17,6 +17,11 @@
17
17
  * @return string Returns the post breadcrumb for hierarchical post types.
18
18
  */
19
19
  function render_block_core_breadcrumbs( $attributes, $content, $block ) {
20
+ // Exclude breadcrumbs from special contexts like archives, search, 404, etc.
21
+ // until they are explicitly supported.
22
+ if ( is_archive() || is_search() || is_404() || is_home() || is_front_page() ) {
23
+ return '';
24
+ }
20
25
  if ( ! isset( $block->context['postId'] ) || ! isset( $block->context['postType'] ) ) {
21
26
  return '';
22
27
  }
@@ -24,16 +29,12 @@ function render_block_core_breadcrumbs( $attributes, $content, $block ) {
24
29
  $post_id = $block->context['postId'];
25
30
  $post_type = $block->context['postType'];
26
31
 
27
- // Only render for hierarchical post types.
28
- if ( ! is_post_type_hierarchical( $post_type ) ) {
29
- return '';
30
- }
31
-
32
32
  $post = get_post( $post_id );
33
33
  if ( ! $post ) {
34
34
  return '';
35
35
  }
36
36
 
37
+ $type = $attributes['type'];
37
38
  $breadcrumb_items = array();
38
39
  if ( $attributes['showHomeLink'] ) {
39
40
  $breadcrumb_items[] = sprintf(
@@ -42,18 +43,14 @@ function render_block_core_breadcrumbs( $attributes, $content, $block ) {
42
43
  esc_html__( 'Home' )
43
44
  );
44
45
  }
45
-
46
- $ancestors = get_post_ancestors( $post_id );
47
- $ancestors = array_reverse( $ancestors );
48
-
49
- foreach ( $ancestors as $ancestor_id ) {
50
- $breadcrumb_items[] = sprintf(
51
- '<a href="%s">%s</a>',
52
- esc_url( get_permalink( $ancestor_id ) ),
53
- get_the_title( $ancestor_id )
54
- );
46
+ $supported_types = array( 'postWithAncestors', 'postWithTerms' );
47
+ // If `type` is not set to a specific breadcrumb type, determine it based on the block's default heuristics.
48
+ $breadcrumbs_type = in_array( $type, $supported_types, true ) ? $type : block_core_breadcrumbs_get_breadcrumbs_type( $post_type );
49
+ if ( 'postWithAncestors' === $breadcrumbs_type ) {
50
+ $breadcrumb_items = array_merge( $breadcrumb_items, block_core_breadcrumbs_get_hierarchical_post_type_breadcrumbs( $post_id ) );
51
+ } else {
52
+ $breadcrumb_items = array_merge( $breadcrumb_items, block_core_breadcrumbs_get_terms_breadcrumbs( $post_id, $post_type ) );
55
53
  }
56
-
57
54
  // Add current post title (not linked).
58
55
  $breadcrumb_items[] = sprintf( '<span aria-current="page">%s</span>', get_the_title( $post ) );
59
56
  $wrapper_attributes = get_block_wrapper_attributes(
@@ -80,6 +77,111 @@ function render_block_core_breadcrumbs( $attributes, $content, $block ) {
80
77
  return $breadcrumb_html;
81
78
  }
82
79
 
80
+ /**
81
+ * Determines the breadcrumb type based on the block's default heuristics.
82
+ *
83
+ * @since 6.9.0
84
+ *
85
+ * @param string $post_type The post type name.
86
+ *
87
+ * @return string The breadcrumb type.
88
+ */
89
+ function block_core_breadcrumbs_get_breadcrumbs_type( $post_type ) {
90
+ return is_post_type_hierarchical( $post_type ) ? 'postWithAncestors' : 'postWithTerms';
91
+ }
92
+
93
+ /**
94
+ * Generates breadcrumb items from hierarchical post type ancestors.
95
+ *
96
+ * @since 6.9.0
97
+ *
98
+ * @param int $post_id The post ID.
99
+ *
100
+ * @return array Array of breadcrumb HTML items.
101
+ */
102
+ function block_core_breadcrumbs_get_hierarchical_post_type_breadcrumbs( $post_id ) {
103
+ $breadcrumb_items = array();
104
+ $ancestors = get_post_ancestors( $post_id );
105
+ $ancestors = array_reverse( $ancestors );
106
+
107
+ foreach ( $ancestors as $ancestor_id ) {
108
+ $breadcrumb_items[] = sprintf(
109
+ '<a href="%s">%s</a>',
110
+ esc_url( get_permalink( $ancestor_id ) ),
111
+ get_the_title( $ancestor_id )
112
+ );
113
+ }
114
+ return $breadcrumb_items;
115
+ }
116
+
117
+
118
+ /**
119
+ * Generates breadcrumb items from taxonomy terms.
120
+ *
121
+ * Finds the first publicly queryable taxonomy with terms assigned to the post
122
+ * and generates breadcrumb links, including hierarchical term ancestors if applicable.
123
+ *
124
+ * @since 6.9.0
125
+ *
126
+ * @param int $post_id The post ID.
127
+ * @param string $post_type The post type name.
128
+ *
129
+ * @return array Array of breadcrumb HTML items.
130
+ */
131
+ function block_core_breadcrumbs_get_terms_breadcrumbs( $post_id, $post_type ) {
132
+ $breadcrumb_items = array();
133
+ // Get public taxonomies for this post type.
134
+ $taxonomies = wp_filter_object_list(
135
+ get_object_taxonomies( $post_type, 'objects' ),
136
+ array(
137
+ 'publicly_queryable' => true,
138
+ 'show_in_rest' => true,
139
+ )
140
+ );
141
+
142
+ if ( empty( $taxonomies ) ) {
143
+ return array();
144
+ }
145
+
146
+ // Find the first taxonomy that has terms assigned to this post.
147
+ $taxonomy_name = null;
148
+ $terms = array();
149
+ foreach ( $taxonomies as $taxonomy ) {
150
+ $post_terms = get_the_terms( $post_id, $taxonomy->name );
151
+ if ( ! empty( $post_terms ) && ! is_wp_error( $post_terms ) ) {
152
+ $taxonomy_name = $taxonomy->name;
153
+ $terms = $post_terms;
154
+ break;
155
+ }
156
+ }
157
+
158
+ if ( ! empty( $terms ) ) {
159
+ // Use the first term (if multiple are assigned).
160
+ $term = reset( $terms );
161
+ // Check if taxonomy is hierarchical also add ancestor term links
162
+ if ( is_taxonomy_hierarchical( $taxonomy_name ) ) {
163
+ $term_ancestors = get_ancestors( $term->term_id, $taxonomy_name, 'taxonomy' );
164
+ $term_ancestors = array_reverse( $term_ancestors );
165
+ foreach ( $term_ancestors as $ancestor_id ) {
166
+ $ancestor_term = get_term( $ancestor_id, $taxonomy_name );
167
+ if ( $ancestor_term && ! is_wp_error( $ancestor_term ) ) {
168
+ $breadcrumb_items[] = sprintf(
169
+ '<a href="%s">%s</a>',
170
+ esc_url( get_term_link( $ancestor_term ) ),
171
+ esc_html( $ancestor_term->name )
172
+ );
173
+ }
174
+ }
175
+ }
176
+ $breadcrumb_items[] = sprintf(
177
+ '<a href="%s">%s</a>',
178
+ esc_url( get_term_link( $term ) ),
179
+ esc_html( $term->name )
180
+ );
181
+ }
182
+ return $breadcrumb_items;
183
+ }
184
+
83
185
  /**
84
186
  * Registers the `core/breadcrumbs` block on the server.
85
187
  *
@@ -7,7 +7,7 @@ import { __unstableCreateElement as createElement } from '@wordpress/rich-text';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
- import { getTransformedMetadata } from '../utils/get-transformed-metadata';
10
+ import { getTransformedAttributes } from '../utils/get-transformed-attributes';
11
11
 
12
12
  const transforms = {
13
13
  from: [
@@ -38,7 +38,7 @@ const transforms = {
38
38
  {},
39
39
  // Loop the selected buttons.
40
40
  buttons.map( ( attributes ) => {
41
- const { content, metadata } = attributes;
41
+ const { content } = attributes;
42
42
  const element = createElement( document, content );
43
43
  // Remove any HTML tags.
44
44
  const text = element.innerText || '';
@@ -47,15 +47,15 @@ const transforms = {
47
47
  const url = link?.getAttribute( 'href' );
48
48
  // Create singular button in the buttons block.
49
49
  return createBlock( 'core/button', {
50
- text,
51
- url,
52
- metadata: getTransformedMetadata(
53
- metadata,
50
+ ...getTransformedAttributes(
51
+ attributes,
54
52
  'core/button',
55
53
  ( { content: contentBinding } ) => ( {
56
54
  text: contentBinding,
57
55
  } )
58
56
  ),
57
+ text,
58
+ url,
59
59
  } );
60
60
  } )
61
61
  ),
@@ -7,7 +7,7 @@ import { create, toHTMLString } from '@wordpress/rich-text';
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
- import { getTransformedMetadata } from '../utils/get-transformed-metadata';
10
+ import { getTransformedAttributes } from '../utils/get-transformed-attributes';
11
11
 
12
12
  const transforms = {
13
13
  from: [
@@ -19,21 +19,24 @@ const transforms = {
19
19
  {
20
20
  type: 'block',
21
21
  blocks: [ 'core/paragraph' ],
22
- transform: ( { content, metadata } ) =>
23
- createBlock( 'core/code', {
22
+ transform: ( attributes ) => {
23
+ const { content } = attributes;
24
+ return createBlock( 'core/code', {
25
+ ...getTransformedAttributes( attributes, 'core/code' ),
24
26
  content,
25
- metadata: getTransformedMetadata( metadata, 'core/code' ),
26
- } ),
27
+ } );
28
+ },
27
29
  },
28
30
  {
29
31
  type: 'block',
30
32
  blocks: [ 'core/html' ],
31
- transform: ( { content: text, metadata } ) => {
33
+ transform: ( attributes ) => {
34
+ const { content: text } = attributes;
32
35
  return createBlock( 'core/code', {
36
+ ...getTransformedAttributes( attributes, 'core/code' ),
33
37
  // The HTML is plain text (with plain line breaks), so
34
38
  // convert it to rich text.
35
39
  content: toHTMLString( { value: create( { text } ) } ),
36
- metadata: getTransformedMetadata( metadata, 'core/code' ),
37
40
  } );
38
41
  },
39
42
  },
@@ -60,14 +63,13 @@ const transforms = {
60
63
  {
61
64
  type: 'block',
62
65
  blocks: [ 'core/paragraph' ],
63
- transform: ( { content, metadata } ) =>
64
- createBlock( 'core/paragraph', {
66
+ transform: ( attributes ) => {
67
+ const { content } = attributes;
68
+ return createBlock( 'core/paragraph', {
69
+ ...getTransformedAttributes( attributes, 'core/paragraph' ),
65
70
  content,
66
- metadata: getTransformedMetadata(
67
- metadata,
68
- 'core/paragraph'
69
- ),
70
- } ),
71
+ } );
72
+ },
71
73
  },
72
74
  ],
73
75
  };
@@ -13,7 +13,6 @@ import edit from './edit';
13
13
  import metadata from './block.json';
14
14
  import save from './save';
15
15
  import transforms from './transforms';
16
- import variations from './variations';
17
16
 
18
17
  const { name } = metadata;
19
18
 
@@ -66,7 +65,6 @@ export const settings = {
66
65
  },
67
66
  edit,
68
67
  save,
69
- variations,
70
68
  };
71
69
 
72
70
  export const init = () => initBlock( { name, metadata, settings } );
@@ -7,7 +7,7 @@ import { createBlock, getBlockAttributes } from '@wordpress/blocks';
7
7
  * Internal dependencies
8
8
  */
9
9
  import { getLevelFromHeadingNodeName } from './shared';
10
- import { getTransformedMetadata } from '../utils/get-transformed-metadata';
10
+ import { getTransformedAttributes } from '../utils/get-transformed-attributes';
11
11
 
12
12
  const transforms = {
13
13
  from: [
@@ -16,21 +16,21 @@ const transforms = {
16
16
  isMultiBlock: true,
17
17
  blocks: [ 'core/paragraph' ],
18
18
  transform: ( attributes ) =>
19
- attributes.map(
20
- ( { content, anchor, align: textAlign, metadata } ) =>
21
- createBlock( 'core/heading', {
22
- content,
23
- anchor,
24
- textAlign,
25
- metadata: getTransformedMetadata(
26
- metadata,
27
- 'core/heading',
28
- ( { content: contentBinding } ) => ( {
29
- content: contentBinding,
30
- } )
31
- ),
32
- } )
33
- ),
19
+ attributes.map( ( _attributes ) => {
20
+ const { content, anchor, align: textAlign } = _attributes;
21
+ return createBlock( 'core/heading', {
22
+ ...getTransformedAttributes(
23
+ _attributes,
24
+ 'core/heading',
25
+ ( { content: contentBinding } ) => ( {
26
+ content: contentBinding,
27
+ } )
28
+ ),
29
+ content,
30
+ anchor,
31
+ textAlign,
32
+ } );
33
+ } ),
34
34
  },
35
35
  {
36
36
  type: 'raw',
@@ -91,19 +91,20 @@ const transforms = {
91
91
  isMultiBlock: true,
92
92
  blocks: [ 'core/paragraph' ],
93
93
  transform: ( attributes ) =>
94
- attributes.map( ( { content, textAlign: align, metadata } ) =>
95
- createBlock( 'core/paragraph', {
96
- content,
97
- align,
98
- metadata: getTransformedMetadata(
99
- metadata,
94
+ attributes.map( ( _attributes ) => {
95
+ const { content, textAlign: align } = _attributes;
96
+ return createBlock( 'core/paragraph', {
97
+ ...getTransformedAttributes(
98
+ _attributes,
100
99
  'core/paragraph',
101
100
  ( { content: contentBinding } ) => ( {
102
101
  content: contentBinding,
103
102
  } )
104
103
  ),
105
- } )
106
- ),
104
+ content,
105
+ align,
106
+ } );
107
+ } ),
107
108
  },
108
109
  ],
109
110
  };
package/src/index.js CHANGED
@@ -72,6 +72,7 @@ import * as image from './image';
72
72
  import * as latestComments from './latest-comments';
73
73
  import * as latestPosts from './latest-posts';
74
74
  import * as list from './list';
75
+ import * as math from './math';
75
76
  import * as listItem from './list-item';
76
77
  import * as logInOut from './loginout';
77
78
  import * as mediaText from './media-text';
@@ -163,7 +164,6 @@ const getAllBlocks = () => {
163
164
  accordionPanel,
164
165
  archives,
165
166
  audio,
166
- breadcrumbs,
167
167
  button,
168
168
  buttons,
169
169
  calendar,
@@ -178,6 +178,7 @@ const getAllBlocks = () => {
178
178
  file,
179
179
  group,
180
180
  html,
181
+ math,
181
182
  latestComments,
182
183
  latestPosts,
183
184
  mediaText,
@@ -254,13 +255,14 @@ const getAllBlocks = () => {
254
255
  termCount,
255
256
  termDescription,
256
257
  termName,
258
+ termsQuery,
259
+ termTemplate,
257
260
  queryTitle,
258
261
  postAuthorBiography,
259
262
  ];
260
263
 
261
264
  if ( window?.__experimentalEnableBlockExperiments ) {
262
- blocks.push( termsQuery );
263
- blocks.push( termTemplate );
265
+ blocks.push( breadcrumbs );
264
266
  }
265
267
 
266
268
  if ( window?.__experimentalEnableFormBlocks ) {
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "core/math",
5
+ "title": "Math",
6
+ "category": "text",
7
+ "description": "Display mathematical notation using LaTeX.",
8
+ "keywords": [ "equation", "formula", "latex", "mathematics" ],
9
+ "textdomain": "default",
10
+ "attributes": {
11
+ "latex": {
12
+ "type": "string",
13
+ "role": "content"
14
+ },
15
+ "mathML": {
16
+ "type": "string",
17
+ "source": "html",
18
+ "selector": "math"
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import {
6
+ useBlockProps,
7
+ store as blockEditorStore,
8
+ } from '@wordpress/block-editor';
9
+ import {
10
+ TextareaControl,
11
+ Popover,
12
+ __experimentalVStack as VStack,
13
+ privateApis as componentsPrivateApis,
14
+ } from '@wordpress/components';
15
+ import { useState, useEffect, useRef } from '@wordpress/element';
16
+ import { useDispatch } from '@wordpress/data';
17
+
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+ import { unlock } from '../lock-unlock';
22
+
23
+ const { Badge } = unlock( componentsPrivateApis );
24
+
25
+ export default function MathEdit( { attributes, setAttributes, isSelected } ) {
26
+ const { latex } = attributes;
27
+ const [ blockRef, setBlockRef ] = useState();
28
+ const [ error, setError ] = useState( null );
29
+ const [ latexToMathML, setLatexToMathML ] = useState();
30
+ const initialLatex = useRef( attributes.latex );
31
+ const { __unstableMarkNextChangeAsNotPersistent } =
32
+ useDispatch( blockEditorStore );
33
+
34
+ useEffect( () => {
35
+ import( '@wordpress/latex-to-mathml' ).then( ( module ) => {
36
+ setLatexToMathML( () => module.default );
37
+ if ( initialLatex.current ) {
38
+ __unstableMarkNextChangeAsNotPersistent();
39
+ setAttributes( {
40
+ mathML: module.default( initialLatex.current, {
41
+ displayMode: true,
42
+ } ),
43
+ } );
44
+ }
45
+ } );
46
+ }, [
47
+ initialLatex,
48
+ setAttributes,
49
+ __unstableMarkNextChangeAsNotPersistent,
50
+ ] );
51
+
52
+ const blockProps = useBlockProps( {
53
+ ref: setBlockRef,
54
+ position: 'relative',
55
+ } );
56
+
57
+ return (
58
+ <div { ...blockProps }>
59
+ { attributes.mathML ? (
60
+ <math
61
+ // We can't spread block props on the math element because
62
+ // it only supports a limited amount of global attributes.
63
+ // For example, draggable will have no effect.
64
+ display="block"
65
+ dangerouslySetInnerHTML={ { __html: attributes.mathML } }
66
+ />
67
+ ) : (
68
+ '\u200B'
69
+ ) }
70
+ { isSelected && (
71
+ <Popover
72
+ placement="bottom-start"
73
+ offset={ 8 }
74
+ anchor={ blockRef }
75
+ focusOnMount="firstContentElement"
76
+ >
77
+ <div style={ { padding: '4px', minWidth: '300px' } }>
78
+ <VStack spacing={ 1 }>
79
+ <TextareaControl
80
+ __nextHasNoMarginBottom
81
+ __next40pxDefaultSize
82
+ label={ __( 'LaTeX math syntax' ) }
83
+ hideLabelFromVision
84
+ value={ latex }
85
+ onChange={ ( newLatex ) => {
86
+ if ( ! latexToMathML ) {
87
+ setAttributes( { latex: newLatex } );
88
+ return;
89
+ }
90
+ let mathML = '';
91
+ try {
92
+ mathML = latexToMathML( newLatex, {
93
+ displayMode: true,
94
+ } );
95
+ setError( null );
96
+ } catch ( err ) {
97
+ setError( err.message );
98
+ }
99
+ setAttributes( {
100
+ mathML,
101
+ latex: newLatex,
102
+ } );
103
+ } }
104
+ placeholder={ __( 'e.g., x^2, \\frac{a}{b}' ) }
105
+ />
106
+ { error && (
107
+ <>
108
+ <Badge
109
+ intent="error"
110
+ className="wp-block-math__error"
111
+ >
112
+ { error }
113
+ </Badge>
114
+ <style children=".wp-block-math__error .components-badge__content{white-space:normal}" />
115
+ </>
116
+ ) }
117
+ </VStack>
118
+ </div>
119
+ </Popover>
120
+ ) }
121
+ </div>
122
+ );
123
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { math as icon } from '@wordpress/icons';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import initBlock from '../utils/init-block';
10
+ import edit from './edit';
11
+ import metadata from './block.json';
12
+ import save from './save';
13
+
14
+ const { name } = metadata;
15
+
16
+ export { metadata, name };
17
+
18
+ export const settings = {
19
+ icon,
20
+ example: {
21
+ attributes: {
22
+ latex: 'x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}',
23
+ mathML: '<semantics><mrow><mi>x</mi><mo>=</mo><mfrac><mrow><mo lspace="0em" rspace="0em">−</mo><mi>b</mi><mo>±</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo>−</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}</annotation></semantics>',
24
+ },
25
+ viewportWidth: 300,
26
+ },
27
+ edit,
28
+ save,
29
+ };
30
+
31
+ export const init = () => initBlock( { name, metadata, settings } );
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ export { init, metadata, name, settings } from './index';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useBlockProps } from '@wordpress/block-editor';
5
+
6
+ export default function save( { attributes } ) {
7
+ const { latex, mathML } = attributes;
8
+
9
+ if ( ! latex ) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <math
15
+ { ...useBlockProps.save() }
16
+ display="block"
17
+ dangerouslySetInnerHTML={ { __html: mathML } }
18
+ />
19
+ );
20
+ }
@@ -111,17 +111,18 @@ function AdditionalBlockContent( { block, insertedBlock, setInsertedBlock } ) {
111
111
  } }
112
112
  onChange={ ( updatedValue ) => {
113
113
  // updateAttributes determines the final state and returns metadata
114
- const { isEntityLink } = updateAttributes(
115
- updatedValue,
116
- setInsertedBlockAttributes( insertedBlock?.clientId ),
117
- insertedBlock?.attributes
118
- );
114
+ const { isEntityLink, attributes: updatedAttributes } =
115
+ updateAttributes(
116
+ updatedValue,
117
+ setInsertedBlockAttributes( insertedBlock?.clientId ),
118
+ insertedBlock?.attributes
119
+ );
119
120
 
120
121
  // Handle URL binding based on the final computed state
121
122
  // Only create bindings for entity links (posts, pages, taxonomies)
122
123
  // Never create bindings for custom links (manual URLs)
123
124
  if ( isEntityLink ) {
124
- createBinding();
125
+ createBinding( updatedAttributes );
125
126
  } else {
126
127
  clearBinding();
127
128
  }
@@ -543,7 +543,10 @@ export default function NavigationLinkEdit( {
543
543
  anchor={ popoverAnchor }
544
544
  onRemove={ removeLink }
545
545
  onChange={ ( updatedValue ) => {
546
- const { isEntityLink } = updateAttributes(
546
+ const {
547
+ isEntityLink,
548
+ attributes: updatedAttributes,
549
+ } = updateAttributes(
547
550
  updatedValue,
548
551
  setAttributes,
549
552
  attributes
@@ -553,7 +556,7 @@ export default function NavigationLinkEdit( {
553
556
  // Only create bindings for entity links (posts, pages, taxonomies)
554
557
  // Never create bindings for custom links (manual URLs)
555
558
  if ( isEntityLink ) {
556
- createBinding();
559
+ createBinding( updatedAttributes );
557
560
  } else {
558
561
  clearBinding();
559
562
  }
@@ -110,7 +110,7 @@
110
110
  .link-control-transform__subheading {
111
111
  font-size: 11px;
112
112
  text-transform: uppercase;
113
- font-weight: 500;
113
+ font-weight: $font-weight-medium;
114
114
  color: $gray-900;
115
115
  margin-bottom: 1.5em;
116
116
  }