@wordpress/block-library 8.24.1 → 8.25.1-next.79a6196f.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 (509) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE.md +1 -1
  3. package/build/audio/edit.js +15 -62
  4. package/build/audio/edit.js.map +1 -1
  5. package/build/audio/edit.native.js +1 -1
  6. package/build/audio/edit.native.js.map +1 -1
  7. package/build/audio/index.js +2 -2
  8. package/build/block/edit.js +157 -19
  9. package/build/block/edit.js.map +1 -1
  10. package/build/block/index.js +3 -2
  11. package/build/block/index.js.map +1 -1
  12. package/build/block/v1/edit.js +116 -0
  13. package/build/block/v1/edit.js.map +1 -0
  14. package/build/block/{edit.native.js → v1/edit.native.js} +2 -2
  15. package/build/block/v1/edit.native.js.map +1 -0
  16. package/build/button/index.js +2 -2
  17. package/build/button/save.js +1 -1
  18. package/build/button/save.js.map +1 -1
  19. package/build/code/edit.native.js +13 -14
  20. package/build/code/edit.native.js.map +1 -1
  21. package/build/code/index.js +2 -2
  22. package/build/code/save.js +6 -2
  23. package/build/code/save.js.map +1 -1
  24. package/build/comments-title/deprecated.js +1 -1
  25. package/build/comments-title/index.js +1 -1
  26. package/build/cover/edit/inspector-controls.js +1 -1
  27. package/build/cover/edit/inspector-controls.js.map +1 -1
  28. package/build/cover/edit.native.js +1 -0
  29. package/build/cover/edit.native.js.map +1 -1
  30. package/build/details/index.js +2 -2
  31. package/build/embed/deprecated.js +2 -2
  32. package/build/embed/embed-preview.native.js +1 -1
  33. package/build/embed/embed-preview.native.js.map +1 -1
  34. package/build/embed/icons.js +1 -1
  35. package/build/embed/icons.js.map +1 -1
  36. package/build/embed/index.js +2 -2
  37. package/build/embed/transforms.js +2 -2
  38. package/build/embed/util.js +6 -6
  39. package/build/embed/util.js.map +1 -1
  40. package/build/file/edit.js +20 -28
  41. package/build/file/edit.js.map +1 -1
  42. package/build/file/edit.native.js +1 -1
  43. package/build/file/edit.native.js.map +1 -1
  44. package/build/file/index.js +4 -4
  45. package/build/file/save.js +4 -1
  46. package/build/file/save.js.map +1 -1
  47. package/build/form-input/deprecated.js +147 -0
  48. package/build/form-input/deprecated.js.map +1 -0
  49. package/build/form-input/edit.js +1 -1
  50. package/build/form-input/edit.js.map +1 -1
  51. package/build/form-input/index.js +4 -2
  52. package/build/form-input/index.js.map +1 -1
  53. package/build/form-input/save.js +7 -9
  54. package/build/form-input/save.js.map +1 -1
  55. package/build/gallery/edit.js +38 -58
  56. package/build/gallery/edit.js.map +1 -1
  57. package/build/gallery/gallery.js +19 -24
  58. package/build/gallery/gallery.js.map +1 -1
  59. package/build/gallery/gallery.native.js +1 -1
  60. package/build/gallery/gallery.native.js.map +1 -1
  61. package/build/gallery/index.js +8 -4
  62. package/build/gallery/index.js.map +1 -1
  63. package/build/gallery/transforms.js +4 -68
  64. package/build/gallery/transforms.js.map +1 -1
  65. package/build/gallery/v1/gallery.native.js +1 -1
  66. package/build/gallery/v1/gallery.native.js.map +1 -1
  67. package/build/group/edit.js +6 -1
  68. package/build/group/edit.js.map +1 -1
  69. package/build/group/index.js +5 -1
  70. package/build/group/index.js.map +1 -1
  71. package/build/heading/index.js +3 -6
  72. package/build/heading/index.js.map +1 -1
  73. package/build/image/deprecated.js +11 -0
  74. package/build/image/deprecated.js.map +1 -1
  75. package/build/image/edit.native.js +4 -1
  76. package/build/image/edit.native.js.map +1 -1
  77. package/build/image/image.js +35 -71
  78. package/build/image/image.js.map +1 -1
  79. package/build/image/index.js +2 -2
  80. package/build/image/save.js +3 -1
  81. package/build/image/save.js.map +1 -1
  82. package/build/image/view.js +7 -1
  83. package/build/image/view.js.map +1 -1
  84. package/build/list/edit.js +10 -15
  85. package/build/list/edit.js.map +1 -1
  86. package/build/list-item/edit.js +17 -2
  87. package/build/list-item/edit.js.map +1 -1
  88. package/build/list-item/hooks/use-enter.js +5 -3
  89. package/build/list-item/hooks/use-enter.js.map +1 -1
  90. package/build/list-item/hooks/use-enter.native.js +4 -3
  91. package/build/list-item/hooks/use-enter.native.js.map +1 -1
  92. package/build/list-item/hooks/use-indent-list-item.js +2 -3
  93. package/build/list-item/hooks/use-indent-list-item.js.map +1 -1
  94. package/build/list-item/hooks/use-merge.js +1 -1
  95. package/build/list-item/hooks/use-merge.js.map +1 -1
  96. package/build/list-item/hooks/use-outdent-list-item.js +3 -17
  97. package/build/list-item/hooks/use-outdent-list-item.js.map +1 -1
  98. package/build/list-item/hooks/use-space.js +8 -4
  99. package/build/list-item/hooks/use-space.js.map +1 -1
  100. package/build/list-item/index.js +10 -3
  101. package/build/list-item/index.js.map +1 -1
  102. package/build/media-text/media-container.native.js +3 -0
  103. package/build/media-text/media-container.native.js.map +1 -1
  104. package/build/navigation/constants.js +3 -1
  105. package/build/navigation/constants.js.map +1 -1
  106. package/build/navigation/edit/index.js +5 -1
  107. package/build/navigation/edit/index.js.map +1 -1
  108. package/build/navigation/view.js +25 -1
  109. package/build/navigation/view.js.map +1 -1
  110. package/build/page-list/convert-to-links-modal.js +2 -2
  111. package/build/page-list/convert-to-links-modal.js.map +1 -1
  112. package/build/paragraph/edit.js +54 -32
  113. package/build/paragraph/edit.js.map +1 -1
  114. package/build/paragraph/index.js +2 -4
  115. package/build/paragraph/index.js.map +1 -1
  116. package/build/paragraph/transforms.js +2 -4
  117. package/build/paragraph/transforms.js.map +1 -1
  118. package/build/pattern/edit.js +24 -2
  119. package/build/pattern/edit.js.map +1 -1
  120. package/build/pattern/recursion-detector.js +147 -0
  121. package/build/pattern/recursion-detector.js.map +1 -0
  122. package/build/post-featured-image/edit.js +19 -2
  123. package/build/post-featured-image/edit.js.map +1 -1
  124. package/build/post-featured-image/index.js +4 -0
  125. package/build/post-featured-image/index.js.map +1 -1
  126. package/build/post-title/index.js +1 -3
  127. package/build/post-title/index.js.map +1 -1
  128. package/build/preformatted/index.js +2 -3
  129. package/build/preformatted/index.js.map +1 -1
  130. package/build/pullquote/index.js +5 -7
  131. package/build/pullquote/index.js.map +1 -1
  132. package/build/query/edit/inspector-controls/index.js +3 -1
  133. package/build/query/edit/inspector-controls/index.js.map +1 -1
  134. package/build/query/edit/inspector-controls/taxonomy-controls.js +2 -0
  135. package/build/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  136. package/build/query-pagination-numbers/index.js +1 -1
  137. package/build/query-title/index.js +1 -3
  138. package/build/query-title/index.js.map +1 -1
  139. package/build/quote/index.js +3 -5
  140. package/build/quote/index.js.map +1 -1
  141. package/build/quote/transforms.js +7 -6
  142. package/build/quote/transforms.js.map +1 -1
  143. package/build/search/edit.js +3 -5
  144. package/build/search/edit.js.map +1 -1
  145. package/build/search/index.js +0 -4
  146. package/build/search/index.js.map +1 -1
  147. package/build/site-logo/edit.js +7 -6
  148. package/build/site-logo/edit.js.map +1 -1
  149. package/build/site-title/index.js +1 -5
  150. package/build/site-title/index.js.map +1 -1
  151. package/build/social-link/icons/gravatar.js +22 -0
  152. package/build/social-link/icons/gravatar.js.map +1 -0
  153. package/build/social-link/icons/index.js +11 -0
  154. package/build/social-link/icons/index.js.map +1 -1
  155. package/build/social-link/variations.js +7 -0
  156. package/build/social-link/variations.js.map +1 -1
  157. package/build/spacer/edit.native.js +2 -2
  158. package/build/spacer/edit.native.js.map +1 -1
  159. package/build/table/edit.js +3 -1
  160. package/build/table/edit.js.map +1 -1
  161. package/build/table/index.js +9 -10
  162. package/build/table/index.js.map +1 -1
  163. package/build/table-of-contents/edit.js +2 -2
  164. package/build/table-of-contents/edit.js.map +1 -1
  165. package/build/table-of-contents/index.js +5 -2
  166. package/build/table-of-contents/index.js.map +1 -1
  167. package/build/tag-cloud/edit.js +5 -9
  168. package/build/tag-cloud/edit.js.map +1 -1
  169. package/build/utils/caption.js +90 -0
  170. package/build/utils/caption.js.map +1 -0
  171. package/build/utils/constants.js +16 -0
  172. package/build/utils/constants.js.map +1 -0
  173. package/build/utils/remove-anchor-tag.js +2 -1
  174. package/build/utils/remove-anchor-tag.js.map +1 -1
  175. package/build/verse/index.js +3 -5
  176. package/build/verse/index.js.map +1 -1
  177. package/build/video/deprecated.js +2 -2
  178. package/build/video/edit.js +16 -57
  179. package/build/video/edit.js.map +1 -1
  180. package/build/video/edit.native.js +1 -1
  181. package/build/video/edit.native.js.map +1 -1
  182. package/build/video/index.js +2 -2
  183. package/build-module/audio/edit.js +19 -66
  184. package/build-module/audio/edit.js.map +1 -1
  185. package/build-module/audio/edit.native.js +2 -2
  186. package/build-module/audio/edit.native.js.map +1 -1
  187. package/build-module/audio/index.js +2 -2
  188. package/build-module/block/edit.js +160 -22
  189. package/build-module/block/edit.js.map +1 -1
  190. package/build-module/block/index.js +3 -2
  191. package/build-module/block/index.js.map +1 -1
  192. package/build-module/block/v1/edit.js +108 -0
  193. package/build-module/block/v1/edit.js.map +1 -0
  194. package/build-module/block/{edit.native.js → v1/edit.native.js} +2 -2
  195. package/build-module/block/v1/edit.native.js.map +1 -0
  196. package/build-module/button/index.js +2 -2
  197. package/build-module/button/save.js +1 -1
  198. package/build-module/button/save.js.map +1 -1
  199. package/build-module/code/edit.native.js +14 -16
  200. package/build-module/code/edit.native.js.map +1 -1
  201. package/build-module/code/index.js +2 -2
  202. package/build-module/code/save.js +6 -2
  203. package/build-module/code/save.js.map +1 -1
  204. package/build-module/comments-title/deprecated.js +1 -1
  205. package/build-module/comments-title/index.js +1 -1
  206. package/build-module/cover/edit/inspector-controls.js +1 -1
  207. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  208. package/build-module/cover/edit.native.js +1 -0
  209. package/build-module/cover/edit.native.js.map +1 -1
  210. package/build-module/details/index.js +2 -2
  211. package/build-module/embed/deprecated.js +2 -2
  212. package/build-module/embed/embed-preview.native.js +2 -2
  213. package/build-module/embed/embed-preview.native.js.map +1 -1
  214. package/build-module/embed/icons.js +1 -1
  215. package/build-module/embed/icons.js.map +1 -1
  216. package/build-module/embed/index.js +2 -2
  217. package/build-module/embed/transforms.js +2 -2
  218. package/build-module/embed/util.js +6 -6
  219. package/build-module/embed/util.js.map +1 -1
  220. package/build-module/file/edit.js +20 -28
  221. package/build-module/file/edit.js.map +1 -1
  222. package/build-module/file/edit.native.js +1 -1
  223. package/build-module/file/edit.native.js.map +1 -1
  224. package/build-module/file/index.js +4 -4
  225. package/build-module/file/save.js +4 -1
  226. package/build-module/file/save.js.map +1 -1
  227. package/build-module/form-input/deprecated.js +138 -0
  228. package/build-module/form-input/deprecated.js.map +1 -0
  229. package/build-module/form-input/edit.js +1 -1
  230. package/build-module/form-input/edit.js.map +1 -1
  231. package/build-module/form-input/index.js +4 -2
  232. package/build-module/form-input/index.js.map +1 -1
  233. package/build-module/form-input/save.js +8 -10
  234. package/build-module/form-input/save.js.map +1 -1
  235. package/build-module/gallery/edit.js +41 -61
  236. package/build-module/gallery/edit.js.map +1 -1
  237. package/build-module/gallery/gallery.js +18 -21
  238. package/build-module/gallery/gallery.js.map +1 -1
  239. package/build-module/gallery/gallery.native.js +2 -2
  240. package/build-module/gallery/gallery.native.js.map +1 -1
  241. package/build-module/gallery/index.js +8 -4
  242. package/build-module/gallery/index.js.map +1 -1
  243. package/build-module/gallery/transforms.js +4 -68
  244. package/build-module/gallery/transforms.js.map +1 -1
  245. package/build-module/gallery/v1/gallery.native.js +2 -2
  246. package/build-module/gallery/v1/gallery.native.js.map +1 -1
  247. package/build-module/group/edit.js +6 -1
  248. package/build-module/group/edit.js.map +1 -1
  249. package/build-module/group/index.js +5 -1
  250. package/build-module/group/index.js.map +1 -1
  251. package/build-module/heading/index.js +3 -6
  252. package/build-module/heading/index.js.map +1 -1
  253. package/build-module/image/deprecated.js +11 -0
  254. package/build-module/image/deprecated.js.map +1 -1
  255. package/build-module/image/edit.native.js +5 -2
  256. package/build-module/image/edit.native.js.map +1 -1
  257. package/build-module/image/image.js +35 -71
  258. package/build-module/image/image.js.map +1 -1
  259. package/build-module/image/index.js +2 -2
  260. package/build-module/image/save.js +3 -1
  261. package/build-module/image/save.js.map +1 -1
  262. package/build-module/image/view.js +7 -1
  263. package/build-module/image/view.js.map +1 -1
  264. package/build-module/list/edit.js +10 -15
  265. package/build-module/list/edit.js.map +1 -1
  266. package/build-module/list-item/edit.js +18 -3
  267. package/build-module/list-item/edit.js.map +1 -1
  268. package/build-module/list-item/hooks/use-enter.js +5 -3
  269. package/build-module/list-item/hooks/use-enter.js.map +1 -1
  270. package/build-module/list-item/hooks/use-enter.native.js +4 -3
  271. package/build-module/list-item/hooks/use-enter.native.js.map +1 -1
  272. package/build-module/list-item/hooks/use-indent-list-item.js +2 -3
  273. package/build-module/list-item/hooks/use-indent-list-item.js.map +1 -1
  274. package/build-module/list-item/hooks/use-merge.js +1 -1
  275. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  276. package/build-module/list-item/hooks/use-outdent-list-item.js +3 -17
  277. package/build-module/list-item/hooks/use-outdent-list-item.js.map +1 -1
  278. package/build-module/list-item/hooks/use-space.js +8 -4
  279. package/build-module/list-item/hooks/use-space.js.map +1 -1
  280. package/build-module/list-item/index.js +10 -3
  281. package/build-module/list-item/index.js.map +1 -1
  282. package/build-module/media-text/media-container.native.js +3 -0
  283. package/build-module/media-text/media-container.native.js.map +1 -1
  284. package/build-module/navigation/constants.js +1 -0
  285. package/build-module/navigation/constants.js.map +1 -1
  286. package/build-module/navigation/edit/index.js +7 -3
  287. package/build-module/navigation/edit/index.js.map +1 -1
  288. package/build-module/navigation/view.js +25 -1
  289. package/build-module/navigation/view.js.map +1 -1
  290. package/build-module/page-list/convert-to-links-modal.js +2 -2
  291. package/build-module/page-list/convert-to-links-modal.js.map +1 -1
  292. package/build-module/paragraph/edit.js +54 -32
  293. package/build-module/paragraph/edit.js.map +1 -1
  294. package/build-module/paragraph/index.js +2 -4
  295. package/build-module/paragraph/index.js.map +1 -1
  296. package/build-module/paragraph/transforms.js +2 -4
  297. package/build-module/paragraph/transforms.js.map +1 -1
  298. package/build-module/pattern/edit.js +26 -4
  299. package/build-module/pattern/edit.js.map +1 -1
  300. package/build-module/pattern/recursion-detector.js +139 -0
  301. package/build-module/pattern/recursion-detector.js.map +1 -0
  302. package/build-module/post-featured-image/edit.js +19 -2
  303. package/build-module/post-featured-image/edit.js.map +1 -1
  304. package/build-module/post-featured-image/index.js +4 -0
  305. package/build-module/post-featured-image/index.js.map +1 -1
  306. package/build-module/post-title/index.js +1 -3
  307. package/build-module/post-title/index.js.map +1 -1
  308. package/build-module/preformatted/index.js +2 -3
  309. package/build-module/preformatted/index.js.map +1 -1
  310. package/build-module/pullquote/index.js +5 -7
  311. package/build-module/pullquote/index.js.map +1 -1
  312. package/build-module/query/edit/inspector-controls/index.js +3 -1
  313. package/build-module/query/edit/inspector-controls/index.js.map +1 -1
  314. package/build-module/query/edit/inspector-controls/taxonomy-controls.js +2 -0
  315. package/build-module/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  316. package/build-module/query-pagination-numbers/index.js +1 -1
  317. package/build-module/query-title/index.js +1 -3
  318. package/build-module/query-title/index.js.map +1 -1
  319. package/build-module/quote/index.js +3 -5
  320. package/build-module/quote/index.js.map +1 -1
  321. package/build-module/quote/transforms.js +7 -6
  322. package/build-module/quote/transforms.js.map +1 -1
  323. package/build-module/search/edit.js +3 -5
  324. package/build-module/search/edit.js.map +1 -1
  325. package/build-module/search/index.js +0 -4
  326. package/build-module/search/index.js.map +1 -1
  327. package/build-module/site-logo/edit.js +7 -6
  328. package/build-module/site-logo/edit.js.map +1 -1
  329. package/build-module/site-title/index.js +1 -5
  330. package/build-module/site-title/index.js.map +1 -1
  331. package/build-module/social-link/icons/gravatar.js +14 -0
  332. package/build-module/social-link/icons/gravatar.js.map +1 -0
  333. package/build-module/social-link/icons/index.js +1 -0
  334. package/build-module/social-link/icons/index.js.map +1 -1
  335. package/build-module/social-link/variations.js +8 -1
  336. package/build-module/social-link/variations.js.map +1 -1
  337. package/build-module/spacer/edit.native.js +2 -2
  338. package/build-module/spacer/edit.native.js.map +1 -1
  339. package/build-module/table/edit.js +3 -1
  340. package/build-module/table/edit.js.map +1 -1
  341. package/build-module/table/index.js +9 -10
  342. package/build-module/table/index.js.map +1 -1
  343. package/build-module/table-of-contents/edit.js +1 -1
  344. package/build-module/table-of-contents/edit.js.map +1 -1
  345. package/build-module/table-of-contents/index.js +5 -1
  346. package/build-module/table-of-contents/index.js.map +1 -1
  347. package/build-module/tag-cloud/edit.js +6 -10
  348. package/build-module/tag-cloud/edit.js.map +1 -1
  349. package/build-module/utils/caption.js +82 -0
  350. package/build-module/utils/caption.js.map +1 -0
  351. package/build-module/utils/constants.js +9 -0
  352. package/build-module/utils/constants.js.map +1 -0
  353. package/build-module/utils/remove-anchor-tag.js +2 -1
  354. package/build-module/utils/remove-anchor-tag.js.map +1 -1
  355. package/build-module/verse/index.js +3 -5
  356. package/build-module/verse/index.js.map +1 -1
  357. package/build-module/video/deprecated.js +2 -2
  358. package/build-module/video/edit.js +21 -62
  359. package/build-module/video/edit.js.map +1 -1
  360. package/build-module/video/edit.native.js +2 -2
  361. package/build-module/video/edit.native.js.map +1 -1
  362. package/build-module/video/index.js +2 -2
  363. package/build-style/button/editor-rtl.css +0 -37
  364. package/build-style/button/editor.css +0 -37
  365. package/build-style/button/style-rtl.css +6 -6
  366. package/build-style/button/style.css +6 -6
  367. package/build-style/editor-rtl.css +3 -55
  368. package/build-style/editor.css +3 -55
  369. package/build-style/navigation/editor-rtl.css +2 -4
  370. package/build-style/navigation/editor.css +2 -4
  371. package/build-style/navigation/style-rtl.css +14 -18
  372. package/build-style/navigation/style.css +14 -18
  373. package/build-style/search/style-rtl.css +26 -27
  374. package/build-style/search/style.css +26 -27
  375. package/build-style/social-links/style-rtl.css +14 -2
  376. package/build-style/social-links/style.css +14 -2
  377. package/build-style/style-rtl.css +60 -53
  378. package/build-style/style.css +60 -53
  379. package/build-style/table/editor-rtl.css +1 -14
  380. package/build-style/table/editor.css +1 -14
  381. package/package.json +32 -32
  382. package/src/audio/block.json +2 -2
  383. package/src/audio/edit.js +29 -92
  384. package/src/audio/edit.native.js +2 -1
  385. package/src/audio/test/__snapshots__/edit.native.js.snap +12 -0
  386. package/src/audio/test/edit.native.js +29 -0
  387. package/src/block/edit.js +218 -37
  388. package/src/block/index.js +3 -2
  389. package/src/block/index.php +48 -0
  390. package/src/block/v1/edit.js +163 -0
  391. package/src/block/{edit.native.js → v1/edit.native.js} +2 -2
  392. package/src/button/block.json +2 -2
  393. package/src/button/editor.scss +0 -43
  394. package/src/button/save.js +1 -1
  395. package/src/button/style.scss +6 -6
  396. package/src/buttons/test/__snapshots__/edit.native.js.snap +6 -0
  397. package/src/buttons/test/edit.native.js +49 -0
  398. package/src/code/block.json +2 -2
  399. package/src/code/edit.native.js +11 -13
  400. package/src/code/save.js +4 -1
  401. package/src/code/test/edit.native.js +2 -2
  402. package/src/comments-title/block.json +1 -1
  403. package/src/cover/edit/inspector-controls.js +1 -1
  404. package/src/cover/edit.native.js +1 -0
  405. package/src/cover/test/edit.native.js +7 -1
  406. package/src/details/block.json +2 -2
  407. package/src/embed/block.json +2 -2
  408. package/src/embed/embed-preview.native.js +2 -1
  409. package/src/embed/icons.js +1 -1
  410. package/src/embed/util.js +2 -2
  411. package/src/file/block.json +4 -4
  412. package/src/file/edit.js +18 -25
  413. package/src/file/edit.native.js +1 -1
  414. package/src/file/save.js +5 -1
  415. package/src/form-input/block.json +2 -2
  416. package/src/form-input/deprecated.js +142 -0
  417. package/src/form-input/edit.js +1 -1
  418. package/src/form-input/index.js +2 -0
  419. package/src/form-input/save.js +27 -24
  420. package/src/gallery/block.json +8 -4
  421. package/src/gallery/edit.js +70 -98
  422. package/src/gallery/gallery.js +22 -36
  423. package/src/gallery/gallery.native.js +6 -2
  424. package/src/gallery/index.php +15 -0
  425. package/src/gallery/transforms.js +2 -55
  426. package/src/gallery/v1/gallery.native.js +2 -1
  427. package/src/group/block.json +5 -1
  428. package/src/group/edit.js +4 -1
  429. package/src/heading/block.json +3 -6
  430. package/src/image/block.json +2 -2
  431. package/src/image/deprecated.js +8 -0
  432. package/src/image/edit.native.js +5 -3
  433. package/src/image/image.js +77 -127
  434. package/src/image/index.php +1 -6
  435. package/src/image/save.js +3 -1
  436. package/src/image/view.js +5 -2
  437. package/src/list/edit.js +27 -35
  438. package/src/list-item/block.json +10 -3
  439. package/src/list-item/edit.js +18 -2
  440. package/src/list-item/hooks/use-enter.js +63 -62
  441. package/src/list-item/hooks/use-enter.native.js +9 -5
  442. package/src/list-item/hooks/use-indent-list-item.js +43 -53
  443. package/src/list-item/hooks/use-merge.js +1 -1
  444. package/src/list-item/hooks/use-outdent-list-item.js +50 -69
  445. package/src/list-item/hooks/use-space.js +7 -4
  446. package/src/media-text/media-container.native.js +3 -1
  447. package/src/navigation/constants.js +2 -0
  448. package/src/navigation/edit/index.js +18 -3
  449. package/src/navigation/editor.scss +1 -1
  450. package/src/navigation/index.php +1 -1
  451. package/src/navigation/style.scss +18 -16
  452. package/src/navigation/view.js +29 -3
  453. package/src/navigation-link/test/__snapshots__/hooks.js.snap +6 -3
  454. package/src/page-list/convert-to-links-modal.js +2 -2
  455. package/src/paragraph/block.json +2 -4
  456. package/src/paragraph/edit.js +53 -40
  457. package/src/paragraph/test/__snapshots__/edit.native.js.snap +12 -0
  458. package/src/paragraph/test/edit.native.js +114 -0
  459. package/src/pattern/edit.js +35 -3
  460. package/src/pattern/index.php +16 -0
  461. package/src/pattern/recursion-detector.js +145 -0
  462. package/src/pattern/test/index.js +74 -0
  463. package/src/post-featured-image/block.json +4 -0
  464. package/src/post-featured-image/edit.js +32 -1
  465. package/src/post-featured-image/index.php +31 -0
  466. package/src/post-title/block.json +1 -3
  467. package/src/preformatted/block.json +2 -3
  468. package/src/pullquote/block.json +5 -7
  469. package/src/query/edit/inspector-controls/index.js +2 -0
  470. package/src/query/edit/inspector-controls/taxonomy-controls.js +2 -0
  471. package/src/query-pagination-numbers/block.json +1 -1
  472. package/src/query-title/block.json +1 -3
  473. package/src/quote/block.json +3 -5
  474. package/src/quote/transforms.js +12 -11
  475. package/src/search/block.json +0 -4
  476. package/src/search/edit.js +2 -8
  477. package/src/search/index.php +3 -7
  478. package/src/search/style.scss +27 -29
  479. package/src/site-logo/edit.js +3 -4
  480. package/src/site-title/block.json +1 -5
  481. package/src/social-link/icons/gravatar.js +10 -0
  482. package/src/social-link/icons/index.js +1 -0
  483. package/src/social-link/index.php +5 -1
  484. package/src/social-link/socials-with-bg.scss +5 -0
  485. package/src/social-link/socials-without-bg.scss +4 -0
  486. package/src/social-link/variations.js +7 -0
  487. package/src/social-links/style.scss +14 -8
  488. package/src/spacer/edit.native.js +4 -2
  489. package/src/table/block.json +9 -10
  490. package/src/table/edit.js +3 -1
  491. package/src/table/editor.scss +1 -17
  492. package/src/table-of-contents/edit.js +1 -1
  493. package/src/table-of-contents/index.js +5 -1
  494. package/src/tag-cloud/edit.js +7 -7
  495. package/src/template-part/index.php +6 -0
  496. package/src/utils/caption.js +108 -0
  497. package/src/utils/constants.js +8 -0
  498. package/src/utils/remove-anchor-tag.js +2 -1
  499. package/src/verse/block.json +3 -5
  500. package/src/video/block.json +2 -2
  501. package/src/video/edit.js +40 -100
  502. package/src/video/edit.native.js +2 -1
  503. package/build/block/edit.native.js.map +0 -1
  504. package/build/table-of-contents/icon.js +0 -22
  505. package/build/table-of-contents/icon.js.map +0 -1
  506. package/build-module/block/edit.native.js.map +0 -1
  507. package/build-module/table-of-contents/icon.js +0 -15
  508. package/build-module/table-of-contents/icon.js.map +0 -1
  509. package/src/table-of-contents/icon.js +0 -18
