@wordpress/block-library 8.26.0 → 8.27.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 (254) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/avatar/edit.js +2 -2
  3. package/build/avatar/edit.js.map +1 -1
  4. package/build/block/edit.js +76 -13
  5. package/build/block/edit.js.map +1 -1
  6. package/build/block/{v1/edit.native.js → edit.native.js} +4 -4
  7. package/build/block/edit.native.js.map +1 -0
  8. package/build/block/index.js +5 -3
  9. package/build/block/index.js.map +1 -1
  10. package/build/button/edit.js +24 -6
  11. package/build/button/edit.js.map +1 -1
  12. package/build/button/index.js +1 -0
  13. package/build/button/index.js.map +1 -1
  14. package/build/button/save.js +3 -1
  15. package/build/button/save.js.map +1 -1
  16. package/build/cover/edit.native.js +1 -0
  17. package/build/cover/edit.native.js.map +1 -1
  18. package/build/embed/edit.js +3 -2
  19. package/build/embed/edit.js.map +1 -1
  20. package/build/file/index.js +0 -1
  21. package/build/file/index.js.map +1 -1
  22. package/build/footnotes/edit.js +2 -1
  23. package/build/footnotes/edit.js.map +1 -1
  24. package/build/footnotes/format.js +17 -19
  25. package/build/footnotes/format.js.map +1 -1
  26. package/build/heading/edit.js +2 -1
  27. package/build/heading/edit.js.map +1 -1
  28. package/build/heading/edit.native.js +141 -0
  29. package/build/heading/edit.native.js.map +1 -0
  30. package/build/heading/index.js +1 -0
  31. package/build/heading/index.js.map +1 -1
  32. package/build/image/edit.js +8 -4
  33. package/build/image/edit.js.map +1 -1
  34. package/build/image/image.js +33 -7
  35. package/build/image/image.js.map +1 -1
  36. package/build/image/index.js +6 -3
  37. package/build/image/index.js.map +1 -1
  38. package/build/more/index.js +4 -0
  39. package/build/more/index.js.map +1 -1
  40. package/build/navigation/edit/index.js +2 -2
  41. package/build/navigation/edit/index.js.map +1 -1
  42. package/build/navigation/index.js +0 -1
  43. package/build/navigation/index.js.map +1 -1
  44. package/build/paragraph/edit.js +2 -1
  45. package/build/paragraph/edit.js.map +1 -1
  46. package/build/paragraph/index.js +1 -2
  47. package/build/paragraph/index.js.map +1 -1
  48. package/build/paragraph/transforms.js +1 -2
  49. package/build/paragraph/transforms.js.map +1 -1
  50. package/build/post-content/edit.js +2 -2
  51. package/build/post-content/edit.js.map +1 -1
  52. package/build/post-date/edit.js +1 -1
  53. package/build/post-date/edit.js.map +1 -1
  54. package/build/post-navigation-link/edit.js +43 -2
  55. package/build/post-navigation-link/edit.js.map +1 -1
  56. package/build/post-navigation-link/index.js +8 -0
  57. package/build/post-navigation-link/index.js.map +1 -1
  58. package/build/pullquote/index.js +4 -0
  59. package/build/pullquote/index.js.map +1 -1
  60. package/build/query/edit/inspector-controls/index.js +3 -3
  61. package/build/query/edit/inspector-controls/index.js.map +1 -1
  62. package/build/query/edit/query-content.js +2 -2
  63. package/build/query/edit/query-content.js.map +1 -1
  64. package/build/query/edit/query-placeholder.js +6 -7
  65. package/build/query/edit/query-placeholder.js.map +1 -1
  66. package/build/query/index.js +1 -2
  67. package/build/query/index.js.map +1 -1
  68. package/build/query/variations.js +8 -1
  69. package/build/query/variations.js.map +1 -1
  70. package/build/query/view.js +31 -12
  71. package/build/query/view.js.map +1 -1
  72. package/build/search/index.js +0 -1
  73. package/build/search/index.js.map +1 -1
  74. package/build/table-of-contents/hooks.js +2 -2
  75. package/build/table-of-contents/hooks.js.map +1 -1
  76. package/build/template-part/edit/advanced-controls.js +1 -4
  77. package/build/template-part/edit/advanced-controls.js.map +1 -1
  78. package/build/template-part/edit/index.js +39 -17
  79. package/build/template-part/edit/index.js.map +1 -1
  80. package/build/video/edit.native.js +7 -2
  81. package/build/video/edit.native.js.map +1 -1
  82. package/build/video/transforms.js +17 -0
  83. package/build/video/transforms.js.map +1 -1
  84. package/build-module/avatar/edit.js +2 -2
  85. package/build-module/avatar/edit.js.map +1 -1
  86. package/build-module/block/edit.js +76 -13
  87. package/build-module/block/edit.js.map +1 -1
  88. package/build-module/block/{v1/edit.native.js → edit.native.js} +3 -3
  89. package/build-module/block/edit.native.js.map +1 -0
  90. package/build-module/block/index.js +5 -3
  91. package/build-module/block/index.js.map +1 -1
  92. package/build-module/button/edit.js +25 -7
  93. package/build-module/button/edit.js.map +1 -1
  94. package/build-module/button/index.js +1 -0
  95. package/build-module/button/index.js.map +1 -1
  96. package/build-module/button/save.js +4 -2
  97. package/build-module/button/save.js.map +1 -1
  98. package/build-module/cover/edit.native.js +1 -0
  99. package/build-module/cover/edit.native.js.map +1 -1
  100. package/build-module/embed/edit.js +3 -2
  101. package/build-module/embed/edit.js.map +1 -1
  102. package/build-module/file/index.js +0 -1
  103. package/build-module/file/index.js.map +1 -1
  104. package/build-module/footnotes/edit.js +2 -1
  105. package/build-module/footnotes/edit.js.map +1 -1
  106. package/build-module/footnotes/format.js +17 -19
  107. package/build-module/footnotes/format.js.map +1 -1
  108. package/build-module/heading/edit.js +3 -2
  109. package/build-module/heading/edit.js.map +1 -1
  110. package/build-module/heading/edit.native.js +132 -0
  111. package/build-module/heading/edit.native.js.map +1 -0
  112. package/build-module/heading/index.js +1 -0
  113. package/build-module/heading/index.js.map +1 -1
  114. package/build-module/image/edit.js +9 -5
  115. package/build-module/image/edit.js.map +1 -1
  116. package/build-module/image/image.js +33 -7
  117. package/build-module/image/image.js.map +1 -1
  118. package/build-module/image/index.js +6 -3
  119. package/build-module/image/index.js.map +1 -1
  120. package/build-module/more/index.js +4 -0
  121. package/build-module/more/index.js.map +1 -1
  122. package/build-module/navigation/edit/index.js +1 -1
  123. package/build-module/navigation/edit/index.js.map +1 -1
  124. package/build-module/navigation/index.js +0 -1
  125. package/build-module/navigation/index.js.map +1 -1
  126. package/build-module/paragraph/edit.js +3 -2
  127. package/build-module/paragraph/edit.js.map +1 -1
  128. package/build-module/paragraph/index.js +1 -2
  129. package/build-module/paragraph/index.js.map +1 -1
  130. package/build-module/paragraph/transforms.js +1 -2
  131. package/build-module/paragraph/transforms.js.map +1 -1
  132. package/build-module/post-content/edit.js +1 -1
  133. package/build-module/post-content/edit.js.map +1 -1
  134. package/build-module/post-date/edit.js +1 -1
  135. package/build-module/post-date/edit.js.map +1 -1
  136. package/build-module/post-navigation-link/edit.js +44 -3
  137. package/build-module/post-navigation-link/edit.js.map +1 -1
  138. package/build-module/post-navigation-link/index.js +8 -0
  139. package/build-module/post-navigation-link/index.js.map +1 -1
  140. package/build-module/pullquote/index.js +4 -0
  141. package/build-module/pullquote/index.js.map +1 -1
  142. package/build-module/query/edit/inspector-controls/index.js +4 -4
  143. package/build-module/query/edit/inspector-controls/index.js.map +1 -1
  144. package/build-module/query/edit/query-content.js +2 -2
  145. package/build-module/query/edit/query-content.js.map +1 -1
  146. package/build-module/query/edit/query-placeholder.js +7 -8
  147. package/build-module/query/edit/query-placeholder.js.map +1 -1
  148. package/build-module/query/index.js +1 -2
  149. package/build-module/query/index.js.map +1 -1
  150. package/build-module/query/variations.js +8 -1
  151. package/build-module/query/variations.js.map +1 -1
  152. package/build-module/query/view.js +30 -9
  153. package/build-module/query/view.js.map +1 -1
  154. package/build-module/search/index.js +0 -1
  155. package/build-module/search/index.js.map +1 -1
  156. package/build-module/table-of-contents/hooks.js +2 -2
  157. package/build-module/table-of-contents/hooks.js.map +1 -1
  158. package/build-module/template-part/edit/advanced-controls.js +1 -4
  159. package/build-module/template-part/edit/advanced-controls.js.map +1 -1
  160. package/build-module/template-part/edit/index.js +38 -16
  161. package/build-module/template-part/edit/index.js.map +1 -1
  162. package/build-module/video/edit.native.js +7 -2
  163. package/build-module/video/edit.native.js.map +1 -1
  164. package/build-module/video/transforms.js +17 -0
  165. package/build-module/video/transforms.js.map +1 -1
  166. package/build-style/common-rtl.css +4 -2
  167. package/build-style/common.css +4 -2
  168. package/build-style/cover/style-rtl.css +1 -2
  169. package/build-style/cover/style.css +1 -2
  170. package/build-style/editor-rtl.css +6 -4
  171. package/build-style/editor.css +6 -4
  172. package/build-style/gallery/style-rtl.css +2 -4
  173. package/build-style/gallery/style.css +2 -4
  174. package/build-style/image/editor-rtl.css +6 -0
  175. package/build-style/image/editor.css +6 -0
  176. package/build-style/page-list/editor-rtl.css +0 -4
  177. package/build-style/page-list/editor.css +0 -4
  178. package/build-style/pullquote/style-rtl.css +10 -1
  179. package/build-style/pullquote/style.css +10 -1
  180. package/build-style/search/style-rtl.css +2 -1
  181. package/build-style/search/style.css +2 -1
  182. package/build-style/style-rtl.css +19 -11
  183. package/build-style/style.css +19 -11
  184. package/build-style/video/style-rtl.css +1 -2
  185. package/build-style/video/style.css +1 -2
  186. package/package.json +34 -32
  187. package/src/avatar/edit.js +16 -18
  188. package/src/block/block.json +3 -0
  189. package/src/block/edit.js +102 -20
  190. package/src/block/{v1/edit.native.js → edit.native.js} +4 -4
  191. package/src/block/index.js +2 -3
  192. package/src/block/index.php +3 -31
  193. package/src/button/block.json +1 -0
  194. package/src/button/edit.js +76 -43
  195. package/src/button/save.js +3 -0
  196. package/src/buttons/test/__snapshots__/edit.native.js.snap +6 -0
  197. package/src/buttons/test/edit.native.js +49 -0
  198. package/src/cover/edit.native.js +1 -0
  199. package/src/embed/edit.js +3 -2
  200. package/src/file/block.json +0 -1
  201. package/src/file/index.php +11 -57
  202. package/src/footnotes/edit.js +2 -1
  203. package/src/footnotes/format.js +34 -31
  204. package/src/footnotes/index.php +20 -11
  205. package/src/gallery/index.php +0 -3
  206. package/src/heading/block.json +1 -0
  207. package/src/heading/edit.js +18 -14
  208. package/src/heading/edit.native.js +144 -0
  209. package/src/image/block.json +7 -3
  210. package/src/image/edit.js +19 -6
  211. package/src/image/editor.scss +6 -1
  212. package/src/image/image.js +101 -42
  213. package/src/image/index.js +6 -0
  214. package/src/image/index.php +14 -51
  215. package/src/more/index.js +6 -0
  216. package/src/navigation/block.json +0 -1
  217. package/src/navigation/edit/index.js +2 -2
  218. package/src/navigation/index.php +777 -28
  219. package/src/navigation-link/index.php +78 -16
  220. package/src/page-list/editor.scss +0 -4
  221. package/src/paragraph/block.json +1 -2
  222. package/src/paragraph/edit.js +23 -19
  223. package/src/post-content/edit.js +2 -2
  224. package/src/post-date/edit.js +38 -33
  225. package/src/post-navigation-link/block.json +8 -0
  226. package/src/post-navigation-link/edit.js +63 -1
  227. package/src/post-navigation-link/index.php +17 -3
  228. package/src/post-terms/index.php +13 -4
  229. package/src/pullquote/block.json +4 -0
  230. package/src/pullquote/style.scss +13 -1
  231. package/src/query/block.json +1 -2
  232. package/src/query/edit/inspector-controls/index.js +137 -146
  233. package/src/query/edit/query-content.js +9 -7
  234. package/src/query/edit/query-placeholder.js +11 -11
  235. package/src/query/index.php +33 -71
  236. package/src/query/variations.js +4 -0
  237. package/src/query/view.js +24 -19
  238. package/src/search/block.json +0 -1
  239. package/src/search/index.php +18 -36
  240. package/src/table-of-contents/hooks.js +2 -2
  241. package/src/template-part/edit/advanced-controls.js +2 -3
  242. package/src/template-part/edit/index.js +77 -50
  243. package/src/template-part/index.php +2 -2
  244. package/src/video/edit.native.js +5 -2
  245. package/src/video/test/edit.native.js +38 -0
  246. package/src/video/transforms.js +32 -0
  247. package/tsconfig.json +1 -0
  248. package/build/block/v1/edit.js +0 -116
  249. package/build/block/v1/edit.js.map +0 -1
  250. package/build/block/v1/edit.native.js.map +0 -1
  251. package/build-module/block/v1/edit.js +0 -108
  252. package/build-module/block/v1/edit.js.map +0 -1
  253. package/build-module/block/v1/edit.native.js.map +0 -1
  254. package/src/block/v1/edit.js +0 -163
