@wordpress/block-editor 8.4.0 → 8.5.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 (369) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +56 -19
  3. package/build/components/alignment-control/index.js +13 -6
  4. package/build/components/alignment-control/index.js.map +1 -1
  5. package/build/components/block-alignment-control/index.js +13 -6
  6. package/build/components/block-alignment-control/index.js.map +1 -1
  7. package/build/components/block-draggable/index.js +2 -3
  8. package/build/components/block-draggable/index.js.map +1 -1
  9. package/build/components/block-icon/index.js +4 -0
  10. package/build/components/block-icon/index.js.map +1 -1
  11. package/build/components/block-inspector/index.js +6 -1
  12. package/build/components/block-inspector/index.js.map +1 -1
  13. package/build/components/block-list/use-block-props/index.js +1 -6
  14. package/build/components/block-list/use-block-props/index.js.map +1 -1
  15. package/build/components/block-list/use-block-props/use-focus-first-element.js +14 -17
  16. package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  17. package/build/components/block-list/use-block-props/use-focus-handler.js +7 -1
  18. package/build/components/block-list/use-block-props/use-focus-handler.js.map +1 -1
  19. package/build/components/block-list-appender/index.js +6 -1
  20. package/build/components/block-list-appender/index.js.map +1 -1
  21. package/build/components/block-lock/menu-item.js +9 -0
  22. package/build/components/block-lock/menu-item.js.map +1 -1
  23. package/build/components/block-lock/modal.js +4 -13
  24. package/build/components/block-lock/modal.js.map +1 -1
  25. package/build/components/block-lock/toolbar.js +11 -3
  26. package/build/components/block-lock/toolbar.js.map +1 -1
  27. package/build/components/block-mover/index.js +4 -0
  28. package/build/components/block-mover/index.js.map +1 -1
  29. package/build/components/block-settings-menu/block-settings-dropdown.js +50 -5
  30. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  31. package/build/components/block-switcher/index.js +1 -1
  32. package/build/components/block-switcher/index.js.map +1 -1
  33. package/build/components/block-title/index.js +2 -2
  34. package/build/components/block-title/index.js.map +1 -1
  35. package/build/components/block-title/use-block-display-title.js +1 -1
  36. package/build/components/block-title/use-block-display-title.js.map +1 -1
  37. package/build/components/block-toolbar/block-name-context.js +17 -0
  38. package/build/components/block-toolbar/block-name-context.js.map +1 -0
  39. package/build/components/block-toolbar/block-toolbar-last-item.js +20 -0
  40. package/build/components/block-toolbar/block-toolbar-last-item.js.map +1 -0
  41. package/build/components/block-toolbar/index.js +20 -5
  42. package/build/components/block-toolbar/index.js.map +1 -1
  43. package/build/components/block-tools/index.js +0 -16
  44. package/build/components/block-tools/index.js.map +1 -1
  45. package/build/components/block-variation-transforms/index.js +92 -47
  46. package/build/components/block-variation-transforms/index.js.map +1 -1
  47. package/build/components/block-vertical-alignment-control/index.js +13 -6
  48. package/build/components/block-vertical-alignment-control/index.js.map +1 -1
  49. package/build/components/contrast-checker/index.js +4 -0
  50. package/build/components/contrast-checker/index.js.map +1 -1
  51. package/build/components/convert-to-group-buttons/index.js +8 -0
  52. package/build/components/convert-to-group-buttons/index.js.map +1 -1
  53. package/build/components/convert-to-group-buttons/toolbar.js +105 -0
  54. package/build/components/convert-to-group-buttons/toolbar.js.map +1 -0
  55. package/build/components/copy-handler/index.js +4 -0
  56. package/build/components/copy-handler/index.js.map +1 -1
  57. package/build/components/font-sizes/font-size-picker.js +4 -0
  58. package/build/components/font-sizes/font-size-picker.js.map +1 -1
  59. package/build/components/iframe/index.js +6 -9
  60. package/build/components/iframe/index.js.map +1 -1
  61. package/build/components/index.js +18 -0
  62. package/build/components/index.js.map +1 -1
  63. package/build/components/justify-content-control/index.js +13 -6
  64. package/build/components/justify-content-control/index.js.map +1 -1
  65. package/build/components/keyboard-shortcuts/index.js +1 -1
  66. package/build/components/keyboard-shortcuts/index.js.map +1 -1
  67. package/build/components/line-height-control/index.js +10 -3
  68. package/build/components/line-height-control/index.js.map +1 -1
  69. package/build/components/list-view/block-select-button.js +25 -6
  70. package/build/components/list-view/block-select-button.js.map +1 -1
  71. package/build/components/list-view/block.js +5 -1
  72. package/build/components/list-view/block.js.map +1 -1
  73. package/build/components/list-view/branch.js +1 -1
  74. package/build/components/list-view/branch.js.map +1 -1
  75. package/build/components/media-replace-flow/index.js +4 -0
  76. package/build/components/media-replace-flow/index.js.map +1 -1
  77. package/build/components/multi-selection-inspector/index.js +1 -1
  78. package/build/components/multi-selection-inspector/index.js.map +1 -1
  79. package/build/components/rich-text/index.js +26 -4
  80. package/build/components/rich-text/index.js.map +1 -1
  81. package/build/components/rich-text/split-value.js +12 -2
  82. package/build/components/rich-text/split-value.js.map +1 -1
  83. package/build/components/rich-text/use-firefox-compat.js +49 -0
  84. package/build/components/rich-text/use-firefox-compat.js.map +1 -0
  85. package/build/components/rich-text/use-input-rules.js +34 -2
  86. package/build/components/rich-text/use-input-rules.js.map +1 -1
  87. package/build/components/skip-to-selected-block/index.js +4 -0
  88. package/build/components/skip-to-selected-block/index.js.map +1 -1
  89. package/build/components/writing-flow/index.js +9 -1
  90. package/build/components/writing-flow/index.js.map +1 -1
  91. package/build/components/writing-flow/use-arrow-nav.js +3 -44
  92. package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
  93. package/build/components/writing-flow/use-click-selection.js +68 -0
  94. package/build/components/writing-flow/use-click-selection.js.map +1 -0
  95. package/build/components/writing-flow/use-drag-selection.js +134 -0
  96. package/build/components/writing-flow/use-drag-selection.js.map +1 -0
  97. package/build/components/writing-flow/use-input.js +116 -0
  98. package/build/components/writing-flow/use-input.js.map +1 -0
  99. package/build/components/writing-flow/use-multi-selection.js +18 -38
  100. package/build/components/writing-flow/use-multi-selection.js.map +1 -1
  101. package/build/components/writing-flow/use-selection-observer.js +161 -0
  102. package/build/components/writing-flow/use-selection-observer.js.map +1 -0
  103. package/build/components/writing-flow/use-tab-nav.js +1 -8
  104. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  105. package/build/hooks/border-color.js +3 -3
  106. package/build/hooks/border-color.js.map +1 -1
  107. package/build/hooks/border.js +0 -14
  108. package/build/hooks/border.js.map +1 -1
  109. package/build/hooks/color.js +20 -17
  110. package/build/hooks/color.js.map +1 -1
  111. package/build/hooks/font-family.js +5 -1
  112. package/build/hooks/font-family.js.map +1 -1
  113. package/build/hooks/font-size.js +4 -2
  114. package/build/hooks/font-size.js.map +1 -1
  115. package/build/hooks/gap.js +23 -16
  116. package/build/hooks/gap.js.map +1 -1
  117. package/build/hooks/layout.js +7 -2
  118. package/build/hooks/layout.js.map +1 -1
  119. package/build/hooks/style.js +34 -3
  120. package/build/hooks/style.js.map +1 -1
  121. package/build/hooks/utils.js +29 -0
  122. package/build/hooks/utils.js.map +1 -1
  123. package/build/layouts/flex.js +76 -12
  124. package/build/layouts/flex.js.map +1 -1
  125. package/build/layouts/flow.js +9 -4
  126. package/build/layouts/flow.js.map +1 -1
  127. package/build/store/actions.js +297 -51
  128. package/build/store/actions.js.map +1 -1
  129. package/build/store/defaults.js +5 -2
  130. package/build/store/defaults.js.map +1 -1
  131. package/build/store/reducer.js +25 -13
  132. package/build/store/reducer.js.map +1 -1
  133. package/build/store/selectors.js +142 -18
  134. package/build/store/selectors.js.map +1 -1
  135. package/build/utils/dom.js +2 -1
  136. package/build/utils/dom.js.map +1 -1
  137. package/build-module/components/alignment-control/index.js +12 -4
  138. package/build-module/components/alignment-control/index.js.map +1 -1
  139. package/build-module/components/block-alignment-control/index.js +12 -4
  140. package/build-module/components/block-alignment-control/index.js.map +1 -1
  141. package/build-module/components/block-draggable/index.js +2 -3
  142. package/build-module/components/block-draggable/index.js.map +1 -1
  143. package/build-module/components/block-icon/index.js +4 -0
  144. package/build-module/components/block-icon/index.js.map +1 -1
  145. package/build-module/components/block-inspector/index.js +6 -1
  146. package/build-module/components/block-inspector/index.js.map +1 -1
  147. package/build-module/components/block-list/use-block-props/index.js +1 -4
  148. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  149. package/build-module/components/block-list/use-block-props/use-focus-first-element.js +15 -17
  150. package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
  151. package/build-module/components/block-list/use-block-props/use-focus-handler.js +7 -1
  152. package/build-module/components/block-list/use-block-props/use-focus-handler.js.map +1 -1
  153. package/build-module/components/block-list-appender/index.js +6 -1
  154. package/build-module/components/block-list-appender/index.js.map +1 -1
  155. package/build-module/components/block-lock/menu-item.js +9 -0
  156. package/build-module/components/block-lock/menu-item.js.map +1 -1
  157. package/build-module/components/block-lock/modal.js +5 -14
  158. package/build-module/components/block-lock/modal.js.map +1 -1
  159. package/build-module/components/block-lock/toolbar.js +11 -3
  160. package/build-module/components/block-lock/toolbar.js.map +1 -1
  161. package/build-module/components/block-mover/index.js +4 -0
  162. package/build-module/components/block-mover/index.js.map +1 -1
  163. package/build-module/components/block-settings-menu/block-settings-dropdown.js +50 -7
  164. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  165. package/build-module/components/block-switcher/index.js +2 -2
  166. package/build-module/components/block-switcher/index.js.map +1 -1
  167. package/build-module/components/block-title/index.js +2 -2
  168. package/build-module/components/block-title/index.js.map +1 -1
  169. package/build-module/components/block-title/use-block-display-title.js +1 -1
  170. package/build-module/components/block-title/use-block-display-title.js.map +1 -1
  171. package/build-module/components/block-toolbar/block-name-context.js +9 -0
  172. package/build-module/components/block-toolbar/block-name-context.js.map +1 -0
  173. package/build-module/components/block-toolbar/block-toolbar-last-item.js +11 -0
  174. package/build-module/components/block-toolbar/block-toolbar-last-item.js.map +1 -0
  175. package/build-module/components/block-toolbar/index.js +16 -4
  176. package/build-module/components/block-toolbar/index.js.map +1 -1
  177. package/build-module/components/block-tools/index.js +0 -16
  178. package/build-module/components/block-tools/index.js.map +1 -1
  179. package/build-module/components/block-variation-transforms/index.js +95 -49
  180. package/build-module/components/block-variation-transforms/index.js.map +1 -1
  181. package/build-module/components/block-vertical-alignment-control/index.js +12 -4
  182. package/build-module/components/block-vertical-alignment-control/index.js.map +1 -1
  183. package/build-module/components/contrast-checker/index.js +4 -0
  184. package/build-module/components/contrast-checker/index.js.map +1 -1
  185. package/build-module/components/convert-to-group-buttons/index.js +2 -1
  186. package/build-module/components/convert-to-group-buttons/index.js.map +1 -1
  187. package/build-module/components/convert-to-group-buttons/toolbar.js +90 -0
  188. package/build-module/components/convert-to-group-buttons/toolbar.js.map +1 -0
  189. package/build-module/components/copy-handler/index.js +4 -0
  190. package/build-module/components/copy-handler/index.js.map +1 -1
  191. package/build-module/components/font-sizes/font-size-picker.js +4 -0
  192. package/build-module/components/font-sizes/font-size-picker.js.map +1 -1
  193. package/build-module/components/iframe/index.js +6 -9
  194. package/build-module/components/iframe/index.js.map +1 -1
  195. package/build-module/components/index.js +2 -0
  196. package/build-module/components/index.js.map +1 -1
  197. package/build-module/components/justify-content-control/index.js +12 -4
  198. package/build-module/components/justify-content-control/index.js.map +1 -1
  199. package/build-module/components/keyboard-shortcuts/index.js +1 -1
  200. package/build-module/components/keyboard-shortcuts/index.js.map +1 -1
  201. package/build-module/components/line-height-control/index.js +9 -2
  202. package/build-module/components/line-height-control/index.js.map +1 -1
  203. package/build-module/components/list-view/block-select-button.js +22 -6
  204. package/build-module/components/list-view/block-select-button.js.map +1 -1
  205. package/build-module/components/list-view/block.js +5 -1
  206. package/build-module/components/list-view/block.js.map +1 -1
  207. package/build-module/components/list-view/branch.js +1 -1
  208. package/build-module/components/list-view/branch.js.map +1 -1
  209. package/build-module/components/media-replace-flow/index.js +4 -0
  210. package/build-module/components/media-replace-flow/index.js.map +1 -1
  211. package/build-module/components/multi-selection-inspector/index.js +2 -2
  212. package/build-module/components/multi-selection-inspector/index.js.map +1 -1
  213. package/build-module/components/rich-text/index.js +25 -4
  214. package/build-module/components/rich-text/index.js.map +1 -1
  215. package/build-module/components/rich-text/split-value.js +12 -2
  216. package/build-module/components/rich-text/split-value.js.map +1 -1
  217. package/build-module/components/rich-text/use-firefox-compat.js +39 -0
  218. package/build-module/components/rich-text/use-firefox-compat.js.map +1 -0
  219. package/build-module/components/rich-text/use-input-rules.js +35 -4
  220. package/build-module/components/rich-text/use-input-rules.js.map +1 -1
  221. package/build-module/components/skip-to-selected-block/index.js +4 -0
  222. package/build-module/components/skip-to-selected-block/index.js.map +1 -1
  223. package/build-module/components/writing-flow/index.js +5 -1
  224. package/build-module/components/writing-flow/index.js.map +1 -1
  225. package/build-module/components/writing-flow/use-arrow-nav.js +4 -45
  226. package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
  227. package/build-module/components/writing-flow/use-click-selection.js +57 -0
  228. package/build-module/components/writing-flow/use-click-selection.js.map +1 -0
  229. package/build-module/components/writing-flow/use-drag-selection.js +124 -0
  230. package/build-module/components/writing-flow/use-drag-selection.js.map +1 -0
  231. package/build-module/components/writing-flow/use-input.js +104 -0
  232. package/build-module/components/writing-flow/use-input.js.map +1 -0
  233. package/build-module/components/writing-flow/use-multi-selection.js +18 -37
  234. package/build-module/components/writing-flow/use-multi-selection.js.map +1 -1
  235. package/build-module/components/writing-flow/use-selection-observer.js +150 -0
  236. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -0
  237. package/build-module/components/writing-flow/use-tab-nav.js +1 -9
  238. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  239. package/build-module/hooks/border-color.js +5 -5
  240. package/build-module/hooks/border-color.js.map +1 -1
  241. package/build-module/hooks/border.js +0 -12
  242. package/build-module/hooks/border.js.map +1 -1
  243. package/build-module/hooks/color.js +19 -18
  244. package/build-module/hooks/color.js.map +1 -1
  245. package/build-module/hooks/font-family.js +3 -1
  246. package/build-module/hooks/font-family.js.map +1 -1
  247. package/build-module/hooks/font-size.js +4 -3
  248. package/build-module/hooks/font-size.js.map +1 -1
  249. package/build-module/hooks/gap.js +22 -15
  250. package/build-module/hooks/gap.js.map +1 -1
  251. package/build-module/hooks/layout.js +7 -2
  252. package/build-module/hooks/layout.js.map +1 -1
  253. package/build-module/hooks/style.js +33 -3
  254. package/build-module/hooks/style.js.map +1 -1
  255. package/build-module/hooks/utils.js +26 -0
  256. package/build-module/hooks/utils.js.map +1 -1
  257. package/build-module/layouts/flex.js +76 -13
  258. package/build-module/layouts/flex.js.map +1 -1
  259. package/build-module/layouts/flow.js +9 -5
  260. package/build-module/layouts/flow.js.map +1 -1
  261. package/build-module/store/actions.js +286 -49
  262. package/build-module/store/actions.js.map +1 -1
  263. package/build-module/store/defaults.js +5 -2
  264. package/build-module/store/defaults.js.map +1 -1
  265. package/build-module/store/reducer.js +25 -13
  266. package/build-module/store/reducer.js.map +1 -1
  267. package/build-module/store/selectors.js +138 -19
  268. package/build-module/store/selectors.js.map +1 -1
  269. package/build-module/utils/dom.js +2 -1
  270. package/build-module/utils/dom.js.map +1 -1
  271. package/build-style/style-rtl.css +107 -74
  272. package/build-style/style.css +107 -74
  273. package/build-types/utils/dom.d.ts.map +1 -1
  274. package/package.json +28 -28
  275. package/src/components/alignment-control/index.js +9 -4
  276. package/src/components/block-alignment-control/index.js +9 -4
  277. package/src/components/block-draggable/index.js +2 -5
  278. package/src/components/block-icon/index.js +3 -0
  279. package/src/components/block-inspector/index.js +4 -0
  280. package/src/components/block-list/style.scss +4 -5
  281. package/src/components/block-list/use-block-props/index.js +0 -5
  282. package/src/components/block-list/use-block-props/use-focus-first-element.js +19 -26
  283. package/src/components/block-list/use-block-props/use-focus-handler.js +8 -0
  284. package/src/components/block-list-appender/index.js +5 -0
  285. package/src/components/block-lock/menu-item.js +8 -1
  286. package/src/components/block-lock/modal.js +18 -13
  287. package/src/components/block-lock/style.scss +6 -3
  288. package/src/components/block-lock/toolbar.js +12 -2
  289. package/src/components/block-mover/index.js +3 -0
  290. package/src/components/block-mover/style.scss +4 -0
  291. package/src/components/block-settings-menu/block-settings-dropdown.js +62 -4
  292. package/src/components/block-switcher/index.js +2 -2
  293. package/src/components/block-switcher/style.scss +8 -1
  294. package/src/components/block-switcher/test/index.js +2 -2
  295. package/src/components/block-title/index.js +2 -2
  296. package/src/components/block-title/use-block-display-title.js +1 -1
  297. package/src/components/block-toolbar/block-name-context.js +8 -0
  298. package/src/components/block-toolbar/block-toolbar-last-item.js +12 -0
  299. package/src/components/block-toolbar/index.js +18 -2
  300. package/src/components/block-toolbar/style.scss +6 -0
  301. package/src/components/block-tools/index.js +0 -19
  302. package/src/components/block-tools/style.scss +3 -5
  303. package/src/components/block-variation-transforms/index.js +105 -36
  304. package/src/components/block-variation-transforms/style.scss +1 -1
  305. package/src/components/block-vertical-alignment-control/index.js +9 -4
  306. package/src/components/button-block-appender/style.scss +5 -1
  307. package/src/components/contrast-checker/index.js +3 -0
  308. package/src/components/convert-to-group-buttons/index.js +6 -1
  309. package/src/components/convert-to-group-buttons/toolbar.js +87 -0
  310. package/src/components/copy-handler/index.js +3 -0
  311. package/src/components/font-sizes/font-size-picker.js +3 -0
  312. package/src/components/iframe/index.js +5 -7
  313. package/src/components/index.js +2 -0
  314. package/src/components/justify-content-control/index.js +9 -4
  315. package/src/components/keyboard-shortcuts/index.js +1 -1
  316. package/src/components/line-height-control/index.js +8 -3
  317. package/src/components/list-view/block-select-button.js +21 -3
  318. package/src/components/list-view/block.js +8 -1
  319. package/src/components/list-view/branch.js +1 -1
  320. package/src/components/list-view/style.scss +56 -14
  321. package/src/components/media-placeholder/README.md +8 -0
  322. package/src/components/media-replace-flow/index.js +3 -0
  323. package/src/components/multi-selection-inspector/index.js +2 -2
  324. package/src/components/rich-text/index.js +24 -1
  325. package/src/components/rich-text/split-value.js +5 -1
  326. package/src/components/rich-text/use-firefox-compat.js +39 -0
  327. package/src/components/rich-text/use-input-rules.js +40 -3
  328. package/src/components/skip-to-selected-block/index.js +3 -0
  329. package/src/components/url-input/style.scss +3 -2
  330. package/src/components/writing-flow/index.js +8 -0
  331. package/src/components/writing-flow/readme.md +28 -0
  332. package/src/components/writing-flow/use-arrow-nav.js +4 -53
  333. package/src/components/writing-flow/use-click-selection.js +65 -0
  334. package/src/components/writing-flow/use-drag-selection.js +126 -0
  335. package/src/components/writing-flow/use-input.js +112 -0
  336. package/src/components/writing-flow/use-multi-selection.js +13 -36
  337. package/src/components/writing-flow/use-selection-observer.js +153 -0
  338. package/src/components/writing-flow/use-tab-nav.js +1 -11
  339. package/src/hooks/border-color.js +5 -5
  340. package/src/hooks/border.js +0 -13
  341. package/src/hooks/color.js +51 -24
  342. package/src/hooks/font-family.js +5 -2
  343. package/src/hooks/font-size.js +10 -7
  344. package/src/hooks/gap.js +25 -17
  345. package/src/hooks/layout.js +11 -1
  346. package/src/hooks/style.js +40 -4
  347. package/src/hooks/test/gap.js +25 -1
  348. package/src/hooks/test/style.js +94 -0
  349. package/src/hooks/test/utils.js +1 -1
  350. package/src/hooks/utils.js +26 -0
  351. package/src/layouts/flex.js +89 -5
  352. package/src/layouts/flow.js +15 -4
  353. package/src/store/actions.js +349 -32
  354. package/src/store/defaults.js +7 -2
  355. package/src/store/reducer.js +25 -10
  356. package/src/store/selectors.js +181 -24
  357. package/src/store/test/selectors.js +242 -5
  358. package/src/utils/dom.js +2 -1
  359. package/tsconfig.tsbuildinfo +1 -1
  360. package/build/components/block-list/use-block-props/use-multi-selection.js +0 -205
  361. package/build/components/block-list/use-block-props/use-multi-selection.js.map +0 -1
  362. package/build/components/block-list/use-block-props/use-scroll-into-view.js +0 -77
  363. package/build/components/block-list/use-block-props/use-scroll-into-view.js.map +0 -1
  364. package/build-module/components/block-list/use-block-props/use-multi-selection.js +0 -192
  365. package/build-module/components/block-list/use-block-props/use-multi-selection.js.map +0 -1
  366. package/build-module/components/block-list/use-block-props/use-scroll-into-view.js +0 -63
  367. package/build-module/components/block-list/use-block-props/use-scroll-into-view.js.map +0 -1
  368. package/src/components/block-list/use-block-props/use-multi-selection.js +0 -227
  369. package/src/components/block-list/use-block-props/use-scroll-into-view.js +0 -73
