@wordpress/block-library 10.1.1-next.v.202607070741.0 → 10.2.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 (371) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/build/accordion/block.json +1 -0
  3. package/build/button/edit.cjs +18 -8
  4. package/build/button/edit.cjs.map +2 -2
  5. package/build/cover/block.json +11 -0
  6. package/build/cover/edit/block-controls.cjs +11 -4
  7. package/build/cover/edit/block-controls.cjs.map +2 -2
  8. package/build/cover/edit/embed-video-url-input.cjs +5 -3
  9. package/build/cover/edit/embed-video-url-input.cjs.map +3 -3
  10. package/build/cover/edit/index.cjs +1 -1
  11. package/build/cover/edit/index.cjs.map +2 -2
  12. package/build/cover/embed-video-utils.cjs +17 -7
  13. package/build/cover/embed-video-utils.cjs.map +2 -2
  14. package/build/details/transforms.cjs +1 -3
  15. package/build/details/transforms.cjs.map +2 -2
  16. package/build/embed/embed-placeholder.cjs +0 -1
  17. package/build/embed/embed-placeholder.cjs.map +2 -2
  18. package/build/file/edit.cjs +4 -3
  19. package/build/file/edit.cjs.map +2 -2
  20. package/build/file/transforms.cjs +25 -60
  21. package/build/file/transforms.cjs.map +2 -2
  22. package/build/gallery/block.json +4 -2
  23. package/build/gallery/edit.cjs +1 -1
  24. package/build/gallery/edit.cjs.map +3 -3
  25. package/build/gallery/gap-styles.cjs +49 -13
  26. package/build/gallery/gap-styles.cjs.map +3 -3
  27. package/build/group/transforms.cjs +1 -1
  28. package/build/group/transforms.cjs.map +2 -2
  29. package/build/icon/components/custom-inserter/icon-grid.cjs +25 -12
  30. package/build/icon/components/custom-inserter/icon-grid.cjs.map +2 -2
  31. package/build/icon/components/custom-inserter/index.cjs +100 -31
  32. package/build/icon/components/custom-inserter/index.cjs.map +3 -3
  33. package/build/icon/edit.cjs +11 -12
  34. package/build/icon/edit.cjs.map +2 -2
  35. package/build/image/block.json +1 -1
  36. package/build/image/edit.cjs +0 -34
  37. package/build/image/edit.cjs.map +2 -2
  38. package/build/image/image.cjs +4 -23
  39. package/build/image/image.cjs.map +3 -3
  40. package/build/image/transforms.cjs +78 -0
  41. package/build/image/transforms.cjs.map +3 -3
  42. package/build/index.cjs +18 -8
  43. package/build/index.cjs.map +2 -2
  44. package/build/latest-posts/edit.cjs +5 -8
  45. package/build/latest-posts/edit.cjs.map +2 -2
  46. package/build/list-item/edit.cjs +1 -1
  47. package/build/list-item/edit.cjs.map +2 -2
  48. package/build/list-item/hooks/use-enter.cjs +14 -17
  49. package/build/list-item/hooks/use-enter.cjs.map +3 -3
  50. package/build/list-item/hooks/use-space.cjs +3 -2
  51. package/build/list-item/hooks/use-space.cjs.map +3 -3
  52. package/build/paragraph/block.json +1 -0
  53. package/build/paragraph/use-enter.cjs +3 -7
  54. package/build/paragraph/use-enter.cjs.map +3 -3
  55. package/build/playlist/block.json +29 -10
  56. package/build/playlist/edit.cjs +216 -14
  57. package/build/playlist/edit.cjs.map +3 -3
  58. package/build/playlist/index.cjs +1 -1
  59. package/build/playlist/index.cjs.map +2 -2
  60. package/build/playlist/utils.cjs +19 -5
  61. package/build/playlist/utils.cjs.map +2 -2
  62. package/build/playlist/view.cjs +83 -13
  63. package/build/playlist/view.cjs.map +2 -2
  64. package/build/playlist-track/block.json +4 -2
  65. package/build/playlist-track/edit.cjs +94 -64
  66. package/build/playlist-track/edit.cjs.map +2 -2
  67. package/build/post-content/block.json +1 -0
  68. package/build/post-template/block.json +2 -1
  69. package/build/post-template/edit.cjs +10 -1
  70. package/build/post-template/edit.cjs.map +2 -2
  71. package/build/pullquote/block.json +3 -1
  72. package/build/query/block.json +3 -2
  73. package/build/query/edit/inspector-controls/index.cjs +38 -4
  74. package/build/query/edit/inspector-controls/index.cjs.map +2 -2
  75. package/build/query/edit/inspector-controls/offset-controls.cjs +0 -1
  76. package/build/query/edit/inspector-controls/offset-controls.cjs.map +2 -2
  77. package/build/query/edit/inspector-controls/pages-control.cjs +0 -1
  78. package/build/query/edit/inspector-controls/pages-control.cjs.map +2 -2
  79. package/build/query/edit/query-content.cjs +10 -3
  80. package/build/query/edit/query-content.cjs.map +2 -2
  81. package/build/query/index.cjs +2 -1
  82. package/build/query/index.cjs.map +2 -2
  83. package/build/quote/block.json +3 -1
  84. package/build/quote/transforms.cjs +1 -3
  85. package/build/quote/transforms.cjs.map +2 -2
  86. package/build/rss/edit.cjs +0 -1
  87. package/build/rss/edit.cjs.map +2 -2
  88. package/build/tab-list/block.json +2 -2
  89. package/build/tab-list/edit.cjs +65 -11
  90. package/build/tab-list/edit.cjs.map +3 -3
  91. package/build/tab-panel/block.json +1 -6
  92. package/build/tab-panel/edit.cjs +15 -15
  93. package/build/tab-panel/edit.cjs.map +2 -2
  94. package/build/tab-panels/block.json +0 -1
  95. package/build/tabs/block.json +0 -5
  96. package/build/tabs/edit.cjs +4 -39
  97. package/build/tabs/edit.cjs.map +3 -3
  98. package/build/tabs/use-tab-list-items-sync.cjs +19 -1
  99. package/build/tabs/use-tab-list-items-sync.cjs.map +2 -2
  100. package/build/term-name/block.json +1 -3
  101. package/build/term-name/deprecated.cjs +105 -0
  102. package/build/term-name/deprecated.cjs.map +7 -0
  103. package/build/term-name/edit.cjs +11 -37
  104. package/build/term-name/edit.cjs.map +3 -3
  105. package/build/term-name/index.cjs +3 -1
  106. package/build/term-name/index.cjs.map +3 -3
  107. package/build/utils/waveform-player.cjs +138 -22
  108. package/build/utils/waveform-player.cjs.map +2 -2
  109. package/build/utils/waveform-utils.cjs +315 -17
  110. package/build/utils/waveform-utils.cjs.map +2 -2
  111. package/build/video/edit.cjs +2 -11
  112. package/build/video/edit.cjs.map +3 -3
  113. package/build-module/accordion/block.json +1 -0
  114. package/build-module/button/edit.mjs +19 -14
  115. package/build-module/button/edit.mjs.map +2 -2
  116. package/build-module/cover/block.json +11 -0
  117. package/build-module/cover/edit/block-controls.mjs +11 -4
  118. package/build-module/cover/edit/block-controls.mjs.map +2 -2
  119. package/build-module/cover/edit/embed-video-url-input.mjs +5 -4
  120. package/build-module/cover/edit/embed-video-url-input.mjs.map +2 -2
  121. package/build-module/cover/edit/index.mjs +1 -1
  122. package/build-module/cover/edit/index.mjs.map +2 -2
  123. package/build-module/cover/embed-video-utils.mjs +16 -7
  124. package/build-module/cover/embed-video-utils.mjs.map +2 -2
  125. package/build-module/details/transforms.mjs +2 -7
  126. package/build-module/details/transforms.mjs.map +2 -2
  127. package/build-module/embed/embed-placeholder.mjs +0 -1
  128. package/build-module/embed/embed-placeholder.mjs.map +2 -2
  129. package/build-module/file/edit.mjs +4 -3
  130. package/build-module/file/edit.mjs.map +2 -2
  131. package/build-module/file/transforms.mjs +25 -60
  132. package/build-module/file/transforms.mjs.map +2 -2
  133. package/build-module/gallery/block.json +4 -2
  134. package/build-module/gallery/edit.mjs +3 -3
  135. package/build-module/gallery/edit.mjs.map +2 -2
  136. package/build-module/gallery/gap-styles.mjs +53 -14
  137. package/build-module/gallery/gap-styles.mjs.map +2 -2
  138. package/build-module/group/transforms.mjs +2 -5
  139. package/build-module/group/transforms.mjs.map +2 -2
  140. package/build-module/icon/components/custom-inserter/icon-grid.mjs +25 -12
  141. package/build-module/icon/components/custom-inserter/icon-grid.mjs.map +2 -2
  142. package/build-module/icon/components/custom-inserter/index.mjs +102 -33
  143. package/build-module/icon/components/custom-inserter/index.mjs.map +2 -2
  144. package/build-module/icon/edit.mjs +11 -12
  145. package/build-module/icon/edit.mjs.map +2 -2
  146. package/build-module/image/block.json +1 -1
  147. package/build-module/image/edit.mjs +0 -34
  148. package/build-module/image/edit.mjs.map +2 -2
  149. package/build-module/image/image.mjs +4 -13
  150. package/build-module/image/image.mjs.map +2 -2
  151. package/build-module/image/transforms.mjs +78 -0
  152. package/build-module/image/transforms.mjs.map +2 -2
  153. package/build-module/index.mjs +18 -8
  154. package/build-module/index.mjs.map +2 -2
  155. package/build-module/latest-posts/edit.mjs +5 -8
  156. package/build-module/latest-posts/edit.mjs.map +2 -2
  157. package/build-module/list-item/edit.mjs +1 -1
  158. package/build-module/list-item/edit.mjs.map +2 -2
  159. package/build-module/list-item/hooks/use-enter.mjs +15 -21
  160. package/build-module/list-item/hooks/use-enter.mjs.map +2 -2
  161. package/build-module/list-item/hooks/use-space.mjs +4 -6
  162. package/build-module/list-item/hooks/use-space.mjs.map +2 -2
  163. package/build-module/paragraph/block.json +1 -0
  164. package/build-module/paragraph/use-enter.mjs +4 -11
  165. package/build-module/paragraph/use-enter.mjs.map +2 -2
  166. package/build-module/playlist/block.json +29 -10
  167. package/build-module/playlist/edit.mjs +220 -16
  168. package/build-module/playlist/edit.mjs.map +2 -2
  169. package/build-module/playlist/index.mjs +1 -1
  170. package/build-module/playlist/index.mjs.map +2 -2
  171. package/build-module/playlist/utils.mjs +17 -4
  172. package/build-module/playlist/utils.mjs.map +2 -2
  173. package/build-module/playlist/view.mjs +89 -14
  174. package/build-module/playlist/view.mjs.map +2 -2
  175. package/build-module/playlist-track/block.json +4 -2
  176. package/build-module/playlist-track/edit.mjs +96 -65
  177. package/build-module/playlist-track/edit.mjs.map +2 -2
  178. package/build-module/post-content/block.json +1 -0
  179. package/build-module/post-template/block.json +2 -1
  180. package/build-module/post-template/edit.mjs +10 -1
  181. package/build-module/post-template/edit.mjs.map +2 -2
  182. package/build-module/pullquote/block.json +3 -1
  183. package/build-module/query/block.json +3 -2
  184. package/build-module/query/edit/inspector-controls/index.mjs +40 -5
  185. package/build-module/query/edit/inspector-controls/index.mjs.map +2 -2
  186. package/build-module/query/edit/inspector-controls/offset-controls.mjs +0 -1
  187. package/build-module/query/edit/inspector-controls/offset-controls.mjs.map +2 -2
  188. package/build-module/query/edit/inspector-controls/pages-control.mjs +0 -1
  189. package/build-module/query/edit/inspector-controls/pages-control.mjs.map +2 -2
  190. package/build-module/query/edit/query-content.mjs +10 -3
  191. package/build-module/query/edit/query-content.mjs.map +2 -2
  192. package/build-module/query/index.mjs +2 -1
  193. package/build-module/query/index.mjs.map +2 -2
  194. package/build-module/quote/block.json +3 -1
  195. package/build-module/quote/transforms.mjs +2 -4
  196. package/build-module/quote/transforms.mjs.map +2 -2
  197. package/build-module/rss/edit.mjs +0 -1
  198. package/build-module/rss/edit.mjs.map +2 -2
  199. package/build-module/tab-list/block.json +2 -2
  200. package/build-module/tab-list/edit.mjs +72 -13
  201. package/build-module/tab-list/edit.mjs.map +2 -2
  202. package/build-module/tab-panel/block.json +1 -6
  203. package/build-module/tab-panel/edit.mjs +16 -16
  204. package/build-module/tab-panel/edit.mjs.map +2 -2
  205. package/build-module/tab-panels/block.json +0 -1
  206. package/build-module/tabs/block.json +0 -5
  207. package/build-module/tabs/edit.mjs +5 -45
  208. package/build-module/tabs/edit.mjs.map +2 -2
  209. package/build-module/tabs/use-tab-list-items-sync.mjs +19 -1
  210. package/build-module/tabs/use-tab-list-items-sync.mjs.map +2 -2
  211. package/build-module/term-name/block.json +1 -3
  212. package/build-module/term-name/deprecated.mjs +74 -0
  213. package/build-module/term-name/deprecated.mjs.map +7 -0
  214. package/build-module/term-name/edit.mjs +11 -28
  215. package/build-module/term-name/edit.mjs.map +2 -2
  216. package/build-module/term-name/index.mjs +3 -1
  217. package/build-module/term-name/index.mjs.map +2 -2
  218. package/build-module/utils/waveform-player.mjs +144 -23
  219. package/build-module/utils/waveform-player.mjs.map +2 -2
  220. package/build-module/utils/waveform-utils.mjs +310 -16
  221. package/build-module/utils/waveform-utils.mjs.map +2 -2
  222. package/build-module/video/edit.mjs +2 -11
  223. package/build-module/video/edit.mjs.map +2 -2
  224. package/build-style/editor-rtl.css +46 -21
  225. package/build-style/editor.css +46 -21
  226. package/build-style/icon/editor-rtl.css +80 -7
  227. package/build-style/icon/editor.css +80 -7
  228. package/build-style/more/editor-rtl.css +2 -2
  229. package/build-style/more/editor.css +2 -2
  230. package/build-style/navigation/editor-rtl.css +3 -4
  231. package/build-style/navigation/editor.css +3 -4
  232. package/build-style/navigation-link/editor-rtl.css +1 -1
  233. package/build-style/navigation-link/editor.css +1 -1
  234. package/build-style/nextpage/editor-rtl.css +2 -2
  235. package/build-style/nextpage/editor.css +2 -2
  236. package/build-style/playlist/editor-rtl.css +6 -0
  237. package/build-style/playlist/editor.css +6 -0
  238. package/build-style/playlist/style-rtl.css +37 -1
  239. package/build-style/playlist/style.css +37 -1
  240. package/build-style/playlist-track/style-rtl.css +10 -0
  241. package/build-style/playlist-track/style.css +10 -0
  242. package/build-style/style-rtl.css +47 -1
  243. package/build-style/style.css +47 -1
  244. package/build-style/video/editor-rtl.css +1 -1
  245. package/build-style/video/editor.css +1 -1
  246. package/build-types/table-of-contents/list.d.ts +1 -1
  247. package/build-types/table-of-contents/list.d.ts.map +1 -1
  248. package/package.json +46 -44
  249. package/src/accordion/README.md +1 -0
  250. package/src/accordion/block.json +1 -0
  251. package/src/button/edit.js +21 -15
  252. package/src/cover/README.md +60 -0
  253. package/src/cover/block.json +11 -0
  254. package/src/cover/edit/block-controls.js +21 -11
  255. package/src/cover/edit/embed-video-url-input.js +5 -4
  256. package/src/cover/edit/index.js +9 -11
  257. package/src/cover/embed-video-utils.js +38 -13
  258. package/src/details/transforms.js +2 -7
  259. package/src/embed/embed-placeholder.js +0 -1
  260. package/src/file/edit.js +8 -8
  261. package/src/file/transforms.js +28 -60
  262. package/src/gallery/README.md +1 -1
  263. package/src/gallery/block.json +4 -2
  264. package/src/gallery/edit.js +3 -3
  265. package/src/gallery/gap-styles.js +79 -20
  266. package/src/gallery/index.php +103 -43
  267. package/src/group/transforms.js +2 -5
  268. package/src/icon/components/custom-inserter/icon-grid.js +40 -11
  269. package/src/icon/components/custom-inserter/index.js +98 -25
  270. package/src/icon/edit.js +11 -17
  271. package/src/icon/editor.scss +33 -8
  272. package/src/image/README.md +1 -1
  273. package/src/image/block.json +1 -1
  274. package/src/image/edit.js +0 -52
  275. package/src/image/editor.scss +2 -0
  276. package/src/image/image.js +19 -24
  277. package/src/image/transforms.js +128 -0
  278. package/src/index.js +19 -7
  279. package/src/latest-posts/edit.js +5 -8
  280. package/src/latest-posts/index.php +46 -16
  281. package/src/list-item/edit.js +1 -1
  282. package/src/list-item/hooks/use-enter.js +15 -22
  283. package/src/list-item/hooks/use-space.js +4 -6
  284. package/src/media-text/editor.scss +1 -0
  285. package/src/more/editor.scss +1 -1
  286. package/src/navigation/editor.scss +1 -2
  287. package/src/navigation-link/editor.scss +1 -1
  288. package/src/navigation-link/index.php +6 -3
  289. package/src/navigation-submenu/index.php +6 -3
  290. package/src/nextpage/editor.scss +1 -1
  291. package/src/paragraph/README.md +1 -0
  292. package/src/paragraph/block.json +1 -0
  293. package/src/paragraph/use-enter.js +4 -11
  294. package/src/playlist/README.md +17 -18
  295. package/src/playlist/block.json +29 -10
  296. package/src/playlist/edit.js +247 -15
  297. package/src/playlist/editor.scss +6 -0
  298. package/src/playlist/index.js +1 -1
  299. package/src/playlist/index.php +58 -14
  300. package/src/playlist/style.scss +51 -1
  301. package/src/playlist/test/edit.js +13 -2
  302. package/src/playlist/utils.js +25 -7
  303. package/src/playlist/view.js +97 -16
  304. package/src/playlist-track/README.md +3 -3
  305. package/src/playlist-track/block.json +4 -2
  306. package/src/playlist-track/edit.js +94 -70
  307. package/src/playlist-track/index.php +20 -6
  308. package/src/playlist-track/style.scss +10 -0
  309. package/src/playlist-track/test/edit.js +169 -0
  310. package/src/post-content/README.md +1 -0
  311. package/src/post-content/block.json +1 -0
  312. package/src/post-template/README.md +1 -0
  313. package/src/post-template/block.json +2 -1
  314. package/src/post-template/edit.js +9 -0
  315. package/src/pullquote/README.md +1 -0
  316. package/src/pullquote/block.json +3 -1
  317. package/src/query/README.md +2 -1
  318. package/src/query/block.json +3 -2
  319. package/src/query/edit/inspector-controls/index.js +43 -3
  320. package/src/query/edit/inspector-controls/offset-controls.js +0 -1
  321. package/src/query/edit/inspector-controls/pages-control.js +0 -1
  322. package/src/query/edit/query-content.js +19 -3
  323. package/src/query/index.js +1 -0
  324. package/src/quote/README.md +1 -0
  325. package/src/quote/block.json +3 -1
  326. package/src/quote/transforms.js +2 -4
  327. package/src/rss/edit.js +0 -1
  328. package/src/rss/index.php +1 -1
  329. package/src/tab-list/README.md +4 -5
  330. package/src/tab-list/block.json +2 -2
  331. package/src/tab-list/edit.js +90 -28
  332. package/src/tab-list/index.php +9 -4
  333. package/src/tab-panel/README.md +4 -6
  334. package/src/tab-panel/block.json +1 -6
  335. package/src/tab-panel/edit.js +19 -24
  336. package/src/tab-panels/README.md +5 -3
  337. package/src/tab-panels/block.json +0 -1
  338. package/src/tabs/README.md +18 -9
  339. package/src/tabs/block.json +0 -5
  340. package/src/tabs/edit.js +7 -64
  341. package/src/tabs/use-tab-list-items-sync.js +24 -4
  342. package/src/template-part/index.php +1 -16
  343. package/src/term-name/README.md +1 -1
  344. package/src/term-name/block.json +1 -3
  345. package/src/term-name/deprecated.js +74 -0
  346. package/src/term-name/edit.js +2 -18
  347. package/src/term-name/index.js +2 -0
  348. package/src/utils/media-control.scss +1 -5
  349. package/src/utils/test/waveform-player.js +297 -34
  350. package/src/utils/test/waveform-utils.js +410 -5
  351. package/src/utils/waveform-player.js +189 -59
  352. package/src/utils/waveform-utils.js +443 -40
  353. package/src/video/edit.js +0 -8
  354. package/src/video/editor.scss +1 -1
  355. package/build/image/animated-gif-convert-control.cjs +0 -105
  356. package/build/image/animated-gif-convert-control.cjs.map +0 -7
  357. package/build/utils/gif-conversion-attributes.cjs +0 -40
  358. package/build/utils/gif-conversion-attributes.cjs.map +0 -7
  359. package/build/video/gif-restore-control.cjs +0 -73
  360. package/build/video/gif-restore-control.cjs.map +0 -7
  361. package/build-module/image/animated-gif-convert-control.mjs +0 -87
  362. package/build-module/image/animated-gif-convert-control.mjs.map +0 -7
  363. package/build-module/utils/gif-conversion-attributes.mjs +0 -15
  364. package/build-module/utils/gif-conversion-attributes.mjs.map +0 -7
  365. package/build-module/video/gif-restore-control.mjs +0 -55
  366. package/build-module/video/gif-restore-control.mjs.map +0 -7
  367. package/src/image/animated-gif-convert-control.js +0 -135
  368. package/src/image/test/animated-gif-convert-control.js +0 -276
  369. package/src/utils/gif-conversion-attributes.js +0 -30
  370. package/src/utils/test/gif-conversion-attributes.js +0 -60
  371. package/src/video/gif-restore-control.js +0 -92