@@ -12,6 +12,7 @@ import {
12
12
  __experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
13
13
  __experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
14
14
  __experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles,
15
+ __experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
15
16
  __experimentalGetElementClassName,
16
17
  } from '@wordpress/block-editor';
17
18
 
@@ -40,6 +41,7 @@ export default function save( { attributes, className } ) {
40
41
  const borderProps = getBorderClassesAndStyles( attributes );
41
42
  const colorProps = getColorClassesAndStyles( attributes );
42
43
  const spacingProps = getSpacingClassesAndStyles( attributes );
44
+ const shadowProps = getShadowClassesAndStyles( attributes );
43
45
  const buttonClasses = classnames(
44
46
  'wp-block-button__link',
45
47
  colorProps.className,
@@ -56,6 +58,7 @@ export default function save( { attributes, className } ) {
56
58
  ...borderProps.style,
57
59
  ...colorProps.style,
58
60
  ...spacingProps.style,
61
+ ...shadowProps.style,
59
62
  };
60
63
 
61
64
  // The use of a `title` attribute here is soft-deprecated, but still applied
@@ -6,6 +6,12 @@ exports[`Buttons block color customization sets a background color 1`] = `
6
6
  <!-- /wp:buttons -->"
7
7
  `;
8
8
 
9
+ exports[`Buttons block color customization sets a custom gradient background color 1`] = `
10
+ "<!-- wp:buttons -->
11
+ <div class="wp-block-buttons"><!-- wp:button {"style":{"color":{"gradient":"linear-gradient(200deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)"}}} /--></div>
12
+ <!-- /wp:buttons -->"
13
+ `;
14
+
9
15
  exports[`Buttons block color customization sets a gradient background color 1`] = `
10
16
  "<!-- wp:buttons -->
11
17
  <div class="wp-block-buttons"><!-- wp:button {"gradient":"light-green-cyan-to-vivid-green-cyan"} /--></div>
@@ -10,6 +10,7 @@ import {
10
10
  initializeEditor,
11
11
  triggerBlockListLayout,
12
12
  typeInRichText,
13
+ openBlockSettings,
13
14
  waitFor,
14
15
  } from 'test/helpers';
15
16
 
@@ -391,5 +392,53 @@ describe( 'Buttons block', () => {
391
392
  // Assert
392
393
  expect( getEditorHtml() ).toMatchSnapshot();
393
394
  } );
395
+
396
+ it( 'sets a custom gradient background color', async () => {
397
+ // Arrange
398
+ const screen = await initializeEditor();
399
+ await addBlock( screen, 'Buttons' );
400
+
401
+ // Act
402
+ const buttonsBlock = getBlock( screen, 'Buttons' );
403
+ fireEvent.press( buttonsBlock );
404
+
405
+ // Trigger onLayout for the list
406
+ await triggerBlockListLayout( buttonsBlock );
407
+
408
+ const buttonBlock = await getBlock( screen, 'Button' );
409
+ fireEvent.press( buttonBlock );
410
+
411
+ // Open Block Settings.
412
+ await openBlockSettings( screen );
413
+
414
+ // Open Text color settings
415
+ fireEvent.press( screen.getByLabelText( 'Background, Default' ) );
416
+
417
+ // Tap on the gradient segment
418
+ fireEvent.press( screen.getByLabelText( 'Gradient' ) );
419
+
420
+ // Tap one gradient color
421
+ fireEvent.press(
422
+ screen.getByLabelText( 'Light green cyan to vivid green cyan' )
423
+ );
424
+
425
+ // Tap on Customize Gradient
426
+ fireEvent.press( screen.getByLabelText( /Customize Gradient/ ) );
427
+
428
+ // Change the current angle
429
+ fireEvent.press( screen.getByText( '135', { hidden: true } ) );
430
+ const angleTextInput = screen.getByDisplayValue( '135', {
431
+ hidden: true,
432
+ } );
433
+ fireEvent.changeText( angleTextInput, '200' );
434
+
435
+ // Go back to the settings list.
436
+ fireEvent.press( await screen.findByLabelText( 'Go back' ) );
437
+
438
+ // Assert
439
+ const customButton = await screen.findByText( 'CUSTOM' );
440
+ expect( customButton ).toBeVisible();
441
+ expect( getEditorHtml() ).toMatchSnapshot();
442
+ } );
394
443
  } );
395
444
  } );
@@ -538,6 +538,7 @@ const Cover = ( {
538
538
  <BottomSheetConsumer>
539
539
  { ( { shouldEnableBottomSheetScroll } ) => (
540
540
  <ColorPalette
541
+ enableCustomColor={ true }
541
542
  customColorIndicatorStyles={
542
543
  styles.paletteColorIndicator
543
544
  }
package/src/embed/edit.js CHANGED
@@ -127,16 +127,17 @@ const EmbedEdit = ( props ) => {
127
127
  };
128
128
 
129
129
  useEffect( () => {
130
- if ( ! preview?.html || ! cannotEmbed || fetching ) {
130
+ if ( preview?.html || ! cannotEmbed || fetching ) {
131
131
  return;
132
132
  }
133
+
133
134
  // At this stage, we're not fetching the preview and know it can't be embedded,
134
135
  // so try removing any trailing slash, and resubmit.
135
136
  const newURL = attributesUrl.replace( /\/$/, '' );
136
137
  setURL( newURL );
137
138
  setIsEditingURL( false );
138
139
  setAttributes( { url: newURL } );
139
- }, [ preview?.html, attributesUrl, cannotEmbed, fetching ] );
140
+ }, [ preview?.html, attributesUrl, cannotEmbed, fetching, setAttributes ] );
140
141
 
141
142
  // Try a different provider in case the embed url is not supported.
142
143
  useEffect( () => {
@@ -72,7 +72,6 @@
72
72
  },
73
73
  "interactivity": true
74
74
  },
75
- "viewScript": "file:./view.min.js",
76
75
  "editorStyle": "wp-block-file-editor",
77
76
  "style": "wp-block-file"
78
77
  }
@@ -14,35 +14,8 @@
14
14
  *
15
15
  * @return string Returns the block content.
16
16
  */
17
- function render_block_core_file( $attributes, $content, $block ) {
18
- $is_gutenberg_plugin = defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN;
19
- $should_load_view_script = ! empty( $attributes['displayPreview'] );
20
- $view_js_file = 'wp-block-file-view';
21
- $script_handles = $block->block_type->view_script_handles;
22
-
23
- if ( $is_gutenberg_plugin ) {
24
- if ( $should_load_view_script ) {
25
- gutenberg_enqueue_module( '@wordpress/block-library/file-block' );
26
- }
27
- // Remove the view script because we are using the module.
28
- $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) );
29
- } else {
30
- // If the script already exists, there is no point in removing it from viewScript.
31
- if ( ! wp_script_is( $view_js_file ) ) {
32
-
33
- // If the script is not needed, and it is still in the `view_script_handles`, remove it.
34
- if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles, true ) ) {
35
- $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) );
36
- }
37
- // If the script is needed, but it was previously removed, add it again.
38
- if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles, true ) ) {
39
- $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) );
40
- }
41
- }
42
- }
43
-
17
+ function render_block_core_file( $attributes, $content ) {
44
18
  // Update object's aria-label attribute if present in block HTML.
45
-
46
19
  // Match an aria-label attribute from an object tag.
47
20
  $pattern = '@<object.+(?<attribute>aria-label="(?<filename>[^"]+)?")@i';
48
21
  $content = preg_replace_callback(
@@ -63,8 +36,10 @@ function render_block_core_file( $attributes, $content, $block ) {
63
36
  $content
64
37
  );
65
38
 
66
- // If it uses the Interactivity API, add the directives.
67
- if ( $should_load_view_script ) {
39
+ // If it's interactive, enqueue the script module and add the directives.
40
+ if ( ! empty( $attributes['displayPreview'] ) ) {
41
+ wp_enqueue_script_module( '@wordpress/block-library/file-block' );
42
+
68
43
  $processor = new WP_HTML_Tag_Processor( $content );
69
44
  $processor->next_tag();
70
45
  $processor->set_attribute( 'data-wp-interactive', '{"namespace":"core/file"}' );
@@ -77,25 +52,6 @@ function render_block_core_file( $attributes, $content, $block ) {
77
52
  return $content;
78
53
  }
79
54
 
80
- /**
81
- * Ensure that the view script has the `wp-interactivity` dependency.
82
- *
83
- * @since 6.4.0
84
- *
85
- * @global WP_Scripts $wp_scripts
86
- */
87
- function block_core_file_ensure_interactivity_dependency() {
88
- global $wp_scripts;
89
- if (
90
- isset( $wp_scripts->registered['wp-block-file-view'] ) &&
91
- ! in_array( 'wp-interactivity', $wp_scripts->registered['wp-block-file-view']->deps, true )
92
- ) {
93
- $wp_scripts->registered['wp-block-file-view']->deps[] = 'wp-interactivity';
94
- }
95
- }
96
-
97
- add_action( 'wp_print_scripts', 'block_core_file_ensure_interactivity_dependency' );
98
-
99
55
  /**
100
56
  * Registers the `core/file` block on server.
101
57
  */
@@ -107,13 +63,11 @@ function register_block_core_file() {
107
63
  )
108
64
  );
109
65
 
110
- if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
111
- gutenberg_register_module(
112
- '@wordpress/block-library/file-block',
113
- gutenberg_url( '/build/interactivity/file.min.js' ),
114
- array( '@wordpress/interactivity' ),
115
- defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
116
- );
117
- }
66
+ wp_register_script_module(
67
+ '@wordpress/block-library/file-block',
68
+ gutenberg_url( '/build/interactivity/file.min.js' ),
69
+ array( '@wordpress/interactivity' ),
70
+ defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
71
+ );
118
72
  }
119
73
  add_action( 'init', 'register_block_core_file' );
@@ -14,10 +14,11 @@ export default function FootnotesEdit( { context: { postType, postId } } ) {
14
14
  'meta',
15
15
  postId
16
16
  );
17
+ const footnotesSupported = 'string' === typeof meta?.footnotes;
17
18
  const footnotes = meta?.footnotes ? JSON.parse( meta.footnotes ) : [];
18
19
  const blockProps = useBlockProps();
19
20
 
20
- if ( postType !== 'post' && postType !== 'page' ) {
21
+ if ( ! footnotesSupported ) {
21
22
  return (
22
23
  <div { ...blockProps }>
23
24
  <Placeholder
@@ -15,6 +15,7 @@ import {
15
15
  privateApis,
16
16
  } from '@wordpress/block-editor';
17
17
  import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
18
+ import { store as coreDataStore } from '@wordpress/core-data';
18
19
  import { createBlock, store as blocksStore } from '@wordpress/blocks';
19
20
 
20
21
  /**
@@ -38,12 +39,12 @@ export const format = {
38
39
  },
39
40
  interactive: true,
40
41
  contentEditable: false,
41
- [ usesContextKey ]: [ 'postType' ],
42
+ [ usesContextKey ]: [ 'postType', 'postId' ],
42
43
  edit: function Edit( {
43
44
  value,
44
45
  onChange,
45
46
  isObjectActive,
46
- context: { postType },
47
+ context: { postType, postId },
47
48
  } ) {
48
49
  const registry = useRegistry();
49
50
  const {
@@ -53,40 +54,42 @@ export const format = {
53
54
  getBlockName,
54
55
  getBlockParentsByBlockName,
55
56
  } = registry.select( blockEditorStore );
56
- const hasFootnotesBlockType = useSelect(
57
- ( select ) =>
58
- !! select( blocksStore ).getBlockType( 'core/footnotes' ),
59
- []
57
+ const isFootnotesSupported = useSelect(
58
+ ( select ) => {
59
+ if (
60
+ ! select( blocksStore ).getBlockType( 'core/footnotes' )
61
+ ) {
62
+ return false;
63
+ }
64
+
65
+ const entityRecord = select( coreDataStore ).getEntityRecord(
66
+ 'postType',
67
+ postType,
68
+ postId
69
+ );
70
+
71
+ if ( 'string' !== typeof entityRecord?.meta?.footnotes ) {
72
+ return false;
73
+ }
74
+
75
+ // Checks if the selected block lives within a pattern.
76
+ const {
77
+ getBlockParentsByBlockName: _getBlockParentsByBlockName,
78
+ getSelectedBlockClientId: _getSelectedBlockClientId,
79
+ } = select( blockEditorStore );
80
+ const parentCoreBlocks = _getBlockParentsByBlockName(
81
+ _getSelectedBlockClientId(),
82
+ SYNCED_PATTERN_BLOCK_NAME
83
+ );
84
+ return ! parentCoreBlocks || parentCoreBlocks.length === 0;
85
+ },
86
+ [ postType, postId ]
60
87
  );
61
- /*
62
- * This useSelect exists because we need to use its return value
63
- * outside the event callback.
64
- */
65
- const isBlockWithinPattern = useSelect( ( select ) => {
66
- const {
67
- getBlockParentsByBlockName: _getBlockParentsByBlockName,
68
- getSelectedBlockClientId: _getSelectedBlockClientId,
69
- } = select( blockEditorStore );
70
- const parentCoreBlocks = _getBlockParentsByBlockName(
71
- _getSelectedBlockClientId(),
72
- SYNCED_PATTERN_BLOCK_NAME
73
- );
74
- return parentCoreBlocks && parentCoreBlocks.length > 0;
75
- }, [] );
76
88
 
77
89
  const { selectionChange, insertBlock } =
78
90
  useDispatch( blockEditorStore );
79
91
 
80
- if ( ! hasFootnotesBlockType ) {
81
- return null;
82
- }
83
-
84
- if ( postType !== 'post' && postType !== 'page' ) {
85
- return null;
86
- }
87
-
88
- // Checks if the selected block lives within a pattern.
89
- if ( isBlockWithinPattern ) {
92
+ if ( ! isFootnotesSupported ) {
90
93
  return null;
91
94
  }
92
95
 
@@ -68,17 +68,26 @@ function render_block_core_footnotes( $attributes, $content, $block ) {
68
68
  * @since 6.3.0
69
69
  */
70
70
  function register_block_core_footnotes() {
71
- foreach ( array( 'post', 'page' ) as $post_type ) {
72
- register_post_meta(
73
- $post_type,
74
- 'footnotes',
75
- array(
76
- 'show_in_rest' => true,
77
- 'single' => true,
78
- 'type' => 'string',
79
- 'revisions_enabled' => true,
80
- )
81
- );
71
+ $post_types = get_post_types(
72
+ array(
73
+ 'show_in_rest' => true,
74
+ 'public' => true,
75
+ )
76
+ );
77
+ foreach ( $post_types as $post_type ) {
78
+ // Only register the meta field if the post type supports the editor, custom fields, and revisions.
79
+ if ( post_type_supports( $post_type, 'editor' ) && post_type_supports( $post_type, 'custom-fields' ) && post_type_supports( $post_type, 'revisions' ) ) {
80
+ register_post_meta(
81
+ $post_type,
82
+ 'footnotes',
83
+ array(
84
+ 'show_in_rest' => true,
85
+ 'single' => true,
86
+ 'type' => 'string',
87
+ 'revisions_enabled' => true,
88
+ )
89
+ );
90
+ }
82
91
  }
83
92
  register_block_type_from_metadata(
84
93
  __DIR__ . '/footnotes',
@@ -42,9 +42,6 @@ function block_core_gallery_random_order( $parsed_block ) {
42
42
  if ( 'core/gallery' === $parsed_block['blockName'] && ! empty( $parsed_block['attrs']['randomOrder'] ) ) {
43
43
  shuffle( $parsed_block['innerBlocks'] );
44
44
  }
45
-
46
- return $parsed_block;
47
-
48
45
  return $parsed_block;
49
46
  }
50
47
 
@@ -7,6 +7,7 @@
7
7
  "description": "Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.",
8
8
  "keywords": [ "title", "subtitle" ],
9
9
  "textdomain": "default",
10
+ "usesContext": [ "pattern/overrides" ],
10
11
  "attributes": {
11
12
  "textAlign": {
12
13
  "type": "string"
@@ -17,6 +17,7 @@ import {
17
17
  useBlockProps,
18
18
  store as blockEditorStore,
19
19
  HeadingLevelDropdown,
20
+ useBlockEditingMode,
20
21
  } from '@wordpress/block-editor';
21
22
 
22
23
  /**
@@ -40,6 +41,7 @@ function HeadingEdit( {
40
41
  } ),
41
42
  style,
42
43
  } );
44
+ const blockEditingMode = useBlockEditingMode();
43
45
 
44
46
  const { canGenerateAnchors } = useSelect( ( select ) => {
45
47
  const { getGlobalBlockCount, getSettings } = select( blockEditorStore );
@@ -90,20 +92,22 @@ function HeadingEdit( {
90
92
 
91
93
  return (
92
94
  <>
93
- <BlockControls group="block">
94
- <HeadingLevelDropdown
95
- value={ level }
96
- onChange={ ( newLevel ) =>
97
- setAttributes( { level: newLevel } )
98
- }
99
- />
100
- <AlignmentControl
101
- value={ textAlign }
102
- onChange={ ( nextAlign ) => {
103
- setAttributes( { textAlign: nextAlign } );
104
- } }
105
- />
106
- </BlockControls>
95
+ { blockEditingMode === 'default' && (
96
+ <BlockControls group="block">
97
+ <HeadingLevelDropdown
98
+ value={ level }
99
+ onChange={ ( newLevel ) =>
100
+ setAttributes( { level: newLevel } )
101
+ }
102
+ />
103
+ <AlignmentControl
104
+ value={ textAlign }
105
+ onChange={ ( nextAlign ) => {
106
+ setAttributes( { textAlign: nextAlign } );
107
+ } }
108
+ />
109
+ </BlockControls>
110
+ ) }
107
111
  <RichText
108
112
  identifier="content"
109
113
  tagName={ tagName }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __ } from '@wordpress/i18n';
10
+ import { useEffect, Platform } from '@wordpress/element';
11
+ import { useDispatch, useSelect } from '@wordpress/data';
12
+ import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
13
+ import {
14
+ AlignmentControl,
15
+ BlockControls,
16
+ RichText,
17
+ useBlockProps,
18
+ store as blockEditorStore,
19
+ HeadingLevelDropdown,
20
+ } from '@wordpress/block-editor';
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ import { generateAnchor, setAnchor } from './autogenerate-anchors';
26
+
27
+ function HeadingEdit( {
28
+ attributes,
29
+ setAttributes,
30
+ mergeBlocks,
31
+ onReplace,
32
+ style,
33
+ clientId,
34
+ } ) {
35
+ const { textAlign, content, level, placeholder, anchor } = attributes;
36
+ const tagName = 'h' + level;
37
+ const blockProps = useBlockProps( {
38
+ className: classnames( {
39
+ [ `has-text-align-${ textAlign }` ]: textAlign,
40
+ } ),
41
+ style,
42
+ } );
43
+
44
+ const { canGenerateAnchors } = useSelect( ( select ) => {
45
+ const { getGlobalBlockCount, getSettings } = select( blockEditorStore );
46
+ const settings = getSettings();
47
+
48
+ return {
49
+ canGenerateAnchors:
50
+ !! settings.generateAnchors ||
51
+ getGlobalBlockCount( 'core/table-of-contents' ) > 0,
52
+ };
53
+ }, [] );
54
+
55
+ const { __unstableMarkNextChangeAsNotPersistent } =
56
+ useDispatch( blockEditorStore );
57
+
58
+ // Initially set anchor for headings that have content but no anchor set.
59
+ // This is used when transforming a block to heading, or for legacy anchors.
60
+ useEffect( () => {
61
+ if ( ! canGenerateAnchors ) {
62
+ return;
63
+ }
64
+
65
+ if ( ! anchor && content ) {
66
+ // This side-effect should not create an undo level.
67
+ __unstableMarkNextChangeAsNotPersistent();
68
+ setAttributes( {
69
+ anchor: generateAnchor( clientId, content ),
70
+ } );
71
+ }
72
+ setAnchor( clientId, anchor );
73
+
74
+ // Remove anchor map when block unmounts.
75
+ return () => setAnchor( clientId, null );
76
+ }, [ anchor, content, clientId, canGenerateAnchors ] );
77
+
78
+ const onContentChange = ( value ) => {
79
+ const newAttrs = { content: value };
80
+ if (
81
+ canGenerateAnchors &&
82
+ ( ! anchor ||
83
+ ! value ||
84
+ generateAnchor( clientId, content ) === anchor )
85
+ ) {
86
+ newAttrs.anchor = generateAnchor( clientId, value );
87
+ }
88
+ setAttributes( newAttrs );
89
+ };
90
+
91
+ return (
92
+ <>
93
+ <BlockControls group="block">
94
+ <HeadingLevelDropdown
95
+ value={ level }
96
+ onChange={ ( newLevel ) =>
97
+ setAttributes( { level: newLevel } )
98
+ }
99
+ />
100
+ <AlignmentControl
101
+ value={ textAlign }
102
+ onChange={ ( nextAlign ) => {
103
+ setAttributes( { textAlign: nextAlign } );
104
+ } }
105
+ />
106
+ </BlockControls>
107
+ <RichText
108
+ identifier="content"
109
+ tagName={ tagName }
110
+ value={ content }
111
+ onChange={ onContentChange }
112
+ onMerge={ mergeBlocks }
113
+ onSplit={ ( value, isOriginal ) => {
114
+ let block;
115
+
116
+ if ( isOriginal || value ) {
117
+ block = createBlock( 'core/heading', {
118
+ ...attributes,
119
+ content: value,
120
+ } );
121
+ } else {
122
+ block = createBlock(
123
+ getDefaultBlockName() ?? 'core/heading'
124
+ );
125
+ }
126
+
127
+ if ( isOriginal ) {
128
+ block.clientId = clientId;
129
+ }
130
+
131
+ return block;
132
+ } }
133
+ onReplace={ onReplace }
134
+ onRemove={ () => onReplace( [] ) }
135
+ placeholder={ placeholder || __( 'Heading' ) }
136
+ textAlign={ textAlign }
137
+ { ...( Platform.isNative && { deleteEnter: true } ) } // setup RichText on native mobile to delete the "Enter" key as it's handled by the JS/RN side
138
+ { ...blockProps }
139
+ />
140
+ </>
141
+ );
142
+ }
143
+
144
+ export default HeadingEdit;
@@ -4,7 +4,12 @@
4
4
  "name": "core/image",
5
5
  "title": "Image",
6
6
  "category": "media",
7
- "usesContext": [ "allowResize", "imageCrop", "fixedHeight" ],
7
+ "usesContext": [
8
+ "allowResize",
9
+ "imageCrop",
10
+ "fixedHeight",
11
+ "pattern/overrides"
12
+ ],
8
13
  "description": "Insert an image to make a visual statement.",
9
14
  "keywords": [ "img", "photo", "picture" ],
10
15
  "textdomain": "default",
@@ -129,6 +134,5 @@
129
134
  { "name": "rounded", "label": "Rounded" }
130
135
  ],
131
136
  "editorStyle": "wp-block-image-editor",
132
- "style": "wp-block-image",
133
- "viewScript": "file:./view.min.js"
137
+ "style": "wp-block-image"
134
138
  }
package/src/image/edit.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  } from '@wordpress/block-editor';
20
20
  import { useEffect, useRef, useState } from '@wordpress/element';
21
21
  import { __ } from '@wordpress/i18n';
22
- import { image as icon } from '@wordpress/icons';
22
+ import { image as icon, plugins as pluginsIcon } from '@wordpress/icons';
23
23
  import { store as noticesStore } from '@wordpress/notices';
24
24
 
25
25
  /**
@@ -111,6 +111,7 @@ export function ImageEdit( {
111
111
  aspectRatio,
112
112
  scale,
113
113
  align,
114
+ metadata,
114
115
  } = attributes;
115
116
  const [ temporaryURL, setTemporaryURL ] = useState();
116
117
 
@@ -332,6 +333,7 @@ export function ImageEdit( {
332
333
  } );
333
334
 
334
335
  // Much of this description is duplicated from MediaPlaceholder.
336
+ const isUrlAttributeConnected = !! metadata?.bindings?.url;
335
337
  const placeholder = ( content ) => {
336
338
  return (
337
339
  <Placeholder
@@ -340,11 +342,14 @@ export function ImageEdit( {
340
342
  !! borderProps.className && ! isSelected,
341
343
  } ) }
342
344
  withIllustration={ true }
343
- icon={ icon }
345
+ icon={ isUrlAttributeConnected ? pluginsIcon : icon }
344
346
  label={ __( 'Image' ) }
345
- instructions={ __(
346
- 'Upload an image file, pick one from your media library, or add one with a URL.'
347
- ) }
347
+ instructions={
348
+ ! isUrlAttributeConnected &&
349
+ __(
350
+ 'Upload an image file, pick one from your media library, or add one with a URL.'
351
+ )
352
+ }
348
353
  style={ {
349
354
  aspectRatio:
350
355
  ! ( width && height ) && aspectRatio
@@ -356,7 +361,15 @@ export function ImageEdit( {
356
361
  ...borderProps.style,
357
362
  } }
358
363
  >
359
- { content }
364
+ { isUrlAttributeConnected ? (
365
+ <span
366
+ className={ 'block-bindings-media-placeholder-message' }
367
+ >
368
+ { __( 'Connected to a custom field' ) }
369
+ </span>
370
+ ) : (
371
+ content
372
+ ) }
360
373
  </Placeholder>
361
374
  );
362
375
  };