@wordpress/block-editor 11.0.0 → 11.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 (470) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +2 -1
  4. package/build/components/alignment-control/ui.js +1 -7
  5. package/build/components/alignment-control/ui.js.map +1 -1
  6. package/build/components/block-actions/index.js +9 -0
  7. package/build/components/block-actions/index.js.map +1 -1
  8. package/build/components/block-alignment-control/use-available-alignments.js +4 -3
  9. package/build/components/block-alignment-control/use-available-alignments.js.map +1 -1
  10. package/build/components/block-icon/index.js +4 -2
  11. package/build/components/block-icon/index.js.map +1 -1
  12. package/build/components/block-inspector/index.js +58 -5
  13. package/build/components/block-inspector/index.js.map +1 -1
  14. package/build/components/block-list-appender/index.js +46 -34
  15. package/build/components/block-list-appender/index.js.map +1 -1
  16. package/build/components/block-list-appender/index.native.js +39 -34
  17. package/build/components/block-list-appender/index.native.js.map +1 -1
  18. package/build/components/block-mobile-toolbar/block-actions-menu.native.js +18 -18
  19. package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  20. package/build/components/block-mobile-toolbar/index.native.js +1 -1
  21. package/build/components/block-mobile-toolbar/index.native.js.map +1 -1
  22. package/build/components/block-pattern-setup/index.js +14 -7
  23. package/build/components/block-pattern-setup/index.js.map +1 -1
  24. package/build/components/block-preview/auto.js +1 -4
  25. package/build/components/block-preview/auto.js.map +1 -1
  26. package/build/components/block-settings-menu/block-settings-dropdown.js +4 -1
  27. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  28. package/build/components/block-styles/index.js +3 -1
  29. package/build/components/block-styles/index.js.map +1 -1
  30. package/build/components/block-styles/index.native.js +1 -3
  31. package/build/components/block-styles/index.native.js.map +1 -1
  32. package/build/components/block-styles/utils.js +7 -10
  33. package/build/components/block-styles/utils.js.map +1 -1
  34. package/build/components/block-toolbar/index.native.js +6 -8
  35. package/build/components/block-toolbar/index.native.js.map +1 -1
  36. package/build/components/block-tools/selected-block-popover.js +1 -3
  37. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  38. package/build/components/block-tools/use-block-toolbar-popover-props.js +43 -10
  39. package/build/components/block-tools/use-block-toolbar-popover-props.js.map +1 -1
  40. package/build/components/block-variation-picker/index.js +1 -1
  41. package/build/components/block-variation-picker/index.js.map +1 -1
  42. package/build/components/colors/utils.js +2 -6
  43. package/build/components/colors/utils.js.map +1 -1
  44. package/build/components/colors-gradients/control.js +0 -3
  45. package/build/components/colors-gradients/control.js.map +1 -1
  46. package/build/components/colors-gradients/dropdown.js +0 -2
  47. package/build/components/colors-gradients/dropdown.js.map +1 -1
  48. package/build/components/colors-gradients/panel-color-gradient-settings.js +2 -19
  49. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  50. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -3
  51. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -1
  52. package/build/components/copy-handler/index.js +37 -9
  53. package/build/components/copy-handler/index.js.map +1 -1
  54. package/build/components/default-style-picker/index.js +1 -0
  55. package/build/components/default-style-picker/index.js.map +1 -1
  56. package/build/components/font-sizes/fluid-utils.js +5 -2
  57. package/build/components/font-sizes/fluid-utils.js.map +1 -1
  58. package/build/components/font-sizes/utils.js +10 -4
  59. package/build/components/font-sizes/utils.js.map +1 -1
  60. package/build/components/font-sizes/with-font-sizes.js +14 -12
  61. package/build/components/font-sizes/with-font-sizes.js.map +1 -1
  62. package/build/components/gradients/use-gradient.js +2 -8
  63. package/build/components/gradients/use-gradient.js.map +1 -1
  64. package/build/components/iframe/index.js +48 -101
  65. package/build/components/iframe/index.js.map +1 -1
  66. package/build/components/iframe/use-compatibility-styles.js +98 -0
  67. package/build/components/iframe/use-compatibility-styles.js.map +1 -0
  68. package/build/components/image-size-control/index.js +1 -0
  69. package/build/components/image-size-control/index.js.map +1 -1
  70. package/build/components/inner-blocks/index.js +6 -2
  71. package/build/components/inner-blocks/index.js.map +1 -1
  72. package/build/components/inserter/block-patterns-tab.js +4 -4
  73. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  74. package/build/components/inserter/hooks/use-insertion-point.js +4 -3
  75. package/build/components/inserter/hooks/use-insertion-point.js.map +1 -1
  76. package/build/components/inserter/index.js +16 -6
  77. package/build/components/inserter/index.js.map +1 -1
  78. package/build/components/inserter/media-tab/hooks.js +8 -5
  79. package/build/components/inserter/media-tab/hooks.js.map +1 -1
  80. package/build/components/inserter/menu.js +11 -5
  81. package/build/components/inserter/menu.js.map +1 -1
  82. package/build/components/inserter/quick-inserter.js +6 -3
  83. package/build/components/inserter/quick-inserter.js.map +1 -1
  84. package/build/components/inserter/search-items.js +15 -14
  85. package/build/components/inserter/search-items.js.map +1 -1
  86. package/build/components/inserter/search-results.js +4 -2
  87. package/build/components/inserter/search-results.js.map +1 -1
  88. package/build/components/inspector-controls/groups.js +3 -1
  89. package/build/components/inspector-controls/groups.js.map +1 -1
  90. package/build/components/inspector-controls-tabs/position-controls-panel.js +46 -0
  91. package/build/components/inspector-controls-tabs/position-controls-panel.js.map +1 -0
  92. package/build/components/inspector-controls-tabs/settings-tab.js +3 -1
  93. package/build/components/inspector-controls-tabs/settings-tab.js.map +1 -1
  94. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js +4 -11
  95. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +1 -1
  96. package/build/components/link-control/search-input.js +1 -0
  97. package/build/components/link-control/search-input.js.map +1 -1
  98. package/build/components/list-view/block-select-button.js +1 -1
  99. package/build/components/list-view/block-select-button.js.map +1 -1
  100. package/build/components/off-canvas-editor/appender.js +3 -44
  101. package/build/components/off-canvas-editor/appender.js.map +1 -1
  102. package/build/components/off-canvas-editor/block-contents.js +38 -5
  103. package/build/components/off-canvas-editor/block-contents.js.map +1 -1
  104. package/build/components/off-canvas-editor/block-select-button.js +3 -2
  105. package/build/components/off-canvas-editor/block-select-button.js.map +1 -1
  106. package/build/components/off-canvas-editor/block.js +51 -57
  107. package/build/components/off-canvas-editor/block.js.map +1 -1
  108. package/build/components/off-canvas-editor/index.js +12 -5
  109. package/build/components/off-canvas-editor/index.js.map +1 -1
  110. package/build/components/off-canvas-editor/use-inserted-block.js +58 -0
  111. package/build/components/off-canvas-editor/use-inserted-block.js.map +1 -0
  112. package/build/components/provider/index.js +3 -1
  113. package/build/components/provider/index.js.map +1 -1
  114. package/build/components/responsive-block-control/label.js.map +1 -1
  115. package/build/components/rich-text/format-edit.js +12 -10
  116. package/build/components/rich-text/format-edit.js.map +1 -1
  117. package/build/components/rich-text/index.js.map +1 -1
  118. package/build/components/rich-text/use-enter.js +4 -5
  119. package/build/components/rich-text/use-enter.js.map +1 -1
  120. package/build/components/rich-text/use-paste-handler.js +21 -12
  121. package/build/components/rich-text/use-paste-handler.js.map +1 -1
  122. package/build/components/spacing-sizes-control/index.js +0 -1
  123. package/build/components/spacing-sizes-control/index.js.map +1 -1
  124. package/build/components/spacing-sizes-control/utils.js +1 -1
  125. package/build/components/spacing-sizes-control/utils.js.map +1 -1
  126. package/build/components/typewriter/index.js +1 -1
  127. package/build/components/typewriter/index.js.map +1 -1
  128. package/build/components/url-input/button.js +1 -0
  129. package/build/components/url-input/button.js.map +1 -1
  130. package/build/components/url-input/index.js +15 -1
  131. package/build/components/url-input/index.js.map +1 -1
  132. package/build/components/url-popover/image-url-input-ui.js +2 -2
  133. package/build/components/url-popover/image-url-input-ui.js.map +1 -1
  134. package/build/components/url-popover/link-editor.js +1 -0
  135. package/build/components/url-popover/link-editor.js.map +1 -1
  136. package/build/components/use-paste-styles/index.js +188 -0
  137. package/build/components/use-paste-styles/index.js.map +1 -0
  138. package/build/components/writing-flow/index.js +1 -1
  139. package/build/components/writing-flow/index.js.map +1 -1
  140. package/build/components/writing-flow/use-arrow-nav.js +22 -29
  141. package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
  142. package/build/hooks/border.js +0 -1
  143. package/build/hooks/border.js.map +1 -1
  144. package/build/hooks/color-panel.js +0 -1
  145. package/build/hooks/color-panel.js.map +1 -1
  146. package/build/hooks/color.js +1 -2
  147. package/build/hooks/color.js.map +1 -1
  148. package/build/hooks/font-family.js +4 -4
  149. package/build/hooks/font-family.js.map +1 -1
  150. package/build/hooks/font-size.js +5 -3
  151. package/build/hooks/font-size.js.map +1 -1
  152. package/build/hooks/index.js +2 -0
  153. package/build/hooks/index.js.map +1 -1
  154. package/build/hooks/metadata.js +1 -1
  155. package/build/hooks/metadata.js.map +1 -1
  156. package/build/hooks/position.js +376 -0
  157. package/build/hooks/position.js.map +1 -0
  158. package/build/hooks/supports.js +328 -0
  159. package/build/hooks/supports.js.map +1 -0
  160. package/build/hooks/use-typography-props.js +11 -8
  161. package/build/hooks/use-typography-props.js.map +1 -1
  162. package/build/store/reducer.js +27 -9
  163. package/build/store/reducer.js.map +1 -1
  164. package/build/store/selectors.js +9 -7
  165. package/build/store/selectors.js.map +1 -1
  166. package/build/utils/pasting.js +6 -11
  167. package/build/utils/pasting.js.map +1 -1
  168. package/build-module/components/alignment-control/ui.js +1 -6
  169. package/build-module/components/alignment-control/ui.js.map +1 -1
  170. package/build-module/components/block-actions/index.js +6 -0
  171. package/build-module/components/block-actions/index.js.map +1 -1
  172. package/build-module/components/block-alignment-control/use-available-alignments.js +4 -3
  173. package/build-module/components/block-alignment-control/use-available-alignments.js.map +1 -1
  174. package/build-module/components/block-icon/index.js +4 -2
  175. package/build-module/components/block-icon/index.js.map +1 -1
  176. package/build-module/components/block-inspector/index.js +58 -6
  177. package/build-module/components/block-inspector/index.js.map +1 -1
  178. package/build-module/components/block-list-appender/index.js +46 -34
  179. package/build-module/components/block-list-appender/index.js.map +1 -1
  180. package/build-module/components/block-list-appender/index.native.js +39 -32
  181. package/build-module/components/block-list-appender/index.native.js.map +1 -1
  182. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +18 -18
  183. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  184. package/build-module/components/block-mobile-toolbar/index.native.js +1 -1
  185. package/build-module/components/block-mobile-toolbar/index.native.js.map +1 -1
  186. package/build-module/components/block-pattern-setup/index.js +14 -7
  187. package/build-module/components/block-pattern-setup/index.js.map +1 -1
  188. package/build-module/components/block-preview/auto.js +1 -4
  189. package/build-module/components/block-preview/auto.js.map +1 -1
  190. package/build-module/components/block-settings-menu/block-settings-dropdown.js +4 -1
  191. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  192. package/build-module/components/block-styles/index.js +2 -1
  193. package/build-module/components/block-styles/index.js.map +1 -1
  194. package/build-module/components/block-styles/index.native.js +1 -2
  195. package/build-module/components/block-styles/index.native.js.map +1 -1
  196. package/build-module/components/block-styles/utils.js +7 -9
  197. package/build-module/components/block-styles/utils.js.map +1 -1
  198. package/build-module/components/block-toolbar/index.native.js +6 -8
  199. package/build-module/components/block-toolbar/index.native.js.map +1 -1
  200. package/build-module/components/block-tools/selected-block-popover.js +1 -2
  201. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  202. package/build-module/components/block-tools/use-block-toolbar-popover-props.js +42 -11
  203. package/build-module/components/block-tools/use-block-toolbar-popover-props.js.map +1 -1
  204. package/build-module/components/block-variation-picker/index.js +1 -1
  205. package/build-module/components/block-variation-picker/index.js.map +1 -1
  206. package/build-module/components/colors/utils.js +3 -7
  207. package/build-module/components/colors/utils.js.map +1 -1
  208. package/build-module/components/colors-gradients/control.js +0 -3
  209. package/build-module/components/colors-gradients/control.js.map +1 -1
  210. package/build-module/components/colors-gradients/dropdown.js +0 -2
  211. package/build-module/components/colors-gradients/dropdown.js.map +1 -1
  212. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +4 -19
  213. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  214. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -2
  215. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -1
  216. package/build-module/components/copy-handler/index.js +38 -10
  217. package/build-module/components/copy-handler/index.js.map +1 -1
  218. package/build-module/components/default-style-picker/index.js +1 -0
  219. package/build-module/components/default-style-picker/index.js.map +1 -1
  220. package/build-module/components/font-sizes/fluid-utils.js +5 -2
  221. package/build-module/components/font-sizes/fluid-utils.js.map +1 -1
  222. package/build-module/components/font-sizes/utils.js +11 -5
  223. package/build-module/components/font-sizes/utils.js.map +1 -1
  224. package/build-module/components/font-sizes/with-font-sizes.js +14 -11
  225. package/build-module/components/font-sizes/with-font-sizes.js.map +1 -1
  226. package/build-module/components/gradients/use-gradient.js +2 -7
  227. package/build-module/components/gradients/use-gradient.js.map +1 -1
  228. package/build-module/components/iframe/index.js +46 -102
  229. package/build-module/components/iframe/index.js.map +1 -1
  230. package/build-module/components/iframe/use-compatibility-styles.js +90 -0
  231. package/build-module/components/iframe/use-compatibility-styles.js.map +1 -0
  232. package/build-module/components/image-size-control/index.js +1 -0
  233. package/build-module/components/image-size-control/index.js.map +1 -1
  234. package/build-module/components/inner-blocks/index.js +6 -2
  235. package/build-module/components/inner-blocks/index.js.map +1 -1
  236. package/build-module/components/inserter/block-patterns-tab.js +4 -4
  237. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  238. package/build-module/components/inserter/hooks/use-insertion-point.js +4 -3
  239. package/build-module/components/inserter/hooks/use-insertion-point.js.map +1 -1
  240. package/build-module/components/inserter/index.js +16 -6
  241. package/build-module/components/inserter/index.js.map +1 -1
  242. package/build-module/components/inserter/media-tab/hooks.js +8 -5
  243. package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
  244. package/build-module/components/inserter/menu.js +11 -5
  245. package/build-module/components/inserter/menu.js.map +1 -1
  246. package/build-module/components/inserter/quick-inserter.js +6 -3
  247. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  248. package/build-module/components/inserter/search-items.js +15 -13
  249. package/build-module/components/inserter/search-items.js.map +1 -1
  250. package/build-module/components/inserter/search-results.js +4 -2
  251. package/build-module/components/inserter/search-results.js.map +1 -1
  252. package/build-module/components/inspector-controls/groups.js +3 -1
  253. package/build-module/components/inspector-controls/groups.js.map +1 -1
  254. package/build-module/components/inspector-controls-tabs/position-controls-panel.js +33 -0
  255. package/build-module/components/inspector-controls-tabs/position-controls-panel.js.map +1 -0
  256. package/build-module/components/inspector-controls-tabs/settings-tab.js +2 -1
  257. package/build-module/components/inspector-controls-tabs/settings-tab.js.map +1 -1
  258. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js +4 -11
  259. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +1 -1
  260. package/build-module/components/link-control/search-input.js +1 -0
  261. package/build-module/components/link-control/search-input.js.map +1 -1
  262. package/build-module/components/list-view/block-select-button.js +1 -1
  263. package/build-module/components/list-view/block-select-button.js.map +1 -1
  264. package/build-module/components/off-canvas-editor/appender.js +5 -44
  265. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  266. package/build-module/components/off-canvas-editor/block-contents.js +37 -7
  267. package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
  268. package/build-module/components/off-canvas-editor/block-select-button.js +3 -2
  269. package/build-module/components/off-canvas-editor/block-select-button.js.map +1 -1
  270. package/build-module/components/off-canvas-editor/block.js +54 -60
  271. package/build-module/components/off-canvas-editor/block.js.map +1 -1
  272. package/build-module/components/off-canvas-editor/index.js +12 -5
  273. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  274. package/build-module/components/off-canvas-editor/use-inserted-block.js +47 -0
  275. package/build-module/components/off-canvas-editor/use-inserted-block.js.map +1 -0
  276. package/build-module/components/provider/index.js +3 -1
  277. package/build-module/components/provider/index.js.map +1 -1
  278. package/build-module/components/responsive-block-control/label.js +1 -2
  279. package/build-module/components/responsive-block-control/label.js.map +1 -1
  280. package/build-module/components/rich-text/format-edit.js +12 -9
  281. package/build-module/components/rich-text/format-edit.js.map +1 -1
  282. package/build-module/components/rich-text/index.js.map +1 -1
  283. package/build-module/components/rich-text/use-enter.js +4 -5
  284. package/build-module/components/rich-text/use-enter.js.map +1 -1
  285. package/build-module/components/rich-text/use-paste-handler.js +22 -12
  286. package/build-module/components/rich-text/use-paste-handler.js.map +1 -1
  287. package/build-module/components/spacing-sizes-control/index.js +0 -1
  288. package/build-module/components/spacing-sizes-control/index.js.map +1 -1
  289. package/build-module/components/spacing-sizes-control/utils.js +1 -1
  290. package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
  291. package/build-module/components/typewriter/index.js +1 -1
  292. package/build-module/components/typewriter/index.js.map +1 -1
  293. package/build-module/components/url-input/button.js +1 -0
  294. package/build-module/components/url-input/button.js.map +1 -1
  295. package/build-module/components/url-input/index.js +14 -1
  296. package/build-module/components/url-input/index.js.map +1 -1
  297. package/build-module/components/url-popover/image-url-input-ui.js +3 -3
  298. package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
  299. package/build-module/components/url-popover/link-editor.js +1 -0
  300. package/build-module/components/url-popover/link-editor.js.map +1 -1
  301. package/build-module/components/use-paste-styles/index.js +174 -0
  302. package/build-module/components/use-paste-styles/index.js.map +1 -0
  303. package/build-module/components/writing-flow/index.js +1 -1
  304. package/build-module/components/writing-flow/index.js.map +1 -1
  305. package/build-module/components/writing-flow/use-arrow-nav.js +22 -29
  306. package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
  307. package/build-module/hooks/border.js +0 -1
  308. package/build-module/hooks/border.js.map +1 -1
  309. package/build-module/hooks/color-panel.js +0 -1
  310. package/build-module/hooks/color-panel.js.map +1 -1
  311. package/build-module/hooks/color.js +1 -2
  312. package/build-module/hooks/color.js.map +1 -1
  313. package/build-module/hooks/font-family.js +5 -5
  314. package/build-module/hooks/font-family.js.map +1 -1
  315. package/build-module/hooks/font-size.js +5 -3
  316. package/build-module/hooks/font-size.js.map +1 -1
  317. package/build-module/hooks/index.js +1 -0
  318. package/build-module/hooks/index.js.map +1 -1
  319. package/build-module/hooks/metadata.js +1 -1
  320. package/build-module/hooks/metadata.js.map +1 -1
  321. package/build-module/hooks/position.js +337 -0
  322. package/build-module/hooks/position.js.map +1 -0
  323. package/build-module/hooks/supports.js +257 -0
  324. package/build-module/hooks/supports.js.map +1 -0
  325. package/build-module/hooks/use-typography-props.js +11 -8
  326. package/build-module/hooks/use-typography-props.js.map +1 -1
  327. package/build-module/store/reducer.js +27 -8
  328. package/build-module/store/reducer.js.map +1 -1
  329. package/build-module/store/selectors.js +9 -7
  330. package/build-module/store/selectors.js.map +1 -1
  331. package/build-module/utils/pasting.js +6 -10
  332. package/build-module/utils/pasting.js.map +1 -1
  333. package/build-style/content-rtl.css +60 -3
  334. package/build-style/content.css +60 -3
  335. package/build-style/default-editor-styles-rtl.css +3 -3
  336. package/build-style/default-editor-styles.css +3 -3
  337. package/build-style/style-rtl.css +62 -69
  338. package/build-style/style.css +62 -69
  339. package/package.json +29 -29
  340. package/src/components/alignment-control/test/index.js +2 -0
  341. package/src/components/alignment-control/ui.js +1 -7
  342. package/src/components/block-actions/index.js +5 -0
  343. package/src/components/block-alignment-control/test/index.js +2 -0
  344. package/src/components/block-alignment-control/use-available-alignments.js +4 -3
  345. package/src/components/block-icon/index.js +4 -2
  346. package/src/components/block-icon/test/index.js +9 -5
  347. package/src/components/block-inspector/index.js +79 -4
  348. package/src/components/block-inspector/style.scss +7 -0
  349. package/src/components/block-list-appender/index.js +65 -54
  350. package/src/components/block-list-appender/index.native.js +45 -34
  351. package/src/components/block-mobile-toolbar/block-actions-menu.native.js +18 -22
  352. package/src/components/block-mobile-toolbar/index.native.js +1 -1
  353. package/src/components/block-mobile-toolbar/test/__snapshots__/block-actions-menu.native.js.snap +125 -0
  354. package/src/components/block-mobile-toolbar/test/block-actions-menu.native.js +439 -0
  355. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +42 -0
  356. package/src/components/block-mover/test/index.native.js +157 -1
  357. package/src/components/block-pattern-setup/index.js +15 -6
  358. package/src/components/block-pattern-setup/style.scss +29 -1
  359. package/src/components/block-preview/auto.js +2 -4
  360. package/src/components/block-settings-menu/block-settings-dropdown.js +4 -0
  361. package/src/components/block-styles/index.js +4 -1
  362. package/src/components/block-styles/index.native.js +1 -2
  363. package/src/components/block-styles/utils.js +5 -7
  364. package/src/components/block-switcher/test/index.js +3 -2
  365. package/src/components/block-toolbar/index.native.js +8 -11
  366. package/src/components/block-tools/selected-block-popover.js +1 -3
  367. package/src/components/block-tools/use-block-toolbar-popover-props.js +68 -12
  368. package/src/components/block-variation-picker/index.js +5 -1
  369. package/src/components/block-vertical-alignment-control/test/index.js +2 -0
  370. package/src/components/button-block-appender/{style.scss → content.scss} +0 -0
  371. package/src/components/colors/test/with-colors.js +2 -0
  372. package/src/components/colors/utils.js +5 -3
  373. package/src/components/colors-gradients/control.js +0 -7
  374. package/src/components/colors-gradients/dropdown.js +0 -2
  375. package/src/components/colors-gradients/panel-color-gradient-settings.js +4 -22
  376. package/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -2
  377. package/src/components/copy-handler/index.js +53 -7
  378. package/src/components/default-block-appender/test/index.js +2 -0
  379. package/src/components/default-style-picker/index.js +1 -0
  380. package/src/components/font-sizes/fluid-utils.js +7 -1
  381. package/src/components/font-sizes/utils.js +5 -3
  382. package/src/components/font-sizes/with-font-sizes.js +36 -36
  383. package/src/components/gradients/use-gradient.js +2 -7
  384. package/src/components/iframe/index.js +60 -122
  385. package/src/components/iframe/use-compatibility-styles.js +101 -0
  386. package/src/components/image-size-control/index.js +1 -0
  387. package/src/components/image-size-control/test/index.js +147 -79
  388. package/src/components/inner-blocks/index.js +4 -2
  389. package/src/components/inserter/block-patterns-tab.js +7 -4
  390. package/src/components/inserter/hooks/use-insertion-point.js +3 -2
  391. package/src/components/inserter/index.js +61 -43
  392. package/src/components/inserter/media-tab/hooks.js +5 -4
  393. package/src/components/inserter/menu.js +8 -4
  394. package/src/components/inserter/quick-inserter.js +3 -0
  395. package/src/components/inserter/search-items.js +1 -2
  396. package/src/components/inserter/search-results.js +2 -0
  397. package/src/components/inserter/test/__snapshots__/index.native.js.snap +117 -0
  398. package/src/components/inserter/test/index.native.js +255 -1
  399. package/src/components/inspector-controls/groups.js +2 -0
  400. package/src/components/inspector-controls-tabs/position-controls-panel.js +37 -0
  401. package/src/components/inspector-controls-tabs/settings-tab.js +2 -0
  402. package/src/components/inspector-controls-tabs/style.scss +15 -0
  403. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +3 -8
  404. package/src/components/link-control/search-input.js +1 -0
  405. package/src/components/link-control/style.scss +1 -0
  406. package/src/components/link-control/test/index.js +18 -4
  407. package/src/components/list-view/block-select-button.js +1 -1
  408. package/src/components/list-view/style.scss +14 -10
  409. package/src/components/media-replace-flow/test/index.js +2 -0
  410. package/src/components/off-canvas-editor/appender.js +4 -49
  411. package/src/components/off-canvas-editor/block-contents.js +84 -23
  412. package/src/components/off-canvas-editor/block-select-button.js +6 -2
  413. package/src/components/off-canvas-editor/block.js +90 -105
  414. package/src/components/off-canvas-editor/index.js +21 -2
  415. package/src/components/off-canvas-editor/style.scss +5 -1
  416. package/src/components/off-canvas-editor/test/use-inserted-block.js +108 -0
  417. package/src/components/off-canvas-editor/use-inserted-block.js +47 -0
  418. package/src/components/provider/index.js +4 -1
  419. package/src/components/responsive-block-control/label.js +2 -3
  420. package/src/components/responsive-block-control/test/index.js +4 -2
  421. package/src/components/rich-text/format-edit.js +6 -10
  422. package/src/components/rich-text/index.js +1 -0
  423. package/src/components/rich-text/use-enter.js +4 -4
  424. package/src/components/rich-text/use-paste-handler.js +33 -14
  425. package/src/components/spacing-sizes-control/index.js +0 -1
  426. package/src/components/spacing-sizes-control/utils.js +1 -1
  427. package/src/components/typewriter/index.js +3 -1
  428. package/src/components/url-input/README.md +5 -0
  429. package/src/components/url-input/button.js +1 -0
  430. package/src/components/url-input/index.js +15 -1
  431. package/src/components/url-input/test/button.js +2 -0
  432. package/src/components/url-popover/image-url-input-ui.js +5 -4
  433. package/src/components/url-popover/link-editor.js +1 -0
  434. package/src/components/url-popover/test/index.js +21 -5
  435. package/src/components/use-paste-styles/index.js +230 -0
  436. package/src/components/warning/test/index.js +2 -0
  437. package/src/components/writing-flow/index.js +1 -1
  438. package/src/components/writing-flow/use-arrow-nav.js +20 -28
  439. package/src/content.scss +1 -0
  440. package/src/hooks/border.js +0 -1
  441. package/src/hooks/color-panel.js +0 -1
  442. package/src/hooks/color.js +0 -2
  443. package/src/hooks/font-family.js +3 -5
  444. package/src/hooks/font-size.js +13 -4
  445. package/src/hooks/index.js +1 -0
  446. package/src/hooks/metadata.js +1 -2
  447. package/src/hooks/position.js +375 -0
  448. package/src/hooks/position.scss +18 -0
  449. package/src/hooks/supports.js +302 -0
  450. package/src/hooks/test/__snapshots__/align.native.js.snap +73 -0
  451. package/src/hooks/test/align.native.js +133 -0
  452. package/src/hooks/test/use-typography-props.js +26 -0
  453. package/src/hooks/use-typography-props.js +15 -7
  454. package/src/store/reducer.js +20 -8
  455. package/src/store/selectors.js +7 -8
  456. package/src/store/test/reducer.js +45 -3
  457. package/src/store/test/selectors.js +12 -9
  458. package/src/style.scss +2 -1
  459. package/src/utils/pasting.js +3 -9
  460. package/tsconfig.tsbuildinfo +1 -1
  461. package/build/components/colors-gradients/use-common-single-multiple-selects.js +0 -21
  462. package/build/components/colors-gradients/use-common-single-multiple-selects.js.map +0 -1
  463. package/build/components/rich-text/file-paste-handler.js +0 -21
  464. package/build/components/rich-text/file-paste-handler.js.map +0 -1
  465. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js +0 -11
  466. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js.map +0 -1
  467. package/build-module/components/rich-text/file-paste-handler.js +0 -13
  468. package/build-module/components/rich-text/file-paste-handler.js.map +0 -1
  469. package/src/components/colors-gradients/use-common-single-multiple-selects.js +0 -11
  470. package/src/components/rich-text/file-paste-handler.js +0 -13