@@ -1,276 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { render, screen } from '@testing-library/react';
5
- import userEvent from '@testing-library/user-event';
6
-
7
- /**
8
- * WordPress dependencies
9
- */
10
- import { useSelect, useDispatch } from '@wordpress/data';
11
-
12
- /**
13
- * Internal dependencies
14
- */
15
- import AnimatedGifConvertControl from '../animated-gif-convert-control';
16
-
17
- jest.mock( '@wordpress/block-editor', () => ( {
18
- store: 'core/block-editor',
19
- BlockControls: ( { children } ) => <div>{ children }</div>,
20
- } ) );
21
-
22
- jest.mock( '@wordpress/core-data', () => ( {
23
- store: 'core',
24
- } ) );
25
-
26
- jest.mock( '@wordpress/data', () => ( {
27
- useSelect: jest.fn(),
28
- useDispatch: jest.fn(),
29
- /*
30
- * Passthroughs needed because @wordpress/components transitively pulls in
31
- * the rich-text store, which registers via these helpers at import time.
32
- */
33
- combineReducers: jest.fn( ( reducers ) => ( state = {}, action ) => {
34
- const newState = {};
35
- Object.keys( reducers ).forEach( ( key ) => {
36
- newState[ key ] = reducers[ key ]( state[ key ], action );
37
- } );
38
- return newState;
39
- } ),
40
- createSelector: jest.fn( ( fn ) => fn ),
41
- createRegistrySelector: jest.fn( ( fn ) => fn ),
42
- createReduxStore: jest.fn( () => ( {} ) ),
43
- register: jest.fn(),
44
- } ) );
45
-
46
- /*
47
- * core/video is not registered in this unit test, so stub createBlock with a
48
- * lightweight factory that preserves the name and attributes for assertion.
49
- */
50
- jest.mock( '@wordpress/blocks', () => ( {
51
- createBlock: jest.fn( ( name, attributes ) => ( {
52
- name,
53
- attributes,
54
- clientId: 'new-video-block',
55
- } ) ),
56
- } ) );
57
-
58
- /**
59
- * Builds a `select` function that returns the given store mocks and records
60
- * whether the attachment record was requested.
61
- *
62
- * @param {Object} options Options.
63
- * @param {string} [options.rootBlockName] Block name of the block's root (e.g. 'core/gallery').
64
- * @param {Function} options.getEntityRecord Spy used for getEntityRecord.
65
- * @return {Function} A select() implementation.
66
- */
67
- function makeSelect( { rootBlockName = undefined, getEntityRecord } ) {
68
- return ( storeName ) => {
69
- if ( storeName === 'core/block-editor' ) {
70
- return {
71
- getBlockRootClientId: () =>
72
- rootBlockName ? 'root-client-id' : undefined,
73
- getBlockName: () => rootBlockName,
74
- };
75
- }
76
- // core-data store.
77
- return {
78
- getEntityRecord: ( ...args ) => getEntityRecord( ...args ),
79
- };
80
- };
81
- }
82
-
83
- describe( 'AnimatedGifConvertControl', () => {
84
- let replaceBlocks;
85
- let getEntityRecord;
86
-
87
- const companionRecord = {
88
- source_url: 'https://example.com/wp-content/uploads/cat.gif',
89
- media_details: {
90
- animated_video: 'cat.mp4',
91
- animated_video_poster: 'cat.jpg',
92
- width: 320,
93
- height: 240,
94
- },
95
- };
96
-
97
- beforeEach( () => {
98
- jest.clearAllMocks();
99
- replaceBlocks = jest.fn();
100
- getEntityRecord = jest.fn( () => companionRecord );
101
- useDispatch.mockReturnValue( { replaceBlocks } );
102
- } );
103
-
104
- /*
105
- * Renders the control, running the real selector against a controlled
106
- * `select` so the gating logic (and any attachment fetch) is exercised.
107
- */
108
- function renderControl( { attributes, select } ) {
109
- useSelect.mockImplementation( ( mapSelect ) => mapSelect( select ) );
110
- return render(
111
- <AnimatedGifConvertControl
112
- attributes={ attributes }
113
- clientId="block-1"
114
- />
115
- );
116
- }
117
-
118
- it( 'renders the "Display as video" button when a video companion exists', () => {
119
- renderControl( {
120
- attributes: {
121
- id: 7,
122
- url: 'https://example.com/wp-content/uploads/cat.gif',
123
- },
124
- select: makeSelect( { getEntityRecord } ),
125
- } );
126
-
127
- expect(
128
- screen.getByRole( 'button', { name: 'Display as video' } )
129
- ).toBeVisible();
130
- expect( getEntityRecord ).toHaveBeenCalledWith(
131
- 'postType',
132
- 'attachment',
133
- 7,
134
- { context: 'view' }
135
- );
136
- } );
137
-
138
- it( 'still recognizes a GIF URL that carries a query string', () => {
139
- renderControl( {
140
- attributes: {
141
- id: 7,
142
- url: 'https://example.com/wp-content/uploads/cat.gif?ver=2',
143
- },
144
- select: makeSelect( { getEntityRecord } ),
145
- } );
146
-
147
- expect( getEntityRecord ).toHaveBeenCalledWith(
148
- 'postType',
149
- 'attachment',
150
- 7,
151
- { context: 'view' }
152
- );
153
- expect(
154
- screen.getByRole( 'button', { name: 'Display as video' } )
155
- ).toBeVisible();
156
- } );
157
-
158
- it( 'does not fetch the attachment for a non-GIF image', () => {
159
- const { container } = renderControl( {
160
- attributes: {
161
- id: 7,
162
- url: 'https://example.com/wp-content/uploads/cat.jpg',
163
- },
164
- select: makeSelect( { getEntityRecord } ),
165
- } );
166
-
167
- expect( getEntityRecord ).not.toHaveBeenCalled();
168
- expect( container ).toBeEmptyDOMElement();
169
- } );
170
-
171
- it( 'does not fetch the attachment when the block has no id', () => {
172
- const { container } = renderControl( {
173
- attributes: {
174
- url: 'https://example.com/wp-content/uploads/cat.gif',
175
- },
176
- select: makeSelect( { getEntityRecord } ),
177
- } );
178
-
179
- expect( getEntityRecord ).not.toHaveBeenCalled();
180
- expect( container ).toBeEmptyDOMElement();
181
- } );
182
-
183
- it( 'hides the control inside a gallery without fetching', () => {
184
- const { container } = renderControl( {
185
- attributes: {
186
- id: 7,
187
- url: 'https://example.com/wp-content/uploads/cat.gif',
188
- },
189
- select: makeSelect( {
190
- rootBlockName: 'core/gallery',
191
- getEntityRecord,
192
- } ),
193
- } );
194
-
195
- expect( getEntityRecord ).not.toHaveBeenCalled();
196
- expect( container ).toBeEmptyDOMElement();
197
- } );
198
-
199
- it( 'renders nothing when the attachment has no animated_video companion', () => {
200
- const { container } = renderControl( {
201
- attributes: {
202
- id: 7,
203
- url: 'https://example.com/wp-content/uploads/cat.gif',
204
- },
205
- select: makeSelect( {
206
- getEntityRecord: jest.fn( () => ( {
207
- source_url: 'https://example.com/x/cat.gif',
208
- media_details: {},
209
- } ) ),
210
- } ),
211
- } );
212
-
213
- expect( container ).toBeEmptyDOMElement();
214
- } );
215
-
216
- it( 'replaces the image with a GIF-style video block built from the companion', async () => {
217
- const user = userEvent.setup();
218
- renderControl( {
219
- attributes: {
220
- id: 7,
221
- url: 'https://example.com/wp-content/uploads/cat.gif',
222
- caption: 'A cat',
223
- },
224
- select: makeSelect( { getEntityRecord } ),
225
- } );
226
-
227
- await user.click(
228
- screen.getByRole( 'button', { name: 'Display as video' } )
229
- );
230
-
231
- expect( replaceBlocks ).toHaveBeenCalledTimes( 1 );
232
- const [ replacedClientId, newBlock ] = replaceBlocks.mock.calls[ 0 ];
233
- expect( replacedClientId ).toBe( 'block-1' );
234
- expect( newBlock.name ).toBe( 'core/video' );
235
- expect( newBlock.attributes ).toMatchObject( {
236
- id: 7,
237
- src: 'https://example.com/wp-content/uploads/cat.mp4',
238
- poster: 'https://example.com/wp-content/uploads/cat.jpg',
239
- caption: 'A cat',
240
- controls: false,
241
- loop: true,
242
- autoplay: true,
243
- muted: true,
244
- playsInline: true,
245
- width: 320,
246
- height: 240,
247
- } );
248
- } );
249
-
250
- it( 'carries align, anchor, className and margin onto the video block', async () => {
251
- const user = userEvent.setup();
252
- renderControl( {
253
- attributes: {
254
- id: 7,
255
- url: 'https://example.com/wp-content/uploads/cat.gif',
256
- align: 'wide',
257
- anchor: 'cat-gif',
258
- className: 'is-style-rounded',
259
- style: { spacing: { margin: { top: '20px' } } },
260
- },
261
- select: makeSelect( { getEntityRecord } ),
262
- } );
263
-
264
- await user.click(
265
- screen.getByRole( 'button', { name: 'Display as video' } )
266
- );
267
-
268
- const [ , newBlock ] = replaceBlocks.mock.calls[ 0 ];
269
- expect( newBlock.attributes ).toMatchObject( {
270
- align: 'wide',
271
- anchor: 'cat-gif',
272
- className: 'is-style-rounded',
273
- style: { spacing: { margin: { top: '20px' } } },
274
- } );
275
- } );
276
- } );
@@ -1,30 +0,0 @@
1
- /**
2
- * Returns the subset of block attributes that should be carried over when
3
- * converting between the animated-GIF Image block and its converted Video
4
- * block (in either direction).
5
- *
6
- * The conversion swaps one block for another via `createBlock`, which would
7
- * otherwise drop everything the author set on the original block. This carries
8
- * the attributes both blocks support, so the conversion (and its reverse) keeps
9
- * them: block alignment, the HTML anchor, custom class names, and margin
10
- * spacing.
11
- *
12
- * Image-only attributes such as links (`href`/`linkDestination`), sizing
13
- * (`sizeSlug`/`scale`), and `border`/`shadow` styles are intentionally not
14
- * carried: the Video block has no equivalent, so copying them would leave
15
- * attributes the target block cannot represent.
16
- *
17
- * @param {Object} attributes Source block attributes.
18
- * @return {Object} Attributes to spread into the converted block.
19
- */
20
- export function getCarriedGifConversionAttributes( attributes ) {
21
- const { align, anchor, className, style } = attributes;
22
- const margin = style?.spacing?.margin;
23
-
24
- return {
25
- ...( align && { align } ),
26
- ...( anchor && { anchor } ),
27
- ...( className && { className } ),
28
- ...( margin && { style: { spacing: { margin } } } ),
29
- };
30
- }
@@ -1,60 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import { getCarriedGifConversionAttributes } from '../gif-conversion-attributes';
5
-
6
- describe( 'getCarriedGifConversionAttributes', () => {
7
- it( 'carries align, anchor, className and margin spacing', () => {
8
- const result = getCarriedGifConversionAttributes( {
9
- align: 'wide',
10
- anchor: 'my-gif',
11
- className: 'is-style-rounded',
12
- style: { spacing: { margin: { top: '10px', bottom: '10px' } } },
13
- } );
14
-
15
- expect( result ).toEqual( {
16
- align: 'wide',
17
- anchor: 'my-gif',
18
- className: 'is-style-rounded',
19
- style: { spacing: { margin: { top: '10px', bottom: '10px' } } },
20
- } );
21
- } );
22
-
23
- it( 'omits attributes that are not set', () => {
24
- expect( getCarriedGifConversionAttributes( {} ) ).toEqual( {} );
25
- expect(
26
- getCarriedGifConversionAttributes( { align: 'full' } )
27
- ).toEqual( { align: 'full' } );
28
- } );
29
-
30
- it( 'carries only margin from style, dropping unsupported styles', () => {
31
- const result = getCarriedGifConversionAttributes( {
32
- style: {
33
- spacing: {
34
- margin: { top: '5px' },
35
- padding: { top: '5px' },
36
- },
37
- border: { radius: '8px' },
38
- shadow: 'var:preset|shadow|natural',
39
- },
40
- } );
41
-
42
- // Only spacing.margin survives; padding/border/shadow are not carried
43
- // because the converted block may not support them.
44
- expect( result ).toEqual( {
45
- style: { spacing: { margin: { top: '5px' } } },
46
- } );
47
- } );
48
-
49
- it( 'does not carry image-only attributes such as links or sizing', () => {
50
- const result = getCarriedGifConversionAttributes( {
51
- align: 'center',
52
- href: 'https://example.com',
53
- linkDestination: 'custom',
54
- sizeSlug: 'large',
55
- scale: 'cover',
56
- } );
57
-
58
- expect( result ).toEqual( { align: 'center' } );
59
- } );
60
- } );
@@ -1,92 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
5
- import {
6
- BlockControls,
7
- store as blockEditorStore,
8
- } from '@wordpress/block-editor';
9
- import { store as coreStore } from '@wordpress/core-data';
10
- import { createBlock } from '@wordpress/blocks';
11
- import { useDispatch, useSelect } from '@wordpress/data';
12
- import { image as imageIcon } from '@wordpress/icons';
13
- import { __ } from '@wordpress/i18n';
14
-
15
- /**
16
- * Internal dependencies
17
- */
18
- import { getCarriedGifConversionAttributes } from '../utils/gif-conversion-attributes';
19
-
20
- /**
21
- * Toolbar control that turns a converted GIF video block back into the original
22
- * animated GIF Image block.
23
- *
24
- * An animated GIF uploaded through the editor is converted to a muted, looping
25
- * video and presented as the Video block's "GIF" variation, while the original
26
- * GIF stays the underlying image attachment. This control switches the block
27
- * back to a `core/image` pointing at that GIF and opts the image out of being
28
- * re-converted.
29
- *
30
- * It only renders when the block's media is an image attachment (i.e. an
31
- * editor-converted GIF), so it never appears on regular videos that happen to
32
- * be muted and looping.
33
- *
34
- * @param {Object} props Component props.
35
- * @param {Object} props.attributes Video block attributes.
36
- * @param {string} props.clientId Block client ID.
37
- *
38
- * @return {Component|null} The control, or null when restoring does not apply.
39
- */
40
- export default function GifRestoreControl( { attributes, clientId } ) {
41
- const { id, caption } = attributes;
42
- const { replaceBlocks } = useDispatch( blockEditorStore );
43
-
44
- // The original GIF is the underlying image attachment. Only offer the
45
- // restore when the media resolves to an image (an editor-converted GIF),
46
- // not when a regular video has simply been set to loop/autoplay/mute.
47
- const gif = useSelect(
48
- ( select ) => {
49
- if ( ! id ) {
50
- return null;
51
- }
52
- const record = select( coreStore ).getEntityRecord(
53
- 'postType',
54
- 'attachment',
55
- id,
56
- { context: 'view' }
57
- );
58
- if ( ! record?.mime_type?.startsWith( 'image/' ) ) {
59
- return null;
60
- }
61
- return record;
62
- },
63
- [ id ]
64
- );
65
-
66
- if ( ! gif?.source_url ) {
67
- return null;
68
- }
69
-
70
- function restoreToImage() {
71
- replaceBlocks(
72
- clientId,
73
- createBlock( 'core/image', {
74
- ...getCarriedGifConversionAttributes( attributes ),
75
- id,
76
- url: gif.source_url,
77
- alt: gif.alt_text || '',
78
- caption,
79
- } )
80
- );
81
- }
82
-
83
- return (
84
- <BlockControls group="other">
85
- <ToolbarGroup>
86
- <ToolbarButton icon={ imageIcon } onClick={ restoreToImage }>
87
- { __( 'Display as GIF' ) }
88
- </ToolbarButton>
89
- </ToolbarGroup>
90
- </BlockControls>
91
- );
92
- }