@ckeditor/ckeditor5-ui 47.6.1 → 48.0.0-alpha.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 (367) hide show
  1. package/LICENSE.md +1 -1
  2. package/ckeditor5-metadata.json +3 -3
  3. package/{src → dist}/colorselector/documentcolorcollection.d.ts +4 -4
  4. package/{src → dist}/dialog/dialog.d.ts +1 -1
  5. package/dist/index-editor.css +2728 -587
  6. package/dist/index.css +2673 -850
  7. package/dist/index.css.map +1 -1
  8. package/dist/index.js +11 -1
  9. package/dist/index.js.map +1 -1
  10. package/{src → dist}/menubar/menubarmenuview.d.ts +4 -0
  11. package/{src → dist}/view.d.ts +1 -1
  12. package/package.json +25 -47
  13. package/lang/contexts.json +0 -51
  14. package/lang/translations/af.po +0 -208
  15. package/lang/translations/ar.po +0 -208
  16. package/lang/translations/ast.po +0 -208
  17. package/lang/translations/az.po +0 -208
  18. package/lang/translations/be.po +0 -208
  19. package/lang/translations/bg.po +0 -208
  20. package/lang/translations/bn.po +0 -208
  21. package/lang/translations/bs.po +0 -208
  22. package/lang/translations/ca.po +0 -208
  23. package/lang/translations/cs.po +0 -208
  24. package/lang/translations/da.po +0 -208
  25. package/lang/translations/de-ch.po +0 -208
  26. package/lang/translations/de.po +0 -208
  27. package/lang/translations/el.po +0 -208
  28. package/lang/translations/en-au.po +0 -208
  29. package/lang/translations/en-gb.po +0 -208
  30. package/lang/translations/en.po +0 -208
  31. package/lang/translations/eo.po +0 -208
  32. package/lang/translations/es-co.po +0 -208
  33. package/lang/translations/es.po +0 -208
  34. package/lang/translations/et.po +0 -208
  35. package/lang/translations/eu.po +0 -208
  36. package/lang/translations/fa.po +0 -208
  37. package/lang/translations/fi.po +0 -208
  38. package/lang/translations/fr.po +0 -208
  39. package/lang/translations/gl.po +0 -208
  40. package/lang/translations/gu.po +0 -208
  41. package/lang/translations/he.po +0 -208
  42. package/lang/translations/hi.po +0 -208
  43. package/lang/translations/hr.po +0 -208
  44. package/lang/translations/hu.po +0 -208
  45. package/lang/translations/hy.po +0 -208
  46. package/lang/translations/id.po +0 -208
  47. package/lang/translations/it.po +0 -208
  48. package/lang/translations/ja.po +0 -208
  49. package/lang/translations/jv.po +0 -208
  50. package/lang/translations/kk.po +0 -208
  51. package/lang/translations/km.po +0 -208
  52. package/lang/translations/kn.po +0 -208
  53. package/lang/translations/ko.po +0 -208
  54. package/lang/translations/ku.po +0 -208
  55. package/lang/translations/lt.po +0 -208
  56. package/lang/translations/lv.po +0 -208
  57. package/lang/translations/ms.po +0 -208
  58. package/lang/translations/nb.po +0 -208
  59. package/lang/translations/ne.po +0 -208
  60. package/lang/translations/nl.po +0 -208
  61. package/lang/translations/no.po +0 -208
  62. package/lang/translations/oc.po +0 -208
  63. package/lang/translations/pl.po +0 -208
  64. package/lang/translations/pt-br.po +0 -208
  65. package/lang/translations/pt.po +0 -208
  66. package/lang/translations/ro.po +0 -208
  67. package/lang/translations/ru.po +0 -208
  68. package/lang/translations/si.po +0 -208
  69. package/lang/translations/sk.po +0 -208
  70. package/lang/translations/sl.po +0 -208
  71. package/lang/translations/sq.po +0 -208
  72. package/lang/translations/sr-latn.po +0 -208
  73. package/lang/translations/sr.po +0 -208
  74. package/lang/translations/sv.po +0 -208
  75. package/lang/translations/th.po +0 -208
  76. package/lang/translations/ti.po +0 -208
  77. package/lang/translations/tk.po +0 -208
  78. package/lang/translations/tr.po +0 -208
  79. package/lang/translations/tt.po +0 -208
  80. package/lang/translations/ug.po +0 -208
  81. package/lang/translations/uk.po +0 -208
  82. package/lang/translations/ur.po +0 -208
  83. package/lang/translations/uz.po +0 -208
  84. package/lang/translations/vi.po +0 -208
  85. package/lang/translations/zh-cn.po +0 -208
  86. package/lang/translations/zh.po +0 -208
  87. package/src/arialiveannouncer.js +0 -189
  88. package/src/augmentation.js +0 -5
  89. package/src/autocomplete/autocompleteview.js +0 -157
  90. package/src/badge/badge.js +0 -226
  91. package/src/bindings/addkeyboardhandlingforgrid.js +0 -107
  92. package/src/bindings/clickoutsidehandler.js +0 -36
  93. package/src/bindings/csstransitiondisablermixin.js +0 -58
  94. package/src/bindings/draggableviewmixin.js +0 -144
  95. package/src/bindings/preventdefault.js +0 -35
  96. package/src/bindings/submithandler.js +0 -47
  97. package/src/button/button.js +0 -5
  98. package/src/button/buttonlabel.js +0 -5
  99. package/src/button/buttonlabelview.js +0 -42
  100. package/src/button/buttonview.js +0 -278
  101. package/src/button/filedialogbuttonview.js +0 -147
  102. package/src/button/listitembuttonview.js +0 -136
  103. package/src/button/switchbuttonview.js +0 -79
  104. package/src/collapsible/collapsibleview.js +0 -106
  105. package/src/colorgrid/colorgridview.js +0 -140
  106. package/src/colorgrid/colortileview.js +0 -42
  107. package/src/colorgrid/utils.js +0 -84
  108. package/src/colorpicker/colorpickerview.js +0 -356
  109. package/src/colorpicker/utils.js +0 -108
  110. package/src/colorselector/colorgridsfragmentview.js +0 -368
  111. package/src/colorselector/colorpickerfragmentview.js +0 -254
  112. package/src/colorselector/colorselectorview.js +0 -294
  113. package/src/colorselector/documentcolorcollection.js +0 -42
  114. package/src/componentfactory.js +0 -108
  115. package/src/dialog/dialog.js +0 -325
  116. package/src/dialog/dialogactionsview.js +0 -118
  117. package/src/dialog/dialogcontentview.js +0 -39
  118. package/src/dialog/dialogview.js +0 -507
  119. package/src/dropdown/button/dropdownbutton.js +0 -5
  120. package/src/dropdown/button/dropdownbuttonview.js +0 -70
  121. package/src/dropdown/button/splitbuttonview.js +0 -178
  122. package/src/dropdown/dropdownpanelfocusable.js +0 -5
  123. package/src/dropdown/dropdownpanelview.js +0 -106
  124. package/src/dropdown/dropdownview.js +0 -438
  125. package/src/dropdown/menu/dropdownmenubehaviors.js +0 -125
  126. package/src/dropdown/menu/dropdownmenubuttonview.js +0 -69
  127. package/src/dropdown/menu/dropdownmenulistitembuttonview.js +0 -30
  128. package/src/dropdown/menu/dropdownmenulistitemview.js +0 -38
  129. package/src/dropdown/menu/dropdownmenulistview.js +0 -29
  130. package/src/dropdown/menu/dropdownmenunestedmenupanelview.js +0 -63
  131. package/src/dropdown/menu/dropdownmenunestedmenuview.js +0 -214
  132. package/src/dropdown/menu/dropdownmenurootlistview.js +0 -168
  133. package/src/dropdown/menu/utils.js +0 -61
  134. package/src/dropdown/utils.js +0 -654
  135. package/src/editableui/editableuiview.js +0 -130
  136. package/src/editableui/inline/inlineeditableuiview.js +0 -75
  137. package/src/editorui/accessibilityhelp/accessibilityhelp.js +0 -142
  138. package/src/editorui/accessibilityhelp/accessibilityhelpcontentview.js +0 -112
  139. package/src/editorui/bodycollection.js +0 -128
  140. package/src/editorui/boxed/boxededitoruiview.js +0 -95
  141. package/src/editorui/editorui.js +0 -586
  142. package/src/editorui/editoruiview.js +0 -60
  143. package/src/editorui/evaluationbadge.js +0 -99
  144. package/src/editorui/poweredby.js +0 -120
  145. package/src/focuscycler.js +0 -383
  146. package/src/formheader/formheaderview.js +0 -77
  147. package/src/formrow/formrowview.js +0 -56
  148. package/src/highlightedtext/buttonlabelwithhighlightview.js +0 -31
  149. package/src/highlightedtext/highlightedtextview.js +0 -102
  150. package/src/highlightedtext/labelwithhighlightview.js +0 -37
  151. package/src/icon/iconview.js +0 -123
  152. package/src/iframe/iframeview.js +0 -63
  153. package/src/index.js +0 -132
  154. package/src/input/inputbase.js +0 -119
  155. package/src/input/inputview.js +0 -24
  156. package/src/inputnumber/inputnumberview.js +0 -40
  157. package/src/inputtext/inputtextview.js +0 -27
  158. package/src/label/labelview.js +0 -46
  159. package/src/labeledfield/labeledfieldview.js +0 -177
  160. package/src/labeledfield/utils.js +0 -176
  161. package/src/labeledinput/labeledinputview.js +0 -138
  162. package/src/legacyerrors.js +0 -20
  163. package/src/list/listitemgroupview.js +0 -82
  164. package/src/list/listitemview.js +0 -46
  165. package/src/list/listseparatorview.js +0 -28
  166. package/src/list/listview.js +0 -210
  167. package/src/menubar/menubarmenubuttonview.js +0 -68
  168. package/src/menubar/menubarmenulistitembuttonview.js +0 -30
  169. package/src/menubar/menubarmenulistitemfiledialogbuttonview.js +0 -32
  170. package/src/menubar/menubarmenulistitemview.js +0 -34
  171. package/src/menubar/menubarmenulistview.js +0 -72
  172. package/src/menubar/menubarmenupanelview.js +0 -64
  173. package/src/menubar/menubarmenuview.js +0 -198
  174. package/src/menubar/menubarview.js +0 -281
  175. package/src/menubar/utils.js +0 -1432
  176. package/src/model.js +0 -31
  177. package/src/notification/notification.js +0 -192
  178. package/src/panel/balloon/balloonpanelview.js +0 -1077
  179. package/src/panel/balloon/contextualballoon.js +0 -616
  180. package/src/panel/sticky/stickypanelview.js +0 -246
  181. package/src/search/filteredview.js +0 -5
  182. package/src/search/filtergroupanditemnames.js +0 -38
  183. package/src/search/searchinfoview.js +0 -59
  184. package/src/search/searchresultsview.js +0 -83
  185. package/src/search/text/searchtextqueryview.js +0 -87
  186. package/src/search/text/searchtextview.js +0 -242
  187. package/src/spinner/spinnerview.js +0 -38
  188. package/src/template.js +0 -1396
  189. package/src/textarea/textareaview.js +0 -189
  190. package/src/toolbar/balloon/balloontoolbar.js +0 -358
  191. package/src/toolbar/block/blockbuttonview.js +0 -41
  192. package/src/toolbar/block/blocktoolbar.js +0 -507
  193. package/src/toolbar/normalizetoolbarconfig.js +0 -52
  194. package/src/toolbar/toolbarlinebreakview.js +0 -28
  195. package/src/toolbar/toolbarseparatorview.js +0 -28
  196. package/src/toolbar/toolbarview.js +0 -873
  197. package/src/tooltipmanager.js +0 -454
  198. package/src/view.js +0 -471
  199. package/src/viewcollection.js +0 -210
  200. package/theme/components/arialiveannouncer/arialiveannouncer.css +0 -14
  201. package/theme/components/autocomplete/autocomplete.css +0 -22
  202. package/theme/components/button/button.css +0 -39
  203. package/theme/components/button/listitembutton.css +0 -48
  204. package/theme/components/button/switchbutton.css +0 -14
  205. package/theme/components/collapsible/collapsible.css +0 -10
  206. package/theme/components/colorgrid/colorgrid.css +0 -8
  207. package/theme/components/colorpicker/colorpicker.css +0 -34
  208. package/theme/components/colorselector/colorselector.css +0 -35
  209. package/theme/components/dialog/dialog.css +0 -42
  210. package/theme/components/dialog/dialogactions.css +0 -11
  211. package/theme/components/dropdown/dropdown.css +0 -95
  212. package/theme/components/dropdown/listdropdown.css +0 -10
  213. package/theme/components/dropdown/menu/dropdownmenu.css +0 -8
  214. package/theme/components/dropdown/menu/dropdownmenubutton.css +0 -9
  215. package/theme/components/dropdown/menu/dropdownmenulistitem.css +0 -10
  216. package/theme/components/dropdown/menu/dropdownmenulistitembutton.css +0 -10
  217. package/theme/components/dropdown/menu/dropdownmenupanel.css +0 -11
  218. package/theme/components/dropdown/splitbutton.css +0 -14
  219. package/theme/components/dropdown/toolbardropdown.css +0 -20
  220. package/theme/components/editorui/accessibilityhelp.css +0 -10
  221. package/theme/components/editorui/editorui.css +0 -10
  222. package/theme/components/form/form.css +0 -87
  223. package/theme/components/formheader/formheader.css +0 -18
  224. package/theme/components/formrow/formrow.css +0 -32
  225. package/theme/components/highlightedtext/highlightedtext.css +0 -12
  226. package/theme/components/icon/icon.css +0 -8
  227. package/theme/components/input/input.css +0 -10
  228. package/theme/components/label/label.css +0 -12
  229. package/theme/components/labeledfield/labeledfieldview.css +0 -16
  230. package/theme/components/labeledinput/labeledinput.css +0 -10
  231. package/theme/components/list/list.css +0 -26
  232. package/theme/components/menubar/menubar.css +0 -10
  233. package/theme/components/menubar/menubarmenu.css +0 -9
  234. package/theme/components/menubar/menubarmenubutton.css +0 -11
  235. package/theme/components/menubar/menubarmenulistitem.css +0 -10
  236. package/theme/components/menubar/menubarmenulistitembutton.css +0 -10
  237. package/theme/components/menubar/menubarmenupanel.css +0 -62
  238. package/theme/components/panel/balloonpanel.css +0 -56
  239. package/theme/components/panel/balloonrotator.css +0 -17
  240. package/theme/components/panel/fakepanel.css +0 -23
  241. package/theme/components/panel/stickypanel.css +0 -17
  242. package/theme/components/responsive-form/responsiveform.css +0 -42
  243. package/theme/components/search/search.css +0 -43
  244. package/theme/components/spinner/spinner.css +0 -23
  245. package/theme/components/textarea/textarea.css +0 -10
  246. package/theme/components/toolbar/blocktoolbar.css +0 -9
  247. package/theme/components/toolbar/toolbar.css +0 -58
  248. package/theme/components/tooltip/tooltip.css +0 -12
  249. package/theme/globals/_evaluationbadge.css +0 -54
  250. package/theme/globals/_hidden.css +0 -13
  251. package/theme/globals/_poweredby.css +0 -84
  252. package/theme/globals/_transition.css +0 -12
  253. package/theme/globals/_zindex.css +0 -10
  254. package/theme/globals/globals.css +0 -10
  255. package/theme/mixins/_dir.css +0 -10
  256. package/theme/mixins/_mediacolors.css +0 -20
  257. package/theme/mixins/_rwd.css +0 -10
  258. package/theme/mixins/_unselectable.css +0 -14
  259. /package/{src → dist}/arialiveannouncer.d.ts +0 -0
  260. /package/{src → dist}/augmentation.d.ts +0 -0
  261. /package/{src → dist}/autocomplete/autocompleteview.d.ts +0 -0
  262. /package/{src → dist}/badge/badge.d.ts +0 -0
  263. /package/{src → dist}/bindings/addkeyboardhandlingforgrid.d.ts +0 -0
  264. /package/{src → dist}/bindings/clickoutsidehandler.d.ts +0 -0
  265. /package/{src → dist}/bindings/csstransitiondisablermixin.d.ts +0 -0
  266. /package/{src → dist}/bindings/draggableviewmixin.d.ts +0 -0
  267. /package/{src → dist}/bindings/preventdefault.d.ts +0 -0
  268. /package/{src → dist}/bindings/submithandler.d.ts +0 -0
  269. /package/{src → dist}/button/button.d.ts +0 -0
  270. /package/{src → dist}/button/buttonlabel.d.ts +0 -0
  271. /package/{src → dist}/button/buttonlabelview.d.ts +0 -0
  272. /package/{src → dist}/button/buttonview.d.ts +0 -0
  273. /package/{src → dist}/button/filedialogbuttonview.d.ts +0 -0
  274. /package/{src → dist}/button/listitembuttonview.d.ts +0 -0
  275. /package/{src → dist}/button/switchbuttonview.d.ts +0 -0
  276. /package/{src → dist}/collapsible/collapsibleview.d.ts +0 -0
  277. /package/{src → dist}/colorgrid/colorgridview.d.ts +0 -0
  278. /package/{src → dist}/colorgrid/colortileview.d.ts +0 -0
  279. /package/{src → dist}/colorgrid/utils.d.ts +0 -0
  280. /package/{src → dist}/colorpicker/colorpickerview.d.ts +0 -0
  281. /package/{src → dist}/colorpicker/utils.d.ts +0 -0
  282. /package/{src → dist}/colorselector/colorgridsfragmentview.d.ts +0 -0
  283. /package/{src → dist}/colorselector/colorpickerfragmentview.d.ts +0 -0
  284. /package/{src → dist}/colorselector/colorselectorview.d.ts +0 -0
  285. /package/{src → dist}/componentfactory.d.ts +0 -0
  286. /package/{src → dist}/dialog/dialogactionsview.d.ts +0 -0
  287. /package/{src → dist}/dialog/dialogcontentview.d.ts +0 -0
  288. /package/{src → dist}/dialog/dialogview.d.ts +0 -0
  289. /package/{src → dist}/dropdown/button/dropdownbutton.d.ts +0 -0
  290. /package/{src → dist}/dropdown/button/dropdownbuttonview.d.ts +0 -0
  291. /package/{src → dist}/dropdown/button/splitbuttonview.d.ts +0 -0
  292. /package/{src → dist}/dropdown/dropdownpanelfocusable.d.ts +0 -0
  293. /package/{src → dist}/dropdown/dropdownpanelview.d.ts +0 -0
  294. /package/{src → dist}/dropdown/dropdownview.d.ts +0 -0
  295. /package/{src → dist}/dropdown/menu/dropdownmenubehaviors.d.ts +0 -0
  296. /package/{src → dist}/dropdown/menu/dropdownmenubuttonview.d.ts +0 -0
  297. /package/{src → dist}/dropdown/menu/dropdownmenulistitembuttonview.d.ts +0 -0
  298. /package/{src → dist}/dropdown/menu/dropdownmenulistitemview.d.ts +0 -0
  299. /package/{src → dist}/dropdown/menu/dropdownmenulistview.d.ts +0 -0
  300. /package/{src → dist}/dropdown/menu/dropdownmenunestedmenupanelview.d.ts +0 -0
  301. /package/{src → dist}/dropdown/menu/dropdownmenunestedmenuview.d.ts +0 -0
  302. /package/{src → dist}/dropdown/menu/dropdownmenurootlistview.d.ts +0 -0
  303. /package/{src → dist}/dropdown/menu/utils.d.ts +0 -0
  304. /package/{src → dist}/dropdown/utils.d.ts +0 -0
  305. /package/{src → dist}/editableui/editableuiview.d.ts +0 -0
  306. /package/{src → dist}/editableui/inline/inlineeditableuiview.d.ts +0 -0
  307. /package/{src → dist}/editorui/accessibilityhelp/accessibilityhelp.d.ts +0 -0
  308. /package/{src → dist}/editorui/accessibilityhelp/accessibilityhelpcontentview.d.ts +0 -0
  309. /package/{src → dist}/editorui/bodycollection.d.ts +0 -0
  310. /package/{src → dist}/editorui/boxed/boxededitoruiview.d.ts +0 -0
  311. /package/{src → dist}/editorui/editorui.d.ts +0 -0
  312. /package/{src → dist}/editorui/editoruiview.d.ts +0 -0
  313. /package/{src → dist}/editorui/evaluationbadge.d.ts +0 -0
  314. /package/{src → dist}/editorui/poweredby.d.ts +0 -0
  315. /package/{src → dist}/focuscycler.d.ts +0 -0
  316. /package/{src → dist}/formheader/formheaderview.d.ts +0 -0
  317. /package/{src → dist}/formrow/formrowview.d.ts +0 -0
  318. /package/{src → dist}/highlightedtext/buttonlabelwithhighlightview.d.ts +0 -0
  319. /package/{src → dist}/highlightedtext/highlightedtextview.d.ts +0 -0
  320. /package/{src → dist}/highlightedtext/labelwithhighlightview.d.ts +0 -0
  321. /package/{src → dist}/icon/iconview.d.ts +0 -0
  322. /package/{src → dist}/iframe/iframeview.d.ts +0 -0
  323. /package/{src → dist}/index.d.ts +0 -0
  324. /package/{src → dist}/input/inputbase.d.ts +0 -0
  325. /package/{src → dist}/input/inputview.d.ts +0 -0
  326. /package/{src → dist}/inputnumber/inputnumberview.d.ts +0 -0
  327. /package/{src → dist}/inputtext/inputtextview.d.ts +0 -0
  328. /package/{src → dist}/label/labelview.d.ts +0 -0
  329. /package/{src → dist}/labeledfield/labeledfieldview.d.ts +0 -0
  330. /package/{src → dist}/labeledfield/utils.d.ts +0 -0
  331. /package/{src → dist}/labeledinput/labeledinputview.d.ts +0 -0
  332. /package/{src → dist}/legacyerrors.d.ts +0 -0
  333. /package/{src → dist}/list/listitemgroupview.d.ts +0 -0
  334. /package/{src → dist}/list/listitemview.d.ts +0 -0
  335. /package/{src → dist}/list/listseparatorview.d.ts +0 -0
  336. /package/{src → dist}/list/listview.d.ts +0 -0
  337. /package/{src → dist}/menubar/menubarmenubuttonview.d.ts +0 -0
  338. /package/{src → dist}/menubar/menubarmenulistitembuttonview.d.ts +0 -0
  339. /package/{src → dist}/menubar/menubarmenulistitemfiledialogbuttonview.d.ts +0 -0
  340. /package/{src → dist}/menubar/menubarmenulistitemview.d.ts +0 -0
  341. /package/{src → dist}/menubar/menubarmenulistview.d.ts +0 -0
  342. /package/{src → dist}/menubar/menubarmenupanelview.d.ts +0 -0
  343. /package/{src → dist}/menubar/menubarview.d.ts +0 -0
  344. /package/{src → dist}/menubar/utils.d.ts +0 -0
  345. /package/{src → dist}/model.d.ts +0 -0
  346. /package/{src → dist}/notification/notification.d.ts +0 -0
  347. /package/{src → dist}/panel/balloon/balloonpanelview.d.ts +0 -0
  348. /package/{src → dist}/panel/balloon/contextualballoon.d.ts +0 -0
  349. /package/{src → dist}/panel/sticky/stickypanelview.d.ts +0 -0
  350. /package/{src → dist}/search/filteredview.d.ts +0 -0
  351. /package/{src → dist}/search/filtergroupanditemnames.d.ts +0 -0
  352. /package/{src → dist}/search/searchinfoview.d.ts +0 -0
  353. /package/{src → dist}/search/searchresultsview.d.ts +0 -0
  354. /package/{src → dist}/search/text/searchtextqueryview.d.ts +0 -0
  355. /package/{src → dist}/search/text/searchtextview.d.ts +0 -0
  356. /package/{src → dist}/spinner/spinnerview.d.ts +0 -0
  357. /package/{src → dist}/template.d.ts +0 -0
  358. /package/{src → dist}/textarea/textareaview.d.ts +0 -0
  359. /package/{src → dist}/toolbar/balloon/balloontoolbar.d.ts +0 -0
  360. /package/{src → dist}/toolbar/block/blockbuttonview.d.ts +0 -0
  361. /package/{src → dist}/toolbar/block/blocktoolbar.d.ts +0 -0
  362. /package/{src → dist}/toolbar/normalizetoolbarconfig.d.ts +0 -0
  363. /package/{src → dist}/toolbar/toolbarlinebreakview.d.ts +0 -0
  364. /package/{src → dist}/toolbar/toolbarseparatorview.d.ts +0 -0
  365. /package/{src → dist}/toolbar/toolbarview.d.ts +0 -0
  366. /package/{src → dist}/tooltipmanager.d.ts +0 -0
  367. /package/{src → dist}/viewcollection.d.ts +0 -0