@@ -0,0 +1,126 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { useRefEffect } from '@wordpress/compose';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as blockEditorStore } from '../../store';
11
+
12
+ /**
13
+ * Sets the `contenteditable` wrapper element to `value`.
14
+ *
15
+ * @param {HTMLElement} node Block element.
16
+ * @param {boolean} value `contentEditable` value (true or false)
17
+ */
18
+ function setContentEditableWrapper( node, value ) {
19
+ node.contentEditable = value;
20
+ // Firefox doesn't automatically move focus.
21
+ if ( value ) node.focus();
22
+ }
23
+
24
+ /**
25
+ * Sets a multi-selection based on the native selection across blocks.
26
+ */
27
+ export default function useDragSelection() {
28
+ const { startMultiSelect, stopMultiSelect } = useDispatch(
29
+ blockEditorStore
30
+ );
31
+ const { isSelectionEnabled, hasMultiSelection } = useSelect(
32
+ blockEditorStore
33
+ );
34
+ return useRefEffect(
35
+ ( node ) => {
36
+ const { ownerDocument } = node;
37
+ const { defaultView } = ownerDocument;
38
+
39
+ let anchorElement;
40
+ let rafId;
41
+
42
+ function onMouseUp() {
43
+ stopMultiSelect();
44
+ // Equivalent to attaching the listener once.
45
+ defaultView.removeEventListener( 'mouseup', onMouseUp );
46
+ // The browser selection won't have updated yet at this point,
47
+ // so wait until the next animation frame to get the browser
48
+ // selection.
49
+ rafId = defaultView.requestAnimationFrame( () => {
50
+ if ( hasMultiSelection() ) {
51
+ return;
52
+ }
53
+
54
+ // If the selection is complete (on mouse up), and no
55
+ // multiple blocks have been selected, set focus back to the
56
+ // anchor element. if the anchor element contains the
57
+ // selection. Additionally, the contentEditable wrapper can
58
+ // now be disabled again.
59
+ setContentEditableWrapper( node, false );
60
+
61
+ const selection = defaultView.getSelection();
62
+
63
+ if ( selection.rangeCount ) {
64
+ const {
65
+ commonAncestorContainer,
66
+ } = selection.getRangeAt( 0 );
67
+
68
+ if (
69
+ anchorElement.contains( commonAncestorContainer )
70
+ ) {
71
+ anchorElement.focus();
72
+ }
73
+ }
74
+ } );
75
+ }
76
+
77
+ function onMouseLeave( { buttons, target } ) {
78
+ // The primary button must be pressed to initiate selection.
79
+ // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
80
+ if ( buttons !== 1 ) {
81
+ return;
82
+ }
83
+
84
+ // Check the attribute, not the contentEditable attribute. All
85
+ // child elements of the content editable wrapper are editable
86
+ // and return true for this property. We only want to start
87
+ // multi selecting when the mouse leaves the wrapper.
88
+ if ( ! target.getAttribute( 'contenteditable' ) ) {
89
+ return;
90
+ }
91
+
92
+ if ( ! isSelectionEnabled() ) {
93
+ return;
94
+ }
95
+
96
+ anchorElement = ownerDocument.activeElement;
97
+ startMultiSelect();
98
+
99
+ // `onSelectionStart` is called after `mousedown` and
100
+ // `mouseleave` (from a block). The selection ends when
101
+ // `mouseup` happens anywhere in the window.
102
+ defaultView.addEventListener( 'mouseup', onMouseUp );
103
+
104
+ // Allow cross contentEditable selection by temporarily making
105
+ // all content editable. We can't rely on using the store and
106
+ // React because re-rending happens too slowly. We need to be
107
+ // able to select across instances immediately.
108
+ setContentEditableWrapper( node, true );
109
+ }
110
+
111
+ node.addEventListener( 'mouseout', onMouseLeave );
112
+
113
+ return () => {
114
+ node.removeEventListener( 'mouseout', onMouseLeave );
115
+ defaultView.removeEventListener( 'mouseup', onMouseUp );
116
+ defaultView.cancelAnimationFrame( rafId );
117
+ };
118
+ },
119
+ [
120
+ startMultiSelect,
121
+ stopMultiSelect,
122
+ isSelectionEnabled,
123
+ hasMultiSelection,
124
+ ]
125
+ );
126
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { useRefEffect } from '@wordpress/compose';
6
+ import { ENTER, BACKSPACE, DELETE } from '@wordpress/keycodes';
7
+ import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { store as blockEditorStore } from '../../store';
13
+
14
+ /**
15
+ * Handles input for selections across blocks.
16
+ */
17
+ export default function useInput() {
18
+ const {
19
+ __unstableIsFullySelected,
20
+ getSelectedBlockClientIds,
21
+ __unstableIsSelectionMergeable,
22
+ hasMultiSelection,
23
+ } = useSelect( blockEditorStore );
24
+ const {
25
+ replaceBlocks,
26
+ __unstableSplitSelection,
27
+ removeBlocks,
28
+ __unstableDeleteSelection,
29
+ __unstableExpandSelection,
30
+ } = useDispatch( blockEditorStore );
31
+
32
+ return useRefEffect( ( node ) => {
33
+ function onKeyDown( event ) {
34
+ if ( event.defaultPrevented ) {
35
+ return;
36
+ }
37
+
38
+ if ( ! hasMultiSelection() ) {
39
+ return;
40
+ }
41
+
42
+ if ( event.keyCode === ENTER ) {
43
+ node.contentEditable = false;
44
+ event.preventDefault();
45
+ if ( __unstableIsFullySelected() ) {
46
+ replaceBlocks(
47
+ getSelectedBlockClientIds(),
48
+ createBlock( getDefaultBlockName() )
49
+ );
50
+ } else {
51
+ __unstableSplitSelection();
52
+ }
53
+ } else if (
54
+ event.keyCode === BACKSPACE ||
55
+ event.keyCode === DELETE
56
+ ) {
57
+ node.contentEditable = false;
58
+ event.preventDefault();
59
+ if ( __unstableIsFullySelected() ) {
60
+ removeBlocks( getSelectedBlockClientIds() );
61
+ } else if ( __unstableIsSelectionMergeable() ) {
62
+ __unstableDeleteSelection( event.keyCode === DELETE );
63
+ } else {
64
+ __unstableExpandSelection();
65
+ }
66
+ } else if (
67
+ // If key.length is longer than 1, it's a control key that doesn't
68
+ // input anything.
69
+ event.key.length === 1 &&
70
+ ! ( event.metaKey || event.ctrlKey )
71
+ ) {
72
+ node.contentEditable = false;
73
+ if ( __unstableIsSelectionMergeable() ) {
74
+ __unstableDeleteSelection( event.keyCode === DELETE );
75
+ } else {
76
+ event.preventDefault();
77
+ // Safari does not stop default behaviour with either
78
+ // event.preventDefault() or node.contentEditable = false, so
79
+ // remove the selection to stop browser manipulation.
80
+ node.ownerDocument.defaultView
81
+ .getSelection()
82
+ .removeAllRanges();
83
+ }
84
+ }
85
+ }
86
+
87
+ function onCompositionStart( event ) {
88
+ if ( ! hasMultiSelection() ) {
89
+ return;
90
+ }
91
+
92
+ node.contentEditable = false;
93
+
94
+ if ( __unstableIsSelectionMergeable() ) {
95
+ __unstableDeleteSelection();
96
+ } else {
97
+ event.preventDefault();
98
+ // Safari does not stop default behaviour with either
99
+ // event.preventDefault() or node.contentEditable = false, so
100
+ // remove the selection to stop browser manipulation.
101
+ node.ownerDocument.defaultView.getSelection().removeAllRanges();
102
+ }
103
+ }
104
+
105
+ node.addEventListener( 'keydown', onKeyDown );
106
+ node.addEventListener( 'compositionstart', onCompositionStart );
107
+ return () => {
108
+ node.removeEventListener( 'keydown', onKeyDown );
109
+ node.removeEventListener( 'compositionstart', onCompositionStart );
110
+ };
111
+ }, [] );
112
+ }
@@ -15,32 +15,6 @@ import { useSelect } from '@wordpress/data';
15
15
  import { store as blockEditorStore } from '../../store';
16
16
  import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs';
17
17
 
18
- /**
19
- * Returns for the deepest node at the start or end of a container node. Ignores
20
- * any text nodes that only contain HTML formatting whitespace.
21
- *
22
- * @param {Element} node Container to search.
23
- * @param {string} type 'start' or 'end'.
24
- */
25
- function getDeepestNode( node, type ) {
26
- const child = type === 'start' ? 'firstChild' : 'lastChild';
27
- const sibling = type === 'start' ? 'nextSibling' : 'previousSibling';
28
-
29
- while ( node[ child ] ) {
30
- node = node[ child ];
31
-
32
- while (
33
- node.nodeType === node.TEXT_NODE &&
34
- /^[ \t\n]*$/.test( node.data ) &&
35
- node[ sibling ]
36
- ) {
37
- node = node[ sibling ];
38
- }
39
- }
40
-
41
- return node;
42
- }
43
-
44
18
  function selector( select ) {
45
19
  const {
46
20
  isMultiSelecting,
@@ -48,6 +22,7 @@ function selector( select ) {
48
22
  hasMultiSelection,
49
23
  getSelectedBlockClientId,
50
24
  getSelectedBlocksInitialCaretPosition,
25
+ __unstableIsFullySelected,
51
26
  } = select( blockEditorStore );
52
27
 
53
28
  return {
@@ -56,6 +31,7 @@ function selector( select ) {
56
31
  hasMultiSelection: hasMultiSelection(),
57
32
  selectedBlockClientId: getSelectedBlockClientId(),
58
33
  initialPosition: getSelectedBlocksInitialCaretPosition(),
34
+ isFullSelection: __unstableIsFullySelected(),
59
35
  };
60
36
  }
61
37
 
@@ -66,6 +42,7 @@ export default function useMultiSelection() {
66
42
  multiSelectedBlockClientIds,
67
43
  hasMultiSelection,
68
44
  selectedBlockClientId,
45
+ isFullSelection,
69
46
  } = useSelect( selector, [] );
70
47
  const selectedRef = useBlockRef( selectedBlockClientId );
71
48
  // These must be in the right DOM order.
@@ -120,9 +97,7 @@ export default function useMultiSelection() {
120
97
  return;
121
98
  }
122
99
 
123
- // The block refs might not be immediately available
124
- // when dragging blocks into another block.
125
- if ( ! startRef.current || ! endRef.current ) {
100
+ if ( ! isFullSelection ) {
126
101
  return;
127
102
  }
128
103
 
@@ -136,17 +111,18 @@ export default function useMultiSelection() {
136
111
  // BEFORE selection.
137
112
  node.focus();
138
113
 
114
+ // The block refs might not be immediately available
115
+ // when dragging blocks into another block.
116
+ if ( ! startRef.current || ! endRef.current ) {
117
+ return;
118
+ }
119
+
139
120
  const selection = defaultView.getSelection();
140
121
  const range = ownerDocument.createRange();
141
122
 
142
123
  // These must be in the right DOM order.
143
- // The most stable way to select the whole block contents is to start
144
- // and end at the deepest points.
145
- const startNode = getDeepestNode( startRef.current, 'start' );
146
- const endNode = getDeepestNode( endRef.current, 'end' );
147
-
148
- range.setStartBefore( startNode );
149
- range.setEndAfter( endNode );
124
+ range.setStartBefore( startRef.current );
125
+ range.setEndAfter( endRef.current );
150
126
 
151
127
  selection.removeAllRanges();
152
128
  selection.addRange( range );
@@ -157,6 +133,7 @@ export default function useMultiSelection() {
157
133
  multiSelectedBlockClientIds,
158
134
  selectedBlockClientId,
159
135
  initialPosition,
136
+ isFullSelection,
160
137
  ]
161
138
  );
162
139
  }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect, useDispatch } from '@wordpress/data';
5
+ import { useRefEffect } from '@wordpress/compose';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { store as blockEditorStore } from '../../store';
11
+ import { getBlockClientId } from '../../utils/dom';
12
+
13
+ /**
14
+ * Extract the selection start node from the selection. When the anchor node is
15
+ * not a text node, the selection offset is the index of a child node.
16
+ *
17
+ * @param {Selection} selection The selection.
18
+ *
19
+ * @return {Element} The selection start node.
20
+ */
21
+ function extractSelectionStartNode( selection ) {
22
+ const { anchorNode, anchorOffset } = selection;
23
+
24
+ if ( anchorNode.nodeType === anchorNode.TEXT_NODE ) {
25
+ return anchorNode;
26
+ }
27
+
28
+ return anchorNode.childNodes[ anchorOffset ];
29
+ }
30
+
31
+ /**
32
+ * Extract the selection end node from the selection. When the focus node is not
33
+ * a text node, the selection offset is the index of a child node. The selection
34
+ * reaches up to but excluding that child node.
35
+ *
36
+ * @param {Selection} selection The selection.
37
+ *
38
+ * @return {Element} The selection start node.
39
+ */
40
+ function extractSelectionEndNode( selection ) {
41
+ const { focusNode, focusOffset } = selection;
42
+
43
+ if ( focusNode.nodeType === focusNode.TEXT_NODE ) {
44
+ return focusNode;
45
+ }
46
+
47
+ return focusNode.childNodes[ focusOffset - 1 ];
48
+ }
49
+
50
+ function findDepth( a, b ) {
51
+ let depth = 0;
52
+
53
+ while ( a[ depth ] === b[ depth ] ) {
54
+ depth++;
55
+ }
56
+
57
+ return depth;
58
+ }
59
+
60
+ /**
61
+ * Sets the `contenteditable` wrapper element to `value`.
62
+ *
63
+ * @param {HTMLElement} node Block element.
64
+ * @param {boolean} value `contentEditable` value (true or false)
65
+ */
66
+ function setContentEditableWrapper( node, value ) {
67
+ node.contentEditable = value;
68
+ // Firefox doesn't automatically move focus.
69
+ if ( value ) node.focus();
70
+ }
71
+
72
+ /**
73
+ * Sets a multi-selection based on the native selection across blocks.
74
+ */
75
+ export default function useSelectionObserver() {
76
+ const { multiSelect, selectBlock, selectionChange } = useDispatch(
77
+ blockEditorStore
78
+ );
79
+ const { getBlockParents } = useSelect( blockEditorStore );
80
+ return useRefEffect(
81
+ ( node ) => {
82
+ const { ownerDocument } = node;
83
+ const { defaultView } = ownerDocument;
84
+
85
+ function onSelectionChange() {
86
+ const selection = defaultView.getSelection();
87
+
88
+ // If no selection is found, end multi selection and disable the
89
+ // contentEditable wrapper.
90
+ if ( ! selection.rangeCount || selection.isCollapsed ) {
91
+ setContentEditableWrapper( node, false );
92
+ return;
93
+ }
94
+
95
+ const clientId = getBlockClientId(
96
+ extractSelectionStartNode( selection )
97
+ );
98
+ const endClientId = getBlockClientId(
99
+ extractSelectionEndNode( selection )
100
+ );
101
+ const isSingularSelection = clientId === endClientId;
102
+
103
+ if ( isSingularSelection ) {
104
+ selectBlock( clientId );
105
+ } else {
106
+ const startPath = [
107
+ ...getBlockParents( clientId ),
108
+ clientId,
109
+ ];
110
+ const endPath = [
111
+ ...getBlockParents( endClientId ),
112
+ endClientId,
113
+ ];
114
+ const depth = findDepth( startPath, endPath );
115
+
116
+ multiSelect( startPath[ depth ], endPath[ depth ] );
117
+ }
118
+ }
119
+
120
+ function addListeners() {
121
+ ownerDocument.addEventListener(
122
+ 'selectionchange',
123
+ onSelectionChange
124
+ );
125
+ defaultView.addEventListener( 'mouseup', onSelectionChange );
126
+ }
127
+
128
+ function removeListeners() {
129
+ ownerDocument.removeEventListener(
130
+ 'selectionchange',
131
+ onSelectionChange
132
+ );
133
+ defaultView.removeEventListener( 'mouseup', onSelectionChange );
134
+ }
135
+
136
+ function resetListeners() {
137
+ removeListeners();
138
+ addListeners();
139
+ }
140
+
141
+ addListeners();
142
+ // We must allow rich text to set selection first. This ensures that
143
+ // our `selectionchange` listener is always reset to be called after
144
+ // the rich text one.
145
+ node.addEventListener( 'focusin', resetListeners );
146
+ return () => {
147
+ removeListeners();
148
+ node.removeEventListener( 'focusin', resetListeners );
149
+ };
150
+ },
151
+ [ multiSelect, selectBlock, selectionChange, getBlockParents ]
152
+ );
153
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { focus } from '@wordpress/dom';
4
+ import { focus, isFormElement } from '@wordpress/dom';
5
5
  import { TAB, ESCAPE } from '@wordpress/keycodes';
6
6
  import { useSelect, useDispatch } from '@wordpress/data';
7
7
  import { useRefEffect, useMergeRefs } from '@wordpress/compose';
@@ -12,16 +12,6 @@ import { useRef } from '@wordpress/element';
12
12
  */
13
13
  import { store as blockEditorStore } from '../../store';
14
14
 
15
- function isFormElement( element ) {
16
- const { tagName } = element;
17
- return (
18
- tagName === 'INPUT' ||
19
- tagName === 'BUTTON' ||
20
- tagName === 'SELECT' ||
21
- tagName === 'TEXTAREA'
22
- );
23
- }
24
-
25
15
  export default function useTabNav() {
26
16
  const container = useRef();
27
17
  const focusCaptureBeforeRef = useRef();
@@ -23,11 +23,11 @@ import {
23
23
  } from '../components/colors';
24
24
  import useSetting from '../components/use-setting';
25
25
  import {
26
+ BORDER_SUPPORT_KEY,
26
27
  hasBorderSupport,
27
28
  removeBorderAttribute,
28
- shouldSkipSerialization,
29
29
  } from './border';
30
- import { cleanEmptyObject } from './utils';
30
+ import { cleanEmptyObject, shouldSkipSerialization } from './utils';
31
31
 
32
32
  // Defining empty array here instead of inline avoids unnecessary re-renders of
33
33
  // color control.
@@ -200,7 +200,7 @@ function addAttributes( settings ) {
200
200
  function addSaveProps( props, blockType, attributes ) {
201
201
  if (
202
202
  ! hasBorderSupport( blockType, 'color' ) ||
203
- shouldSkipSerialization( blockType )
203
+ shouldSkipSerialization( blockType, BORDER_SUPPORT_KEY, 'color' )
204
204
  ) {
205
205
  return props;
206
206
  }
@@ -231,7 +231,7 @@ function addSaveProps( props, blockType, attributes ) {
231
231
  function addEditProps( settings ) {
232
232
  if (
233
233
  ! hasBorderSupport( settings, 'color' ) ||
234
- shouldSkipSerialization( settings )
234
+ shouldSkipSerialization( settings, BORDER_SUPPORT_KEY, 'color' )
235
235
  ) {
236
236
  return settings;
237
237
  }
@@ -266,7 +266,7 @@ export const withBorderColorPaletteStyles = createHigherOrderComponent(
266
266
 
267
267
  if (
268
268
  ! hasBorderSupport( name, 'color' ) ||
269
- shouldSkipSerialization( name )
269
+ shouldSkipSerialization( name, BORDER_SUPPORT_KEY, 'color' )
270
270
  ) {
271
271
  return <BlockListBlock { ...props } />;
272
272
  }
@@ -171,19 +171,6 @@ export function hasBorderSupport( blockName, feature = 'any' ) {
171
171
  return !! support?.[ feature ];
172
172
  }
173
173
 
174
- /**
175
- * Check whether serialization of border classes and styles should be skipped.
176
- *
177
- * @param {string|Object} blockType Block name or block type object.
178
- *
179
- * @return {boolean} Whether serialization of border properties should occur.
180
- */
181
- export function shouldSkipSerialization( blockType ) {
182
- const support = getBlockSupport( blockType, BORDER_SUPPORT_KEY );
183
-
184
- return support?.__experimentalSkipSerialization;
185
- }
186
-
187
174
  /**
188
175
  * Returns a new style object where the specified border attribute has been
189
176
  * removed.