@wordpress/block-library 10.5.2-next.v.202608281122.0 → 11.0.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 (588) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/build/audio/edit.cjs +5 -5
  3. package/build/audio/edit.cjs.map +2 -2
  4. package/build/audio/index.cjs +0 -37
  5. package/build/audio/index.cjs.map +3 -3
  6. package/build/button/index.cjs +0 -34
  7. package/build/button/index.cjs.map +3 -3
  8. package/build/code/index.cjs +0 -17
  9. package/build/code/index.cjs.map +3 -3
  10. package/build/comment-template/edit.cjs.map +1 -1
  11. package/build/cover/index.cjs +0 -38
  12. package/build/cover/index.cjs.map +3 -3
  13. package/build/details/index.cjs +0 -17
  14. package/build/details/index.cjs.map +3 -3
  15. package/build/file/index.cjs +0 -43
  16. package/build/file/index.cjs.map +3 -3
  17. package/build/footnotes/format.cjs +1 -1
  18. package/build/footnotes/format.cjs.map +2 -2
  19. package/build/gallery/dynamic-gallery.cjs +22 -12
  20. package/build/gallery/dynamic-gallery.cjs.map +2 -2
  21. package/build/heading/index.cjs +0 -16
  22. package/build/heading/index.cjs.map +3 -3
  23. package/build/image/image.cjs +7 -5
  24. package/build/image/image.cjs.map +2 -2
  25. package/build/image/index.cjs +0 -81
  26. package/build/image/index.cjs.map +3 -3
  27. package/build/image/use-open-image-media-editor-modal.cjs +81 -14
  28. package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
  29. package/build/index.cjs +0 -10
  30. package/build/index.cjs.map +2 -2
  31. package/build/latest-posts/edit.cjs.map +1 -1
  32. package/build/list-item/edit.cjs +14 -11
  33. package/build/list-item/edit.cjs.map +2 -2
  34. package/build/list-item/hooks/index.cjs +6 -9
  35. package/build/list-item/hooks/index.cjs.map +2 -2
  36. package/build/list-item/hooks/use-enter.cjs +62 -67
  37. package/build/list-item/hooks/use-enter.cjs.map +3 -3
  38. package/build/list-item/hooks/use-merge.cjs +26 -44
  39. package/build/list-item/hooks/use-merge.cjs.map +3 -3
  40. package/build/list-item/hooks/use-multi-select-tab.cjs +80 -0
  41. package/build/list-item/hooks/use-multi-select-tab.cjs.map +7 -0
  42. package/build/list-item/hooks/use-tab.cjs +65 -0
  43. package/build/list-item/hooks/use-tab.cjs.map +7 -0
  44. package/build/list-item/index.cjs +0 -17
  45. package/build/list-item/index.cjs.map +3 -3
  46. package/build/list-item/utils.cjs +169 -0
  47. package/build/list-item/utils.cjs.map +7 -0
  48. package/build/math/block.json +3 -0
  49. package/build/media-text/index.cjs +0 -50
  50. package/build/media-text/index.cjs.map +3 -3
  51. package/build/media-text/media-container.cjs +16 -11
  52. package/build/media-text/media-container.cjs.map +2 -2
  53. package/build/more/index.cjs +0 -18
  54. package/build/more/index.cjs.map +3 -3
  55. package/build/navigation/constants.cjs +1 -1
  56. package/build/navigation/constants.cjs.map +1 -1
  57. package/build/navigation-link/block.json +1 -1
  58. package/build/navigation-link/deprecated.cjs +69 -0
  59. package/build/navigation-link/deprecated.cjs.map +7 -0
  60. package/build/navigation-link/index.cjs +6 -74
  61. package/build/navigation-link/index.cjs.map +4 -4
  62. package/build/{form-submit-button/init.cjs → navigation-link/variations.cjs} +23 -8
  63. package/build/navigation-link/variations.cjs.map +7 -0
  64. package/build/navigation-submenu/index.cjs +0 -32
  65. package/build/navigation-submenu/index.cjs.map +3 -3
  66. package/build/paragraph/index.cjs +0 -17
  67. package/build/paragraph/index.cjs.map +3 -3
  68. package/build/paragraph/use-enter.cjs +8 -4
  69. package/build/paragraph/use-enter.cjs.map +2 -2
  70. package/build/post-template/edit.cjs +3 -1
  71. package/build/post-template/edit.cjs.map +2 -2
  72. package/build/preformatted/index.cjs +0 -17
  73. package/build/preformatted/index.cjs.map +3 -3
  74. package/build/pullquote/index.cjs +0 -24
  75. package/build/pullquote/index.cjs.map +3 -3
  76. package/build/query/edit/inspector-controls/enhanced-pagination-control.cjs +13 -5
  77. package/build/query/edit/inspector-controls/enhanced-pagination-control.cjs.map +2 -2
  78. package/build/query/edit/inspector-controls/index.cjs +9 -4
  79. package/build/query/edit/inspector-controls/index.cjs.map +2 -2
  80. package/build/query/edit/query-content.cjs +30 -9
  81. package/build/query/edit/query-content.cjs.map +3 -3
  82. package/build/query/utils.cjs +11 -4
  83. package/build/query/utils.cjs.map +2 -2
  84. package/build/search/edit.cjs +3 -1
  85. package/build/search/edit.cjs.map +2 -2
  86. package/build/search/index.cjs +0 -31
  87. package/build/search/index.cjs.map +3 -3
  88. package/build/site-tagline/edit.cjs +11 -17
  89. package/build/site-tagline/edit.cjs.map +2 -2
  90. package/build/site-title/edit.cjs +12 -18
  91. package/build/site-title/edit.cjs.map +2 -2
  92. package/build/social-link/index.cjs +0 -31
  93. package/build/social-link/index.cjs.map +3 -3
  94. package/build/verse/index.cjs +0 -17
  95. package/build/verse/index.cjs.map +3 -3
  96. package/build/video/index.cjs +0 -40
  97. package/build/video/index.cjs.map +3 -3
  98. package/build/video/tracks-editor.cjs +2 -3
  99. package/build/video/tracks-editor.cjs.map +3 -3
  100. package/build-module/audio/edit.mjs +5 -5
  101. package/build-module/audio/edit.mjs.map +2 -2
  102. package/build-module/audio/index.mjs +0 -37
  103. package/build-module/audio/index.mjs.map +2 -2
  104. package/build-module/button/index.mjs +0 -34
  105. package/build-module/button/index.mjs.map +2 -2
  106. package/build-module/code/index.mjs +0 -17
  107. package/build-module/code/index.mjs.map +2 -2
  108. package/build-module/comment-template/edit.mjs.map +1 -1
  109. package/build-module/cover/index.mjs +0 -38
  110. package/build-module/cover/index.mjs.map +2 -2
  111. package/build-module/details/index.mjs +0 -17
  112. package/build-module/details/index.mjs.map +2 -2
  113. package/build-module/file/index.mjs +1 -44
  114. package/build-module/file/index.mjs.map +2 -2
  115. package/build-module/footnotes/format.mjs +1 -1
  116. package/build-module/footnotes/format.mjs.map +2 -2
  117. package/build-module/gallery/dynamic-gallery.mjs +23 -13
  118. package/build-module/gallery/dynamic-gallery.mjs.map +2 -2
  119. package/build-module/heading/index.mjs +1 -21
  120. package/build-module/heading/index.mjs.map +2 -2
  121. package/build-module/image/image.mjs +7 -5
  122. package/build-module/image/image.mjs.map +2 -2
  123. package/build-module/image/index.mjs +0 -81
  124. package/build-module/image/index.mjs.map +2 -2
  125. package/build-module/image/use-open-image-media-editor-modal.mjs +84 -14
  126. package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
  127. package/build-module/index.mjs +0 -10
  128. package/build-module/index.mjs.map +2 -2
  129. package/build-module/latest-posts/edit.mjs.map +1 -1
  130. package/build-module/list-item/edit.mjs +20 -18
  131. package/build-module/list-item/edit.mjs.map +2 -2
  132. package/build-module/list-item/hooks/index.mjs +8 -10
  133. package/build-module/list-item/hooks/index.mjs.map +2 -2
  134. package/build-module/list-item/hooks/use-enter.mjs +63 -58
  135. package/build-module/list-item/hooks/use-enter.mjs.map +2 -2
  136. package/build-module/list-item/hooks/use-merge.mjs +27 -35
  137. package/build-module/list-item/hooks/use-merge.mjs.map +2 -2
  138. package/build-module/list-item/hooks/use-multi-select-tab.mjs +59 -0
  139. package/build-module/list-item/hooks/use-multi-select-tab.mjs.map +7 -0
  140. package/build-module/list-item/hooks/use-tab.mjs +44 -0
  141. package/build-module/list-item/hooks/use-tab.mjs.map +7 -0
  142. package/build-module/list-item/index.mjs +0 -17
  143. package/build-module/list-item/index.mjs.map +2 -2
  144. package/build-module/list-item/utils.mjs +140 -0
  145. package/build-module/list-item/utils.mjs.map +7 -0
  146. package/build-module/math/block.json +3 -0
  147. package/build-module/media-text/index.mjs +0 -50
  148. package/build-module/media-text/index.mjs.map +2 -2
  149. package/build-module/media-text/media-container.mjs +17 -12
  150. package/build-module/media-text/media-container.mjs.map +2 -2
  151. package/build-module/more/index.mjs +0 -18
  152. package/build-module/more/index.mjs.map +2 -2
  153. package/build-module/navigation/constants.mjs +1 -1
  154. package/build-module/navigation/constants.mjs.map +1 -1
  155. package/build-module/navigation-link/block.json +1 -1
  156. package/build-module/navigation-link/deprecated.mjs +48 -0
  157. package/build-module/navigation-link/deprecated.mjs.map +7 -0
  158. package/build-module/navigation-link/index.mjs +7 -75
  159. package/build-module/navigation-link/index.mjs.map +3 -3
  160. package/build-module/navigation-link/variations.mjs +22 -0
  161. package/build-module/navigation-link/variations.mjs.map +7 -0
  162. package/build-module/navigation-submenu/index.mjs +1 -33
  163. package/build-module/navigation-submenu/index.mjs.map +2 -2
  164. package/build-module/paragraph/index.mjs +0 -17
  165. package/build-module/paragraph/index.mjs.map +2 -2
  166. package/build-module/paragraph/use-enter.mjs +8 -4
  167. package/build-module/paragraph/use-enter.mjs.map +2 -2
  168. package/build-module/post-template/edit.mjs +3 -1
  169. package/build-module/post-template/edit.mjs.map +2 -2
  170. package/build-module/preformatted/index.mjs +0 -17
  171. package/build-module/preformatted/index.mjs.map +2 -2
  172. package/build-module/pullquote/index.mjs +0 -24
  173. package/build-module/pullquote/index.mjs.map +2 -2
  174. package/build-module/query/edit/inspector-controls/enhanced-pagination-control.mjs +14 -6
  175. package/build-module/query/edit/inspector-controls/enhanced-pagination-control.mjs.map +2 -2
  176. package/build-module/query/edit/inspector-controls/index.mjs +9 -4
  177. package/build-module/query/edit/inspector-controls/index.mjs.map +2 -2
  178. package/build-module/query/edit/query-content.mjs +32 -11
  179. package/build-module/query/edit/query-content.mjs.map +2 -2
  180. package/build-module/query/utils.mjs +10 -7
  181. package/build-module/query/utils.mjs.map +2 -2
  182. package/build-module/search/edit.mjs +4 -2
  183. package/build-module/search/edit.mjs.map +2 -2
  184. package/build-module/search/index.mjs +0 -31
  185. package/build-module/search/index.mjs.map +2 -2
  186. package/build-module/site-tagline/edit.mjs +13 -19
  187. package/build-module/site-tagline/edit.mjs.map +2 -2
  188. package/build-module/site-title/edit.mjs +14 -20
  189. package/build-module/site-title/edit.mjs.map +2 -2
  190. package/build-module/social-link/index.mjs +0 -31
  191. package/build-module/social-link/index.mjs.map +2 -2
  192. package/build-module/verse/index.mjs +0 -17
  193. package/build-module/verse/index.mjs.map +2 -2
  194. package/build-module/video/index.mjs +0 -40
  195. package/build-module/video/index.mjs.map +2 -2
  196. package/build-module/video/tracks-editor.mjs +3 -5
  197. package/build-module/video/tracks-editor.mjs.map +2 -2
  198. package/build-style/columns/style-rtl.css +1 -1
  199. package/build-style/columns/style.css +1 -1
  200. package/build-style/comment-template/style-rtl.css +0 -1
  201. package/build-style/comment-template/style.css +0 -1
  202. package/build-style/cover/style-rtl.css +1 -2
  203. package/build-style/cover/style.css +1 -2
  204. package/build-style/editor-rtl.css +20 -81
  205. package/build-style/editor.css +20 -81
  206. package/build-style/gallery/style-rtl.css +2 -4
  207. package/build-style/gallery/style.css +2 -4
  208. package/build-style/group/theme-rtl.css +1 -1
  209. package/build-style/group/theme.css +1 -1
  210. package/build-style/heading/style-rtl.css +1 -1
  211. package/build-style/heading/style.css +1 -1
  212. package/build-style/icon/style-rtl.css +3 -0
  213. package/build-style/icon/style.css +3 -0
  214. package/build-style/image/editor-rtl.css +0 -1
  215. package/build-style/image/editor.css +0 -1
  216. package/build-style/list/style-rtl.css +1 -1
  217. package/build-style/list/style.css +1 -1
  218. package/build-style/media-text/style-rtl.css +2 -3
  219. package/build-style/media-text/style.css +2 -3
  220. package/build-style/navigation/editor-rtl.css +8 -0
  221. package/build-style/navigation/editor.css +8 -0
  222. package/build-style/paragraph/style-rtl.css +1 -1
  223. package/build-style/paragraph/style.css +1 -1
  224. package/build-style/playlist/style-rtl.css +1 -2
  225. package/build-style/playlist/style.css +1 -2
  226. package/build-style/playlist-track/style-rtl.css +1 -2
  227. package/build-style/playlist-track/style.css +1 -2
  228. package/build-style/preformatted/style-rtl.css +1 -1
  229. package/build-style/preformatted/style.css +1 -1
  230. package/build-style/query/editor-rtl.css +5 -15
  231. package/build-style/query/editor.css +5 -15
  232. package/build-style/read-more/style-rtl.css +0 -1
  233. package/build-style/read-more/style.css +0 -1
  234. package/build-style/reset-rtl.css +1 -3
  235. package/build-style/reset.css +1 -3
  236. package/build-style/search/style-rtl.css +1 -3
  237. package/build-style/search/style.css +1 -3
  238. package/build-style/site-logo/editor-rtl.css +1 -2
  239. package/build-style/site-logo/editor.css +1 -2
  240. package/build-style/style-rtl.css +18 -77
  241. package/build-style/style.css +18 -77
  242. package/build-style/tab-list/style-rtl.css +1 -3
  243. package/build-style/tab-list/style.css +1 -3
  244. package/build-style/template-part/editor-rtl.css +4 -8
  245. package/build-style/template-part/editor.css +4 -8
  246. package/build-style/template-part/theme-rtl.css +1 -1
  247. package/build-style/template-part/theme.css +1 -1
  248. package/build-style/theme-rtl.css +2 -2
  249. package/build-style/theme.css +2 -2
  250. package/build-style/video/style-rtl.css +1 -2
  251. package/build-style/video/style.css +1 -2
  252. package/build-types/navigation-link/deprecated.d.ts +48 -0
  253. package/build-types/navigation-link/deprecated.d.ts.map +1 -0
  254. package/package.json +43 -43
  255. package/src/accordion/index.php +2 -2
  256. package/src/accordion-item/index.php +1 -1
  257. package/src/audio/edit.jsx +6 -7
  258. package/src/audio/index.js +0 -37
  259. package/src/breadcrumbs/index.php +4 -4
  260. package/src/button/index.js +0 -34
  261. package/src/button/style.scss +16 -15
  262. package/src/button/test/{get-experimental-label.js → get-experimental-label.jsdom.test.js} +1 -0
  263. package/src/button/test/get-updated-link-attributes.js +1 -0
  264. package/src/button/test/utils.js +1 -0
  265. package/src/categories/index.php +4 -0
  266. package/src/code/index.js +0 -18
  267. package/src/code/test/utils.js +1 -0
  268. package/src/columns/style.scss +2 -1
  269. package/src/columns/test/{transforms.js → transforms.jsdom.test.js} +1 -0
  270. package/src/columns/test/utils.js +1 -0
  271. package/src/comment-template/edit.jsx +1 -1
  272. package/src/comment-template/index.php +2 -2
  273. package/src/comment-template/test/index.js +1 -0
  274. package/src/common.scss +51 -50
  275. package/src/cover/README.md +37 -0
  276. package/src/cover/index.js +0 -39
  277. package/src/cover/style.scss +3 -3
  278. package/src/cover/test/{edit.js → edit.jsdom.test.js} +18 -17
  279. package/src/cover/test/{transforms.js → transforms.jsdom.test.js} +1 -0
  280. package/src/details/index.js +0 -18
  281. package/src/editor.scss +0 -2
  282. package/src/embed/editor.scss +1 -0
  283. package/src/embed/test/{index.js → index.jsdom.test.js} +5 -1
  284. package/src/file/index.js +1 -43
  285. package/src/footnotes/format.jsx +5 -1
  286. package/src/gallery/dynamic-gallery.jsx +31 -4
  287. package/src/gallery/test/dynamic-source.js +1 -0
  288. package/src/gallery/test/{edit.js → edit.jsdom.test.js} +4 -0
  289. package/src/gallery/test/responsive-styles.js +1 -0
  290. package/src/gallery/test/shared.js +1 -0
  291. package/src/gallery/test/{transforms.js → transforms.jsdom.test.js} +1 -0
  292. package/src/gallery/test/{use-get-new-images.jsx → use-get-new-images.jsdom.test.jsx} +1 -0
  293. package/src/gallery/test/variations.js +1 -0
  294. package/src/group/test/{placeholder.jsx → placeholder.jsdom.test.jsx} +1 -0
  295. package/src/group/theme.scss +1 -1
  296. package/src/heading/index.js +1 -22
  297. package/src/heading/index.php +1 -1
  298. package/src/heading/style.scss +1 -1
  299. package/src/heading/test/shared.js +1 -0
  300. package/src/home-link/index.php +2 -2
  301. package/src/html/test/{index.js → index.jsdom.test.js} +9 -0
  302. package/src/html/test/{utils.js → utils.jsdom.test.js} +1 -0
  303. package/src/icon/index.php +18 -6
  304. package/src/icon/style.scss +7 -0
  305. package/src/image/image.jsx +18 -11
  306. package/src/image/index.js +0 -80
  307. package/src/image/test/{transforms.js → transforms.jsdom.test.js} +1 -0
  308. package/src/image/test/{use-open-image-media-editor-modal.js → use-open-image-media-editor-modal.jsdom.test.js} +343 -28
  309. package/src/image/use-open-image-media-editor-modal.js +184 -21
  310. package/src/index.jsx +0 -11
  311. package/src/latest-posts/edit.jsx +1 -1
  312. package/src/latest-posts/test/{deprecated.js → deprecated.jsdom.test.js} +1 -0
  313. package/src/list/index.php +1 -1
  314. package/src/list/style.scss +1 -1
  315. package/src/list-item/edit.jsx +20 -20
  316. package/src/list-item/hooks/index.js +2 -3
  317. package/src/list-item/hooks/use-enter.js +82 -70
  318. package/src/list-item/hooks/use-merge.js +28 -36
  319. package/src/list-item/hooks/use-multi-select-tab.js +83 -0
  320. package/src/list-item/hooks/use-tab.js +62 -0
  321. package/src/list-item/index.js +0 -18
  322. package/src/list-item/utils.js +236 -0
  323. package/src/math/README.md +2 -0
  324. package/src/math/block.json +3 -0
  325. package/src/media-text/index.js +0 -50
  326. package/src/media-text/media-container.jsx +22 -12
  327. package/src/media-text/style.scss +2 -1
  328. package/src/media-text/test/image-fill.js +1 -0
  329. package/src/more/index.js +0 -19
  330. package/src/navigation/constants.js +1 -1
  331. package/src/navigation/edit/test/are-blocks-dirty.js +1 -0
  332. package/src/navigation/edit/test/{layout-custom-properties.js → layout-custom-properties.jsdom.test.js} +8 -7
  333. package/src/navigation/edit/test/{navigation-menu-selector.jsx → navigation-menu-selector.jsdom.test.jsx} +23 -14
  334. package/src/navigation/edit/test/{overlay-template-part-selector.jsx → overlay-template-part-selector.jsdom.test.jsx} +22 -20
  335. package/src/navigation/edit/test/{responsive-wrapper.jsx → responsive-wrapper.jsdom.test.jsx} +14 -13
  336. package/src/navigation/edit/test/{use-create-overlay.js → use-create-overlay.jsdom.test.js} +19 -24
  337. package/src/navigation/edit/test/utils.js +1 -0
  338. package/src/navigation/editor.scss +13 -0
  339. package/src/navigation/index.php +14 -14
  340. package/src/navigation/test/{menu-items-to-blocks.js → menu-items-to-blocks.jsdom.test.js} +3 -2
  341. package/src/navigation/test/{use-navigation-menu.js → use-navigation-menu.jsdom.test.js} +7 -4
  342. package/src/navigation/test/{view.js → view.jsdom.test.js} +4 -2
  343. package/src/navigation-link/block.json +1 -1
  344. package/src/navigation-link/deprecated.tsx +58 -0
  345. package/src/navigation-link/{index.jsx → index.js} +5 -77
  346. package/src/navigation-link/index.php +5 -5
  347. package/src/navigation-link/shared/test/{controls.jsx → controls.jsdom.test.jsx} +18 -18
  348. package/src/navigation-link/shared/test/update-attributes.test.js +52 -51
  349. package/src/navigation-link/shared/test/{use-enable-link-status-validation.test.js → use-enable-link-status-validation.jsdom.test.js} +8 -6
  350. package/src/navigation-link/shared/test/{use-entity-binding.js → use-entity-binding.jsdom.test.js} +12 -11
  351. package/src/navigation-link/shared/test/{use-handle-link-change.test.js → use-handle-link-change.jsdom.test.js} +23 -20
  352. package/src/navigation-link/shared/test/{use-link-preview.test.js → use-link-preview.jsdom.test.js} +17 -14
  353. package/src/navigation-link/test/__snapshots__/{hooks.js.snap → hooks.jsdom.test.js.snap} +23 -6
  354. package/src/navigation-link/test/block-labelling.js +1 -0
  355. package/src/navigation-link/test/{hooks.js → hooks.jsdom.test.js} +1 -0
  356. package/src/navigation-link/variations.js +19 -0
  357. package/src/navigation-submenu/index.js +1 -33
  358. package/src/page-list/index.php +10 -10
  359. package/src/page-list/test/{convert-to-navigation-links.js → convert-to-navigation-links.jsdom.test.js} +3 -2
  360. package/src/paragraph/index.js +0 -18
  361. package/src/paragraph/style.scss +1 -1
  362. package/src/paragraph/use-enter.js +13 -6
  363. package/src/pattern/test/index.js +1 -0
  364. package/src/playlist/test/{edit-component.jsx → edit-component.jsdom.test.jsx} +31 -30
  365. package/src/playlist/test/{edit.js → edit.jsdom.test.js} +1 -0
  366. package/src/playlist/test/{transforms.js → transforms.jsdom.test.js} +1 -0
  367. package/src/playlist-track/test/{edit.jsx → edit.jsdom.test.jsx} +20 -19
  368. package/src/post-author/index.php +3 -3
  369. package/src/post-author-biography/index.php +3 -3
  370. package/src/post-author-name/index.php +3 -3
  371. package/src/post-comments-link/index.php +4 -4
  372. package/src/post-date/test/{edit.js → edit.jsdom.test.js} +1 -0
  373. package/src/post-template/edit.jsx +3 -1
  374. package/src/post-time-to-read/index.php +3 -3
  375. package/src/post-title/style.scss +1 -0
  376. package/src/preformatted/index.js +0 -18
  377. package/src/preformatted/style.scss +1 -1
  378. package/src/pullquote/index.js +0 -24
  379. package/src/query/edit/inspector-controls/enhanced-pagination-control.jsx +13 -6
  380. package/src/query/edit/inspector-controls/index.jsx +9 -4
  381. package/src/query/edit/query-content.jsx +31 -8
  382. package/src/query/editor.scss +1 -7
  383. package/src/query/index.php +2 -2
  384. package/src/query/test/{utils.js → utils.jsdom.test.js} +1 -0
  385. package/src/query/utils.js +15 -11
  386. package/src/quote/test/{migrate.js → migrate.jsdom.test.js} +1 -0
  387. package/src/read-more/index.php +1 -1
  388. package/src/search/edit.jsx +12 -2
  389. package/src/search/index.js +0 -30
  390. package/src/search/index.php +1 -1
  391. package/src/separator/test/{edit.jsx → edit.jsdom.test.jsx} +5 -4
  392. package/src/site-logo/index.php +1 -1
  393. package/src/site-tagline/edit.jsx +18 -27
  394. package/src/site-title/edit.jsx +20 -27
  395. package/src/social-link/index.js +0 -32
  396. package/src/social-link/index.php +0 -1
  397. package/src/style.scss +0 -1
  398. package/src/table/editor.scss +1 -0
  399. package/src/table/style.scss +2 -0
  400. package/src/table/test/state.js +1 -0
  401. package/src/table/test/utils.js +1 -0
  402. package/src/table-of-contents/index.php +3 -3
  403. package/src/template-part/theme.scss +1 -1
  404. package/src/utils/test/search-patterns.js +1 -0
  405. package/src/utils/test/{style-state.js → style-state.jsdom.test.js} +1 -0
  406. package/src/utils/test/{waveform-player-dependency.js → waveform-player-dependency.jsdom.test.js} +15 -21
  407. package/src/verse/index.js +0 -18
  408. package/src/verse/style.scss +1 -0
  409. package/src/video/index.js +0 -40
  410. package/src/video/test/variations.js +1 -0
  411. package/src/video/tracks-editor.jsx +4 -5
  412. package/build/form/block.json +0 -65
  413. package/build/form/deprecated.cjs +0 -111
  414. package/build/form/deprecated.cjs.map +0 -7
  415. package/build/form/edit.cjs +0 -180
  416. package/build/form/edit.cjs.map +0 -7
  417. package/build/form/icons.cjs +0 -33
  418. package/build/form/icons.cjs.map +0 -7
  419. package/build/form/index.cjs +0 -118
  420. package/build/form/index.cjs.map +0 -7
  421. package/build/form/init.cjs +0 -28
  422. package/build/form/init.cjs.map +0 -7
  423. package/build/form/save.cjs +0 -40
  424. package/build/form/save.cjs.map +0 -7
  425. package/build/form/utils.cjs +0 -61
  426. package/build/form/utils.cjs.map +0 -7
  427. package/build/form/variations.cjs +0 -152
  428. package/build/form/variations.cjs.map +0 -7
  429. package/build/form/view.cjs +0 -48
  430. package/build/form/view.cjs.map +0 -7
  431. package/build/form-input/block.json +0 -72
  432. package/build/form-input/deprecated.cjs +0 -252
  433. package/build/form-input/deprecated.cjs.map +0 -7
  434. package/build/form-input/edit.cjs +0 -206
  435. package/build/form-input/edit.cjs.map +0 -7
  436. package/build/form-input/icons.cjs +0 -33
  437. package/build/form-input/icons.cjs.map +0 -7
  438. package/build/form-input/index.cjs +0 -63
  439. package/build/form-input/index.cjs.map +0 -7
  440. package/build/form-input/init.cjs +0 -28
  441. package/build/form-input/init.cjs.map +0 -7
  442. package/build/form-input/save.cjs +0 -88
  443. package/build/form-input/save.cjs.map +0 -7
  444. package/build/form-input/variations.cjs +0 -105
  445. package/build/form-input/variations.cjs.map +0 -7
  446. package/build/form-submission-notification/block.json +0 -19
  447. package/build/form-submission-notification/edit.cjs +0 -71
  448. package/build/form-submission-notification/edit.cjs.map +0 -7
  449. package/build/form-submission-notification/index.cjs +0 -73
  450. package/build/form-submission-notification/index.cjs.map +0 -7
  451. package/build/form-submission-notification/init.cjs +0 -28
  452. package/build/form-submission-notification/init.cjs.map +0 -7
  453. package/build/form-submission-notification/save.cjs +0 -54
  454. package/build/form-submission-notification/save.cjs.map +0 -7
  455. package/build/form-submission-notification/variations.cjs +0 -78
  456. package/build/form-submission-notification/variations.cjs.map +0 -7
  457. package/build/form-submit-button/block.json +0 -15
  458. package/build/form-submit-button/edit.cjs +0 -36
  459. package/build/form-submit-button/edit.cjs.map +0 -7
  460. package/build/form-submit-button/index.cjs +0 -75
  461. package/build/form-submit-button/index.cjs.map +0 -7
  462. package/build/form-submit-button/init.cjs.map +0 -7
  463. package/build/form-submit-button/save.cjs +0 -32
  464. package/build/form-submit-button/save.cjs.map +0 -7
  465. package/build/list-item/hooks/use-indent-list-item.cjs +0 -79
  466. package/build/list-item/hooks/use-indent-list-item.cjs.map +0 -7
  467. package/build/list-item/hooks/use-outdent-list-item.cjs +0 -106
  468. package/build/list-item/hooks/use-outdent-list-item.cjs.map +0 -7
  469. package/build/list-item/hooks/use-space.cjs +0 -83
  470. package/build/list-item/hooks/use-space.cjs.map +0 -7
  471. package/build/query/edit/enhanced-pagination-modal.cjs +0 -89
  472. package/build/query/edit/enhanced-pagination-modal.cjs.map +0 -7
  473. package/build-module/form/block.json +0 -65
  474. package/build-module/form/deprecated.mjs +0 -96
  475. package/build-module/form/deprecated.mjs.map +0 -7
  476. package/build-module/form/edit.mjs +0 -170
  477. package/build-module/form/edit.mjs.map +0 -7
  478. package/build-module/form/icons.mjs +0 -8
  479. package/build-module/form/icons.mjs.map +0 -7
  480. package/build-module/form/index.mjs +0 -83
  481. package/build-module/form/index.mjs.map +0 -7
  482. package/build-module/form/init.mjs +0 -7
  483. package/build-module/form/init.mjs.map +0 -7
  484. package/build-module/form/save.mjs +0 -19
  485. package/build-module/form/save.mjs.map +0 -7
  486. package/build-module/form/utils.mjs +0 -35
  487. package/build-module/form/utils.mjs.map +0 -7
  488. package/build-module/form/variations.mjs +0 -134
  489. package/build-module/form/variations.mjs.map +0 -7
  490. package/build-module/form/view.mjs +0 -46
  491. package/build-module/form/view.mjs.map +0 -7
  492. package/build-module/form-input/block.json +0 -72
  493. package/build-module/form-input/deprecated.mjs +0 -226
  494. package/build-module/form-input/deprecated.mjs.map +0 -7
  495. package/build-module/form-input/edit.mjs +0 -186
  496. package/build-module/form-input/edit.mjs.map +0 -7
  497. package/build-module/form-input/icons.mjs +0 -8
  498. package/build-module/form-input/icons.mjs.map +0 -7
  499. package/build-module/form-input/index.mjs +0 -25
  500. package/build-module/form-input/index.mjs.map +0 -7
  501. package/build-module/form-input/init.mjs +0 -7
  502. package/build-module/form-input/init.mjs.map +0 -7
  503. package/build-module/form-input/save.mjs +0 -62
  504. package/build-module/form-input/save.mjs.map +0 -7
  505. package/build-module/form-input/variations.mjs +0 -84
  506. package/build-module/form-input/variations.mjs.map +0 -7
  507. package/build-module/form-submission-notification/block.json +0 -19
  508. package/build-module/form-submission-notification/edit.mjs +0 -45
  509. package/build-module/form-submission-notification/edit.mjs.map +0 -7
  510. package/build-module/form-submission-notification/index.mjs +0 -35
  511. package/build-module/form-submission-notification/index.mjs.map +0 -7
  512. package/build-module/form-submission-notification/init.mjs +0 -7
  513. package/build-module/form-submission-notification/init.mjs.map +0 -7
  514. package/build-module/form-submission-notification/save.mjs +0 -23
  515. package/build-module/form-submission-notification/save.mjs.map +0 -7
  516. package/build-module/form-submission-notification/variations.mjs +0 -57
  517. package/build-module/form-submission-notification/variations.mjs.map +0 -7
  518. package/build-module/form-submit-button/block.json +0 -15
  519. package/build-module/form-submit-button/edit.mjs +0 -15
  520. package/build-module/form-submit-button/edit.mjs.map +0 -7
  521. package/build-module/form-submit-button/index.mjs +0 -37
  522. package/build-module/form-submit-button/index.mjs.map +0 -7
  523. package/build-module/form-submit-button/init.mjs +0 -7
  524. package/build-module/form-submit-button/init.mjs.map +0 -7
  525. package/build-module/form-submit-button/save.mjs +0 -11
  526. package/build-module/form-submit-button/save.mjs.map +0 -7
  527. package/build-module/list-item/hooks/use-indent-list-item.mjs +0 -58
  528. package/build-module/list-item/hooks/use-indent-list-item.mjs.map +0 -7
  529. package/build-module/list-item/hooks/use-outdent-list-item.mjs +0 -85
  530. package/build-module/list-item/hooks/use-outdent-list-item.mjs.map +0 -7
  531. package/build-module/list-item/hooks/use-space.mjs +0 -52
  532. package/build-module/list-item/hooks/use-space.mjs.map +0 -7
  533. package/build-module/query/edit/enhanced-pagination-modal.mjs +0 -72
  534. package/build-module/query/edit/enhanced-pagination-modal.mjs.map +0 -7
  535. package/build-style/form-input/editor-rtl.css +0 -19
  536. package/build-style/form-input/editor.css +0 -19
  537. package/build-style/form-input/style-rtl.css +0 -48
  538. package/build-style/form-input/style.css +0 -48
  539. package/build-style/form-submission-notification/editor-rtl.css +0 -30
  540. package/build-style/form-submission-notification/editor.css +0 -30
  541. package/build-style/form-submit-button/style-rtl.css +0 -3
  542. package/build-style/form-submit-button/style.css +0 -3
  543. package/src/form/README.md +0 -90
  544. package/src/form/block.json +0 -65
  545. package/src/form/deprecated.jsx +0 -93
  546. package/src/form/edit.jsx +0 -169
  547. package/src/form/icons.jsx +0 -7
  548. package/src/form/index.js +0 -91
  549. package/src/form/index.php +0 -197
  550. package/src/form/init.js +0 -3
  551. package/src/form/save.jsx +0 -15
  552. package/src/form/utils.js +0 -36
  553. package/src/form/variations.js +0 -133
  554. package/src/form/view.js +0 -54
  555. package/src/form-input/README.md +0 -74
  556. package/src/form-input/block.json +0 -72
  557. package/src/form-input/deprecated.jsx +0 -248
  558. package/src/form-input/edit.jsx +0 -187
  559. package/src/form-input/editor.scss +0 -24
  560. package/src/form-input/icons.jsx +0 -7
  561. package/src/form-input/index.js +0 -22
  562. package/src/form-input/index.php +0 -47
  563. package/src/form-input/init.js +0 -3
  564. package/src/form-input/save.jsx +0 -89
  565. package/src/form-input/style.scss +0 -64
  566. package/src/form-input/variations.js +0 -82
  567. package/src/form-submission-notification/README.md +0 -50
  568. package/src/form-submission-notification/block.json +0 -19
  569. package/src/form-submission-notification/edit.jsx +0 -44
  570. package/src/form-submission-notification/editor.scss +0 -45
  571. package/src/form-submission-notification/index.js +0 -33
  572. package/src/form-submission-notification/index.php +0 -48
  573. package/src/form-submission-notification/init.js +0 -3
  574. package/src/form-submission-notification/save.jsx +0 -18
  575. package/src/form-submission-notification/variations.js +0 -56
  576. package/src/form-submit-button/README.md +0 -54
  577. package/src/form-submit-button/block.json +0 -15
  578. package/src/form-submit-button/edit.jsx +0 -12
  579. package/src/form-submit-button/index.js +0 -35
  580. package/src/form-submit-button/init.js +0 -3
  581. package/src/form-submit-button/save.jsx +0 -10
  582. package/src/form-submit-button/style.scss +0 -3
  583. package/src/list-item/hooks/use-indent-list-item.js +0 -73
  584. package/src/list-item/hooks/use-outdent-list-item.js +0 -100
  585. package/src/list-item/hooks/use-space.js +0 -66
  586. package/src/query/edit/enhanced-pagination-modal.jsx +0 -77
  587. /package/src/utils/test/{waveform-player.jsx → waveform-player.jsdom.test.jsx} +0 -0
  588. /package/src/utils/test/{waveform-utils.js → waveform-utils.jsdom.test.js} +0 -0