@@ -1,873 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
- */
5
- /**
6
- * @module ui/toolbar/toolbarview
7
- */
8
- import { View } from '../view.js';
9
- import { FocusCycler, isFocusable } from '../focuscycler.js';
10
- import { ToolbarSeparatorView } from './toolbarseparatorview.js';
11
- import { ToolbarLineBreakView } from './toolbarlinebreakview.js';
12
- import { preventDefault } from '../bindings/preventdefault.js';
13
- import { createDropdown, addToolbarToDropdown } from '../dropdown/utils.js';
14
- import { normalizeToolbarConfig } from './normalizetoolbarconfig.js';
15
- import { FocusTracker, KeystrokeHandler, Rect, ResizeObserver, global, isVisible, logWarning } from '@ckeditor/ckeditor5-utils';
16
- import { IconAlignLeft, IconBold, IconImportExport, IconParagraph, IconPlus, IconText, IconThreeVerticalDots, IconPilcrow, IconDragIndicator } from '@ckeditor/ckeditor5-icons';
17
- import { isObject } from 'es-toolkit/compat';
18
- import '../../theme/components/toolbar/toolbar.css';
19
- /**
20
- * @internal
21
- */
22
- export const NESTED_TOOLBAR_ICONS = /* #__PURE__ */ (() => ({
23
- alignLeft: IconAlignLeft,
24
- bold: IconBold,
25
- importExport: IconImportExport,
26
- paragraph: IconParagraph,
27
- plus: IconPlus,
28
- text: IconText,
29
- threeVerticalDots: IconThreeVerticalDots,
30
- pilcrow: IconPilcrow,
31
- dragIndicator: IconDragIndicator
32
- }))();
33
- /**
34
- * The toolbar view class.
35
- */
36
- export class ToolbarView extends View {
37
- /**
38
- * A reference to the options object passed to the constructor.
39
- */
40
- options;
41
- /**
42
- * A collection of toolbar items (buttons, dropdowns, etc.).
43
- */
44
- items;
45
- /**
46
- * Tracks information about the DOM focus in the toolbar.
47
- */
48
- focusTracker;
49
- /**
50
- * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}
51
- * to handle keyboard navigation in the toolbar.
52
- */
53
- keystrokes;
54
- /**
55
- * A (child) view containing {@link #items toolbar items}.
56
- */
57
- itemsView;
58
- /**
59
- * A top–level collection aggregating building blocks of the toolbar.
60
- *
61
- * ┌───────────────── ToolbarView ─────────────────┐
62
- * | ┌──────────────── #children ────────────────┐ |
63
- * | | ┌──────────── #itemsView ───────────┐ | |
64
- * | | | [ item1 ] [ item2 ] ... [ itemN ] | | |
65
- * | | └──────────────────────────────────-┘ | |
66
- * | └───────────────────────────────────────────┘ |
67
- * └───────────────────────────────────────────────┘
68
- *
69
- * By default, it contains the {@link #itemsView} but it can be extended with additional
70
- * UI elements when necessary.
71
- */
72
- children;
73
- /**
74
- * A collection of {@link #items} that take part in the focus cycling
75
- * (i.e. navigation using the keyboard). Usually, it contains a subset of {@link #items} with
76
- * some optional UI elements that also belong to the toolbar and should be focusable
77
- * by the user.
78
- */
79
- focusables;
80
- /**
81
- * Helps cycling over {@link #focusables focusable items} in the toolbar.
82
- */
83
- _focusCycler;
84
- /**
85
- * An instance of the active toolbar behavior that shapes its look and functionality.
86
- *
87
- * See {@link module:ui/toolbar/toolbarview~ToolbarBehavior} to learn more.
88
- */
89
- _behavior;
90
- /**
91
- * Creates an instance of the {@link module:ui/toolbar/toolbarview~ToolbarView} class.
92
- *
93
- * Also see {@link #render}.
94
- *
95
- * @param locale The localization services instance.
96
- * @param options Configuration options of the toolbar.
97
- */
98
- constructor(locale, options) {
99
- super(locale);
100
- const bind = this.bindTemplate;
101
- const t = this.t;
102
- this.options = options || {};
103
- this.set('ariaLabel', t('Editor toolbar'));
104
- this.set('maxWidth', 'auto');
105
- this.set('role', 'toolbar');
106
- this.set('isGrouping', !!this.options.shouldGroupWhenFull);
107
- this.items = this.createCollection();
108
- this.focusTracker = new FocusTracker();
109
- this.keystrokes = new KeystrokeHandler();
110
- this.set('class', undefined);
111
- this.set('isCompact', false);
112
- // Static toolbar can be vertical when needed.
113
- this.set('isVertical', false);
114
- this.itemsView = new ItemsView(locale);
115
- this.children = this.createCollection();
116
- this.children.add(this.itemsView);
117
- this.focusables = this.createCollection();
118
- const isRtl = locale.uiLanguageDirection === 'rtl';
119
- this._focusCycler = new FocusCycler({
120
- focusables: this.focusables,
121
- focusTracker: this.focusTracker,
122
- keystrokeHandler: this.keystrokes,
123
- actions: {
124
- // Navigate toolbar items backwards using the arrow[left,up] keys.
125
- focusPrevious: [isRtl ? 'arrowright' : 'arrowleft', 'arrowup'],
126
- // Navigate toolbar items forwards using the arrow[right,down] keys.
127
- focusNext: [isRtl ? 'arrowleft' : 'arrowright', 'arrowdown']
128
- }
129
- });
130
- const classes = [
131
- 'ck',
132
- 'ck-toolbar',
133
- bind.to('class'),
134
- bind.if('isCompact', 'ck-toolbar_compact'),
135
- // To group items dynamically, the toolbar needs a dedicated CSS class. Only used for dynamic grouping.
136
- bind.if('isGrouping', 'ck-toolbar_grouping'),
137
- // When vertical, the toolbar has an additional CSS class. Only used for static layout.
138
- bind.if('isVertical', 'ck-toolbar_vertical')
139
- ];
140
- if (this.options.shouldGroupWhenFull && this.options.isFloating) {
141
- classes.push('ck-toolbar_floating');
142
- }
143
- this.setTemplate({
144
- tag: 'div',
145
- attributes: {
146
- class: classes,
147
- role: bind.to('role'),
148
- 'aria-label': bind.to('ariaLabel'),
149
- style: {
150
- maxWidth: bind.to('maxWidth')
151
- },
152
- tabindex: -1
153
- },
154
- children: this.children,
155
- on: {
156
- // https://github.com/ckeditor/ckeditor5-ui/issues/206
157
- mousedown: preventDefault(this)
158
- }
159
- });
160
- this._behavior = this.options.shouldGroupWhenFull ? new DynamicGrouping(this) : new StaticLayout(this);
161
- }
162
- /**
163
- * @inheritDoc
164
- */
165
- render() {
166
- super.render();
167
- this.focusTracker.add(this.element);
168
- // Children added before rendering should be known to the #focusTracker.
169
- for (const item of this.items) {
170
- this.focusTracker.add(item);
171
- }
172
- this.items.on('add', (evt, item) => {
173
- this.focusTracker.add(item);
174
- });
175
- this.items.on('remove', (evt, item) => {
176
- this.focusTracker.remove(item);
177
- });
178
- // Start listening for the keystrokes coming from #element.
179
- this.keystrokes.listenTo(this.element);
180
- this._behavior.render(this);
181
- }
182
- /**
183
- * @inheritDoc
184
- */
185
- destroy() {
186
- this._behavior.destroy();
187
- this.focusTracker.destroy();
188
- this.keystrokes.destroy();
189
- return super.destroy();
190
- }
191
- /**
192
- * Focuses the first focusable in {@link #focusables}.
193
- */
194
- focus() {
195
- this._focusCycler.focusFirst();
196
- }
197
- /**
198
- * Focuses the last focusable in {@link #focusables}.
199
- */
200
- focusLast() {
201
- this._focusCycler.focusLast();
202
- }
203
- /**
204
- * A utility that expands the plain toolbar configuration into
205
- * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.
206
- *
207
- * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.
208
- * @param factory A factory producing toolbar items.
209
- * @param removeItems An array of items names to be removed from the configuration. When present, applies
210
- * to this toolbar and all nested ones as well.
211
- */
212
- fillFromConfig(itemsOrConfig, factory, removeItems) {
213
- this.items.addMany(this._buildItemsFromConfig(itemsOrConfig, factory, removeItems));
214
- }
215
- /**
216
- * Changes the behavior of toolbar if it does not fit into the available space.
217
- */
218
- switchBehavior(newBehaviorType) {
219
- if (this._behavior.type !== newBehaviorType) {
220
- this._behavior.destroy();
221
- this.itemsView.children.clear();
222
- this.focusables.clear();
223
- if (newBehaviorType === 'dynamic') {
224
- this._behavior = new DynamicGrouping(this);
225
- this._behavior.render(this);
226
- this._behavior.refreshItems();
227
- }
228
- else {
229
- this._behavior = new StaticLayout(this);
230
- this._behavior.render(this);
231
- }
232
- }
233
- }
234
- /**
235
- * A utility that expands the plain toolbar configuration into a list of view items using a given component factory.
236
- *
237
- * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.
238
- * @param factory A factory producing toolbar items.
239
- * @param removeItems An array of items names to be removed from the configuration. When present, applies
240
- * to this toolbar and all nested ones as well.
241
- */
242
- _buildItemsFromConfig(itemsOrConfig, factory, removeItems) {
243
- const config = normalizeToolbarConfig(itemsOrConfig);
244
- const normalizedRemoveItems = removeItems || config.removeItems;
245
- const itemsToAdd = this._cleanItemsConfiguration(config.items, factory, normalizedRemoveItems)
246
- .map(item => {
247
- if (isObject(item)) {
248
- return this._createNestedToolbarDropdown(item, factory, normalizedRemoveItems);
249
- }
250
- else if (item === '|') {
251
- return new ToolbarSeparatorView();
252
- }
253
- else if (item === '-') {
254
- return new ToolbarLineBreakView();
255
- }
256
- return factory.create(item);
257
- })
258
- .filter((item) => !!item);
259
- return itemsToAdd;
260
- }
261
- /**
262
- * Cleans up the {@link module:ui/toolbar/toolbarview~ToolbarView#items} of the toolbar by removing unwanted items and
263
- * duplicated (obsolete) separators or line breaks.
264
- *
265
- * @param items The toolbar items configuration.
266
- * @param factory A factory producing toolbar items.
267
- * @param removeItems An array of items names to be removed from the configuration.
268
- * @returns Items after the clean-up.
269
- */
270
- _cleanItemsConfiguration(items, factory, removeItems) {
271
- const filteredItems = items
272
- .filter((item, idx, items) => {
273
- if (item === '|') {
274
- return true;
275
- }
276
- // Items listed in `config.removeItems` should not be added to the toolbar.
277
- if (removeItems.indexOf(item) !== -1) {
278
- return false;
279
- }
280
- if (item === '-') {
281
- // The toolbar line breaks must not be rendered when toolbar grouping is enabled.
282
- // (https://github.com/ckeditor/ckeditor5/issues/8582)
283
- if (this.options.shouldGroupWhenFull) {
284
- /**
285
- * The toolbar multiline breaks (`-` items) only work when the automatic button grouping
286
- * is disabled in the toolbar configuration.
287
- * To do this, set the `shouldNotGroupWhenFull` option to `true` in the editor configuration:
288
- *
289
- * ```ts
290
- * const config = {
291
- * toolbar: {
292
- * items: [ ... ],
293
- * shouldNotGroupWhenFull: true
294
- * }
295
- * }
296
- * ```
297
- *
298
- * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.
299
- *
300
- * @error toolbarview-line-break-ignored-when-grouping-items
301
- */
302
- logWarning('toolbarview-line-break-ignored-when-grouping-items', items);
303
- return false;
304
- }
305
- return true;
306
- }
307
- // For the items that cannot be instantiated we are sending warning message. We also filter them out.
308
- if (!isObject(item) && !factory.has(item)) {
309
- /**
310
- * There was a problem processing the configuration of the toolbar. The item with the given
311
- * name does not exist so it was omitted when rendering the toolbar.
312
- *
313
- * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed
314
- * to provide a toolbar item has not been loaded or there is a typo in the
315
- * {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.
316
- *
317
- * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration
318
- * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.
319
- *
320
- * You can use the following snippet to retrieve all available toolbar items:
321
- *
322
- * ```ts
323
- * Array.from( editor.ui.componentFactory.names() );
324
- * ```
325
- *
326
- * @error toolbarview-item-unavailable
327
- * @param {string} item The name of the component or nested toolbar definition.
328
- */
329
- logWarning('toolbarview-item-unavailable', { item });
330
- return false;
331
- }
332
- return true;
333
- });
334
- return this._cleanSeparatorsAndLineBreaks(filteredItems);
335
- }
336
- /**
337
- * Remove leading, trailing, and duplicated separators (`-` and `|`).
338
- *
339
- * @returns Toolbar items after the separator and line break clean-up.
340
- */
341
- _cleanSeparatorsAndLineBreaks(items) {
342
- const nonSeparatorPredicate = (item) => (item !== '-' && item !== '|');
343
- const count = items.length;
344
- // Find an index of the first item that is not a separator.
345
- const firstCommandItemIndex = items.findIndex(nonSeparatorPredicate);
346
- // Items include separators only. There is no point in displaying them.
347
- if (firstCommandItemIndex === -1) {
348
- return [];
349
- }
350
- // Search from the end of the list, then convert found index back to the original direction.
351
- const lastCommandItemIndex = count - items
352
- .slice()
353
- .reverse()
354
- .findIndex(nonSeparatorPredicate);
355
- return items
356
- // Return items without the leading and trailing separators.
357
- .slice(firstCommandItemIndex, lastCommandItemIndex)
358
- // Remove duplicated separators.
359
- .filter((name, idx, items) => {
360
- // Filter only separators.
361
- if (nonSeparatorPredicate(name)) {
362
- return true;
363
- }
364
- const isDuplicated = idx > 0 && items[idx - 1] === name;
365
- return !isDuplicated;
366
- });
367
- }
368
- /**
369
- * Creates a user-defined dropdown containing a toolbar with items.
370
- *
371
- * @param definition A definition of the nested toolbar dropdown.
372
- * @param definition.label A label of the dropdown.
373
- * @param definition.icon An icon of the drop-down. One of 'bold', 'plus', 'text', 'importExport', 'alignLeft',
374
- * 'paragraph' or an SVG string. When `false` is passed, no icon will be used.
375
- * @param definition.withText When set `true`, the label of the dropdown will be visible. See
376
- * {@link module:ui/button/buttonview~ButtonView#withText} to learn more.
377
- * @param definition.tooltip A tooltip of the dropdown button. See
378
- * {@link module:ui/button/buttonview~ButtonView#tooltip} to learn more. Defaults to `true`.
379
- * @param componentFactory Component factory used to create items
380
- * of the nested toolbar.
381
- */
382
- _createNestedToolbarDropdown(definition, componentFactory, removeItems) {
383
- let { label, icon, items, tooltip = true, withText = false } = definition;
384
- items = this._cleanItemsConfiguration(items, componentFactory, removeItems);
385
- // There is no point in rendering a dropdown without items.
386
- if (!items.length) {
387
- return null;
388
- }
389
- const locale = this.locale;
390
- const dropdownView = createDropdown(locale);
391
- if (!label) {
392
- /**
393
- * A dropdown definition in the toolbar configuration is missing a text label.
394
- *
395
- * Without a label, the dropdown becomes inaccessible to users relying on assistive technologies.
396
- * Make sure the `label` property is set in your drop-down configuration:
397
- *
398
- * ```json
399
- * {
400
- * label: 'A human-readable label',
401
- * icon: '...',
402
- * items: [ ... ]
403
- * },
404
- * ```
405
- *
406
- * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.
407
- *
408
- * @error toolbarview-nested-toolbar-dropdown-missing-label
409
- */
410
- logWarning('toolbarview-nested-toolbar-dropdown-missing-label', definition);
411
- }
412
- dropdownView.class = 'ck-toolbar__nested-toolbar-dropdown';
413
- dropdownView.buttonView.set({
414
- label,
415
- tooltip,
416
- withText: !!withText
417
- });
418
- // Allow disabling icon by passing false.
419
- if (icon !== false) {
420
- // A pre-defined icon picked by name, SVG string, a fallback (default) icon.
421
- dropdownView.buttonView.icon = NESTED_TOOLBAR_ICONS[icon] || icon || IconThreeVerticalDots;
422
- }
423
- // If the icon is disabled, display the label automatically.
424
- else {
425
- dropdownView.buttonView.withText = true;
426
- }
427
- addToolbarToDropdown(dropdownView, () => (dropdownView.toolbarView._buildItemsFromConfig(items, componentFactory, removeItems)));
428
- return dropdownView;
429
- }
430
- }
431
- /**
432
- * An inner block of the {@link module:ui/toolbar/toolbarview~ToolbarView} hosting its
433
- * {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
434
- */
435
- export class ItemsView extends View {
436
- /**
437
- * A collection of items (buttons, dropdowns, etc.).
438
- */
439
- children;
440
- /**
441
- * @inheritDoc
442
- */
443
- constructor(locale) {
444
- super(locale);
445
- this.children = this.createCollection();
446
- this.setTemplate({
447
- tag: 'div',
448
- attributes: {
449
- class: [
450
- 'ck',
451
- 'ck-toolbar__items'
452
- ]
453
- },
454
- children: this.children
455
- });
456
- }
457
- }
458
- /**
459
- * A toolbar behavior that makes it static and unresponsive to the changes of the environment.
460
- * At the same time, it also makes it possible to display a toolbar with a vertical layout
461
- * using the {@link module:ui/toolbar/toolbarview~ToolbarView#isVertical} property.
462
- */
463
- class StaticLayout {
464
- /**
465
- * Toolbar behavior type.
466
- */
467
- type = 'static';
468
- /**
469
- * Creates an instance of the {@link module:ui/toolbar/toolbarview~StaticLayout} toolbar
470
- * behavior.
471
- *
472
- * @param view An instance of the toolbar that this behavior is added to.
473
- */
474
- constructor(view) {
475
- view.isGrouping = false;
476
- // 1:1 pass–through binding, all ToolbarView#items are visible.
477
- view.itemsView.children.bindTo(view.items).using(item => item);
478
- // 1:1 pass–through binding, all ToolbarView#items are focusable.
479
- view.focusables.bindTo(view.items).using(item => isFocusable(item) ? item : null);
480
- }
481
- /**
482
- * @inheritDoc
483
- */
484
- render() { }
485
- /**
486
- * @inheritDoc
487
- */
488
- destroy() { }
489
- }
490
- /**
491
- * A toolbar behavior that makes the items respond to changes in the geometry.
492
- *
493
- * In a nutshell, it groups {@link module:ui/toolbar/toolbarview~ToolbarView#items}
494
- * that do not fit visually into a single row of the toolbar (due to limited space).
495
- * Items that do not fit are aggregated in a dropdown displayed at the end of the toolbar.
496
- *
497
- * ```
498
- * ┌──────────────────────────────────────── ToolbarView ──────────────────────────────────────────┐
499
- * | ┌─────────────────────────────────────── #children ─────────────────────────────────────────┐ |
500
- * | | ┌─────── #itemsView ────────┐ ┌──────────────────────┐ ┌── #groupedItemsDropdown ───┐ | |
501
- * | | | #ungroupedItems | | ToolbarSeparatorView | | #groupedItems | | |
502
- * | | └──────────────────────────-┘ └──────────────────────┘ └────────────────────────────┘ | |
503
- * | | \---------- only when toolbar items overflow -------/ | |
504
- * | └───────────────────────────────────────────────────────────────────────────────────────────┘ |
505
- * └───────────────────────────────────────────────────────────────────────────────────────────────┘
506
- * ```
507
- */
508
- class DynamicGrouping {
509
- /**
510
- * Toolbar behavior type.
511
- */
512
- type = 'dynamic';
513
- /**
514
- * A toolbar view this behavior belongs to.
515
- */
516
- view;
517
- /**
518
- * A collection of toolbar children.
519
- */
520
- viewChildren;
521
- /**
522
- * A collection of focusable toolbar elements.
523
- */
524
- viewFocusables;
525
- /**
526
- * A view containing toolbar items.
527
- */
528
- viewItemsView;
529
- /**
530
- * Toolbar focus tracker.
531
- */
532
- viewFocusTracker;
533
- /**
534
- * Toolbar locale.
535
- */
536
- viewLocale;
537
- /**
538
- * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
539
- * Aggregates items that fit into a single row of the toolbar and were not {@link #groupedItems grouped}
540
- * into a {@link #groupedItemsDropdown dropdown}. Items of this collection are displayed in the
541
- * {@link module:ui/toolbar/toolbarview~ToolbarView#itemsView}.
542
- *
543
- * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped, it
544
- * matches the {@link module:ui/toolbar/toolbarview~ToolbarView#items} collection in size and order.
545
- */
546
- ungroupedItems;
547
- /**
548
- * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.
549
- * A collection of the toolbar items that do not fit into a single row of the toolbar.
550
- * Grouped items are displayed in a dedicated {@link #groupedItemsDropdown dropdown}.
551
- *
552
- * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped,
553
- * this collection is empty.
554
- */
555
- groupedItems;
556
- /**
557
- * The dropdown that aggregates {@link #groupedItems grouped items} that do not fit into a single
558
- * row of the toolbar. It is displayed on demand as the last of
559
- * {@link module:ui/toolbar/toolbarview~ToolbarView#children toolbar children} and offers another
560
- * (nested) toolbar which displays items that would normally overflow.
561
- */
562
- groupedItemsDropdown;
563
- /**
564
- * An instance of the resize observer that helps dynamically determine the geometry of the toolbar
565
- * and manage items that do not fit into a single row.
566
- *
567
- * **Note:** Created in {@link #_enableGroupingOnResize}.
568
- *
569
- * @readonly
570
- */
571
- resizeObserver = null;
572
- /**
573
- * A cached value of the horizontal padding style used by {@link #_updateGrouping}
574
- * to manage the {@link module:ui/toolbar/toolbarview~ToolbarView#items} that do not fit into
575
- * a single toolbar line. This value can be reused between updates because it is unlikely that
576
- * the padding will change and re–using `Window.getComputedStyle()` is expensive.
577
- *
578
- * @readonly
579
- */
580
- cachedPadding = null;
581
- /**
582
- * A flag indicating that an items grouping update has been queued (e.g. due to the toolbar being visible)
583
- * and should be executed immediately the next time the toolbar shows up.
584
- *
585
- * @readonly
586
- */
587
- shouldUpdateGroupingOnNextResize = false;
588
- /**
589
- * Toolbar element.
590
- *
591
- * @readonly
592
- */
593
- viewElement;
594
- /**
595
- * Creates an instance of the {@link module:ui/toolbar/toolbarview~DynamicGrouping} toolbar
596
- * behavior.
597
- *
598
- * @param view An instance of the toolbar that this behavior is added to.
599
- */
600
- constructor(view) {
601
- this.view = view;
602
- this.viewChildren = view.children;
603
- this.viewFocusables = view.focusables;
604
- this.viewItemsView = view.itemsView;
605
- this.viewFocusTracker = view.focusTracker;
606
- this.viewLocale = view.locale;
607
- this.view.isGrouping = true;
608
- this.ungroupedItems = view.createCollection();
609
- this.groupedItems = view.createCollection();
610
- this.groupedItemsDropdown = this._createGroupedItemsDropdown();
611
- // Only those items that were not grouped are visible to the user.
612
- view.itemsView.children.bindTo(this.ungroupedItems).using(item => item);
613
- // Make sure all #items visible in the main space of the toolbar are "focuscyclable".
614
- this.ungroupedItems.on('change', this._updateFocusCyclableItems.bind(this));
615
- // Make sure the #groupedItemsDropdown is also included in cycling when it appears.
616
- view.children.on('change', this._updateFocusCyclableItems.bind(this));
617
- // ToolbarView#items is dynamic. When an item is added or removed, it should be automatically
618
- // represented in either grouped or ungrouped items at the right index.
619
- // In other words #items == concat( #ungroupedItems, #groupedItems )
620
- // (in length and order).
621
- view.items.on('change', (evt, changeData) => {
622
- const index = changeData.index;
623
- const added = Array.from(changeData.added);
624
- // Removing.
625
- for (const removedItem of changeData.removed) {
626
- if (index >= this.ungroupedItems.length) {
627
- this.groupedItems.remove(removedItem);
628
- }
629
- else {
630
- this.ungroupedItems.remove(removedItem);
631
- }
632
- }
633
- // Adding.
634
- for (let currentIndex = index; currentIndex < index + added.length; currentIndex++) {
635
- const addedItem = added[currentIndex - index];
636
- if (currentIndex > this.ungroupedItems.length) {
637
- this.groupedItems.add(addedItem, currentIndex - this.ungroupedItems.length);
638
- }
639
- else {
640
- this.ungroupedItems.add(addedItem, currentIndex);
641
- }
642
- }
643
- // When new ungrouped items join in and land in #ungroupedItems, there's a chance it causes
644
- // the toolbar to overflow.
645
- // Consequently if removed from grouped or ungrouped items, there is a chance
646
- // some new space is available and we could do some ungrouping.
647
- this._updateGrouping();
648
- });
649
- }
650
- /**
651
- * Enables dynamic items grouping based on the dimensions of the toolbar.
652
- *
653
- * @param view An instance of the toolbar that this behavior is added to.
654
- */
655
- render(view) {
656
- this.viewElement = view.element;
657
- this._enableGroupingOnResize();
658
- this._enableGroupingOnMaxWidthChange(view);
659
- }
660
- /**
661
- * Cleans up the internals used by this behavior.
662
- */
663
- destroy() {
664
- // The dropdown may not be in ToolbarView#children at the moment of toolbar destruction
665
- // so let's make sure it's actually destroyed along with the toolbar.
666
- this.groupedItemsDropdown.destroy();
667
- // Do not try to remove the same elements if they are already removed.
668
- if (this.viewChildren.length > 1) {
669
- this.viewChildren.remove(this.groupedItemsDropdown);
670
- this.viewChildren.remove(this.viewChildren.last);
671
- }
672
- this.resizeObserver.destroy();
673
- }
674
- /**
675
- * Re-adds all items to the toolbar. Use when the toolbar is re-rendered and the items grouping is lost.
676
- */
677
- refreshItems() {
678
- const view = this.view;
679
- if (view.items.length) {
680
- for (let currentIndex = 0; currentIndex < view.items.length; currentIndex++) {
681
- const item = [...view.items][currentIndex];
682
- this.ungroupedItems.add(item, currentIndex);
683
- }
684
- this._updateGrouping();
685
- }
686
- }
687
- /**
688
- * When called, it will check if any of the {@link #ungroupedItems} do not fit into a single row of the toolbar,
689
- * and it will move them to the {@link #groupedItems} when it happens.
690
- *
691
- * At the same time, it will also check if there is enough space in the toolbar for the first of the
692
- * {@link #groupedItems} to be returned back to {@link #ungroupedItems} and still fit into a single row
693
- * without the toolbar wrapping.
694
- */
695
- _updateGrouping() {
696
- // Do no grouping–related geometry analysis when the toolbar is detached from visible DOM,
697
- // for instance before #render(), or after render but without a parent or a parent detached
698
- // from DOM. DOMRects won't work anyway and there will be tons of warning in the console and
699
- // nothing else. This happens, for instance, when the toolbar is detached from DOM and
700
- // some logic adds or removes its #items.
701
- if (!this.viewElement.ownerDocument.body.contains(this.viewElement)) {
702
- return;
703
- }
704
- // Do not update grouping when the element is invisible. Such toolbar has DOMRect filled with zeros
705
- // and that would cause all items to be grouped. Instead, queue the grouping so it runs next time
706
- // the toolbar is visible (the next ResizeObserver callback execution). This is handy because
707
- // the grouping could be caused by increasing the #maxWidth when the toolbar was invisible and the next
708
- // time it shows up, some items could actually be ungrouped (https://github.com/ckeditor/ckeditor5/issues/6575).
709
- if (!isVisible(this.viewElement)) {
710
- this.shouldUpdateGroupingOnNextResize = true;
711
- return;
712
- }
713
- // Remember how many items were initially grouped so at the it is possible to figure out if the number
714
- // of grouped items has changed. If the number has changed, geometry of the toolbar has also changed.
715
- const initialGroupedItemsCount = this.groupedItems.length;
716
- let wereItemsGrouped;
717
- // Group #items as long as some wrap to the next row. This will happen, for instance,
718
- // when the toolbar is getting narrow and there is not enough space to display all items in
719
- // a single row.
720
- while (this._areItemsOverflowing) {
721
- this._groupLastItem();
722
- wereItemsGrouped = true;
723
- }
724
- // If none were grouped now but there were some items already grouped before,
725
- // then, what the hell, maybe let's see if some of them can be ungrouped. This happens when,
726
- // for instance, the toolbar is stretching and there's more space in it than before.
727
- if (!wereItemsGrouped && this.groupedItems.length) {
728
- // Ungroup items as long as none are overflowing or there are none to ungroup left.
729
- while (this.groupedItems.length && !this._areItemsOverflowing) {
730
- this._ungroupFirstItem();
731
- }
732
- // If the ungrouping ended up with some item wrapping to the next row,
733
- // put it back to the group toolbar ("undo the last ungroup"). We don't know whether
734
- // an item will wrap or not until we ungroup it (that's a DOM/CSS thing) so this
735
- // clean–up is vital for the algorithm.
736
- if (this._areItemsOverflowing) {
737
- this._groupLastItem();
738
- }
739
- }
740
- if (this.groupedItems.length !== initialGroupedItemsCount) {
741
- this.view.fire('groupedItemsUpdate');
742
- }
743
- }
744
- /**
745
- * Returns `true` when {@link module:ui/toolbar/toolbarview~ToolbarView#element} children visually overflow,
746
- * for instance if the toolbar is narrower than its members. Returns `false` otherwise.
747
- */
748
- get _areItemsOverflowing() {
749
- // An empty toolbar cannot overflow.
750
- if (!this.ungroupedItems.length) {
751
- return false;
752
- }
753
- const element = this.viewElement;
754
- const uiLanguageDirection = this.viewLocale.uiLanguageDirection;
755
- const lastChildRect = new Rect(element.lastChild);
756
- const toolbarRect = new Rect(element);
757
- if (!this.cachedPadding) {
758
- const computedStyle = global.window.getComputedStyle(element);
759
- const paddingProperty = uiLanguageDirection === 'ltr' ? 'paddingRight' : 'paddingLeft';
760
- // parseInt() is essential because of quirky floating point numbers logic and DOM.
761
- // If the padding turned out too big because of that, the grouped items dropdown would
762
- // always look (from the Rect perspective) like it overflows (while it's not).
763
- this.cachedPadding = Number.parseInt(computedStyle[paddingProperty]);
764
- }
765
- if (uiLanguageDirection === 'ltr') {
766
- return lastChildRect.right > toolbarRect.right - this.cachedPadding;
767
- }
768
- else {
769
- return lastChildRect.left < toolbarRect.left + this.cachedPadding;
770
- }
771
- }
772
- /**
773
- * Enables the functionality that prevents {@link #ungroupedItems} from overflowing (wrapping to the next row)
774
- * upon resize when there is little space available. Instead, the toolbar items are moved to the
775
- * {@link #groupedItems} collection and displayed in a dropdown at the end of the row (which has its own nested toolbar).
776
- *
777
- * When called, the toolbar will automatically analyze the location of its {@link #ungroupedItems} and "group"
778
- * them in the dropdown if necessary. It will also observe the browser window for size changes in
779
- * the future and respond to them by grouping more items or reverting already grouped back, depending
780
- * on the visual space available.
781
- */
782
- _enableGroupingOnResize() {
783
- let previousWidth;
784
- // TODO: Consider debounce.
785
- this.resizeObserver = new ResizeObserver(this.viewElement, entry => {
786
- if (!previousWidth || previousWidth !== entry.contentRect.width || this.shouldUpdateGroupingOnNextResize) {
787
- this.shouldUpdateGroupingOnNextResize = false;
788
- this._updateGrouping();
789
- previousWidth = entry.contentRect.width;
790
- }
791
- });
792
- this._updateGrouping();
793
- }
794
- /**
795
- * Enables the grouping functionality, just like {@link #_enableGroupingOnResize} but the difference is that
796
- * it listens to the changes of {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth} instead.
797
- */
798
- _enableGroupingOnMaxWidthChange(view) {
799
- view.on('change:maxWidth', () => {
800
- this._updateGrouping();
801
- });
802
- }
803
- /**
804
- * When called, it will remove the last item from {@link #ungroupedItems} and move it back
805
- * to the {@link #groupedItems} collection.
806
- *
807
- * The opposite of {@link #_ungroupFirstItem}.
808
- */
809
- _groupLastItem() {
810
- if (!this.groupedItems.length) {
811
- this.viewChildren.add(new ToolbarSeparatorView());
812
- this.viewChildren.add(this.groupedItemsDropdown);
813
- this.viewFocusTracker.add(this.groupedItemsDropdown.element);
814
- }
815
- this.groupedItems.add(this.ungroupedItems.remove(this.ungroupedItems.last), 0);
816
- }
817
- /**
818
- * Moves the very first item belonging to {@link #groupedItems} back
819
- * to the {@link #ungroupedItems} collection.
820
- *
821
- * The opposite of {@link #_groupLastItem}.
822
- */
823
- _ungroupFirstItem() {
824
- this.ungroupedItems.add(this.groupedItems.remove(this.groupedItems.first));
825
- if (!this.groupedItems.length) {
826
- this.viewChildren.remove(this.groupedItemsDropdown);
827
- this.viewChildren.remove(this.viewChildren.last);
828
- this.viewFocusTracker.remove(this.groupedItemsDropdown.element);
829
- }
830
- }
831
- /**
832
- * Creates the {@link #groupedItemsDropdown} that hosts the members of the {@link #groupedItems}
833
- * collection when there is not enough space in the toolbar to display all items in a single row.
834
- */
835
- _createGroupedItemsDropdown() {
836
- const locale = this.viewLocale;
837
- const t = locale.t;
838
- const dropdown = createDropdown(locale);
839
- dropdown.class = 'ck-toolbar__grouped-dropdown';
840
- // Make sure the dropdown never sticks out to the left/right. It should be under the main toolbar.
841
- // (https://github.com/ckeditor/ckeditor5/issues/5608)
842
- dropdown.panelPosition = locale.uiLanguageDirection === 'ltr' ? 'sw' : 'se';
843
- addToolbarToDropdown(dropdown, this.groupedItems);
844
- dropdown.buttonView.set({
845
- label: t('Show more items'),
846
- tooltip: true,
847
- tooltipPosition: locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw',
848
- icon: IconThreeVerticalDots
849
- });
850
- return dropdown;
851
- }
852
- /**
853
- * Updates the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables focus–cyclable items}
854
- * collection so it represents the up–to–date state of the UI from the perspective of the user.
855
- *
856
- * For instance, the {@link #groupedItemsDropdown} can show up and hide but when it is visible,
857
- * it must be subject to focus cycling in the toolbar.
858
- *
859
- * See the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables collection} documentation
860
- * to learn more about the purpose of this method.
861
- */
862
- _updateFocusCyclableItems() {
863
- this.viewFocusables.clear();
864
- this.ungroupedItems.map(item => {
865
- if (isFocusable(item)) {
866
- this.viewFocusables.add(item);
867
- }
868
- });
869
- if (this.groupedItems.length) {
870
- this.viewFocusables.add(this.groupedItemsDropdown);
871
- }
872
- }
873
- }