@wordpress/block-library 7.8.0 → 7.9.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 (292) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/audio/edit.js +1 -0
  3. package/build/audio/edit.js.map +1 -1
  4. package/build/audio/save.js +2 -1
  5. package/build/audio/save.js.map +1 -1
  6. package/build/avatar/hooks.js +2 -2
  7. package/build/avatar/hooks.js.map +1 -1
  8. package/build/button/edit.js +1 -1
  9. package/build/button/edit.js.map +1 -1
  10. package/build/button/index.js +1 -24
  11. package/build/button/index.js.map +1 -1
  12. package/build/button/save.js +1 -1
  13. package/build/button/save.js.map +1 -1
  14. package/build/columns/variations.js +2 -2
  15. package/build/columns/variations.js.map +1 -1
  16. package/build/comment-author-name/edit.js +3 -5
  17. package/build/comment-author-name/edit.js.map +1 -1
  18. package/build/comment-author-name/index.js +0 -4
  19. package/build/comment-author-name/index.js.map +1 -1
  20. package/build/comment-date/edit.js +4 -4
  21. package/build/comment-date/edit.js.map +1 -1
  22. package/build/comment-date/index.js +0 -4
  23. package/build/comment-date/index.js.map +1 -1
  24. package/build/comment-edit-link/index.js +0 -4
  25. package/build/comment-edit-link/index.js.map +1 -1
  26. package/build/comment-reply-link/index.js +0 -4
  27. package/build/comment-reply-link/index.js.map +1 -1
  28. package/build/comments/edit.js +10 -2
  29. package/build/comments/edit.js.map +1 -1
  30. package/build/comments-title/deprecated.js +0 -3
  31. package/build/comments-title/deprecated.js.map +1 -1
  32. package/build/cover/index.js +1 -0
  33. package/build/cover/index.js.map +1 -1
  34. package/build/embed/embed-preview.js +1 -0
  35. package/build/embed/embed-preview.js.map +1 -1
  36. package/build/embed/icons.js +21 -1
  37. package/build/embed/icons.js.map +1 -1
  38. package/build/embed/save.js +1 -0
  39. package/build/embed/save.js.map +1 -1
  40. package/build/embed/variations.js +11 -0
  41. package/build/embed/variations.js.map +1 -1
  42. package/build/file/edit.js +1 -1
  43. package/build/file/edit.js.map +1 -1
  44. package/build/file/save.js +1 -1
  45. package/build/file/save.js.map +1 -1
  46. package/build/gallery/gallery.js +1 -1
  47. package/build/gallery/gallery.js.map +1 -1
  48. package/build/gallery/save.js +1 -1
  49. package/build/gallery/save.js.map +1 -1
  50. package/build/gallery/transforms.js +2 -2
  51. package/build/gallery/transforms.js.map +1 -1
  52. package/build/gallery/v1/edit.js +3 -3
  53. package/build/gallery/v1/edit.js.map +1 -1
  54. package/build/gallery/v1/gallery-image.js +1 -0
  55. package/build/gallery/v1/gallery-image.js.map +1 -1
  56. package/build/gallery/v1/gallery.js +1 -1
  57. package/build/gallery/v1/gallery.js.map +1 -1
  58. package/build/gallery/v1/save.js +10 -2
  59. package/build/gallery/v1/save.js.map +1 -1
  60. package/build/group/index.js +1 -0
  61. package/build/group/index.js.map +1 -1
  62. package/build/html/edit.js +11 -20
  63. package/build/html/edit.js.map +1 -1
  64. package/build/html/preview.js +48 -0
  65. package/build/html/preview.js.map +1 -0
  66. package/build/image/edit.native.js +2 -1
  67. package/build/image/edit.native.js.map +1 -1
  68. package/build/image/image.js +1 -0
  69. package/build/image/image.js.map +1 -1
  70. package/build/image/save.js +1 -0
  71. package/build/image/save.js.map +1 -1
  72. package/build/list/v2/transforms.js +33 -17
  73. package/build/list/v2/transforms.js.map +1 -1
  74. package/build/list-item/hooks/use-enter.js +7 -4
  75. package/build/list-item/hooks/use-enter.js.map +1 -1
  76. package/build/list-item/hooks/use-outdent-list-item.js +36 -15
  77. package/build/list-item/hooks/use-outdent-list-item.js.map +1 -1
  78. package/build/navigation/edit/index.js +1 -1
  79. package/build/navigation/edit/index.js.map +1 -1
  80. package/build/navigation/index.js +9 -0
  81. package/build/navigation/index.js.map +1 -1
  82. package/build/navigation/use-navigation-menu.js +16 -74
  83. package/build/navigation/use-navigation-menu.js.map +1 -1
  84. package/build/navigation/view.js +5 -3
  85. package/build/navigation/view.js.map +1 -1
  86. package/build/navigation-submenu/view.js +5 -3
  87. package/build/navigation-submenu/view.js.map +1 -1
  88. package/build/post-comments-form/edit.js +12 -2
  89. package/build/post-comments-form/edit.js.map +1 -1
  90. package/build/post-comments-form/form.js +1 -1
  91. package/build/post-comments-form/form.js.map +1 -1
  92. package/build/search/edit.js +1 -1
  93. package/build/search/edit.js.map +1 -1
  94. package/build/table/edit.js +1 -0
  95. package/build/table/edit.js.map +1 -1
  96. package/build/table/save.js +2 -1
  97. package/build/table/save.js.map +1 -1
  98. package/build/video/edit.js +1 -0
  99. package/build/video/edit.js.map +1 -1
  100. package/build/video/save.js +1 -0
  101. package/build/video/save.js.map +1 -1
  102. package/build-module/audio/edit.js +2 -1
  103. package/build-module/audio/edit.js.map +1 -1
  104. package/build-module/audio/save.js +3 -2
  105. package/build-module/audio/save.js.map +1 -1
  106. package/build-module/avatar/hooks.js +2 -2
  107. package/build-module/avatar/hooks.js.map +1 -1
  108. package/build-module/button/edit.js +2 -2
  109. package/build-module/button/edit.js.map +1 -1
  110. package/build-module/button/index.js +1 -24
  111. package/build-module/button/index.js.map +1 -1
  112. package/build-module/button/save.js +2 -2
  113. package/build-module/button/save.js.map +1 -1
  114. package/build-module/columns/variations.js +2 -2
  115. package/build-module/columns/variations.js.map +1 -1
  116. package/build-module/comment-author-name/edit.js +3 -5
  117. package/build-module/comment-author-name/edit.js.map +1 -1
  118. package/build-module/comment-author-name/index.js +0 -4
  119. package/build-module/comment-author-name/index.js.map +1 -1
  120. package/build-module/comment-date/edit.js +4 -4
  121. package/build-module/comment-date/edit.js.map +1 -1
  122. package/build-module/comment-date/index.js +0 -4
  123. package/build-module/comment-date/index.js.map +1 -1
  124. package/build-module/comment-edit-link/index.js +0 -4
  125. package/build-module/comment-edit-link/index.js.map +1 -1
  126. package/build-module/comment-reply-link/index.js +0 -4
  127. package/build-module/comment-reply-link/index.js.map +1 -1
  128. package/build-module/comments/edit.js +10 -2
  129. package/build-module/comments/edit.js.map +1 -1
  130. package/build-module/comments-title/deprecated.js +0 -3
  131. package/build-module/comments-title/deprecated.js.map +1 -1
  132. package/build-module/cover/index.js +1 -0
  133. package/build-module/cover/index.js.map +1 -1
  134. package/build-module/embed/embed-preview.js +2 -1
  135. package/build-module/embed/embed-preview.js.map +1 -1
  136. package/build-module/embed/icons.js +19 -0
  137. package/build-module/embed/icons.js.map +1 -1
  138. package/build-module/embed/save.js +2 -1
  139. package/build-module/embed/save.js.map +1 -1
  140. package/build-module/embed/variations.js +12 -1
  141. package/build-module/embed/variations.js.map +1 -1
  142. package/build-module/file/edit.js +2 -2
  143. package/build-module/file/edit.js.map +1 -1
  144. package/build-module/file/save.js +2 -2
  145. package/build-module/file/save.js.map +1 -1
  146. package/build-module/gallery/gallery.js +2 -2
  147. package/build-module/gallery/gallery.js.map +1 -1
  148. package/build-module/gallery/save.js +2 -2
  149. package/build-module/gallery/save.js.map +1 -1
  150. package/build-module/gallery/transforms.js +3 -3
  151. package/build-module/gallery/transforms.js.map +1 -1
  152. package/build-module/gallery/v1/edit.js +4 -4
  153. package/build-module/gallery/v1/edit.js.map +1 -1
  154. package/build-module/gallery/v1/gallery-image.js +2 -1
  155. package/build-module/gallery/v1/gallery-image.js.map +1 -1
  156. package/build-module/gallery/v1/gallery.js +2 -2
  157. package/build-module/gallery/v1/gallery.js.map +1 -1
  158. package/build-module/gallery/v1/save.js +8 -3
  159. package/build-module/gallery/v1/save.js.map +1 -1
  160. package/build-module/group/index.js +1 -0
  161. package/build-module/group/index.js.map +1 -1
  162. package/build-module/html/edit.js +12 -23
  163. package/build-module/html/edit.js.map +1 -1
  164. package/build-module/html/preview.js +38 -0
  165. package/build-module/html/preview.js.map +1 -0
  166. package/build-module/image/edit.native.js +2 -1
  167. package/build-module/image/edit.native.js.map +1 -1
  168. package/build-module/image/image.js +2 -1
  169. package/build-module/image/image.js.map +1 -1
  170. package/build-module/image/save.js +2 -1
  171. package/build-module/image/save.js.map +1 -1
  172. package/build-module/list/v2/transforms.js +32 -17
  173. package/build-module/list/v2/transforms.js.map +1 -1
  174. package/build-module/list-item/hooks/use-enter.js +7 -4
  175. package/build-module/list-item/hooks/use-enter.js.map +1 -1
  176. package/build-module/list-item/hooks/use-outdent-list-item.js +34 -15
  177. package/build-module/list-item/hooks/use-outdent-list-item.js.map +1 -1
  178. package/build-module/navigation/edit/index.js +1 -1
  179. package/build-module/navigation/edit/index.js.map +1 -1
  180. package/build-module/navigation/index.js +9 -0
  181. package/build-module/navigation/index.js.map +1 -1
  182. package/build-module/navigation/use-navigation-menu.js +17 -75
  183. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  184. package/build-module/navigation/view.js +5 -3
  185. package/build-module/navigation/view.js.map +1 -1
  186. package/build-module/navigation-submenu/view.js +5 -3
  187. package/build-module/navigation-submenu/view.js.map +1 -1
  188. package/build-module/post-comments-form/edit.js +12 -3
  189. package/build-module/post-comments-form/edit.js.map +1 -1
  190. package/build-module/post-comments-form/form.js +2 -2
  191. package/build-module/post-comments-form/form.js.map +1 -1
  192. package/build-module/search/edit.js +2 -2
  193. package/build-module/search/edit.js.map +1 -1
  194. package/build-module/table/edit.js +2 -1
  195. package/build-module/table/edit.js.map +1 -1
  196. package/build-module/table/save.js +3 -2
  197. package/build-module/table/save.js.map +1 -1
  198. package/build-module/video/edit.js +2 -1
  199. package/build-module/video/edit.js.map +1 -1
  200. package/build-module/video/save.js +2 -1
  201. package/build-module/video/save.js.map +1 -1
  202. package/build-style/button/style-rtl.css +5 -0
  203. package/build-style/button/style.css +5 -0
  204. package/build-style/editor-rtl.css +3 -0
  205. package/build-style/editor.css +3 -0
  206. package/build-style/file/style-rtl.css +5 -8
  207. package/build-style/file/style.css +5 -8
  208. package/build-style/navigation/style-rtl.css +9 -1
  209. package/build-style/navigation/style.css +9 -1
  210. package/build-style/post-comments/style-rtl.css +2 -1
  211. package/build-style/post-comments/style.css +2 -1
  212. package/build-style/post-comments-form/editor-rtl.css +3 -0
  213. package/build-style/post-comments-form/editor.css +3 -0
  214. package/build-style/post-template/style-rtl.css +9 -18
  215. package/build-style/post-template/style.css +9 -18
  216. package/build-style/search/style-rtl.css +6 -8
  217. package/build-style/search/style.css +6 -8
  218. package/build-style/style-rtl.css +36 -36
  219. package/build-style/style.css +36 -36
  220. package/package.json +28 -28
  221. package/src/audio/edit.js +4 -0
  222. package/src/audio/save.js +12 -2
  223. package/src/avatar/hooks.js +6 -9
  224. package/src/button/block.json +1 -24
  225. package/src/button/edit.js +2 -2
  226. package/src/button/save.js +2 -2
  227. package/src/button/style.scss +10 -0
  228. package/src/columns/variations.js +2 -2
  229. package/src/comment-author-name/block.json +0 -4
  230. package/src/comment-author-name/edit.js +3 -12
  231. package/src/comment-date/block.json +0 -4
  232. package/src/comment-date/edit.js +10 -14
  233. package/src/comment-date/index.php +0 -3
  234. package/src/comment-edit-link/block.json +0 -4
  235. package/src/comment-reply-link/block.json +0 -4
  236. package/src/comments/edit.js +24 -4
  237. package/src/comments-title/deprecated.js +0 -2
  238. package/src/cover/block.json +1 -0
  239. package/src/cover/index.php +21 -8
  240. package/src/embed/embed-preview.js +8 -1
  241. package/src/embed/icons.js +25 -0
  242. package/src/embed/save.js +10 -2
  243. package/src/embed/test/__snapshots__/index.native.js.snap +1 -1
  244. package/src/embed/variations.js +10 -0
  245. package/src/file/edit.js +4 -2
  246. package/src/file/save.js +2 -2
  247. package/src/file/style.scss +5 -5
  248. package/src/freeform/editor.scss +0 -2
  249. package/src/gallery/gallery.js +9 -2
  250. package/src/gallery/index.php +4 -0
  251. package/src/gallery/save.js +5 -1
  252. package/src/gallery/test/__snapshots__/index.native.js.snap +2 -2
  253. package/src/gallery/test/helpers.native.js +11 -198
  254. package/src/gallery/test/index.native.js +19 -29
  255. package/src/gallery/transforms.js +3 -3
  256. package/src/gallery/v1/edit.js +3 -4
  257. package/src/gallery/v1/gallery-image.js +4 -0
  258. package/src/gallery/v1/gallery.js +8 -2
  259. package/src/gallery/v1/save.js +20 -3
  260. package/src/group/block.json +1 -0
  261. package/src/html/edit.js +10 -40
  262. package/src/html/preview.js +46 -0
  263. package/src/image/edit.native.js +1 -0
  264. package/src/image/image.js +2 -0
  265. package/src/image/save.js +10 -2
  266. package/src/image/test/edit.native.js +51 -19
  267. package/src/list/v2/transforms.js +22 -7
  268. package/src/list-item/hooks/use-enter.js +9 -6
  269. package/src/list-item/hooks/use-outdent-list-item.js +48 -21
  270. package/src/navigation/block.json +9 -0
  271. package/src/navigation/edit/index.js +1 -0
  272. package/src/navigation/style.scss +10 -1
  273. package/src/navigation/test/use-navigation-menu.js +16 -11
  274. package/src/navigation/use-navigation-menu.js +26 -83
  275. package/src/navigation/view.js +7 -2
  276. package/src/navigation-submenu/view.js +7 -2
  277. package/src/post-comments/index.php +1 -1
  278. package/src/post-comments/style.scss +7 -3
  279. package/src/post-comments-form/edit.js +20 -3
  280. package/src/post-comments-form/editor.scss +4 -0
  281. package/src/post-comments-form/form.js +2 -2
  282. package/src/post-comments-form/index.php +1 -1
  283. package/src/post-featured-image/index.php +4 -2
  284. package/src/post-template/index.php +15 -3
  285. package/src/post-template/style.scss +1 -7
  286. package/src/search/edit.js +2 -2
  287. package/src/search/index.php +12 -10
  288. package/src/search/style.scss +9 -8
  289. package/src/table/edit.js +2 -0
  290. package/src/table/save.js +6 -1
  291. package/src/video/edit.js +4 -0
  292. package/src/video/save.js +10 -2