@@ -0,0 +1,47 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { store as blockEditorStore } from '../../store';
10
+
11
+ export const useInsertedBlock = ( insertedBlockClientId ) => {
12
+ const { insertedBlockAttributes, insertedBlockName } = useSelect(
13
+ ( select ) => {
14
+ const { getBlockName, getBlockAttributes } =
15
+ select( blockEditorStore );
16
+
17
+ return {
18
+ insertedBlockAttributes: getBlockAttributes(
19
+ insertedBlockClientId
20
+ ),
21
+ insertedBlockName: getBlockName( insertedBlockClientId ),
22
+ };
23
+ },
24
+ [ insertedBlockClientId ]
25
+ );
26
+
27
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
28
+
29
+ const setInsertedBlockAttributes = ( _updatedAttributes ) => {
30
+ if ( ! insertedBlockClientId ) return;
31
+ updateBlockAttributes( insertedBlockClientId, _updatedAttributes );
32
+ };
33
+
34
+ if ( ! insertedBlockClientId ) {
35
+ return {
36
+ insertedBlockAttributes: undefined,
37
+ insertedBlockName: undefined,
38
+ setInsertedBlockAttributes,
39
+ };
40
+ }
41
+
42
+ return {
43
+ insertedBlockAttributes,
44
+ insertedBlockName,
45
+ setInsertedBlockAttributes,
46
+ };
47
+ };
@@ -19,7 +19,10 @@ function BlockEditorProvider( props ) {
19
19
 
20
20
  const { updateSettings } = useDispatch( blockEditorStore );
21
21
  useEffect( () => {
22
- updateSettings( settings );
22
+ updateSettings( {
23
+ ...settings,
24
+ __internalIsInitialized: true,
25
+ } );
23
26
  }, [ settings ] );
24
27
 
25
28
  // Syncs the entity provider with changes in the block-editor store.
@@ -4,7 +4,6 @@
4
4
  import { useInstanceId } from '@wordpress/compose';
5
5
  import { VisuallyHidden } from '@wordpress/components';
6
6
  import { _x, sprintf } from '@wordpress/i18n';
7
- import { Fragment } from '@wordpress/element';
8
7
 
9
8
  export default function ResponsiveBlockControlLabel( {
10
9
  property,
@@ -24,13 +23,13 @@ export default function ResponsiveBlockControlLabel( {
24
23
  viewport.label
25
24
  );
26
25
  return (
27
- <Fragment>
26
+ <>
28
27
  <span aria-describedby={ `rbc-desc-${ instanceId }` }>
29
28
  { viewport.label }
30
29
  </span>
31
30
  <VisuallyHidden as="span" id={ `rbc-desc-${ instanceId }` }>
32
31
  { accessibleLabel }
33
32
  </VisuallyHidden>
34
- </Fragment>
33
+ </>
35
34
  );
36
35
  }
@@ -15,6 +15,8 @@ import { SelectControl } from '@wordpress/components';
15
15
  */
16
16
  import ResponsiveBlockControl from '../index';
17
17
 
18
+ jest.useFakeTimers();
19
+
18
20
  const inputId = 'input-12345678';
19
21
 
20
22
  const sizeOptions = [
@@ -38,13 +40,13 @@ const sizeOptions = [
38
40
 
39
41
  const renderTestDefaultControlComponent = ( labelComponent, device ) => {
40
42
  return (
41
- <Fragment>
43
+ <>
42
44
  <SelectControl label={ labelComponent } options={ sizeOptions } />
43
45
  <p id={ device.id }>
44
46
  { device.label } is used here for testing purposes to ensure we
45
47
  have access to details about the device.
46
48
  </p>
47
- </Fragment>
49
+ </>
48
50
  );
49
51
  };
50
52
 
@@ -6,10 +6,6 @@ import {
6
6
  getActiveObject,
7
7
  isCollapsed,
8
8
  } from '@wordpress/rich-text';
9
- /**
10
- * External dependencies
11
- */
12
- import { find } from 'lodash';
13
9
 
14
10
  export default function FormatEdit( {
15
11
  formatTypes,
@@ -40,13 +36,13 @@ export default function FormatEdit( {
40
36
  if ( name === 'core/link' && ! isCollapsed( value ) ) {
41
37
  const formats = value.formats;
42
38
 
43
- const linkFormatAtStart = find( formats[ value.start ], {
44
- type: 'core/link',
45
- } );
39
+ const linkFormatAtStart = formats[ value.start ]?.find(
40
+ ( { type } ) => type === 'core/link'
41
+ );
46
42
 
47
- const linkFormatAtEnd = find( formats[ value.end - 1 ], {
48
- type: 'core/link',
49
- } );
43
+ const linkFormatAtEnd = formats[ value.end - 1 ]?.find(
44
+ ( { type } ) => type === 'core/link'
45
+ );
50
46
 
51
47
  if (
52
48
  ! linkFormatAtStart ||
@@ -368,6 +368,7 @@ function RichTextWrapper(
368
368
  <Popover.__unstableSlotNameProvider value="__unstable-block-tools-after">
369
369
  { children &&
370
370
  children( { value, onChange, onFocus } ) }
371
+
371
372
  <FormatEdit
372
373
  value={ value }
373
374
  onChange={ onChange }
@@ -28,6 +28,10 @@ export function useEnter( props ) {
28
28
  return;
29
29
  }
30
30
 
31
+ if ( event.keyCode !== ENTER ) {
32
+ return;
33
+ }
34
+
31
35
  const {
32
36
  removeEditorOnlyFormats,
33
37
  value,
@@ -40,10 +44,6 @@ export function useEnter( props ) {
40
44
  onSplitAtEnd,
41
45
  } = propsRef.current;
42
46
 
43
- if ( event.keyCode !== ENTER ) {
44
- return;
45
- }
46
-
47
47
  event.preventDefault();
48
48
 
49
49
  const _value = { ...value };
@@ -4,7 +4,11 @@
4
4
  import { useRef } from '@wordpress/element';
5
5
  import { useRefEffect } from '@wordpress/compose';
6
6
  import { getFilesFromDataTransfer } from '@wordpress/dom';
7
- import { pasteHandler } from '@wordpress/blocks';
7
+ import {
8
+ pasteHandler,
9
+ findTransform,
10
+ getBlockTransforms,
11
+ } from '@wordpress/blocks';
8
12
  import {
9
13
  isEmpty,
10
14
  insert,
@@ -17,7 +21,6 @@ import { isURL } from '@wordpress/url';
17
21
  /**
18
22
  * Internal dependencies
19
23
  */
20
- import { filePasteHandler } from './file-paste-handler';
21
24
  import { addActiveFormats, isShortcode } from './utils';
22
25
  import { splitValue } from './split-value';
23
26
  import { shouldDismissPastedFiles } from '../../utils/pasting';
@@ -155,6 +158,12 @@ export function usePasteHandler( props ) {
155
158
  return;
156
159
  }
157
160
 
161
+ if ( files?.length ) {
162
+ // Allows us to ask for this information when we get a report.
163
+ // eslint-disable-next-line no-console
164
+ window.console.log( 'Received items:\n\n', files );
165
+ }
166
+
158
167
  // Process any attached files, unless we infer that the files in
159
168
  // question are redundant "screenshots" of the actual HTML payload,
160
169
  // as created by certain office-type programs.
@@ -164,23 +173,33 @@ export function usePasteHandler( props ) {
164
173
  files?.length &&
165
174
  ! shouldDismissPastedFiles( files, html, plainText )
166
175
  ) {
167
- const content = pasteHandler( {
168
- HTML: filePasteHandler( files ),
169
- mode: 'BLOCKS',
170
- tagName,
171
- preserveWhiteSpace,
172
- } );
173
-
174
- // Allows us to ask for this information when we get a report.
175
- // eslint-disable-next-line no-console
176
- window.console.log( 'Received items:\n\n', files );
176
+ const fromTransforms = getBlockTransforms( 'from' );
177
+ const blocks = files
178
+ .reduce( ( accumulator, file ) => {
179
+ const transformation = findTransform(
180
+ fromTransforms,
181
+ ( transform ) =>
182
+ transform.type === 'files' &&
183
+ transform.isMatch( [ file ] )
184
+ );
185
+ if ( transformation ) {
186
+ accumulator.push(
187
+ transformation.transform( [ file ] )
188
+ );
189
+ }
190
+ return accumulator;
191
+ }, [] )
192
+ .flat();
193
+ if ( ! blocks.length ) {
194
+ return;
195
+ }
177
196
 
178
197
  if ( onReplace && isEmpty( value ) ) {
179
- onReplace( content );
198
+ onReplace( blocks );
180
199
  } else {
181
200
  splitValue( {
182
201
  value,
183
- pastedBlocks: content,
202
+ pastedBlocks: blocks,
184
203
  onReplace,
185
204
  onSplit,
186
205
  onSplitMiddle,
@@ -78,7 +78,6 @@ export default function SpacingSizesControl( {
78
78
 
79
79
  return (
80
80
  <fieldset
81
- role="region"
82
81
  className={ classnames( 'component-spacing-sizes-control', {
83
82
  'is-unlinked': ! isLinked,
84
83
  } ) }
@@ -96,7 +96,7 @@ export function getSpacingPresetCssVar( value ) {
96
96
  *
97
97
  * @param {string} value Value to extract slug from.
98
98
  *
99
- * @return {number} The int value of the slug from given spacing preset.
99
+ * @return {string|undefined} The int value of the slug from given spacing preset.
100
100
  */
101
101
  export function getSpacingPresetSlug( value ) {
102
102
  if ( ! value ) {
@@ -105,7 +105,9 @@ export function useTypewriter() {
105
105
  return;
106
106
  }
107
107
 
108
- const windowScroll = scrollContainer === ownerDocument.body;
108
+ const windowScroll =
109
+ scrollContainer === ownerDocument.body ||
110
+ scrollContainer === ownerDocument.documentElement;
109
111
  const scrollY = windowScroll
110
112
  ? defaultView.scrollY
111
113
  : scrollContainer.scrollTop;
@@ -160,6 +160,10 @@ When hiding the URLInput using CSS (as is sometimes done for accessibility purpo
160
160
 
161
161
  This prop allows the suggestions list to be programmatically not rendered by passing a boolean—it can be `true` to make sure suggestions aren't rendered, or `false`/`undefined` to fall back to the default behaviour of showing suggestions when matching autocompletion items are found.
162
162
 
163
+ ### `__nextHasNoMarginBottom: Boolean`
164
+
165
+ Start opting into the new margin-free styles that will become the default in a future version, currently scheduled to be WordPress 6.4. (The prop can be safely removed once this happens.)
166
+
163
167
  ## Example
164
168
 
165
169
  {% codetabs %}
@@ -217,6 +221,7 @@ registerBlockType( /* ... */, {
217
221
  edit( { className, attributes, setAttributes } ) {
218
222
  return (
219
223
  <URLInput
224
+ __nextHasNoMarginBottom
220
225
  className={ className }
221
226
  value={ attributes.url }
222
227
  onChange={ ( url, post ) => setAttributes( { url, text: (post && post.title) || 'Click here' } ) }
@@ -57,6 +57,7 @@ class URLInputButton extends Component {
57
57
  onClick={ this.toggle }
58
58
  />
59
59
  <URLInput
60
+ __nextHasNoMarginBottom
60
61
  value={ url || '' }
61
62
  onChange={ onChange }
62
63
  />
@@ -7,6 +7,7 @@ import scrollIntoView from 'dom-scroll-into-view';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
+ import deprecated from '@wordpress/deprecated';
10
11
  import { __, sprintf, _n } from '@wordpress/i18n';
11
12
  import { Component, createRef } from '@wordpress/element';
12
13
  import { UP, DOWN, ENTER, TAB } from '@wordpress/keycodes';
@@ -424,6 +425,8 @@ class URLInput extends Component {
424
425
 
425
426
  renderControl() {
426
427
  const {
428
+ /** Start opting into the new margin-free styles that will become the default in a future version. */
429
+ __nextHasNoMarginBottom = false,
427
430
  label = null,
428
431
  className,
429
432
  isFullWidth,
@@ -477,8 +480,19 @@ class URLInput extends Component {
477
480
  return renderControl( controlProps, inputProps, loading );
478
481
  }
479
482
 
483
+ if ( ! __nextHasNoMarginBottom ) {
484
+ deprecated( 'Bottom margin styles for wp.blockEditor.URLInput', {
485
+ since: '6.2',
486
+ version: '6.5',
487
+ hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version',
488
+ } );
489
+ }
490
+
480
491
  return (
481
- <BaseControl { ...controlProps }>
492
+ <BaseControl
493
+ __nextHasNoMarginBottom={ __nextHasNoMarginBottom }
494
+ { ...controlProps }
495
+ >
482
496
  <input { ...inputProps } />
483
497
  { loading && <Spinner /> }
484
498
  </BaseControl>
@@ -9,6 +9,8 @@ import userEvent from '@testing-library/user-event';
9
9
  */
10
10
  import URLInputButton from '../button';
11
11
 
12
+ jest.useFakeTimers();
13
+
12
14
  describe( 'URLInputButton', () => {
13
15
  it( 'should render a `Insert link` button and not be pressed when `url` is not provided', () => {
14
16
  render( <URLInputButton /> );
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { find, map } from 'lodash';
4
+ import { map } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -189,7 +189,7 @@ const ImageURLInputUI = ( {
189
189
  linkDestinationInput = LINK_DESTINATION_NONE;
190
190
  } else {
191
191
  linkDestinationInput = (
192
- find( linkDestinations, ( destination ) => {
192
+ linkDestinations.find( ( destination ) => {
193
193
  return destination.url === value;
194
194
  } ) || { linkDestination: LINK_DESTINATION_CUSTOM }
195
195
  ).linkDestination;
@@ -236,8 +236,9 @@ const ImageURLInputUI = ( {
236
236
  const linkEditorValue = urlInput !== null ? urlInput : url;
237
237
 
238
238
  const urlLabel = (
239
- find( getLinkDestinations(), [ 'linkDestination', linkDestination ] ) ||
240
- {}
239
+ getLinkDestinations().find(
240
+ ( destination ) => destination.linkDestination === linkDestination
241
+ ) || {}
241
242
  ).title;
242
243
 
243
244
  return (
@@ -31,6 +31,7 @@ export default function LinkEditor( {
31
31
  { ...props }
32
32
  >
33
33
  <URLInput
34
+ __nextHasNoMarginBottom
34
35
  value={ value }
35
36
  onChange={ onChangeInputValue }
36
37
  autocompleteRef={ autocompleteRef }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { act, render, screen } from '@testing-library/react';
4
+ import { render, screen, waitFor } from '@testing-library/react';
5
5
  import userEvent from '@testing-library/user-event';
6
6
 
7
7
  /**
@@ -11,6 +11,16 @@ import URLPopover from '../';
11
11
 
12
12
  jest.useRealTimers();
13
13
 
14
+ /**
15
+ * Returns the first found popover element up the DOM tree.
16
+ *
17
+ * @param {HTMLElement} element Element to start with.
18
+ * @return {HTMLElement|null} Popover element, or `null` if not found.
19
+ */
20
+ function getWrappingPopoverElement( element ) {
21
+ return element.closest( '.components-popover' );
22
+ }
23
+
14
24
  describe( 'URLPopover', () => {
15
25
  it( 'matches the snapshot in its default state', async () => {
16
26
  const { container } = render(
@@ -22,8 +32,11 @@ describe( 'URLPopover', () => {
22
32
  </URLPopover>
23
33
  );
24
34
 
25
- // wait for `Popover` effects to finish
26
- await act( () => Promise.resolve() );
35
+ await waitFor( () =>
36
+ expect(
37
+ getWrappingPopoverElement( screen.getByText( 'Editor' ) )
38
+ ).toBePositionedPopover()
39
+ );
27
40
 
28
41
  expect( container ).toMatchSnapshot();
29
42
  } );
@@ -53,8 +66,11 @@ describe( 'URLPopover', () => {
53
66
  </URLPopover>
54
67
  );
55
68
 
56
- // wait for `Popover` effects to finish
57
- await act( () => Promise.resolve() );
69
+ await waitFor( () =>
70
+ expect(
71
+ getWrappingPopoverElement( screen.getByText( 'Editor' ) )
72
+ ).toBePositionedPopover()
73
+ );
58
74
 
59
75
  expect( container ).toMatchSnapshot();
60
76
  } );
@@ -0,0 +1,230 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useCallback } from '@wordpress/element';
5
+ import { getBlockType, parse } from '@wordpress/blocks';
6
+ import { useDispatch, useRegistry } from '@wordpress/data';
7
+ import { store as noticesStore } from '@wordpress/notices';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { store as blockEditorStore } from '../../store';
14
+ import {
15
+ hasAlignSupport,
16
+ hasBorderSupport,
17
+ hasBackgroundColorSupport,
18
+ hasTextColorSupport,
19
+ hasGradientSupport,
20
+ hasCustomClassNameSupport,
21
+ hasFontFamilySupport,
22
+ hasFontSizeSupport,
23
+ hasLayoutSupport,
24
+ hasStyleSupport,
25
+ } from '../../hooks/supports';
26
+
27
+ /**
28
+ * Determine if the copied text looks like serialized blocks or not.
29
+ * Since plain text will always get parsed into a freeform block,
30
+ * we check that if the parsed blocks is anything other than that.
31
+ *
32
+ * @param {string} text The copied text.
33
+ * @return {boolean} True if the text looks like serialized blocks, false otherwise.
34
+ */
35
+ function hasSerializedBlocks( text ) {
36
+ try {
37
+ const blocks = parse( text, {
38
+ __unstableSkipMigrationLogs: true,
39
+ __unstableSkipAutop: true,
40
+ } );
41
+ if ( blocks.length === 1 && blocks[ 0 ].name === 'core/freeform' ) {
42
+ // It's likely that the text is just plain text and not serialized blocks.
43
+ return false;
44
+ }
45
+ return true;
46
+ } catch ( err ) {
47
+ // Parsing error, the text is not serialized blocks.
48
+ // (Even though that it technically won't happen)
49
+ return false;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Style attributes are attributes being added in `block-editor/src/hooks/*`.
55
+ * (Except for some unrelated to style like `anchor` or `settings`.)
56
+ * They generally represent the default block supports.
57
+ */
58
+ const STYLE_ATTRIBUTES = {
59
+ align: hasAlignSupport,
60
+ borderColor: ( nameOrType ) => hasBorderSupport( nameOrType, 'color' ),
61
+ backgroundColor: hasBackgroundColorSupport,
62
+ textColor: hasTextColorSupport,
63
+ gradient: hasGradientSupport,
64
+ className: hasCustomClassNameSupport,
65
+ fontFamily: hasFontFamilySupport,
66
+ fontSize: hasFontSizeSupport,
67
+ layout: hasLayoutSupport,
68
+ style: hasStyleSupport,
69
+ };
70
+
71
+ /**
72
+ * Get the "style attributes" from a given block to a target block.
73
+ *
74
+ * @param {WPBlock} sourceBlock The source block.
75
+ * @param {WPBlock} targetBlock The target block.
76
+ * @return {Object} the filtered attributes object.
77
+ */
78
+ function getStyleAttributes( sourceBlock, targetBlock ) {
79
+ return Object.entries( STYLE_ATTRIBUTES ).reduce(
80
+ ( attributes, [ attributeKey, hasSupport ] ) => {
81
+ // Only apply the attribute if both blocks support it.
82
+ if (
83
+ hasSupport( sourceBlock.name ) &&
84
+ hasSupport( targetBlock.name )
85
+ ) {
86
+ // Override attributes that are not present in the block to their defaults.
87
+ attributes[ attributeKey ] =
88
+ sourceBlock.attributes[ attributeKey ];
89
+ }
90
+ return attributes;
91
+ },
92
+ {}
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Update the target blocks with style attributes recursively.
98
+ *
99
+ * @param {WPBlock[]} targetBlocks The target blocks to be updated.
100
+ * @param {WPBlock[]} sourceBlocks The source blocks to get th style attributes from.
101
+ * @param {Function} updateBlockAttributes The function to update the attributes.
102
+ */
103
+ function recursivelyUpdateBlockAttributes(
104
+ targetBlocks,
105
+ sourceBlocks,
106
+ updateBlockAttributes
107
+ ) {
108
+ for (
109
+ let index = 0;
110
+ index < Math.min( sourceBlocks.length, targetBlocks.length );
111
+ index += 1
112
+ ) {
113
+ updateBlockAttributes(
114
+ targetBlocks[ index ].clientId,
115
+ getStyleAttributes( sourceBlocks[ index ], targetBlocks[ index ] )
116
+ );
117
+
118
+ recursivelyUpdateBlockAttributes(
119
+ targetBlocks[ index ].innerBlocks,
120
+ sourceBlocks[ index ].innerBlocks,
121
+ updateBlockAttributes
122
+ );
123
+ }
124
+ }
125
+
126
+ /**
127
+ * A hook to return a pasteStyles event function for handling pasting styles to blocks.
128
+ *
129
+ * @return {Function} A function to update the styles to the blocks.
130
+ */
131
+ export default function usePasteStyles() {
132
+ const registry = useRegistry();
133
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
134
+ const { createSuccessNotice, createWarningNotice, createErrorNotice } =
135
+ useDispatch( noticesStore );
136
+
137
+ return useCallback(
138
+ async ( targetBlocks ) => {
139
+ let html = '';
140
+ try {
141
+ // `http:` sites won't have the clipboard property on navigator.
142
+ // (with the exception of localhost.)
143
+ if ( ! window.navigator.clipboard ) {
144
+ createErrorNotice(
145
+ __(
146
+ 'Unable to paste styles. This feature is only available on secure (https) sites in supporting browsers.'
147
+ ),
148
+ { type: 'snackbar' }
149
+ );
150
+ return;
151
+ }
152
+
153
+ html = await window.navigator.clipboard.readText();
154
+ } catch ( error ) {
155
+ // Possibly the permission is denied.
156
+ createErrorNotice(
157
+ __(
158
+ 'Unable to paste styles. Please allow browser clipboard permissions before continuing.'
159
+ ),
160
+ {
161
+ type: 'snackbar',
162
+ }
163
+ );
164
+ return;
165
+ }
166
+
167
+ // Abort if the copied text is empty or doesn't look like serialized blocks.
168
+ if ( ! html || ! hasSerializedBlocks( html ) ) {
169
+ createWarningNotice(
170
+ __(
171
+ "Unable to paste styles. Block styles couldn't be found within the copied content."
172
+ ),
173
+ {
174
+ type: 'snackbar',
175
+ }
176
+ );
177
+ return;
178
+ }
179
+
180
+ const copiedBlocks = parse( html );
181
+
182
+ if ( copiedBlocks.length === 1 ) {
183
+ // Apply styles of the block to all the target blocks.
184
+ registry.batch( () => {
185
+ recursivelyUpdateBlockAttributes(
186
+ targetBlocks,
187
+ targetBlocks.map( () => copiedBlocks[ 0 ] ),
188
+ updateBlockAttributes
189
+ );
190
+ } );
191
+ } else {
192
+ registry.batch( () => {
193
+ recursivelyUpdateBlockAttributes(
194
+ targetBlocks,
195
+ copiedBlocks,
196
+ updateBlockAttributes
197
+ );
198
+ } );
199
+ }
200
+
201
+ if ( targetBlocks.length === 1 ) {
202
+ const title = getBlockType( targetBlocks[ 0 ].name )?.title;
203
+ createSuccessNotice(
204
+ sprintf(
205
+ // Translators: Name of the block being pasted, e.g. "Paragraph".
206
+ __( 'Pasted styles to %s.' ),
207
+ title
208
+ ),
209
+ { type: 'snackbar' }
210
+ );
211
+ } else {
212
+ createSuccessNotice(
213
+ sprintf(
214
+ // Translators: The number of the blocks.
215
+ __( 'Pasted styles to %d blocks.' ),
216
+ targetBlocks.length
217
+ ),
218
+ { type: 'snackbar' }
219
+ );
220
+ }
221
+ },
222
+ [
223
+ registry.batch,
224
+ updateBlockAttributes,
225
+ createSuccessNotice,
226
+ createWarningNotice,
227
+ createErrorNotice,
228
+ ]
229
+ );
230
+ }