package/src/audio/edit.js CHANGED
@@ -13,7 +13,6 @@ import {
13
13
  SelectControl,
14
14
  Spinner,
15
15
  ToggleControl,
16
- ToolbarButton,
17
16
  } from '@wordpress/components';
18
17
  import {
19
18
  BlockControls,
@@ -21,23 +20,20 @@ import {
21
20
  InspectorControls,
22
21
  MediaPlaceholder,
23
22
  MediaReplaceFlow,
24
- RichText,
25
23
  useBlockProps,
26
24
  store as blockEditorStore,
27
- __experimentalGetElementClassName,
28
25
  } from '@wordpress/block-editor';
29
- import { useEffect, useState, useCallback } from '@wordpress/element';
26
+ import { useEffect } from '@wordpress/element';
30
27
  import { __, _x } from '@wordpress/i18n';
31
28
  import { useDispatch, useSelect } from '@wordpress/data';
32
- import { audio as icon, caption as captionIcon } from '@wordpress/icons';
33
- import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
29
+ import { audio as icon } from '@wordpress/icons';
34
30
  import { store as noticesStore } from '@wordpress/notices';
35
- import { usePrevious } from '@wordpress/compose';
36
31
 
37
32
  /**
38
33
  * Internal dependencies
39
34
  */
40
35
  import { createUpgradedEmbedBlock } from '../embed/util';
36
+ import { Caption } from '../utils/caption';
41
37
 
42
38
  const ALLOWED_MEDIA_TYPES = [ 'audio' ];
43
39
 
@@ -46,24 +42,19 @@ function AudioEdit( {
46
42
  className,
47
43
  setAttributes,
48
44
  onReplace,
49
- isSelected,
45
+ isSelected: isSingleSelected,
50
46
  insertBlocksAfter,
51
47
  } ) {
52
- const { id, autoplay, caption, loop, preload, src } = attributes;
53
- const prevCaption = usePrevious( caption );
54
- const [ showCaption, setShowCaption ] = useState( !! caption );
48
+ const { id, autoplay, loop, preload, src } = attributes;
55
49
  const isTemporaryAudio = ! id && isBlobURL( src );
56
- const mediaUpload = useSelect( ( select ) => {
57
- const { getSettings } = select( blockEditorStore );
58
- return getSettings().mediaUpload;
59
- }, [] );
50
+ const { getSettings } = useSelect( blockEditorStore );
60
51
 
61
52
  useEffect( () => {
62
53
  if ( ! id && isBlobURL( src ) ) {
63
54
  const file = getBlobByURL( src );
64
55
 
65
56
  if ( file ) {
66
- mediaUpload( {
57
+ getSettings().mediaUpload( {
67
58
  filesList: [ file ],
68
59
  onFileChange: ( [ media ] ) => onSelectAudio( media ),
69
60
  onError: ( e ) => onUploadError( e ),
@@ -73,30 +64,6 @@ function AudioEdit( {
73
64
  }
74
65
  }, [] );
75
66
 
76
- // We need to show the caption when changes come from
77
- // history navigation(undo/redo).
78
- useEffect( () => {
79
- if ( caption && ! prevCaption ) {
80
- setShowCaption( true );
81
- }
82
- }, [ caption, prevCaption ] );
83
-
84
- // Focus the caption when we click to add one.
85
- const captionRef = useCallback(
86
- ( node ) => {
87
- if ( node && ! caption ) {
88
- node.focus();
89
- }
90
- },
91
- [ caption ]
92
- );
93
-
94
- useEffect( () => {
95
- if ( ! isSelected && ! caption ) {
96
- setShowCaption( false );
97
- }
98
- }, [ isSelected, caption ] );
99
-
100
67
  function toggleAttribute( attribute ) {
101
68
  return ( newValue ) => {
102
69
  setAttributes( { [ attribute ]: newValue } );
@@ -176,34 +143,19 @@ function AudioEdit( {
176
143
 
177
144
  return (
178
145
  <>
179
- <BlockControls group="block">
180
- <ToolbarButton
181
- onClick={ () => {
182
- setShowCaption( ! showCaption );
183
- if ( showCaption && caption ) {
184
- setAttributes( { caption: undefined } );
185
- }
186
- } }
187
- icon={ captionIcon }
188
- isPressed={ showCaption }
189
- label={
190
- showCaption
191
- ? __( 'Remove caption' )
192
- : __( 'Add caption' )
193
- }
194
- />
195
- </BlockControls>
196
- <BlockControls group="other">
197
- <MediaReplaceFlow
198
- mediaId={ id }
199
- mediaURL={ src }
200
- allowedTypes={ ALLOWED_MEDIA_TYPES }
201
- accept="audio/*"
202
- onSelect={ onSelectAudio }
203
- onSelectURL={ onSelectURL }
204
- onError={ onUploadError }
205
- />
206
- </BlockControls>
146
+ { isSingleSelected && (
147
+ <BlockControls group="other">
148
+ <MediaReplaceFlow
149
+ mediaId={ id }
150
+ mediaURL={ src }
151
+ allowedTypes={ ALLOWED_MEDIA_TYPES }
152
+ accept="audio/*"
153
+ onSelect={ onSelectAudio }
154
+ onSelectURL={ onSelectURL }
155
+ onError={ onUploadError }
156
+ />
157
+ </BlockControls>
158
+ ) }
207
159
  <InspectorControls>
208
160
  <PanelBody title={ __( 'Settings' ) }>
209
161
  <ToggleControl
@@ -247,33 +199,18 @@ function AudioEdit( {
247
199
  so the user clicking on it won't play the
248
200
  file or change the position slider when the controls are enabled.
249
201
  */ }
250
- <Disabled isDisabled={ ! isSelected }>
202
+ <Disabled isDisabled={ ! isSingleSelected }>
251
203
  <audio controls="controls" src={ src } />
252
204
  </Disabled>
253
205
  { isTemporaryAudio && <Spinner /> }
254
- { showCaption &&
255
- ( ! RichText.isEmpty( caption ) || isSelected ) && (
256
- <RichText
257
- identifier="caption"
258
- tagName="figcaption"
259
- className={ __experimentalGetElementClassName(
260
- 'caption'
261
- ) }
262
- ref={ captionRef }
263
- aria-label={ __( 'Audio caption text' ) }
264
- placeholder={ __( 'Add caption' ) }
265
- value={ caption }
266
- onChange={ ( value ) =>
267
- setAttributes( { caption: value } )
268
- }
269
- inlineToolbar
270
- __unstableOnSplitAtEnd={ () =>
271
- insertBlocksAfter(
272
- createBlock( getDefaultBlockName() )
273
- )
274
- }
275
- />
276
- ) }
206
+ <Caption
207
+ attributes={ attributes }
208
+ setAttributes={ setAttributes }
209
+ isSelected={ isSingleSelected }
210
+ insertBlocksAfter={ insertBlocksAfter }
211
+ label={ __( 'Audio caption text' ) }
212
+ showToolbarButton={ isSingleSelected }
213
+ />
277
214
  </figure>
278
215
  </>
279
216
  );
@@ -23,6 +23,7 @@ import {
23
23
  MediaPlaceholder,
24
24
  MediaUpload,
25
25
  MediaUploadProgress,
26
+ RichText,
26
27
  store as blockEditorStore,
27
28
  } from '@wordpress/block-editor';
28
29
  import { __, _x, sprintf } from '@wordpress/i18n';
@@ -227,7 +228,7 @@ function AudioEdit( {
227
228
  <BlockCaption
228
229
  accessible={ true }
229
230
  accessibilityLabelCreator={ ( caption ) =>
230
- ! caption
231
+ RichText.isEmpty( caption )
231
232
  ? /* translators: accessibility text. Empty Audio caption. */
232
233
  __( 'Audio caption. Empty' )
233
234
  : sprintf(
@@ -532,3 +532,15 @@ exports[`Audio block renders placeholder without crashing 1`] = `
532
532
  </View>
533
533
  </View>
534
534
  `;
535
+
536
+ exports[`Audio block should enable autoplay setting 1`] = `
537
+ "<!-- wp:audio {"id":5} -->
538
+ <figure class="wp-block-audio"><audio controls src="https://cldup.com/59IrU0WJtq.mp3" autoplay></audio></figure>
539
+ <!-- /wp:audio -->"
540
+ `;
541
+
542
+ exports[`Audio block should enable loop setting 1`] = `
543
+ "<!-- wp:audio {"id":5} -->
544
+ <figure class="wp-block-audio"><audio controls src="https://cldup.com/59IrU0WJtq.mp3" loop></audio></figure>
545
+ <!-- /wp:audio -->"
546
+ `;
@@ -5,7 +5,10 @@ import {
5
5
  addBlock,
6
6
  dismissModal,
7
7
  fireEvent,
8
+ getBlock,
9
+ getEditorHtml,
8
10
  initializeEditor,
11
+ openBlockSettings,
9
12
  render,
10
13
  screen,
11
14
  setupCoreBlocks,
@@ -31,6 +34,10 @@ jest.unmock( '@wordpress/react-native-aztec' );
31
34
 
32
35
  const MEDIA_UPLOAD_STATE_FAILED = 3;
33
36
 
37
+ const AUDIO_BLOCK = `<!-- wp:audio {"id":5} -->
38
+ <figure class="wp-block-audio"><audio controls src="https://cldup.com/59IrU0WJtq.mp3"></audio></figure>
39
+ <!-- /wp:audio -->`;
40
+
34
41
  let uploadCallBack;
35
42
  subscribeMediaUpload.mockImplementation( ( callback ) => {
36
43
  uploadCallBack = callback;
@@ -100,4 +107,26 @@ describe( 'Audio block', () => {
100
107
  screen.getByText( 'Invalid URL. Audio file not found.' )
101
108
  ).toBeVisible();
102
109
  } );
110
+
111
+ it( 'should enable autoplay setting', async () => {
112
+ await initializeEditor( { initialHtml: AUDIO_BLOCK } );
113
+
114
+ const audioBlock = getBlock( screen, 'Audio' );
115
+ fireEvent.press( audioBlock );
116
+ await openBlockSettings( screen );
117
+
118
+ fireEvent.press( screen.getByText( 'Autoplay' ) );
119
+ expect( getEditorHtml() ).toMatchSnapshot();
120
+ } );
121
+
122
+ it( 'should enable loop setting', async () => {
123
+ await initializeEditor( { initialHtml: AUDIO_BLOCK } );
124
+
125
+ const audioBlock = getBlock( screen, 'Audio' );
126
+ fireEvent.press( audioBlock );
127
+ await openBlockSettings( screen );
128
+
129
+ fireEvent.press( screen.getByText( 'Loop' ) );
130
+ expect( getEditorHtml() ).toMatchSnapshot();
131
+ } );
103
132
  } );
package/src/block/edit.js CHANGED
@@ -6,16 +6,14 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import {
10
- useEntityBlockEditor,
11
- useEntityProp,
12
- useEntityRecord,
13
- } from '@wordpress/core-data';
9
+ import { useRegistry, useSelect, useDispatch } from '@wordpress/data';
10
+ import { useRef, useMemo, useEffect } from '@wordpress/element';
11
+ import { useEntityRecord, store as coreStore } from '@wordpress/core-data';
14
12
  import {
15
13
  Placeholder,
16
14
  Spinner,
17
- TextControl,
18
- PanelBody,
15
+ ToolbarButton,
16
+ ToolbarGroup,
19
17
  } from '@wordpress/components';
20
18
  import { __ } from '@wordpress/i18n';
21
19
  import {
@@ -23,12 +21,13 @@ import {
23
21
  __experimentalRecursionProvider as RecursionProvider,
24
22
  __experimentalUseHasRecursion as useHasRecursion,
25
23
  InnerBlocks,
26
- InspectorControls,
27
24
  useBlockProps,
28
25
  Warning,
29
26
  privateApis as blockEditorPrivateApis,
27
+ store as blockEditorStore,
28
+ BlockControls,
30
29
  } from '@wordpress/block-editor';
31
- import { useRef, useMemo } from '@wordpress/element';
30
+ import { parse, cloneBlock } from '@wordpress/blocks';
32
31
 
33
32
  /**
34
33
  * Internal dependencies
@@ -36,6 +35,24 @@ import { useRef, useMemo } from '@wordpress/element';
36
35
  import { unlock } from '../lock-unlock';
37
36
 
38
37
  const { useLayoutClasses } = unlock( blockEditorPrivateApis );
38
+
39
+ function isPartiallySynced( block ) {
40
+ return (
41
+ 'core/paragraph' === block.name &&
42
+ !! block.attributes.metadata?.bindings &&
43
+ Object.values( block.attributes.metadata.bindings ).some(
44
+ ( binding ) => binding.source.name === 'pattern_attributes'
45
+ )
46
+ );
47
+ }
48
+ function getPartiallySyncedAttributes( block ) {
49
+ return Object.entries( block.attributes.metadata.bindings )
50
+ .filter(
51
+ ( [ , binding ] ) => binding.source.name === 'pattern_attributes'
52
+ )
53
+ .map( ( [ attributeKey ] ) => attributeKey );
54
+ }
55
+
39
56
  const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
40
57
 
41
58
  const useInferredLayout = ( blocks, parentLayout ) => {
@@ -67,33 +84,171 @@ const useInferredLayout = ( blocks, parentLayout ) => {
67
84
  }, [ blocks, parentLayout ] );
68
85
  };
69
86
 
87
+ function applyInitialOverrides( blocks, overrides = {}, defaultValues ) {
88
+ return blocks.map( ( block ) => {
89
+ const innerBlocks = applyInitialOverrides(
90
+ block.innerBlocks,
91
+ overrides,
92
+ defaultValues
93
+ );
94
+ const blockId = block.attributes.metadata?.id;
95
+ if ( ! isPartiallySynced( block ) || ! blockId )
96
+ return { ...block, innerBlocks };
97
+ const attributes = getPartiallySyncedAttributes( block );
98
+ const newAttributes = { ...block.attributes };
99
+ for ( const attributeKey of attributes ) {
100
+ defaultValues[ blockId ] ??= {};
101
+ defaultValues[ blockId ][ attributeKey ] =
102
+ block.attributes[ attributeKey ];
103
+ if ( overrides[ blockId ] ) {
104
+ newAttributes[ attributeKey ] =
105
+ overrides[ blockId ][ attributeKey ];
106
+ }
107
+ }
108
+ return {
109
+ ...block,
110
+ attributes: newAttributes,
111
+ innerBlocks,
112
+ };
113
+ } );
114
+ }
115
+
116
+ function getOverridesFromBlocks( blocks, defaultValues ) {
117
+ /** @type {Record<string, Record<string, unknown>>} */
118
+ const overrides = {};
119
+ for ( const block of blocks ) {
120
+ Object.assign(
121
+ overrides,
122
+ getOverridesFromBlocks( block.innerBlocks, defaultValues )
123
+ );
124
+ const blockId = block.attributes.metadata?.id;
125
+ if ( ! isPartiallySynced( block ) || ! blockId ) continue;
126
+ const attributes = getPartiallySyncedAttributes( block );
127
+ for ( const attributeKey of attributes ) {
128
+ if (
129
+ block.attributes[ attributeKey ] !==
130
+ defaultValues[ blockId ][ attributeKey ]
131
+ ) {
132
+ overrides[ blockId ] ??= {};
133
+ overrides[ blockId ][ attributeKey ] =
134
+ block.attributes[ attributeKey ];
135
+ }
136
+ }
137
+ }
138
+ return Object.keys( overrides ).length > 0 ? overrides : undefined;
139
+ }
140
+
141
+ function setBlockEditMode( setEditMode, blocks, mode ) {
142
+ blocks.forEach( ( block ) => {
143
+ const editMode =
144
+ mode || ( isPartiallySynced( block ) ? 'contentOnly' : 'disabled' );
145
+ setEditMode( block.clientId, editMode );
146
+ setBlockEditMode( setEditMode, block.innerBlocks, mode );
147
+ } );
148
+ }
149
+
70
150
  export default function ReusableBlockEdit( {
71
151
  name,
72
- attributes: { ref },
152
+ attributes: { ref, overrides },
73
153
  __unstableParentLayout: parentLayout,
154
+ clientId: patternClientId,
155
+ setAttributes,
74
156
  } ) {
157
+ const registry = useRegistry();
75
158
  const hasAlreadyRendered = useHasRecursion( ref );
76
- const { record, hasResolved } = useEntityRecord(
159
+ const { record, editedRecord, hasResolved } = useEntityRecord(
77
160
  'postType',
78
161
  'wp_block',
79
162
  ref
80
163
  );
81
164
  const isMissing = hasResolved && ! record;
165
+ const initialOverrides = useRef( overrides );
166
+ const defaultValuesRef = useRef( {} );
82
167
 
83
- const [ blocks, onInput, onChange ] = useEntityBlockEditor(
84
- 'postType',
85
- 'wp_block',
86
- { id: ref }
87
- );
168
+ const {
169
+ replaceInnerBlocks,
170
+ __unstableMarkNextChangeAsNotPersistent,
171
+ setBlockEditingMode,
172
+ } = useDispatch( blockEditorStore );
173
+ const { syncDerivedUpdates } = unlock( useDispatch( blockEditorStore ) );
88
174
 
89
- const [ title, setTitle ] = useEntityProp(
90
- 'postType',
91
- 'wp_block',
92
- 'title',
93
- ref
175
+ const { innerBlocks, userCanEdit, getBlockEditingMode, getPostLinkProps } =
176
+ useSelect(
177
+ ( select ) => {
178
+ const { canUser } = select( coreStore );
179
+ const {
180
+ getBlocks,
181
+ getBlockEditingMode: editingMode,
182
+ getSettings,
183
+ } = select( blockEditorStore );
184
+ const blocks = getBlocks( patternClientId );
185
+ const canEdit = canUser( 'update', 'blocks', ref );
186
+
187
+ // For editing link to the site editor if the theme and user permissions support it.
188
+ return {
189
+ innerBlocks: blocks,
190
+ userCanEdit: canEdit,
191
+ getBlockEditingMode: editingMode,
192
+ getPostLinkProps: getSettings().getPostLinkProps,
193
+ };
194
+ },
195
+ [ patternClientId, ref ]
196
+ );
197
+
198
+ const editOriginalProps = getPostLinkProps
199
+ ? getPostLinkProps( {
200
+ postId: ref,
201
+ postType: 'wp_block',
202
+ canvas: 'edit',
203
+ } )
204
+ : {};
205
+
206
+ useEffect(
207
+ () => setBlockEditMode( setBlockEditingMode, innerBlocks ),
208
+ [ innerBlocks, setBlockEditingMode ]
94
209
  );
95
210
 
96
- const { alignment, layout } = useInferredLayout( blocks, parentLayout );
211
+ // Apply the initial overrides from the pattern block to the inner blocks.
212
+ useEffect( () => {
213
+ const initialBlocks =
214
+ // Clone the blocks to generate new client IDs.
215
+ editedRecord.blocks?.map( ( block ) => cloneBlock( block ) ) ??
216
+ ( editedRecord.content && typeof editedRecord.content !== 'function'
217
+ ? parse( editedRecord.content )
218
+ : [] );
219
+
220
+ defaultValuesRef.current = {};
221
+ const editingMode = getBlockEditingMode( patternClientId );
222
+ // Replace the contents of the blocks with the overrides.
223
+ registry.batch( () => {
224
+ setBlockEditingMode( patternClientId, 'default' );
225
+ syncDerivedUpdates( () => {
226
+ replaceInnerBlocks(
227
+ patternClientId,
228
+ applyInitialOverrides(
229
+ initialBlocks,
230
+ initialOverrides.current,
231
+ defaultValuesRef.current
232
+ )
233
+ );
234
+ } );
235
+ setBlockEditingMode( patternClientId, editingMode );
236
+ } );
237
+ }, [
238
+ __unstableMarkNextChangeAsNotPersistent,
239
+ patternClientId,
240
+ editedRecord,
241
+ replaceInnerBlocks,
242
+ registry,
243
+ getBlockEditingMode,
244
+ setBlockEditingMode,
245
+ syncDerivedUpdates,
246
+ ] );
247
+
248
+ const { alignment, layout } = useInferredLayout(
249
+ innerBlocks,
250
+ parentLayout
251
+ );
97
252
  const layoutClasses = useLayoutClasses( { layout }, name );
98
253
 
99
254
  const blockProps = useBlockProps( {
@@ -105,16 +260,41 @@ export default function ReusableBlockEdit( {
105
260
  } );
106
261
 
107
262
  const innerBlocksProps = useInnerBlocksProps( blockProps, {
108
- value: blocks,
263
+ templateLock: 'all',
109
264
  layout,
110
- onInput,
111
- onChange,
112
- renderAppender: blocks?.length
265
+ renderAppender: innerBlocks?.length
113
266
  ? undefined
114
267
  : InnerBlocks.ButtonBlockAppender,
115
268
  } );
116
269
 
270
+ // Sync the `overrides` attribute from the updated blocks to the pattern block.
271
+ // `syncDerivedUpdates` is used here to avoid creating an additional undo level.
272
+ useEffect( () => {
273
+ const { getBlocks } = registry.select( blockEditorStore );
274
+ let prevBlocks = getBlocks( patternClientId );
275
+ return registry.subscribe( () => {
276
+ const blocks = getBlocks( patternClientId );
277
+ if ( blocks !== prevBlocks ) {
278
+ prevBlocks = blocks;
279
+ syncDerivedUpdates( () => {
280
+ setAttributes( {
281
+ overrides: getOverridesFromBlocks(
282
+ blocks,
283
+ defaultValuesRef.current
284
+ ),
285
+ } );
286
+ } );
287
+ }
288
+ }, blockEditorStore );
289
+ }, [ syncDerivedUpdates, patternClientId, registry, setAttributes ] );
290
+
291
+ const handleEditOriginal = ( event ) => {
292
+ setBlockEditMode( setBlockEditingMode, innerBlocks, 'default' );
293
+ editOriginalProps.onClick( event );
294
+ };
295
+
117
296
  let children = null;
297
+
118
298
  if ( hasAlreadyRendered ) {
119
299
  children = (
120
300
  <Warning>
@@ -141,17 +321,18 @@ export default function ReusableBlockEdit( {
141
321
 
142
322
  return (
143
323
  <RecursionProvider uniqueId={ ref }>
144
- <InspectorControls>
145
- <PanelBody>
146
- <TextControl
147
- label={ __( 'Name' ) }
148
- value={ title }
149
- onChange={ setTitle }
150
- __nextHasNoMarginBottom
151
- __next40pxDefaultSize
152
- />
153
- </PanelBody>
154
- </InspectorControls>
324
+ { userCanEdit && editOriginalProps && (
325
+ <BlockControls>
326
+ <ToolbarGroup>
327
+ <ToolbarButton
328
+ href={ editOriginalProps.href }
329
+ onClick={ handleEditOriginal }
330
+ >
331
+ { __( 'Edit original' ) }
332
+ </ToolbarButton>
333
+ </ToolbarGroup>
334
+ </BlockControls>
335
+ ) }
155
336
  { children === null ? (
156
337
  <div { ...innerBlocksProps } />
157
338
  ) : (
@@ -8,14 +8,15 @@ import { symbol as icon } from '@wordpress/icons';
8
8
  */
9
9
  import initBlock from '../utils/init-block';
10
10
  import metadata from './block.json';
11
- import edit from './edit';
11
+ import editV1 from './v1/edit';
12
+ import editV2 from './edit';
12
13
 
13
14
  const { name } = metadata;
14
15
 
15
16
  export { metadata, name };
16
17
 
17
18
  export const settings = {
18
- edit,
19
+ edit: window.__experimentalPatternPartialSyncing ? editV2 : editV1,
19
20
  icon,
20
21
  };
21
22
 
@@ -46,8 +46,31 @@ function render_block_core_block( $attributes ) {
46
46
  $content = $wp_embed->run_shortcode( $reusable_block->post_content );
47
47
  $content = $wp_embed->autoembed( $content );
48
48
 
49
+ $gutenberg_experiments = get_option( 'gutenberg-experiments' );
50
+ $has_partial_synced_overrides = $gutenberg_experiments
51
+ && array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments )
52
+ && isset( $attributes['overrides'] );
53
+
54
+ /**
55
+ * We set the `pattern/overrides` context through the `render_block_context`
56
+ * filter so that it is available when a pattern's inner blocks are
57
+ * rendering via do_blocks given it only receives the inner content.
58
+ */
59
+ if ( $has_partial_synced_overrides ) {
60
+ $filter_block_context = static function ( $context ) use ( $attributes ) {
61
+ $context['pattern/overrides'] = $attributes['overrides'];
62
+ return $context;
63
+ };
64
+ add_filter( 'render_block_context', $filter_block_context, 1 );
65
+ }
66
+
49
67
  $content = do_blocks( $content );
50
68
  unset( $seen_refs[ $attributes['ref'] ] );
69
+
70
+ if ( $has_partial_synced_overrides ) {
71
+ remove_filter( 'render_block_context', $filter_block_context, 1 );
72
+ }
73
+
51
74
  return $content;
52
75
  }
53
76
 
@@ -63,3 +86,28 @@ function register_block_core_block() {
63
86
  );
64
87
  }
65
88
  add_action( 'init', 'register_block_core_block' );
89
+
90
+ $gutenberg_experiments = get_option( 'gutenberg-experiments' );
91
+ if ( $gutenberg_experiments && array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments ) ) {
92
+ /**
93
+ * Registers the overrides attribute for core/block.
94
+ *
95
+ * @param array $args Array of arguments for registering a block type.
96
+ * @param string $block_name Block name including namespace.
97
+ * @return array $args
98
+ */
99
+ function register_block_core_block_args( $args, $block_name ) {
100
+ if ( 'core/block' === $block_name ) {
101
+ $args['attributes'] = array_merge(
102
+ $args['attributes'],
103
+ array(
104
+ 'overrides' => array(
105
+ 'type' => 'object',
106
+ ),
107
+ )
108
+ );
109
+ }
110
+ return $args;
111
+ }
112
+ add_filter( 'register_block_type_args', 'register_block_core_block_args', 10, 2 );
113
+ }