@@ -11,7 +11,6 @@ import {
11
11
  map,
12
12
  reduce,
13
13
  some,
14
- toString,
15
14
  } from 'lodash';
16
15
 
17
16
  /**
@@ -226,7 +225,7 @@ function GalleryEdit( props ) {
226
225
  // The image id in both the images and attachmentCaptions arrays is a
227
226
  // string, so ensure comparison works correctly by converting the
228
227
  // newImage.id to a string.
229
- const newImageId = toString( newImage.id );
228
+ const newImageId = newImage.id.toString();
230
229
  const currentImage = find( images, { id: newImageId } );
231
230
  const currentImageCaption = currentImage
232
231
  ? currentImage.caption
@@ -253,7 +252,7 @@ function GalleryEdit( props ) {
253
252
  newImages.map( ( newImage ) => ( {
254
253
  // Store the attachmentCaption id as a string for consistency
255
254
  // with the type of the id in the images attribute.
256
- id: toString( newImage.id ),
255
+ id: newImage.id.toString(),
257
256
  caption: newImage.caption,
258
257
  } ) )
259
258
  );
@@ -264,7 +263,7 @@ function GalleryEdit( props ) {
264
263
  // The id value is stored in a data attribute, so when the
265
264
  // block is parsed it's converted to a string. Converting
266
265
  // to a string here ensures it's type is consistent.
267
- id: toString( newImage.id ),
266
+ id: newImage.id.toString(),
268
267
  } ) ),
269
268
  columns: attributes.columns
270
269
  ? Math.min( newImages.length, attributes.columns )
@@ -16,6 +16,7 @@ import {
16
16
  RichText,
17
17
  MediaPlaceholder,
18
18
  store as blockEditorStore,
19
+ __experimentalGetElementClassName,
19
20
  } from '@wordpress/block-editor';
20
21
  import { isBlobURL } from '@wordpress/blob';
21
22
  import { compose } from '@wordpress/compose';
@@ -245,6 +246,9 @@ class GalleryImage extends Component {
245
246
  { ! isEditing && ( isSelected || caption ) && (
246
247
  <RichText
247
248
  tagName="figcaption"
249
+ className={ __experimentalGetElementClassName(
250
+ 'caption'
251
+ ) }
248
252
  aria-label={ __( 'Image caption text' ) }
249
253
  placeholder={ isSelected ? __( 'Add caption' ) : null }
250
254
  value={ caption }
@@ -6,7 +6,10 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { RichText } from '@wordpress/block-editor';
9
+ import {
10
+ RichText,
11
+ __experimentalGetElementClassName,
12
+ } from '@wordpress/block-editor';
10
13
  import { VisuallyHidden } from '@wordpress/components';
11
14
  import { __, sprintf } from '@wordpress/i18n';
12
15
  import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
@@ -94,7 +97,10 @@ export const Gallery = ( props ) => {
94
97
  <RichTextVisibilityHelper
95
98
  isHidden={ ! isSelected && RichText.isEmpty( caption ) }
96
99
  tagName="figcaption"
97
- className="blocks-gallery-caption"
100
+ className={ classnames(
101
+ 'blocks-gallery-caption',
102
+ __experimentalGetElementClassName( 'caption' )
103
+ ) }
98
104
  aria-label={ __( 'Gallery caption text' ) }
99
105
  placeholder={ __( 'Write gallery caption…' ) }
100
106
  value={ caption }
@@ -1,7 +1,16 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
4
- import { RichText, useBlockProps } from '@wordpress/block-editor';
9
+ import {
10
+ RichText,
11
+ useBlockProps,
12
+ __experimentalGetElementClassName,
13
+ } from '@wordpress/block-editor';
5
14
 
6
15
  /**
7
16
  * Internal dependencies
@@ -60,7 +69,12 @@ export default function saveV1( { attributes } ) {
60
69
  { ! RichText.isEmpty( image.caption ) && (
61
70
  <RichText.Content
62
71
  tagName="figcaption"
63
- className="blocks-gallery-item__caption"
72
+ className={ classnames(
73
+ 'blocks-gallery-item',
74
+ __experimentalGetElementClassName(
75
+ 'caption'
76
+ )
77
+ ) }
64
78
  value={ image.caption }
65
79
  />
66
80
  ) }
@@ -72,7 +86,10 @@ export default function saveV1( { attributes } ) {
72
86
  { ! RichText.isEmpty( caption ) && (
73
87
  <RichText.Content
74
88
  tagName="figcaption"
75
- className="blocks-gallery-caption"
89
+ className={ classnames(
90
+ 'blocks-gallery-caption',
91
+ __experimentalGetElementClassName( 'caption' )
92
+ ) }
76
93
  value={ caption }
77
94
  />
78
95
  ) }
@@ -21,6 +21,7 @@
21
21
  "__experimentalSettings": true,
22
22
  "align": [ "wide", "full" ],
23
23
  "anchor": true,
24
+ "ariaLabel": true,
24
25
  "html": false,
25
26
  "color": {
26
27
  "gradients": true,
package/src/html/edit.js CHANGED
@@ -6,42 +6,19 @@ import { useContext, useState } from '@wordpress/element';
6
6
  import {
7
7
  BlockControls,
8
8
  PlainText,
9
- transformStyles,
10
9
  useBlockProps,
11
- store as blockEditorStore,
12
10
  } from '@wordpress/block-editor';
13
- import {
14
- ToolbarButton,
15
- Disabled,
16
- SandBox,
17
- ToolbarGroup,
18
- } from '@wordpress/components';
19
- import { useSelect } from '@wordpress/data';
11
+ import { ToolbarButton, Disabled, ToolbarGroup } from '@wordpress/components';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import Preview from './preview';
20
17
 
21
18
  export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
22
19
  const [ isPreview, setIsPreview ] = useState();
23
20
  const isDisabled = useContext( Disabled.Context );
24
21
 
25
- const styles = useSelect( ( select ) => {
26
- // Default styles used to unset some of the styles
27
- // that might be inherited from the editor style.
28
- const defaultStyles = `
29
- html,body,:root {
30
- margin: 0 !important;
31
- padding: 0 !important;
32
- overflow: visible !important;
33
- min-height: auto !important;
34
- }
35
- `;
36
-
37
- return [
38
- defaultStyles,
39
- ...transformStyles(
40
- select( blockEditorStore ).getSettings().styles
41
- ),
42
- ];
43
- }, [] );
44
-
45
22
  function switchToPreview() {
46
23
  setIsPreview( true );
47
24
  }
@@ -71,17 +48,10 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
71
48
  </ToolbarGroup>
72
49
  </BlockControls>
73
50
  { isPreview || isDisabled ? (
74
- <>
75
- <SandBox html={ attributes.content } styles={ styles } />
76
- { /*
77
- An overlay is added when the block is not selected in order to register click events.
78
- Some browsers do not bubble up the clicks from the sandboxed iframe, which makes it
79
- difficult to reselect the block.
80
- */ }
81
- { ! isSelected && (
82
- <div className="block-library-html__preview-overlay"></div>
83
- ) }
84
- </>
51
+ <Preview
52
+ content={ attributes.content }
53
+ isSelected={ isSelected }
54
+ />
85
55
  ) : (
86
56
  <PlainText
87
57
  value={ attributes.content }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo } from '@wordpress/element';