@@ -1,29 +1,31 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
1
2
  import { act, renderHook } from '@testing-library/react';
2
3
  import { useRegistry, useSelect } from '@wordpress/data';
3
4
  import {
4
5
  getImageBlockMetadataFromAttachment,
6
+ getNewAttachmentImageBlockAttributes,
5
7
  getSyncedImageBlockAttributes,
6
8
  useOpenImageMediaEditorModal,
7
9
  } from '../use-open-image-media-editor-modal';
8
10
 
9
11
  const mockOpenMediaEditorModalKey = 'openMediaEditorModal';
10
12
 
11
- jest.mock( '@wordpress/core-data', () => ( {
13
+ vi.mock( import( '@wordpress/core-data' ), () => ( {
12
14
  store: {},
13
15
  } ) );
14
16
 
15
- jest.mock( '@wordpress/data', () => ( {
16
- useRegistry: jest.fn(),
17
- useSelect: jest.fn(),
17
+ vi.mock( import( '@wordpress/data' ), () => ( {
18
+ useRegistry: vi.fn(),
19
+ useSelect: vi.fn(),
18
20
  } ) );
19
21
 
20
- jest.mock( '@wordpress/block-editor', () => ( {
22
+ vi.mock( import( '@wordpress/block-editor' ), () => ( {
21
23
  privateApis: {},
22
24
  store: {},
23
25
  } ) );
24
26
 
25
- jest.mock( '../../lock-unlock', () => ( {
26
- unlock: jest.fn( () => ( {
27
+ vi.mock( import( '../../lock-unlock' ), () => ( {
28
+ unlock: vi.fn( () => ( {
27
29
  openMediaEditorModalKey: 'openMediaEditorModal',
28
30
  } ) ),
29
31
  } ) );
@@ -33,14 +35,14 @@ function createRegistry( {
33
35
  resolveGetEntityRecord = () => undefined,
34
36
  } = {} ) {
35
37
  const actions = {
36
- invalidateResolution: jest.fn(),
38
+ invalidateResolution: vi.fn(),
37
39
  };
38
40
  return {
39
- select: jest.fn( () => ( {
41
+ select: vi.fn( () => ( {
40
42
  getEditedEntityRecord,
41
43
  } ) ),
42
- dispatch: jest.fn( () => actions ),
43
- resolveSelect: jest.fn( () => ( {
44
+ dispatch: vi.fn( () => actions ),
45
+ resolveSelect: vi.fn( () => ( {
44
46
  getEntityRecord: resolveGetEntityRecord,
45
47
  } ) ),
46
48
  actions,
@@ -73,8 +75,8 @@ async function runModalUpdate( {
73
75
  } ) {
74
76
  const registry = createRegistry( registryOptions );
75
77
  useRegistry.mockReturnValue( registry );
76
- const setAttributes = jest.fn();
77
- const openMediaEditorModal = jest.fn();
78
+ const setAttributes = vi.fn();
79
+ const openMediaEditorModal = vi.fn();
78
80
  mockMediaEditorModalSetting( openMediaEditorModal );
79
81
  const { result } = renderHook( () =>
80
82
  useOpenImageMediaEditorModal( {
@@ -94,13 +96,67 @@ async function runModalUpdate( {
94
96
  return { setAttributes, registry, openMediaEditorModal };
95
97
  }
96
98
 
99
+ // The attachment as it was before the edit. Its metadata matches the blocks
100
+ // used below, so the metadata sync never contributes attributes and the
101
+ // assertions stay about the ones derived from the edited attachment.
102
+ const ORIGINAL_ATTACHMENT = {
103
+ id: 1,
104
+ alt_text: '',
105
+ caption: { raw: '' },
106
+ };
107
+
108
+ // Editing media saves to a new attachment, with its own sub-sizes, file and
109
+ // attachment page.
110
+ const CROPPED_ATTACHMENT = {
111
+ id: 2,
112
+ alt_text: '',
113
+ caption: { raw: '' },
114
+ source_url: 'cropped.jpg',
115
+ link: 'https://example.com/cropped/',
116
+ media_details: {
117
+ sizes: {
118
+ medium: { source_url: 'cropped-300x200.jpg' },
119
+ full: { source_url: 'cropped.jpg' },
120
+ },
121
+ },
122
+ };
123
+
124
+ // What the media editor reports after a crop, rotate or flip: it saved to a
125
+ // new attachment, and reports that attachment's full-size file.
126
+ const CROP_UPDATE = {
127
+ id: CROPPED_ATTACHMENT.id,
128
+ url: CROPPED_ATTACHMENT.source_url,
129
+ };
130
+
131
+ /**
132
+ * Registry options for an edit that saved to a new attachment: the pre-edit
133
+ * record is cached, and the edited one is only reachable by resolving it.
134
+ *
135
+ * @param {Object} options Options.
136
+ * @param {boolean} options.hasOriginal Whether the pre-edit attachment is
137
+ * known at all; without it there is no
138
+ * metadata baseline.
139
+ */
140
+ function croppedAttachmentRecords( { hasOriginal = true } = {} ) {
141
+ return {
142
+ getEditedEntityRecord: ( kind, name, attachmentId ) =>
143
+ hasOriginal && attachmentId === ORIGINAL_ATTACHMENT.id
144
+ ? ORIGINAL_ATTACHMENT
145
+ : undefined,
146
+ resolveGetEntityRecord: ( kind, name, attachmentId ) =>
147
+ attachmentId === CROPPED_ATTACHMENT.id
148
+ ? CROPPED_ATTACHMENT
149
+ : undefined,
150
+ };
151
+ }
152
+
97
153
  describe( 'useOpenImageMediaEditorModal', () => {
98
154
  beforeEach( () => {
99
- jest.clearAllMocks();
155
+ vi.clearAllMocks();
100
156
  } );
101
157
 
102
158
  it( 'notifies onUrlChange when the update switches to a new attachment URL', async () => {
103
- const onUrlChange = jest.fn();
159
+ const onUrlChange = vi.fn();
104
160
  await runModalUpdate( {
105
161
  attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
106
162
  updatePayload: { id: 2, url: 'updated.jpg' },
@@ -111,7 +167,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
111
167
  } );
112
168
 
113
169
  it( 'does not notify onUrlChange for a same-attachment update', async () => {
114
- const onUrlChange = jest.fn();
170
+ const onUrlChange = vi.fn();
115
171
  await runModalUpdate( {
116
172
  attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
117
173
  updatePayload: { id: 1, url: 'original.jpg' },
@@ -121,7 +177,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
121
177
  } );
122
178
 
123
179
  it( 'does not notify onUrlChange when the update carries no URL', async () => {
124
- const onUrlChange = jest.fn();
180
+ const onUrlChange = vi.fn();
125
181
  await runModalUpdate( {
126
182
  attributes: { id: 1, url: 'original.jpg', alt: '', caption: '' },
127
183
  updatePayload: { id: 2 },
@@ -142,7 +198,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
142
198
  alt: '',
143
199
  caption: '',
144
200
  },
145
- setAttributes: jest.fn(),
201
+ setAttributes: vi.fn(),
146
202
  } )
147
203
  );
148
204
 
@@ -155,8 +211,8 @@ describe( 'useOpenImageMediaEditorModal', () => {
155
211
  document.body.append( cropButton, otherButton );
156
212
  const registry = createRegistry();
157
213
  useRegistry.mockReturnValue( registry );
158
- const setAttributes = jest.fn();
159
- const openMediaEditorModal = jest.fn();
214
+ const setAttributes = vi.fn();
215
+ const openMediaEditorModal = vi.fn();
160
216
  mockMediaEditorModalSetting( openMediaEditorModal );
161
217
  const onClose = () => cropButton.focus();
162
218
  const { result } = renderHook( () =>
@@ -239,7 +295,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
239
295
  alt_text: 'Updated alt',
240
296
  caption: { raw: 'Updated caption' },
241
297
  };
242
- const resolveGetEntityRecord = jest
298
+ const resolveGetEntityRecord = vi
243
299
  .fn()
244
300
  .mockResolvedValueOnce( originalAttachment )
245
301
  .mockResolvedValueOnce( updatedAttachment );
@@ -281,7 +337,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
281
337
  alt_text: '',
282
338
  caption: { raw: 'Updated attachment caption' },
283
339
  };
284
- const resolveGetEntityRecord = jest
340
+ const resolveGetEntityRecord = vi
285
341
  .fn()
286
342
  .mockResolvedValueOnce( originalAttachment )
287
343
  .mockResolvedValueOnce( updatedAttachment );
@@ -322,7 +378,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
322
378
  alt_text: '',
323
379
  caption: { raw: 'Updated attachment caption' },
324
380
  };
325
- const resolveGetEntityRecord = jest
381
+ const resolveGetEntityRecord = vi
326
382
  .fn()
327
383
  .mockResolvedValueOnce( originalAttachment )
328
384
  .mockResolvedValueOnce( updatedAttachment );
@@ -392,6 +448,121 @@ describe( 'useOpenImageMediaEditorModal', () => {
392
448
  } );
393
449
  } );
394
450
 
451
+ it( 'keeps the selected image size when the edit created a new attachment', async () => {
452
+ const onUrlChange = vi.fn();
453
+ const { setAttributes } = await runModalUpdate( {
454
+ attributes: {
455
+ id: 1,
456
+ url: 'original-300x200.jpg',
457
+ alt: '',
458
+ caption: '',
459
+ sizeSlug: 'medium',
460
+ },
461
+ registryOptions: croppedAttachmentRecords(),
462
+ updatePayload: CROP_UPDATE,
463
+ hookOptions: { onUrlChange },
464
+ } );
465
+
466
+ // Everything lands in one update, so the block never renders against
467
+ // half-updated settings.
468
+ expect( setAttributes ).toHaveBeenCalledTimes( 1 );
469
+ expect( setAttributes ).toHaveBeenCalledWith( {
470
+ id: 2,
471
+ url: 'cropped-300x200.jpg',
472
+ } );
473
+ // The loading state settles against the file the block will render,
474
+ // not the full-size file the media editor reported.
475
+ expect( onUrlChange ).toHaveBeenLastCalledWith( 'cropped-300x200.jpg' );
476
+ } );
477
+
478
+ it( 'falls back to the saved record when the refetch fails', async () => {
479
+ const { setAttributes } = await runModalUpdate( {
480
+ attributes: {
481
+ id: 1,
482
+ url: 'original-300x200.jpg',
483
+ alt: '',
484
+ caption: '',
485
+ sizeSlug: 'medium',
486
+ href: 'original.jpg',
487
+ linkDestination: 'media',
488
+ },
489
+ registryOptions: {
490
+ // The media editor put the saved record in the store, so it
491
+ // is cached even though refetching it fails.
492
+ getEditedEntityRecord: ( kind, name, attachmentId ) =>
493
+ attachmentId === ORIGINAL_ATTACHMENT.id
494
+ ? ORIGINAL_ATTACHMENT
495
+ : CROPPED_ATTACHMENT,
496
+ resolveGetEntityRecord: ( kind, name, attachmentId ) => {
497
+ if ( attachmentId === CROPPED_ATTACHMENT.id ) {
498
+ throw new Error( 'Network error' );
499
+ }
500
+ return undefined;
501
+ },
502
+ },
503
+ updatePayload: CROP_UPDATE,
504
+ } );
505
+
506
+ // The size and link still follow the edited image, rather than the
507
+ // block half-updating to the new file at its old settings.
508
+ expect( setAttributes ).toHaveBeenCalledTimes( 1 );
509
+ expect( setAttributes ).toHaveBeenCalledWith( {
510
+ id: 2,
511
+ url: 'cropped-300x200.jpg',
512
+ href: 'cropped.jpg',
513
+ } );
514
+ } );
515
+
516
+ it( 'derives the size of the edited image without a metadata baseline', async () => {
517
+ const { setAttributes, registry } = await runModalUpdate( {
518
+ // Custom metadata leaves the block with no fallback baseline, and
519
+ // the original attachment is unknown, so no metadata is synced.
520
+ attributes: {
521
+ id: 1,
522
+ url: 'original-300x200.jpg',
523
+ alt: 'Custom alt',
524
+ caption: 'Custom caption',
525
+ sizeSlug: 'medium',
526
+ },
527
+ registryOptions: croppedAttachmentRecords( { hasOriginal: false } ),
528
+ updatePayload: CROP_UPDATE,
529
+ } );
530
+
531
+ expect( setAttributes ).toHaveBeenCalledTimes( 1 );
532
+ expect( setAttributes ).toHaveBeenCalledWith( {
533
+ id: 2,
534
+ url: 'cropped-300x200.jpg',
535
+ } );
536
+ // The size is derived from a freshly resolved record for the edited
537
+ // attachment, not a stale cached one.
538
+ expect( registry.actions.invalidateResolution ).toHaveBeenCalledWith(
539
+ 'getEntityRecord',
540
+ [ 'postType', 'attachment', 2 ]
541
+ );
542
+ } );
543
+
544
+ it( 'points a media file link at the edited image', async () => {
545
+ const { setAttributes } = await runModalUpdate( {
546
+ attributes: {
547
+ id: 1,
548
+ url: 'original.jpg',
549
+ alt: '',
550
+ caption: '',
551
+ href: 'original.jpg',
552
+ linkDestination: 'media',
553
+ },
554
+ registryOptions: croppedAttachmentRecords(),
555
+ updatePayload: CROP_UPDATE,
556
+ } );
557
+
558
+ expect( setAttributes ).toHaveBeenCalledTimes( 1 );
559
+ expect( setAttributes ).toHaveBeenCalledWith( {
560
+ id: 2,
561
+ url: 'cropped.jpg',
562
+ href: 'cropped.jpg',
563
+ } );
564
+ } );
565
+
395
566
  it( 'updates back to the previous attachment from the original modal callback', async () => {
396
567
  const originalAttachment = {
397
568
  id: 1,
@@ -411,8 +582,8 @@ describe( 'useOpenImageMediaEditorModal', () => {
411
582
  attachmentId === 2 ? deferredAttachment.promise : undefined,
412
583
  } );
413
584
  useRegistry.mockReturnValue( registry );
414
- const setAttributes = jest.fn();
415
- const openMediaEditorModal = jest.fn();
585
+ const setAttributes = vi.fn();
586
+ const openMediaEditorModal = vi.fn();
416
587
  mockMediaEditorModalSetting( openMediaEditorModal );
417
588
  const { result } = renderHook(
418
589
  ( { attributes } ) =>
@@ -523,7 +694,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
523
694
  } );
524
695
 
525
696
  it( 'syncs metadata from an empty block when the original attachment is not cached', async () => {
526
- const resolveGetEntityRecord = jest
697
+ const resolveGetEntityRecord = vi
527
698
  .fn()
528
699
  .mockResolvedValueOnce( {
529
700
  id: 1,
@@ -645,8 +816,8 @@ describe( 'useOpenImageMediaEditorModal', () => {
645
816
  resolveGetEntityRecord: () => deferredAttachment.promise,
646
817
  } );
647
818
  useRegistry.mockReturnValue( registry );
648
- const setAttributes = jest.fn();
649
- const openMediaEditorModal = jest.fn();
819
+ const setAttributes = vi.fn();
820
+ const openMediaEditorModal = vi.fn();
650
821
  mockMediaEditorModalSetting( openMediaEditorModal );
651
822
  const { result, rerender } = renderHook(
652
823
  ( { attributes } ) =>
@@ -924,3 +1095,147 @@ describe( 'getSyncedImageBlockAttributes', () => {
924
1095
  ).toEqual( {} );
925
1096
  } );
926
1097
  } );
1098
+
1099
+ describe( 'getNewAttachmentImageBlockAttributes', () => {
1100
+ const croppedAttachment = {
1101
+ id: 2,
1102
+ source_url: 'cropped.jpg',
1103
+ link: 'https://example.com/cropped/',
1104
+ media_details: {
1105
+ sizes: {
1106
+ medium: { source_url: 'cropped-300x200.jpg' },
1107
+ full: { source_url: 'cropped.jpg' },
1108
+ },
1109
+ },
1110
+ };
1111
+
1112
+ it( 'points the URL at the selected size on the new attachment', () => {
1113
+ expect(
1114
+ getNewAttachmentImageBlockAttributes(
1115
+ { sizeSlug: 'medium' },
1116
+ croppedAttachment
1117
+ )
1118
+ ).toEqual( { url: 'cropped-300x200.jpg' } );
1119
+ } );
1120
+
1121
+ it( 'falls back to full when the new attachment lacks the selected size', () => {
1122
+ expect(
1123
+ getNewAttachmentImageBlockAttributes(
1124
+ { sizeSlug: 'large' },
1125
+ croppedAttachment
1126
+ )
1127
+ ).toEqual( { url: 'cropped.jpg', sizeSlug: 'full' } );
1128
+ } );
1129
+
1130
+ it( 'falls back to full when the edited image is too small for any sub-size', () => {
1131
+ // Cropping below the smallest registered size leaves
1132
+ // `media_details.sizes` empty, so the block has to fall back to the
1133
+ // file itself and stop reporting a size it no longer has.
1134
+ expect(
1135
+ getNewAttachmentImageBlockAttributes(
1136
+ { sizeSlug: 'medium' },
1137
+ {
1138
+ id: 2,
1139
+ source_url: 'cropped-103x45.jpg',
1140
+ media_details: { width: 103, height: 45, sizes: {} },
1141
+ }
1142
+ )
1143
+ ).toEqual( {
1144
+ url: 'cropped-103x45.jpg',
1145
+ sizeSlug: 'full',
1146
+ } );
1147
+ } );
1148
+
1149
+ it( 'makes no change when no full-size URL is available', () => {
1150
+ expect(
1151
+ getNewAttachmentImageBlockAttributes(
1152
+ { sizeSlug: 'large' },
1153
+ { id: 2, media_details: { sizes: { medium: {} } } }
1154
+ )
1155
+ ).toEqual( {} );
1156
+ } );
1157
+
1158
+ it( 'makes no change for the full size or an unset size', () => {
1159
+ expect(
1160
+ getNewAttachmentImageBlockAttributes(
1161
+ { sizeSlug: 'full' },
1162
+ croppedAttachment
1163
+ )
1164
+ ).toEqual( {} );
1165
+ expect(
1166
+ getNewAttachmentImageBlockAttributes( {}, croppedAttachment )
1167
+ ).toEqual( {} );
1168
+ } );
1169
+
1170
+ it( 'makes no change when the attachment sizes are unknown', () => {
1171
+ expect(
1172
+ getNewAttachmentImageBlockAttributes(
1173
+ { sizeSlug: 'medium' },
1174
+ { id: 2 }
1175
+ )
1176
+ ).toEqual( {} );
1177
+ } );
1178
+
1179
+ it( 'makes no change when the attachment record is unknown', () => {
1180
+ expect(
1181
+ getNewAttachmentImageBlockAttributes(
1182
+ { sizeSlug: 'medium' },
1183
+ undefined
1184
+ )
1185
+ ).toBeUndefined();
1186
+ } );
1187
+
1188
+ it( 'points a media file link at the new attachment file', () => {
1189
+ expect(
1190
+ getNewAttachmentImageBlockAttributes(
1191
+ { sizeSlug: 'medium', linkDestination: 'media' },
1192
+ croppedAttachment
1193
+ )
1194
+ ).toEqual( {
1195
+ url: 'cropped-300x200.jpg',
1196
+ href: 'cropped.jpg',
1197
+ } );
1198
+ } );
1199
+
1200
+ it( 'points an attachment page link at the new attachment page', () => {
1201
+ expect(
1202
+ getNewAttachmentImageBlockAttributes(
1203
+ { linkDestination: 'attachment' },
1204
+ croppedAttachment
1205
+ )
1206
+ ).toEqual( { href: 'https://example.com/cropped/' } );
1207
+ } );
1208
+
1209
+ it( 'leaves custom and absent links alone', () => {
1210
+ expect(
1211
+ getNewAttachmentImageBlockAttributes(
1212
+ { linkDestination: 'custom' },
1213
+ croppedAttachment
1214
+ )
1215
+ ).toEqual( {} );
1216
+ expect(
1217
+ getNewAttachmentImageBlockAttributes(
1218
+ { linkDestination: 'none' },
1219
+ croppedAttachment
1220
+ )
1221
+ ).toEqual( {} );
1222
+ expect(
1223
+ getNewAttachmentImageBlockAttributes( {}, croppedAttachment )
1224
+ ).toEqual( {} );
1225
+ } );
1226
+
1227
+ it( 'keeps the existing link when the new attachment record lacks it', () => {
1228
+ expect(
1229
+ getNewAttachmentImageBlockAttributes(
1230
+ { linkDestination: 'media' },
1231
+ { id: 2 }
1232
+ )
1233
+ ).toEqual( {} );
1234
+ expect(
1235
+ getNewAttachmentImageBlockAttributes(
1236
+ { linkDestination: 'attachment' },
1237
+ { id: 2 }
1238
+ )
1239
+ ).toEqual( {} );
1240
+ } );
1241
+ } );