5
+ import {
6
+ transformStyles,
7
+ store as blockEditorStore,
8
+ } from '@wordpress/block-editor';
9
+ import { SandBox } from '@wordpress/components';
10
+ import { useSelect } from '@wordpress/data';
11
+
12
+ // Default styles used to unset some of the styles
13
+ // that might be inherited from the editor style.
14
+ const DEFAULT_STYLES = `
15
+ html,body,:root {
16
+ margin: 0 !important;
17
+ padding: 0 !important;
18
+ overflow: visible !important;
19
+ min-height: auto !important;
20
+ }
21
+ `;
22
+
23
+ export default function HTMLEditPreview( { content, isSelected } ) {
24
+ const settingStyles = useSelect( ( select ) => {
25
+ return select( blockEditorStore ).getSettings()?.styles;
26
+ }, [] );
27
+
28
+ const styles = useMemo(
29
+ () => [ DEFAULT_STYLES, ...transformStyles( settingStyles ) ],
30
+ [ settingStyles ]
31
+ );
32
+
33
+ return (
34
+ <>
35
+ <SandBox html={ content } styles={ styles } />
36
+ { /*
37
+ An overlay is added when the block is not selected in order to register click events.
38
+ Some browsers do not bubble up the clicks from the sandboxed iframe, which makes it
39
+ difficult to reselect the block.
40
+ */ }
41
+ { ! isSelected && (
42
+ <div className="block-library-html__preview-overlay"></div>
43
+ ) }
44
+ </>
45
+ );
46
+ }
@@ -428,6 +428,7 @@ export class ImageEdit extends Component {
428
428
  id: media.id,
429
429
  url: media.url,
430
430
  caption: media.caption,
431
+ alt: media.alt,
431
432
  };
432
433
 
433
434
  let additionalAttributes;
@@ -29,6 +29,7 @@ import {
29
29
  BlockAlignmentControl,
30
30
  __experimentalImageEditor as ImageEditor,
31
31
  __experimentalImageEditingProvider as ImageEditingProvider,
32
+ __experimentalGetElementClassName,
32
33
  } from '@wordpress/block-editor';
33
34
  import { useEffect, useMemo, useState, useRef } from '@wordpress/element';
34
35
  import { __, sprintf, isRTL } from '@wordpress/i18n';
@@ -576,6 +577,7 @@ export default function Image( {
576
577
  { img }
577
578
  { ( ! RichText.isEmpty( caption ) || isSelected ) && (
578
579
  <RichText
580
+ className={ __experimentalGetElementClassName( 'caption' ) }
579
581
  ref={ captionRef }
580
582
  tagName="figcaption"
581
583
  aria-label={ __( 'Image caption text' ) }
package/src/image/save.js CHANGED
@@ -7,7 +7,11 @@ import { isEmpty } from 'lodash';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
- import { RichText, useBlockProps } from '@wordpress/block-editor';
10
+ import {
11
+ RichText,
12
+ useBlockProps,
13
+ __experimentalGetElementClassName,
14
+ } from '@wordpress/block-editor';
11
15
 
12
16
  export default function save( { attributes } ) {
13
17
  const {
@@ -60,7 +64,11 @@ export default function save( { attributes } ) {
60
64
  image
61
65
  ) }
62
66
  { ! RichText.isEmpty( caption ) && (
63
- <RichText.Content tagName="figcaption" value={ caption } />
67
+ <RichText.Content
68
+ className={ __experimentalGetElementClassName( 'caption' ) }
69
+ tagName="figcaption"
70
+ value={ caption }
71
+ />
64
72
  ) }
65
73
  </>
66
74
  );
@@ -16,6 +16,7 @@ import Clipboard from '@react-native-clipboard/clipboard';
16
16
  */
17
17
  import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks';
18
18
  import {
19
+ requestMediaPicker,
19
20
  setFeaturedImage,
20
21
  sendMediaUpload,
21
22
  subscribeMediaUpload,
@@ -49,6 +50,10 @@ jest.mock( 'lodash', () => {
49
50
  return { ...actual, delay: ( cb ) => cb() };
50
51
  } );
51
52
 
53
+ function mockGetMedia( media ) {
54
+ jest.spyOn( select( coreStore ), 'getMedia' ).mockReturnValue( media );
55
+ }
56
+
52
57
  const apiFetchPromise = Promise.resolve( {} );
53
58
 
54
59
  const clipboardPromise = Promise.resolve( '' );
@@ -79,7 +84,7 @@ describe( 'Image Block', () => {
79
84
  <a href="https://cldup.com/cXyG__fTLN.jpg">
80
85
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
81
86
  </a>
82
- <figcaption>Mountain</figcaption></figure>
87
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
83
88
  <!-- /wp:image -->`;
84
89
  const screen = await initializeEditor( { initialHtml } );
85
90
  // We must await the image fetch via `getMedia`
@@ -95,7 +100,7 @@ describe( 'Image Block', () => {
95
100
  fireEvent.press( screen.getByText( 'None' ) );
96
101
 
97
102
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"none","className":"is-style-default"} -->
98
- <figure class="wp-block-image size-large is-style-default"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/><figcaption>Mountain</figcaption></figure>
103
+ <figure class="wp-block-image size-large is-style-default"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/><figcaption class="wp-element-caption">Mountain</figcaption></figure>
99
104
  <!-- /wp:image -->`;
100
105
  expect( getEditorHtml() ).toBe( expectedHtml );
101
106
  } );
@@ -105,7 +110,7 @@ describe( 'Image Block', () => {
105
110
  <!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"none","className":"is-style-default"} -->
106
111
  <figure class="wp-block-image size-large is-style-default">
107
112
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
108
- <figcaption>Mountain</figcaption></figure>
113
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
109
114
  <!-- /wp:image -->`;
110
115
  const screen = await initializeEditor( { initialHtml } );
111
116
  // We must await the image fetch via `getMedia`
@@ -121,7 +126,7 @@ describe( 'Image Block', () => {
121
126
  fireEvent.press( screen.getByText( 'Media File' ) );
122
127
 
123
128
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"media","className":"is-style-default"} -->
124
- <figure class="wp-block-image size-large is-style-default"><a href="https://cldup.com/cXyG__fTLN.jpg"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption>Mountain</figcaption></figure>
129
+ <figure class="wp-block-image size-large is-style-default"><a href="https://cldup.com/cXyG__fTLN.jpg"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption class="wp-element-caption">Mountain</figcaption></figure>
125
130
  <!-- /wp:image -->`;
126
131
  expect( getEditorHtml() ).toBe( expectedHtml );
127
132
  } );
@@ -131,7 +136,7 @@ describe( 'Image Block', () => {
131
136
  <!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"none","className":"is-style-default"} -->
132
137
  <figure class="wp-block-image size-large is-style-default">
133
138
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
134
- <figcaption>Mountain</figcaption></figure>
139
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
135
140
  <!-- /wp:image -->`;
136
141
  const screen = await initializeEditor( { initialHtml } );
137
142
  // We must await the image fetch via `getMedia`
@@ -154,7 +159,7 @@ describe( 'Image Block', () => {
154
159
  fireEvent.press( screen.getByA11yLabel( 'Apply' ) );
155
160
 
156
161
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"custom","className":"is-style-default"} -->
157
- <figure class="wp-block-image size-large is-style-default"><a href="http://wordpress.org"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption>Mountain</figcaption></figure>
162
+ <figure class="wp-block-image size-large is-style-default"><a href="http://wordpress.org"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption class="wp-element-caption">Mountain</figcaption></figure>
158
163
  <!-- /wp:image -->`;
159
164
  expect( getEditorHtml() ).toBe( expectedHtml );
160
165
  } );
@@ -164,7 +169,7 @@ describe( 'Image Block', () => {
164
169
  <!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"none","className":"is-style-default"} -->
165
170
  <figure class="wp-block-image size-large is-style-default">
166
171
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
167
- <figcaption>Mountain</figcaption></figure>
172
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
168
173
  <!-- /wp:image -->`;
169
174
  const screen = await initializeEditor( { initialHtml } );
170
175
  // We must await the image fetch via `getMedia`
@@ -192,7 +197,7 @@ describe( 'Image Block', () => {
192
197
  fireEvent.press( screen.getByText( 'Media File' ) );
193
198
 
194
199
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"media","className":"is-style-default"} -->
195
- <figure class="wp-block-image size-large is-style-default"><a href="https://cldup.com/cXyG__fTLN.jpg"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption>Mountain</figcaption></figure>
200
+ <figure class="wp-block-image size-large is-style-default"><a href="https://cldup.com/cXyG__fTLN.jpg"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption class="wp-element-caption">Mountain</figcaption></figure>
196
201
  <!-- /wp:image -->`;
197
202
  expect( getEditorHtml() ).toBe( expectedHtml );
198
203
  } );
@@ -204,7 +209,7 @@ describe( 'Image Block', () => {
204
209
  <a href="https://cldup.com/cXyG__fTLN.jpg">
205
210
  <img src="https://cldup.com/cXyG__fTLN.jpg?w=683" alt="" class="wp-image-1"/>
206
211
  </a>
207
- <figcaption>Mountain</figcaption></figure>
212
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
208
213
  <!-- /wp:image -->`;
209
214
  const screen = await initializeEditor( { initialHtml } );
210
215
  // We must await the image fetch via `getMedia`
@@ -228,7 +233,7 @@ describe( 'Image Block', () => {
228
233
  <a href="https://wordpress.org">
229
234
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
230
235
  </a>
231
- <figcaption>Mountain</figcaption></figure>
236
+ <figcaption class="wp-element-caption">Mountain</figcaption></figure>
232
237
  <!-- /wp:image -->`;
233
238
  const screen = await initializeEditor( { initialHtml } );
234
239
  // We must await the image fetch via `getMedia`
@@ -246,7 +251,7 @@ describe( 'Image Block', () => {
246
251
  fireEvent.press( linkTargetButton );
247
252
 
248
253
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"custom","className":"is-style-default"} -->
249
- <figure class="wp-block-image size-large is-style-default"><a href="https://wordpress.org" target="_blank" rel="noreferrer noopener"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption>Mountain</figcaption></figure>
254
+ <figure class="wp-block-image size-large is-style-default"><a href="https://wordpress.org" target="_blank" rel="noreferrer noopener"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption class="wp-element-caption">Mountain</figcaption></figure>
250
255
  <!-- /wp:image -->`;
251
256
  expect( getEditorHtml() ).toBe( expectedHtml );
252
257
  } );
@@ -258,7 +263,7 @@ describe( 'Image Block', () => {
258
263
  <a href="https://wordpress.org" target="_blank" rel="noreferrer noopener">
259
264
  <img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/>
260
265
  </a>
261
- <figcaption>Mountain</figcaption>
266
+ <figcaption class="wp-element-caption">Mountain</figcaption>
262
267
  </figure>
263
268
  <!-- /wp:image -->`;
264
269
  const screen = await initializeEditor( { initialHtml } );
@@ -277,7 +282,7 @@ describe( 'Image Block', () => {
277
282
  fireEvent.press( linkTargetButton );
278
283
 
279
284
  const expectedHtml = `<!-- wp:image {"id":1,"sizeSlug":"large","linkDestination":"custom","className":"is-style-default"} -->
280
- <figure class="wp-block-image size-large is-style-default"><a href="https://wordpress.org"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption>Mountain</figcaption></figure>
285
+ <figure class="wp-block-image size-large is-style-default"><a href="https://wordpress.org"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-1"/></a><figcaption class="wp-element-caption">Mountain</figcaption></figure>
281
286
  <!-- /wp:image -->`;
282
287
  expect( getEditorHtml() ).toBe( expectedHtml );
283
288
  } );
@@ -292,12 +297,6 @@ describe( 'Image Block', () => {
292
297
  );
293
298
  }
294
299
 
295
- function mockGetMedia( media ) {
296
- jest.spyOn( select( coreStore ), 'getMedia' ).mockReturnValueOnce(
297
- media
298
- );
299
- }
300
-
301
300
  it( 'does not prompt to replace featured image during a new image upload', () => {
302
301
  // Arrange
303
302
  const INITIAL_IMAGE = { id: 1, url: 'mock-url-1' };
@@ -406,4 +405,37 @@ describe( 'Image Block', () => {
406
405
  );
407
406
  } );
408
407
  } );
408
+
409
+ it( 'sets src and alt attributes when selecting media', async () => {
410
+ const IMAGE = { id: 1, url: 'mock-image', alt: 'A beautiful mountain' };
411
+ requestMediaPicker.mockImplementationOnce(
412
+ ( source, filter, multiple, callback ) => {
413
+ callback( {
414
+ id: IMAGE.id,
415
+ url: IMAGE.url,
416
+ alt: IMAGE.alt,
417
+ } );
418
+ }
419
+ );
420
+ mockGetMedia( {
421
+ id: IMAGE.id,
422
+ source_url: IMAGE.url,
423
+ } );
424
+
425
+ const initialHtml = `
426
+ <!-- wp:image -->
427
+ <figure class="wp-block-image">
428
+ <img alt="" />
429
+ </figure>
430
+ <!-- /wp:image -->`;
431
+ const screen = await initializeEditor( { initialHtml } );
432
+
433
+ fireEvent.press( screen.getByText( 'ADD IMAGE' ) );
434
+ fireEvent.press( screen.getByText( 'WordPress Media Library' ) );
435
+
436
+ const expectedHtml = `<!-- wp:image {"id":${ IMAGE.id },"sizeSlug":"large","linkDestination":"none"} -->
437
+ <figure class="wp-block-image size-large"><img src="${ IMAGE.url }" alt="${ IMAGE.alt }" class="wp-image-${ IMAGE.id }"/></figure>
438
+ <!-- /wp:image -->`;
439
+ expect( getEditorHtml() ).toBe( expectedHtml );
440
+ } );
409
441
  } );
@@ -1,3 +1,11 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ /**
5
+ * External dependencies
6
+ */
7
+ import { flatMap } from 'lodash';
8
+
1
9
  /**
2
10
  * WordPress dependencies
3
11
  */
@@ -35,6 +43,15 @@ function getListContentSchema( { phrasingContentSchema } ) {
35
43
  return listContentSchema;
36
44
  }
37
45
 
46
+ function getListContentFlat( blocks ) {
47
+ return flatMap( blocks, ( { name, attributes, innerBlocks = [] } ) => {
48
+ if ( name === 'core/list-item' ) {
49
+ return [ attributes.content, ...getListContentFlat( innerBlocks ) ];
50
+ }
51
+ return getListContentFlat( innerBlocks );
52
+ } );
53
+ }
54
+
38
55
  const transforms = {
39
56
  from: [
40
57
  {
@@ -123,13 +140,11 @@ const transforms = {
123
140
  type: 'block',
124
141
  blocks: [ block ],
125
142
  transform: ( _attributes, childBlocks ) => {
126
- return childBlocks
127
- .filter( ( { name } ) => name === 'core/list-item' )
128
- .map( ( { attributes } ) =>
129
- createBlock( block, {
130
- content: attributes.content,
131
- } )
132
- );
143
+ return getListContentFlat( childBlocks ).map( ( content ) =>
144
+ createBlock( block, {
145
+ content,
146
+ } )
147
+ );
133
148
  },
134
149
  } ) ),
135
150
  ...[ 'core/quote', 'core/pullquote' ].map( ( block ) => ( {
@@ -18,7 +18,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
18
18
  import useOutdentListItem from './use-outdent-list-item';
19
19
 
20
20
  export default function useEnter( props ) {
21
- const { replaceBlocks } = useDispatch( blockEditorStore );
21
+ const { replaceBlocks, selectionChange } = useDispatch( blockEditorStore );
22
22
  const { getBlock, getBlockRootClientId, getBlockIndex } =
23
23
  useSelect( blockEditorStore );
24
24
  const propsRef = useRef( props );
@@ -42,8 +42,9 @@ export default function useEnter( props ) {
42
42
  return;
43
43
  }
44
44
  // Here we are in top level list so we need to split.
45
- const blockRootClientId = getBlockRootClientId( clientId );
46
- const topParentListBlock = getBlock( blockRootClientId );
45
+ const topParentListBlock = getBlock(
46
+ getBlockRootClientId( clientId )
47
+ );
47
48
  const blockIndex = getBlockIndex( clientId );
48
49
  const head = cloneBlock( {
49
50
  ...topParentListBlock,
@@ -69,11 +70,13 @@ export default function useEnter( props ) {
69
70
  ]
70
71
  : [];
71
72
  replaceBlocks(
72
- blockRootClientId,
73
+ topParentListBlock.clientId,
73
74
  [ head, middle, ...tail ],
74
- 1,
75
- 0
75
+ 1
76
76
  );
77
+ // We manually change the selection here because we are replacing
78
+ // a different block than the selected one.
79
+ selectionChange( middle.clientId );
77
80
  }
78
81
 
79
82
  element.addEventListener( 'keydown', onKeyDown );