@ckeditor/ckeditor5-table 0.0.0-nightly-20260124.0 → 0.0.0-nightly-next-20260124.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 (356) hide show
  1. package/ckeditor5-metadata.json +16 -7
  2. package/{src → dist}/augmentation.d.ts +0 -15
  3. package/{src → dist}/commands/insertcolumncommand.d.ts +1 -1
  4. package/{src → dist}/commands/insertrowcommand.d.ts +1 -1
  5. package/{src → dist}/commands/inserttablecommand.d.ts +1 -1
  6. package/{src → dist}/commands/inserttablelayoutcommand.d.ts +1 -1
  7. package/{src → dist}/commands/mergecellcommand.d.ts +3 -3
  8. package/{src → dist}/commands/mergecellscommand.d.ts +1 -1
  9. package/{src → dist}/commands/removecolumncommand.d.ts +1 -1
  10. package/{src → dist}/commands/removerowcommand.d.ts +1 -1
  11. package/{src → dist}/commands/selectcolumncommand.d.ts +1 -1
  12. package/{src → dist}/commands/selectrowcommand.d.ts +1 -1
  13. package/{src → dist}/commands/setheadercolumncommand.d.ts +1 -1
  14. package/{src → dist}/commands/setheaderrowcommand.d.ts +1 -1
  15. package/{src → dist}/commands/splitcellcommand.d.ts +1 -1
  16. package/{src → dist}/converters/downcast.d.ts +2 -2
  17. package/{src → dist}/converters/table-caption-post-fixer.d.ts +1 -1
  18. package/{src → dist}/converters/table-cell-paragraph-post-fixer.d.ts +1 -1
  19. package/{src → dist}/converters/table-cell-refresh-handler.d.ts +1 -1
  20. package/{src → dist}/converters/table-headings-refresh-handler.d.ts +1 -1
  21. package/{src → dist}/converters/table-layout-post-fixer.d.ts +1 -1
  22. package/{src → dist}/converters/tableproperties.d.ts +2 -2
  23. package/{src → dist}/converters/upcasttable.d.ts +1 -1
  24. package/dist/index-content.css +30 -30
  25. package/dist/index-editor.css +104 -170
  26. package/dist/index.css +147 -237
  27. package/dist/index.css.map +1 -1
  28. package/{src → dist}/index.d.ts +2 -5
  29. package/dist/index.js +423 -2408
  30. package/dist/index.js.map +1 -1
  31. package/{src → dist}/plaintableoutput.d.ts +1 -1
  32. package/{src → dist}/table.d.ts +2 -2
  33. package/{src → dist}/tablecaption/tablecaptionediting.d.ts +2 -2
  34. package/{src → dist}/tablecaption/tablecaptionui.d.ts +1 -1
  35. package/{src → dist}/tablecaption/toggletablecaptioncommand.d.ts +1 -1
  36. package/{src → dist}/tablecaption/utils.d.ts +1 -1
  37. package/{src → dist}/tablecaption.d.ts +1 -1
  38. package/{src → dist}/tablecellproperties/commands/tablecellbackgroundcolorcommand.d.ts +1 -1
  39. package/{src → dist}/tablecellproperties/commands/tablecellbordercolorcommand.d.ts +2 -2
  40. package/{src → dist}/tablecellproperties/commands/tablecellborderstylecommand.d.ts +2 -2
  41. package/{src → dist}/tablecellproperties/commands/tablecellborderwidthcommand.d.ts +2 -2
  42. package/{src → dist}/tablecellproperties/commands/tablecellheightcommand.d.ts +1 -1
  43. package/{src → dist}/tablecellproperties/commands/tablecellhorizontalalignmentcommand.d.ts +1 -1
  44. package/{src → dist}/tablecellproperties/commands/tablecellpaddingcommand.d.ts +2 -2
  45. package/{src → dist}/tablecellproperties/commands/tablecellpropertycommand.d.ts +2 -2
  46. package/{src → dist}/tablecellproperties/commands/tablecelltypecommand.d.ts +2 -6
  47. package/{src → dist}/tablecellproperties/commands/tablecellverticalalignmentcommand.d.ts +1 -1
  48. package/{src → dist}/tablecellproperties/tablecellpropertiesediting.d.ts +1 -1
  49. package/{src → dist}/tablecellproperties/tablecellpropertiesui.d.ts +2 -2
  50. package/dist/tablecellproperties/tablecellpropertiesutils.d.ts +18 -0
  51. package/{src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts → dist/tablecellproperties/ui/tablecellpropertiesview.d.ts} +11 -12
  52. package/{src → dist}/tablecellproperties.d.ts +1 -1
  53. package/{src → dist}/tablecellwidth/commands/tablecellwidthcommand.d.ts +1 -1
  54. package/{src → dist}/tablecellwidth/tablecellwidthediting.d.ts +1 -1
  55. package/{src → dist}/tableclipboard.d.ts +3 -3
  56. package/{src → dist}/tablecolumnresize/converters.d.ts +1 -1
  57. package/{src → dist}/tablecolumnresize/tablecolumnresizeediting.d.ts +2 -2
  58. package/{src → dist}/tablecolumnresize/tablewidthscommand.d.ts +2 -2
  59. package/{src → dist}/tablecolumnresize/utils.d.ts +2 -2
  60. package/{src → dist}/tablecolumnresize.d.ts +1 -1
  61. package/{src → dist}/tableconfig.d.ts +26 -6
  62. package/{src → dist}/tableediting.d.ts +3 -3
  63. package/{src → dist}/tablekeyboard.d.ts +3 -3
  64. package/{src → dist}/tablelayout/commands/tabletypecommand.d.ts +1 -1
  65. package/{src → dist}/tablelayout/tablelayoutediting.d.ts +1 -1
  66. package/{src → dist}/tablelayout/tablelayoutui.d.ts +1 -1
  67. package/{src → dist}/tablelayout.d.ts +1 -1
  68. package/{src → dist}/tablemouse/mouseeventsobserver.d.ts +1 -1
  69. package/{src → dist}/tablemouse.d.ts +1 -1
  70. package/{src → dist}/tableproperties/commands/tablealignmentcommand.d.ts +1 -1
  71. package/{src → dist}/tableproperties/commands/tablebackgroundcolorcommand.d.ts +1 -1
  72. package/{src → dist}/tableproperties/commands/tablebordercolorcommand.d.ts +2 -2
  73. package/{src → dist}/tableproperties/commands/tableborderstylecommand.d.ts +2 -2
  74. package/{src → dist}/tableproperties/commands/tableborderwidthcommand.d.ts +2 -2
  75. package/{src → dist}/tableproperties/commands/tableheightcommand.d.ts +1 -1
  76. package/{src → dist}/tableproperties/commands/tablepropertycommand.d.ts +2 -2
  77. package/{src → dist}/tableproperties/commands/tablewidthcommand.d.ts +1 -1
  78. package/{src → dist}/tableproperties/tablepropertiesediting.d.ts +1 -1
  79. package/{src → dist}/tableproperties/tablepropertiesui.d.ts +2 -2
  80. package/{src → dist}/tableproperties/ui/tablepropertiesview.d.ts +10 -2
  81. package/{src → dist}/tableproperties.d.ts +1 -1
  82. package/{src → dist}/tableselection.d.ts +2 -2
  83. package/{src → dist}/tabletoolbar.d.ts +2 -2
  84. package/{src → dist}/tableui.d.ts +1 -1
  85. package/{src → dist}/tableutils.d.ts +2 -2
  86. package/{src → dist}/tablewalker.d.ts +1 -1
  87. package/{src → dist}/ui/colorinputview.d.ts +2 -2
  88. package/{src → dist}/ui/inserttableview.d.ts +2 -2
  89. package/{src → dist}/utils/common.d.ts +2 -2
  90. package/{src → dist}/utils/structure.d.ts +1 -1
  91. package/{src → dist}/utils/table-properties.d.ts +1 -1
  92. package/{src → dist}/utils/ui/contextualballoon.d.ts +2 -2
  93. package/{src → dist}/utils/ui/table-properties.d.ts +2 -2
  94. package/{src → dist}/utils/ui/widget.d.ts +1 -1
  95. package/package.json +26 -49
  96. package/build/table.js +0 -5
  97. package/build/translations/af.js +0 -1
  98. package/build/translations/ar.js +0 -1
  99. package/build/translations/ast.js +0 -1
  100. package/build/translations/az.js +0 -1
  101. package/build/translations/be.js +0 -1
  102. package/build/translations/bg.js +0 -1
  103. package/build/translations/bn.js +0 -1
  104. package/build/translations/bs.js +0 -1
  105. package/build/translations/ca.js +0 -1
  106. package/build/translations/cs.js +0 -1
  107. package/build/translations/da.js +0 -1
  108. package/build/translations/de-ch.js +0 -1
  109. package/build/translations/de.js +0 -1
  110. package/build/translations/el.js +0 -1
  111. package/build/translations/en-au.js +0 -1
  112. package/build/translations/en-gb.js +0 -1
  113. package/build/translations/eo.js +0 -1
  114. package/build/translations/es-co.js +0 -1
  115. package/build/translations/es.js +0 -1
  116. package/build/translations/et.js +0 -1
  117. package/build/translations/eu.js +0 -1
  118. package/build/translations/fa.js +0 -1
  119. package/build/translations/fi.js +0 -1
  120. package/build/translations/fr.js +0 -1
  121. package/build/translations/gl.js +0 -1
  122. package/build/translations/gu.js +0 -1
  123. package/build/translations/he.js +0 -1
  124. package/build/translations/hi.js +0 -1
  125. package/build/translations/hr.js +0 -1
  126. package/build/translations/hu.js +0 -1
  127. package/build/translations/hy.js +0 -1
  128. package/build/translations/id.js +0 -1
  129. package/build/translations/it.js +0 -1
  130. package/build/translations/ja.js +0 -1
  131. package/build/translations/jv.js +0 -1
  132. package/build/translations/kk.js +0 -1
  133. package/build/translations/km.js +0 -1
  134. package/build/translations/kn.js +0 -1
  135. package/build/translations/ko.js +0 -1
  136. package/build/translations/ku.js +0 -1
  137. package/build/translations/lt.js +0 -1
  138. package/build/translations/lv.js +0 -1
  139. package/build/translations/ms.js +0 -1
  140. package/build/translations/nb.js +0 -1
  141. package/build/translations/ne.js +0 -1
  142. package/build/translations/nl.js +0 -1
  143. package/build/translations/no.js +0 -1
  144. package/build/translations/oc.js +0 -1
  145. package/build/translations/pl.js +0 -1
  146. package/build/translations/pt-br.js +0 -1
  147. package/build/translations/pt.js +0 -1
  148. package/build/translations/ro.js +0 -1
  149. package/build/translations/ru.js +0 -1
  150. package/build/translations/si.js +0 -1
  151. package/build/translations/sk.js +0 -1
  152. package/build/translations/sl.js +0 -1
  153. package/build/translations/sq.js +0 -1
  154. package/build/translations/sr-latn.js +0 -1
  155. package/build/translations/sr.js +0 -1
  156. package/build/translations/sv.js +0 -1
  157. package/build/translations/th.js +0 -1
  158. package/build/translations/ti.js +0 -1
  159. package/build/translations/tk.js +0 -1
  160. package/build/translations/tr.js +0 -1
  161. package/build/translations/tt.js +0 -1
  162. package/build/translations/ug.js +0 -1
  163. package/build/translations/uk.js +0 -1
  164. package/build/translations/ur.js +0 -1
  165. package/build/translations/uz.js +0 -1
  166. package/build/translations/vi.js +0 -1
  167. package/build/translations/zh-cn.js +0 -1
  168. package/build/translations/zh.js +0 -1
  169. package/lang/contexts.json +0 -82
  170. package/lang/translations/af.po +0 -332
  171. package/lang/translations/ar.po +0 -332
  172. package/lang/translations/ast.po +0 -332
  173. package/lang/translations/az.po +0 -332
  174. package/lang/translations/be.po +0 -332
  175. package/lang/translations/bg.po +0 -332
  176. package/lang/translations/bn.po +0 -334
  177. package/lang/translations/bs.po +0 -332
  178. package/lang/translations/ca.po +0 -332
  179. package/lang/translations/cs.po +0 -332
  180. package/lang/translations/da.po +0 -332
  181. package/lang/translations/de-ch.po +0 -332
  182. package/lang/translations/de.po +0 -332
  183. package/lang/translations/el.po +0 -332
  184. package/lang/translations/en-au.po +0 -332
  185. package/lang/translations/en-gb.po +0 -332
  186. package/lang/translations/en.po +0 -332
  187. package/lang/translations/eo.po +0 -332
  188. package/lang/translations/es-co.po +0 -332
  189. package/lang/translations/es.po +0 -332
  190. package/lang/translations/et.po +0 -332
  191. package/lang/translations/eu.po +0 -332
  192. package/lang/translations/fa.po +0 -332
  193. package/lang/translations/fi.po +0 -332
  194. package/lang/translations/fr.po +0 -332
  195. package/lang/translations/gl.po +0 -332
  196. package/lang/translations/gu.po +0 -332
  197. package/lang/translations/he.po +0 -332
  198. package/lang/translations/hi.po +0 -332
  199. package/lang/translations/hr.po +0 -332
  200. package/lang/translations/hu.po +0 -332
  201. package/lang/translations/hy.po +0 -332
  202. package/lang/translations/id.po +0 -332
  203. package/lang/translations/it.po +0 -332
  204. package/lang/translations/ja.po +0 -332
  205. package/lang/translations/jv.po +0 -332
  206. package/lang/translations/kk.po +0 -332
  207. package/lang/translations/km.po +0 -332
  208. package/lang/translations/kn.po +0 -332
  209. package/lang/translations/ko.po +0 -332
  210. package/lang/translations/ku.po +0 -332
  211. package/lang/translations/lt.po +0 -332
  212. package/lang/translations/lv.po +0 -332
  213. package/lang/translations/ms.po +0 -332
  214. package/lang/translations/nb.po +0 -332
  215. package/lang/translations/ne.po +0 -332
  216. package/lang/translations/nl.po +0 -332
  217. package/lang/translations/no.po +0 -332
  218. package/lang/translations/oc.po +0 -332
  219. package/lang/translations/pl.po +0 -332
  220. package/lang/translations/pt-br.po +0 -332
  221. package/lang/translations/pt.po +0 -332
  222. package/lang/translations/ro.po +0 -332
  223. package/lang/translations/ru.po +0 -332
  224. package/lang/translations/si.po +0 -332
  225. package/lang/translations/sk.po +0 -332
  226. package/lang/translations/sl.po +0 -332
  227. package/lang/translations/sq.po +0 -332
  228. package/lang/translations/sr-latn.po +0 -332
  229. package/lang/translations/sr.po +0 -332
  230. package/lang/translations/sv.po +0 -332
  231. package/lang/translations/th.po +0 -332
  232. package/lang/translations/ti.po +0 -332
  233. package/lang/translations/tk.po +0 -332
  234. package/lang/translations/tr.po +0 -332
  235. package/lang/translations/tt.po +0 -332
  236. package/lang/translations/ug.po +0 -332
  237. package/lang/translations/uk.po +0 -332
  238. package/lang/translations/ur.po +0 -332
  239. package/lang/translations/uz.po +0 -332
  240. package/lang/translations/vi.po +0 -332
  241. package/lang/translations/zh-cn.po +0 -332
  242. package/lang/translations/zh.po +0 -332
  243. package/src/augmentation.js +0 -5
  244. package/src/commands/insertcolumncommand.js +0 -71
  245. package/src/commands/insertrowcommand.js +0 -70
  246. package/src/commands/inserttablecommand.js +0 -69
  247. package/src/commands/inserttablelayoutcommand.js +0 -65
  248. package/src/commands/mergecellcommand.js +0 -206
  249. package/src/commands/mergecellscommand.js +0 -94
  250. package/src/commands/removecolumncommand.js +0 -109
  251. package/src/commands/removerowcommand.js +0 -82
  252. package/src/commands/selectcolumncommand.js +0 -60
  253. package/src/commands/selectrowcommand.js +0 -56
  254. package/src/commands/setheadercolumncommand.js +0 -76
  255. package/src/commands/setheaderrowcommand.js +0 -83
  256. package/src/commands/splitcellcommand.js +0 -58
  257. package/src/converters/downcast.js +0 -298
  258. package/src/converters/table-caption-post-fixer.js +0 -55
  259. package/src/converters/table-cell-paragraph-post-fixer.js +0 -109
  260. package/src/converters/table-cell-refresh-handler.js +0 -47
  261. package/src/converters/table-headings-refresh-handler.js +0 -51
  262. package/src/converters/table-layout-post-fixer.js +0 -369
  263. package/src/converters/tableproperties.js +0 -444
  264. package/src/converters/upcasttable.js +0 -385
  265. package/src/index.js +0 -98
  266. package/src/plaintableoutput.js +0 -49
  267. package/src/table.js +0 -50
  268. package/src/tablecaption/tablecaptionediting.js +0 -136
  269. package/src/tablecaption/tablecaptionui.js +0 -64
  270. package/src/tablecaption/toggletablecaptioncommand.js +0 -105
  271. package/src/tablecaption/utils.js +0 -61
  272. package/src/tablecaption.js +0 -34
  273. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js +0 -30
  274. package/src/tablecellproperties/commands/tablecellbordercolorcommand.js +0 -44
  275. package/src/tablecellproperties/commands/tablecellborderstylecommand.js +0 -44
  276. package/src/tablecellproperties/commands/tablecellborderwidthcommand.js +0 -64
  277. package/src/tablecellproperties/commands/tablecellheightcommand.js +0 -51
  278. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js +0 -30
  279. package/src/tablecellproperties/commands/tablecellpaddingcommand.js +0 -64
  280. package/src/tablecellproperties/commands/tablecellpropertycommand.js +0 -138
  281. package/src/tablecellproperties/commands/tablecelltypecommand.js +0 -167
  282. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.js +0 -38
  283. package/src/tablecellproperties/tablecellpropertiesediting.js +0 -412
  284. package/src/tablecellproperties/tablecellpropertiesui.js +0 -385
  285. package/src/tablecellproperties/tablecellpropertiesuiexperimental.d.ts +0 -128
  286. package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +0 -408
  287. package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +0 -229
  288. package/src/tablecellproperties/ui/tablecellpropertiesview.js +0 -612
  289. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +0 -744
  290. package/src/tablecellproperties.js +0 -40
  291. package/src/tablecellwidth/commands/tablecellwidthcommand.js +0 -51
  292. package/src/tablecellwidth/tablecellwidthediting.js +0 -53
  293. package/src/tableclipboard.js +0 -500
  294. package/src/tablecolumnresize/constants.js +0 -33
  295. package/src/tablecolumnresize/converters.js +0 -62
  296. package/src/tablecolumnresize/tablecolumnresizeediting.js +0 -734
  297. package/src/tablecolumnresize/tablewidthscommand.js +0 -61
  298. package/src/tablecolumnresize/utils.js +0 -370
  299. package/src/tablecolumnresize.js +0 -36
  300. package/src/tableconfig.js +0 -5
  301. package/src/tableediting.js +0 -246
  302. package/src/tablekeyboard.js +0 -273
  303. package/src/tablelayout/commands/tabletypecommand.js +0 -68
  304. package/src/tablelayout/tablelayoutediting.js +0 -295
  305. package/src/tablelayout/tablelayoutui.js +0 -196
  306. package/src/tablelayout.js +0 -37
  307. package/src/tablemouse/mouseeventsobserver.js +0 -34
  308. package/src/tablemouse.js +0 -178
  309. package/src/tableproperties/commands/tablealignmentcommand.js +0 -30
  310. package/src/tableproperties/commands/tablebackgroundcolorcommand.js +0 -30
  311. package/src/tableproperties/commands/tablebordercolorcommand.js +0 -44
  312. package/src/tableproperties/commands/tableborderstylecommand.js +0 -44
  313. package/src/tableproperties/commands/tableborderwidthcommand.js +0 -64
  314. package/src/tableproperties/commands/tableheightcommand.js +0 -54
  315. package/src/tableproperties/commands/tablepropertycommand.js +0 -103
  316. package/src/tableproperties/commands/tablewidthcommand.js +0 -54
  317. package/src/tableproperties/tablepropertiesediting.js +0 -546
  318. package/src/tableproperties/tablepropertiesui.js +0 -374
  319. package/src/tableproperties/tablepropertiesuiexperimental.d.ts +0 -136
  320. package/src/tableproperties/tablepropertiesuiexperimental.js +0 -375
  321. package/src/tableproperties/ui/tablepropertiesview.js +0 -520
  322. package/src/tableproperties/ui/tablepropertiesviewexperimental.d.ts +0 -216
  323. package/src/tableproperties/ui/tablepropertiesviewexperimental.js +0 -544
  324. package/src/tableproperties.js +0 -40
  325. package/src/tableselection.js +0 -323
  326. package/src/tabletoolbar.js +0 -63
  327. package/src/tableui.js +0 -335
  328. package/src/tableutils.js +0 -1282
  329. package/src/tablewalker.js +0 -489
  330. package/src/ui/colorinputview.js +0 -305
  331. package/src/ui/inserttableview.js +0 -192
  332. package/src/utils/common.js +0 -118
  333. package/src/utils/structure.js +0 -452
  334. package/src/utils/table-properties.js +0 -121
  335. package/src/utils/ui/contextualballoon.js +0 -111
  336. package/src/utils/ui/table-properties.js +0 -390
  337. package/src/utils/ui/table-propertiesexperimental.d.ts +0 -215
  338. package/src/utils/ui/table-propertiesexperimental.js +0 -391
  339. package/src/utils/ui/widget.js +0 -56
  340. package/theme/colorinput.css +0 -39
  341. package/theme/formrow-experimental.css +0 -15
  342. package/theme/formrow.css +0 -13
  343. package/theme/inserttable.css +0 -10
  344. package/theme/table.css +0 -144
  345. package/theme/tablecaption.css +0 -66
  346. package/theme/tablecellproperties-experimental.css +0 -4
  347. package/theme/tablecellproperties.css +0 -28
  348. package/theme/tablecolumnresize.css +0 -62
  349. package/theme/tableediting.css +0 -10
  350. package/theme/tableform-experimental.css +0 -61
  351. package/theme/tableform.css +0 -64
  352. package/theme/tablelayout.css +0 -74
  353. package/theme/tableproperties-experimental.css +0 -78
  354. package/theme/tableproperties.css +0 -18
  355. package/theme/tableselection.css +0 -10
  356. /package/{src → dist}/tablecolumnresize/constants.d.ts +0 -0
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
6
  import { toWidgetEditable, toWidget, Widget, isWidget, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';
7
7
  import { first, global, CKEditorError, KeystrokeHandler, FocusTracker, Collection, getLocalizedArrowKeyCodeDirection, Rect, priorities, DomEmitterMixin, toUnit } from '@ckeditor/ckeditor5-utils/dist/index.js';
8
8
  import { isObject, debounce, isEqual, throttle } from 'es-toolkit/compat';
9
- import { IconTable, IconTableColumn, IconTableRow, IconTableMergeCell, IconCheck, IconCancel, IconAlignBottom, IconAlignMiddle, IconAlignTop, IconAlignJustify, IconAlignRight, IconAlignCenter, IconAlignLeft, IconTableCellProperties, IconTableLayout, IconTableProperties, IconObjectInlineRight, IconObjectCenter, IconObjectInlineLeft, IconCaption, IconPreviousArrow, IconObjectRight, IconObjectLeft } from '@ckeditor/ckeditor5-icons/dist/index.js';
9
+ import { IconTable, IconTableColumn, IconTableRow, IconTableMergeCell, IconPreviousArrow, IconAlignBottom, IconAlignMiddle, IconAlignTop, IconAlignJustify, IconAlignRight, IconAlignCenter, IconAlignLeft, IconTableCellProperties, IconTableLayout, IconTableProperties, IconObjectRight, IconObjectLeft, IconObjectInlineRight, IconObjectCenter, IconObjectInlineLeft, IconCaption } from '@ckeditor/ckeditor5-icons/dist/index.js';
10
10
  import { View, addKeyboardHandlingForGrid, ButtonView, createDropdown, MenuBarMenuView, SwitchButtonView, SplitButtonView, addListToDropdown, UIModel, ViewCollection, FocusCycler, InputTextView, ColorSelectorView, FormHeaderView, FormRowView, submitHandler, LabelView, LabeledFieldView, createLabeledDropdown, createLabeledInputText, ToolbarView, BalloonPanelView, ContextualBalloon, normalizeColorOptions, getLocalizedColorOptions, clickOutsideHandler, DropdownButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
11
11
  import { ClipboardMarkersUtils, ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';
12
12
  import { DomEventObserver, isColorStyleValue, isLengthStyleValue, isPercentageStyleValue, addBorderStylesRules, addPaddingStylesRules, addBackgroundStylesRules, addMarginStylesRules, enableViewPlaceholder, ModelElement } from '@ckeditor/ckeditor5-engine/dist/index.js';
@@ -941,6 +941,22 @@ const downcastTableAlignmentConfig = {
941
941
  // @if CK_DEBUG // } );
942
942
  // @if CK_DEBUG // }
943
943
 
944
+ /**
945
+ * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
946
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
947
+ */ /**
948
+ * @module table/tablecellproperties/tablecellpropertiesutils
949
+ */ /**
950
+ * Type of the table cell.
951
+ */ /**
952
+ * Checks if the given cell type represents a header cell.
953
+ *
954
+ * @param cellType The type of the table cell.
955
+ * @returns `true` if the cell type represents a header cell, `false` otherwise.
956
+ */ function isTableHeaderCellType(cellType) {
957
+ return cellType === 'header' || cellType === 'header-row' || cellType === 'header-column';
958
+ }
959
+
944
960
  /**
945
961
  * A common method to update the numeric value. If a value is the default one, it will be unset.
946
962
  *
@@ -1042,7 +1058,7 @@ const downcastTableAlignmentConfig = {
1042
1058
  });
1043
1059
  for (const { cell } of tableWalker){
1044
1060
  const cellType = cell.getAttribute('tableCellType');
1045
- if (cellType !== 'header') {
1061
+ if (!isTableHeaderCellType(cellType)) {
1046
1062
  return false;
1047
1063
  }
1048
1064
  }
@@ -1053,8 +1069,8 @@ const downcastTableAlignmentConfig = {
1053
1069
  *
1054
1070
  * @internal
1055
1071
  */ function isTableCellTypeEnabled(editor) {
1056
- const { model, config } = editor;
1057
- return model.schema.checkAttribute('tableCell', 'tableCellType') && config.get('experimentalFlags.tableCellTypeSupport') === true;
1072
+ const { model } = editor;
1073
+ return model.schema.checkAttribute('tableCell', 'tableCellType');
1058
1074
  }
1059
1075
 
1060
1076
  /**
@@ -2069,7 +2085,8 @@ const downcastTableAlignmentConfig = {
2069
2085
  return (tableCell, { writer })=>{
2070
2086
  // If the table cell type feature is enabled, then we can simply check the cell type attribute.
2071
2087
  if (options.cellTypeEnabled?.()) {
2072
- const cellElementName = tableCell.getAttribute('tableCellType') === 'header' ? 'th' : 'td';
2088
+ const tableCellType = tableCell.getAttribute('tableCellType');
2089
+ const cellElementName = isTableHeaderCellType(tableCellType) ? 'th' : 'td';
2073
2090
  return createCellElement(writer, cellElementName);
2074
2091
  }
2075
2092
  // If the table cell type feature is not enabled, we should iterate through the table structure
@@ -2175,10 +2192,7 @@ const downcastTableAlignmentConfig = {
2175
2192
  * Downcasts a plain table (also used in the clipboard pipeline).
2176
2193
  */ function convertPlainTable(editor) {
2177
2194
  return (table, conversionApi)=>{
2178
- const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2179
- const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
2180
- const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2181
- if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2195
+ if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2182
2196
  return null;
2183
2197
  }
2184
2198
  return downcastPlainTable(table, conversionApi, editor);
@@ -2188,10 +2202,7 @@ const downcastTableAlignmentConfig = {
2188
2202
  * Downcasts a plain table caption (also used in the clipboard pipeline).
2189
2203
  */ function convertPlainTableCaption(editor) {
2190
2204
  return (modelElement, { writer, options })=>{
2191
- const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2192
- const isClipboardPipeline = options.isClipboardPipeline;
2193
- const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2194
- if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2205
+ if (!options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2195
2206
  return null;
2196
2207
  }
2197
2208
  if (modelElement.parent.name === 'table') {
@@ -2279,10 +2290,7 @@ const downcastTableAlignmentConfig = {
2279
2290
  return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{
2280
2291
  const { item, attributeNewValue } = data;
2281
2292
  const { mapper, writer } = conversionApi;
2282
- const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2283
- const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
2284
- const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2285
- if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2293
+ if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2286
2294
  return;
2287
2295
  }
2288
2296
  if (!conversionApi.consumable.consume(item, evt.name)) {
@@ -3510,6 +3518,7 @@ const downcastTableAlignmentConfig = {
3510
3518
  const isCopyStructure = options.copyStructureFromAbove !== undefined;
3511
3519
  const copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;
3512
3520
  const cellTypeEnabled = isTableCellTypeEnabled(this.editor);
3521
+ const scopedHeaders = !!this.editor.config.get('table.tableCellProperties.scopedHeaders');
3513
3522
  const rows = this.getRows(table);
3514
3523
  const columns = this.getColumns(table);
3515
3524
  if (insertAt > rows) {
@@ -3523,7 +3532,6 @@ const downcastTableAlignmentConfig = {
3523
3532
  }
3524
3533
  model.change((writer)=>{
3525
3534
  let headingRows = table.getAttribute('headingRows') || 0;
3526
- const headingColumns = table.getAttribute('headingColumns') || 0;
3527
3535
  // Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.
3528
3536
  if (headingRows > insertAt) {
3529
3537
  headingRows += rowsToInsert;
@@ -3538,10 +3546,14 @@ const downcastTableAlignmentConfig = {
3538
3546
  for(let rowOffset = 0; rowOffset < rows.length; rowOffset++){
3539
3547
  const row = rows[rowOffset];
3540
3548
  for(let columnIndex = 0; columnIndex < columns; columnIndex++){
3541
- const cell = row[columnIndex];
3542
- if (insertAt + rowOffset < headingRows || columnIndex < headingColumns) {
3543
- writer.setAttribute('tableCellType', 'header', cell);
3544
- }
3549
+ updateTableCellType({
3550
+ table,
3551
+ writer,
3552
+ cell: row[columnIndex],
3553
+ row: insertAt + rowOffset,
3554
+ column: columnIndex,
3555
+ scopedHeaders
3556
+ });
3545
3557
  }
3546
3558
  }
3547
3559
  }
@@ -3576,12 +3588,18 @@ const downcastTableAlignmentConfig = {
3576
3588
  const insertPosition = writer.createPositionAt(tableRow, 'end');
3577
3589
  // Insert the empty cell only if this slot is not row-spanned from any other cell.
3578
3590
  if (colspan > 0) {
3579
- const insertedCells = createEmptyTableCell(writer, insertPosition, colspan > 1 ? {
3591
+ const insertedCell = createEmptyTableCell(writer, insertPosition, colspan > 1 ? {
3580
3592
  colspan
3581
3593
  } : undefined);
3582
- // If we insert row in heading section, set proper cell type.
3583
- if (cellTypeEnabled && (insertAt + rowIndex < headingRows || cellIndex < headingColumns)) {
3584
- writer.setAttribute('tableCellType', 'header', insertedCells);
3594
+ if (cellTypeEnabled) {
3595
+ updateTableCellType({
3596
+ table,
3597
+ writer,
3598
+ cell: insertedCell,
3599
+ row: insertAt + rowIndex,
3600
+ column: cellIndex,
3601
+ scopedHeaders
3602
+ });
3585
3603
  }
3586
3604
  }
3587
3605
  // Skip the col-spanned slots, there won't be any cells.
@@ -3621,8 +3639,8 @@ const downcastTableAlignmentConfig = {
3621
3639
  const insertAt = options.at || 0;
3622
3640
  const columnsToInsert = options.columns || 1;
3623
3641
  const cellTypeEnabled = isTableCellTypeEnabled(this.editor);
3642
+ const scopedHeaders = !!this.editor.config.get('table.tableCellProperties.scopedHeaders');
3624
3643
  model.change((writer)=>{
3625
- const headingRows = table.getAttribute('headingRows') || 0;
3626
3644
  let headingColumns = table.getAttribute('headingColumns');
3627
3645
  // Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.
3628
3646
  if (insertAt < headingColumns) {
@@ -3644,9 +3662,14 @@ const downcastTableAlignmentConfig = {
3644
3662
  if (cellTypeEnabled) {
3645
3663
  // If we insert column in heading section, set proper cell type.
3646
3664
  for(let columnOffset = 0; columnOffset < insertedCells.length; columnOffset++){
3647
- if (insertAt + columnOffset < headingColumns || rowIndex < headingRows) {
3648
- writer.setAttribute('tableCellType', 'header', insertedCells[columnOffset]);
3649
- }
3665
+ updateTableCellType({
3666
+ table,
3667
+ writer,
3668
+ cell: insertedCells[columnOffset],
3669
+ row: rowIndex,
3670
+ column: insertAt + columnOffset,
3671
+ scopedHeaders
3672
+ });
3650
3673
  }
3651
3674
  }
3652
3675
  rowIndex++;
@@ -3679,9 +3702,14 @@ const downcastTableAlignmentConfig = {
3679
3702
  // If we insert column in heading section, set proper cell type.
3680
3703
  if (cellTypeEnabled) {
3681
3704
  for(let columnOffset = 0; columnOffset < insertedCells.length; columnOffset++){
3682
- if (insertAt + columnOffset < headingColumns || row < headingRows) {
3683
- writer.setAttribute('tableCellType', 'header', insertedCells[columnOffset]);
3684
- }
3705
+ updateTableCellType({
3706
+ table,
3707
+ writer,
3708
+ cell: insertedCells[columnOffset],
3709
+ row,
3710
+ column: insertAt + columnOffset,
3711
+ scopedHeaders
3712
+ });
3685
3713
  }
3686
3714
  }
3687
3715
  }
@@ -4192,6 +4220,7 @@ const downcastTableAlignmentConfig = {
4192
4220
  * Default is `true`.
4193
4221
  */ setHeadingRowsCount(writer, table, headingRows, options = {}) {
4194
4222
  const { shallow, resetFormerHeadingCells = true, autoExpand = true } = options;
4223
+ const scopedHeaders = !!this.editor.config.get('table.tableCellProperties.scopedHeaders');
4195
4224
  const oldHeadingRows = table.getAttribute('headingRows') || 0;
4196
4225
  if (headingRows === oldHeadingRows) {
4197
4226
  return;
@@ -4209,7 +4238,8 @@ const downcastTableAlignmentConfig = {
4209
4238
  writer,
4210
4239
  cell,
4211
4240
  row,
4212
- column
4241
+ column,
4242
+ scopedHeaders
4213
4243
  });
4214
4244
  }
4215
4245
  // If heading rows were reduced, set body type to all cells in rows that are no longer in heading section.
@@ -4231,7 +4261,8 @@ const downcastTableAlignmentConfig = {
4231
4261
  writer,
4232
4262
  cell,
4233
4263
  row: cellRow,
4234
- column
4264
+ column,
4265
+ scopedHeaders
4235
4266
  });
4236
4267
  }
4237
4268
  }
@@ -4264,6 +4295,7 @@ const downcastTableAlignmentConfig = {
4264
4295
  */ setHeadingColumnsCount(writer, table, headingColumns, options = {}) {
4265
4296
  const { shallow, resetFormerHeadingCells = true, autoExpand = true } = options;
4266
4297
  const oldHeadingColumns = table.getAttribute('headingColumns') || 0;
4298
+ const scopedHeaders = !!this.editor.config.get('table.tableCellProperties.scopedHeaders');
4267
4299
  if (headingColumns === oldHeadingColumns) {
4268
4300
  return;
4269
4301
  }
@@ -4280,7 +4312,8 @@ const downcastTableAlignmentConfig = {
4280
4312
  writer,
4281
4313
  cell,
4282
4314
  row,
4283
- column
4315
+ column,
4316
+ scopedHeaders
4284
4317
  });
4285
4318
  }
4286
4319
  // If heading columns were reduced, set body type to all cells in columns that are no longer in heading section.
@@ -4302,7 +4335,8 @@ const downcastTableAlignmentConfig = {
4302
4335
  writer,
4303
4336
  cell,
4304
4337
  row,
4305
- column: cellColumn
4338
+ column: cellColumn,
4339
+ scopedHeaders
4306
4340
  });
4307
4341
  }
4308
4342
  }
@@ -4669,14 +4703,23 @@ function compareRangeOrder(rangeA, rangeB) {
4669
4703
  /**
4670
4704
  * Updates the `tableCellType` attribute of a table cell based on its position in the table
4671
4705
  * and the table's `headingRows` and `headingColumns` attributes.
4672
- */ function updateTableCellType({ writer, table, row, column, cell }) {
4706
+ */ function updateTableCellType({ writer, table, row, column, cell, scopedHeaders }) {
4673
4707
  const headingRows = table.getAttribute('headingRows') || 0;
4674
4708
  const headingColumns = table.getAttribute('headingColumns') || 0;
4675
4709
  if (row >= headingRows && column >= headingColumns) {
4676
4710
  writer.removeAttribute('tableCellType', cell);
4677
- } else {
4678
- writer.setAttribute('tableCellType', 'header', cell);
4711
+ return;
4712
+ }
4713
+ let headerCellType = 'header';
4714
+ // If scoped headers are enabled, we prefer to set 'row' or 'column' header types depending on the position.
4715
+ if (scopedHeaders) {
4716
+ if (row < headingRows) {
4717
+ headerCellType = 'header-column';
4718
+ } else {
4719
+ headerCellType = 'header-row';
4720
+ }
4679
4721
  }
4722
+ writer.setAttribute('tableCellType', headerCellType, cell);
4680
4723
  }
4681
4724
 
4682
4725
  /**
@@ -7915,7 +7958,7 @@ const isEmpty = (val)=>val === '';
7915
7958
  *
7916
7959
  * @internal
7917
7960
  * @param t The "t" function provided by the editor that is used to localize strings.
7918
- */ function getBorderStyleLabels$1(t) {
7961
+ */ function getBorderStyleLabels(t) {
7919
7962
  return {
7920
7963
  none: t('None'),
7921
7964
  solid: t('Solid'),
@@ -7985,9 +8028,9 @@ const isEmpty = (val)=>val === '';
7985
8028
  *
7986
8029
  * @internal
7987
8030
  * @param defaultStyle The default border.
7988
- */ function getBorderStyleDefinitions$1(view, defaultStyle) {
8031
+ */ function getBorderStyleDefinitions(view, defaultStyle) {
7989
8032
  const itemDefinitions = new Collection();
7990
- const styleLabels = getBorderStyleLabels$1(view.t);
8033
+ const styleLabels = getBorderStyleLabels(view.t);
7991
8034
  for(const style in styleLabels){
7992
8035
  const definition = {
7993
8036
  type: 'button',
@@ -8030,7 +8073,7 @@ const isEmpty = (val)=>val === '';
8030
8073
  * @param options.propertyName The name of the observable property in the view.
8031
8074
  * @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
8032
8075
  * @param options.defaultValue Default value for the property.
8033
- */ function fillToolbar$1(options) {
8076
+ */ function fillToolbar(options) {
8034
8077
  const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
8035
8078
  for(const name in labels){
8036
8079
  const button = new ButtonView(view.locale);
@@ -8234,10 +8277,10 @@ const isEmpty = (val)=>val === '';
8234
8277
  * @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
8235
8278
  * the "Restore default" button. Instead of clearing the input field, the default color value will be set.
8236
8279
  * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
8237
- */ function getLabeledColorInputCreator$1(options) {
8280
+ */ function getLabeledColorInputCreator(options) {
8238
8281
  return (labeledFieldView, viewUid, statusUid)=>{
8239
8282
  const colorInputView = new ColorInputView(labeledFieldView.locale, {
8240
- colorDefinitions: colorConfigToColorGridDefinitions$1(options.colorConfig),
8283
+ colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
8241
8284
  columns: options.columns,
8242
8285
  defaultColorValue: options.defaultColorValue,
8243
8286
  colorPickerConfig: options.colorPickerConfig
@@ -8264,7 +8307,7 @@ const isEmpty = (val)=>val === '';
8264
8307
  const parsedValue = parseFloat(value);
8265
8308
  return !Number.isNaN(parsedValue) && value === String(parsedValue);
8266
8309
  }
8267
- function colorConfigToColorGridDefinitions$1(colorConfig) {
8310
+ function colorConfigToColorGridDefinitions(colorConfig) {
8268
8311
  return colorConfig.map((item)=>({
8269
8312
  color: item.model,
8270
8313
  label: item.label,
@@ -8302,6 +8345,9 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8302
8345
  /**
8303
8346
  * An input that allows specifying the table cell background color.
8304
8347
  */ backgroundInput;
8348
+ /**
8349
+ * A dropdown that allows selecting the type of the table cell (data or header).
8350
+ */ cellTypeDropdown;
8305
8351
  /**
8306
8352
  * An input that allows specifying the table cell padding.
8307
8353
  */ paddingInput;
@@ -8323,6 +8369,9 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8323
8369
  /**
8324
8370
  * The "Cancel" button view.
8325
8371
  */ cancelButtonView;
8372
+ /**
8373
+ * The "Back" button view.
8374
+ */ backButtonView;
8326
8375
  /**
8327
8376
  * A collection of views that can be focused in the form.
8328
8377
  */ _focusables;
@@ -8348,11 +8397,13 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8348
8397
  width: '',
8349
8398
  height: '',
8350
8399
  horizontalAlignment: '',
8351
- verticalAlignment: ''
8400
+ verticalAlignment: '',
8401
+ cellType: ''
8352
8402
  });
8353
8403
  this.options = options;
8354
8404
  const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
8355
8405
  const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
8406
+ const { cellTypeRowLabel, cellTypeDropdown } = this._createCellTypeField();
8356
8407
  const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
8357
8408
  const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
8358
8409
  this.focusTracker = new FocusTracker();
@@ -8362,6 +8413,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8362
8413
  this.borderWidthInput = borderWidthInput;
8363
8414
  this.borderColorInput = borderColorInput;
8364
8415
  this.backgroundInput = backgroundInput;
8416
+ this.cellTypeDropdown = cellTypeDropdown;
8365
8417
  this.paddingInput = this._createPaddingField();
8366
8418
  this.widthInput = widthInput;
8367
8419
  this.heightInput = heightInput;
@@ -8373,6 +8425,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8373
8425
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
8374
8426
  this.saveButtonView = saveButtonView;
8375
8427
  this.cancelButtonView = cancelButtonView;
8428
+ this.backButtonView = this._createBackButton();
8376
8429
  this._focusables = new ViewCollection();
8377
8430
  this._focusCycler = new FocusCycler({
8378
8431
  focusables: this._focusables,
@@ -8386,28 +8439,42 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8386
8439
  }
8387
8440
  });
8388
8441
  // Form header.
8389
- this.children.add(new FormHeaderView(locale, {
8442
+ const header = new FormHeaderView(locale, {
8390
8443
  label: this.t('Cell properties')
8391
- }));
8444
+ });
8445
+ header.children.add(this.backButtonView, 0);
8446
+ this.children.add(header);
8392
8447
  // Border row.
8393
8448
  this.children.add(new FormRowView(locale, {
8394
8449
  labelView: borderRowLabel,
8395
8450
  children: [
8396
8451
  borderRowLabel,
8397
8452
  borderStyleDropdown,
8398
- borderColorInput,
8399
- borderWidthInput
8453
+ borderWidthInput,
8454
+ borderColorInput
8400
8455
  ],
8401
8456
  class: 'ck-table-form__border-row'
8402
8457
  }));
8403
- // Background.
8458
+ // Background and cell type.
8404
8459
  this.children.add(new FormRowView(locale, {
8405
- labelView: backgroundRowLabel,
8406
8460
  children: [
8407
- backgroundRowLabel,
8408
- backgroundInput
8409
- ],
8410
- class: 'ck-table-form__background-row'
8461
+ new FormRowView(locale, {
8462
+ labelView: cellTypeRowLabel,
8463
+ children: [
8464
+ cellTypeRowLabel,
8465
+ cellTypeDropdown
8466
+ ],
8467
+ class: 'ck-table-form__cell-type-row'
8468
+ }),
8469
+ new FormRowView(locale, {
8470
+ labelView: backgroundRowLabel,
8471
+ children: [
8472
+ backgroundRowLabel,
8473
+ backgroundInput
8474
+ ],
8475
+ class: 'ck-table-form__background-row'
8476
+ })
8477
+ ]
8411
8478
  }));
8412
8479
  // Dimensions row and padding.
8413
8480
  this.children.add(new FormRowView(locale, {
@@ -8445,8 +8512,8 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8445
8512
  // Action row.
8446
8513
  this.children.add(new FormRowView(locale, {
8447
8514
  children: [
8448
- this.saveButtonView,
8449
- this.cancelButtonView
8515
+ this.cancelButtonView,
8516
+ this.saveButtonView
8450
8517
  ],
8451
8518
  class: 'ck-table-form__action-row'
8452
8519
  }));
@@ -8485,14 +8552,16 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8485
8552
  this.borderStyleDropdown,
8486
8553
  this.borderColorInput,
8487
8554
  this.borderWidthInput,
8555
+ this.cellTypeDropdown,
8488
8556
  this.backgroundInput,
8489
8557
  this.widthInput,
8490
8558
  this.heightInput,
8491
8559
  this.paddingInput,
8492
8560
  this.horizontalAlignmentToolbar,
8493
8561
  this.verticalAlignmentToolbar,
8562
+ this.cancelButtonView,
8494
8563
  this.saveButtonView,
8495
- this.cancelButtonView
8564
+ this.backButtonView
8496
8565
  ].forEach((view)=>{
8497
8566
  // Register the view as focusable.
8498
8567
  this._focusables.add(view);
@@ -8527,7 +8596,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8527
8596
  width: defaultTableCellProperties.borderWidth,
8528
8597
  color: defaultTableCellProperties.borderColor
8529
8598
  };
8530
- const colorInputCreator = getLabeledColorInputCreator$1({
8599
+ const colorInputCreator = getLabeledColorInputCreator({
8531
8600
  colorConfig: this.options.borderColors,
8532
8601
  columns: 5,
8533
8602
  defaultColorValue: defaultBorder.color,
@@ -8540,7 +8609,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8540
8609
  const borderRowLabel = new LabelView(locale);
8541
8610
  borderRowLabel.text = t('Border');
8542
8611
  // -- Style ---------------------------------------------------
8543
- const styleLabels = getBorderStyleLabels$1(t);
8612
+ const styleLabels = getBorderStyleLabels(t);
8544
8613
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
8545
8614
  borderStyleDropdown.set({
8546
8615
  label: accessibleLabel,
@@ -8560,7 +8629,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8560
8629
  this.borderStyle = evt.source._borderStyleValue;
8561
8630
  });
8562
8631
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
8563
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
8632
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
8564
8633
  role: 'menu',
8565
8634
  ariaLabel: accessibleLabel
8566
8635
  });
@@ -8571,7 +8640,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8571
8640
  class: 'ck-table-form__border-width'
8572
8641
  });
8573
8642
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
8574
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8643
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8575
8644
  borderWidthInput.fieldView.on('input', ()=>{
8576
8645
  this.borderWidth = borderWidthInput.fieldView.element.value;
8577
8646
  });
@@ -8582,7 +8651,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8582
8651
  class: 'ck-table-form__border-color'
8583
8652
  });
8584
8653
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
8585
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8654
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8586
8655
  borderColorInput.fieldView.on('input', ()=>{
8587
8656
  this.borderColor = borderColorInput.fieldView.value;
8588
8657
  });
@@ -8590,12 +8659,12 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8590
8659
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
8591
8660
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
8592
8661
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
8593
- if (!isBorderStyleSet$3(newValue)) {
8662
+ if (!isBorderStyleSet$1(newValue)) {
8594
8663
  this.borderColor = '';
8595
8664
  this.borderWidth = '';
8596
8665
  }
8597
8666
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
8598
- if (!isBorderStyleSet$3(oldValue)) {
8667
+ if (!isBorderStyleSet$1(oldValue)) {
8599
8668
  this.borderColor = defaultBorder.color;
8600
8669
  this.borderWidth = defaultBorder.width;
8601
8670
  }
@@ -8618,7 +8687,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8618
8687
  const backgroundRowLabel = new LabelView(locale);
8619
8688
  backgroundRowLabel.text = t('Background');
8620
8689
  // -- Background color input -----------------------------------
8621
- const colorInputCreator = getLabeledColorInputCreator$1({
8690
+ const colorInputCreator = getLabeledColorInputCreator({
8622
8691
  colorConfig: this.options.backgroundColors,
8623
8692
  columns: 5,
8624
8693
  defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
@@ -8638,6 +8707,46 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8638
8707
  backgroundInput
8639
8708
  };
8640
8709
  }
8710
+ /**
8711
+ * Create cell type field.
8712
+ *
8713
+ * * {@link #cellTypeDropdown}.
8714
+ *
8715
+ * @internal
8716
+ */ _createCellTypeField() {
8717
+ const locale = this.locale;
8718
+ const t = this.t;
8719
+ const cellTypeRowLabel = new LabelView(locale);
8720
+ cellTypeRowLabel.text = t('Cell type');
8721
+ const cellTypeLabels = this._cellTypeLabels;
8722
+ const cellTypeDropdown = new LabeledFieldView(locale, createLabeledDropdown);
8723
+ cellTypeDropdown.set({
8724
+ label: t('Cell type'),
8725
+ class: 'ck-table-cell-properties-form__cell-type'
8726
+ });
8727
+ cellTypeDropdown.fieldView.buttonView.set({
8728
+ ariaLabel: t('Cell type'),
8729
+ ariaLabelledBy: undefined,
8730
+ isOn: false,
8731
+ withText: true,
8732
+ tooltip: t('Cell type')
8733
+ });
8734
+ cellTypeDropdown.fieldView.buttonView.bind('label').to(this, 'cellType', (value)=>{
8735
+ return cellTypeLabels[value || 'data'];
8736
+ });
8737
+ cellTypeDropdown.fieldView.on('execute', (evt)=>{
8738
+ this.cellType = evt.source._cellTypeValue;
8739
+ });
8740
+ cellTypeDropdown.bind('isEmpty').to(this, 'cellType', (value)=>!value);
8741
+ addListToDropdown(cellTypeDropdown.fieldView, this._getCellTypeDefinitions(), {
8742
+ role: 'menu',
8743
+ ariaLabel: t('Cell type')
8744
+ });
8745
+ return {
8746
+ cellTypeRowLabel,
8747
+ cellTypeDropdown
8748
+ };
8749
+ }
8641
8750
  /**
8642
8751
  * Creates the following form fields:
8643
8752
  *
@@ -8734,9 +8843,10 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8734
8843
  horizontalAlignmentToolbar.set({
8735
8844
  isCompact: true,
8736
8845
  role: 'radiogroup',
8737
- ariaLabel: t('Horizontal text alignment toolbar')
8846
+ ariaLabel: t('Horizontal text alignment toolbar'),
8847
+ class: 'ck-table-cell-properties-form__horizontal-alignment-toolbar'
8738
8848
  });
8739
- fillToolbar$1({
8849
+ fillToolbar({
8740
8850
  view: this,
8741
8851
  icons: ALIGNMENT_ICONS,
8742
8852
  toolbar: horizontalAlignmentToolbar,
@@ -8760,9 +8870,10 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8760
8870
  verticalAlignmentToolbar.set({
8761
8871
  isCompact: true,
8762
8872
  role: 'radiogroup',
8763
- ariaLabel: t('Vertical text alignment toolbar')
8873
+ ariaLabel: t('Vertical text alignment toolbar'),
8874
+ class: 'ck-table-cell-properties-form__vertical-alignment-toolbar'
8764
8875
  });
8765
- fillToolbar$1({
8876
+ fillToolbar({
8766
8877
  view: this,
8767
8878
  icons: ALIGNMENT_ICONS,
8768
8879
  toolbar: verticalAlignmentToolbar,
@@ -8794,8 +8905,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8794
8905
  ];
8795
8906
  saveButtonView.set({
8796
8907
  label: t('Save'),
8797
- icon: IconCheck,
8798
- class: 'ck-button-save',
8908
+ class: 'ck-button-action',
8799
8909
  type: 'submit',
8800
8910
  withText: true
8801
8911
  });
@@ -8804,8 +8914,6 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8804
8914
  });
8805
8915
  cancelButtonView.set({
8806
8916
  label: t('Cancel'),
8807
- icon: IconCancel,
8808
- class: 'ck-button-cancel',
8809
8917
  withText: true
8810
8918
  });
8811
8919
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -8814,6 +8922,47 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8814
8922
  cancelButtonView
8815
8923
  };
8816
8924
  }
8925
+ /**
8926
+ * Creates a back button view that cancels the form.
8927
+ */ _createBackButton() {
8928
+ const t = this.locale.t;
8929
+ const backButton = new ButtonView(this.locale);
8930
+ backButton.set({
8931
+ class: 'ck-button-back',
8932
+ label: t('Back'),
8933
+ icon: IconPreviousArrow,
8934
+ tooltip: true
8935
+ });
8936
+ backButton.delegate('execute').to(this, 'cancel');
8937
+ return backButton;
8938
+ }
8939
+ /**
8940
+ * Creates the cell type dropdown definitions.
8941
+ */ _getCellTypeDefinitions() {
8942
+ const itemDefinitions = new Collection();
8943
+ const labels = this._cellTypeLabels;
8944
+ const types = [
8945
+ 'data',
8946
+ 'header'
8947
+ ];
8948
+ if (this.options.showScopedHeaderOptions) {
8949
+ types.push('header-column', 'header-row');
8950
+ }
8951
+ for (const type of types){
8952
+ const definition = {
8953
+ type: 'button',
8954
+ model: new UIModel({
8955
+ _cellTypeValue: type,
8956
+ label: labels[type],
8957
+ role: 'menuitemradio',
8958
+ withText: true
8959
+ })
8960
+ };
8961
+ definition.model.bind('isOn').to(this, 'cellType', (value)=>value === type);
8962
+ itemDefinitions.add(definition);
8963
+ }
8964
+ return itemDefinitions;
8965
+ }
8817
8966
  /**
8818
8967
  * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
8819
8968
  */ get _horizontalAlignmentLabels() {
@@ -8850,8 +8999,19 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8850
8999
  bottom: t('Align cell text to the bottom')
8851
9000
  };
8852
9001
  }
9002
+ /**
9003
+ * Provides localized labels for {@link #cellTypeDropdown}.
9004
+ */ get _cellTypeLabels() {
9005
+ const t = this.t;
9006
+ return {
9007
+ data: t('Data cell'),
9008
+ header: t('Header cell'),
9009
+ 'header-column': t('Column header'),
9010
+ 'header-row': t('Row header')
9011
+ };
9012
+ }
8853
9013
  }
8854
- function isBorderStyleSet$3(value) {
9014
+ function isBorderStyleSet$1(value) {
8855
9015
  return value !== 'none';
8856
9016
  }
8857
9017
 
@@ -8950,9 +9110,9 @@ const BALLOON_POSITIONS = /* #__PURE__ */ (()=>[
8950
9110
  return Rect.getBoundingRect(rects);
8951
9111
  }
8952
9112
 
8953
- const ERROR_TEXT_TIMEOUT$3 = 500;
9113
+ const ERROR_TEXT_TIMEOUT$1 = 500;
8954
9114
  // Map of view properties and related commands.
8955
- const propertyToCommandMap$3 = {
9115
+ const propertyToCommandMap$1 = {
8956
9116
  borderStyle: 'tableCellBorderStyle',
8957
9117
  borderColor: 'tableCellBorderColor',
8958
9118
  borderWidth: 'tableCellBorderWidth',
@@ -8961,7 +9121,8 @@ const propertyToCommandMap$3 = {
8961
9121
  padding: 'tableCellPadding',
8962
9122
  backgroundColor: 'tableCellBackgroundColor',
8963
9123
  horizontalAlignment: 'tableCellHorizontalAlignment',
8964
- verticalAlignment: 'tableCellVerticalAlignment'
9124
+ verticalAlignment: 'tableCellVerticalAlignment',
9125
+ cellType: 'tableCellType'
8965
9126
  };
8966
9127
  /**
8967
9128
  * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
@@ -9048,7 +9209,7 @@ const propertyToCommandMap$3 = {
9048
9209
  tooltip: true
9049
9210
  });
9050
9211
  this.listenTo(view, 'execute', ()=>this._showView());
9051
- const commands = Object.values(propertyToCommandMap$3).map((commandName)=>editor.commands.get(commandName));
9212
+ const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName)).filter((val)=>!!val);
9052
9213
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
9053
9214
  return view;
9054
9215
  });
@@ -9070,6 +9231,7 @@ const propertyToCommandMap$3 = {
9070
9231
  */ _createPropertiesView(defaultTableCellProperties) {
9071
9232
  const editor = this.editor;
9072
9233
  const config = editor.config.get('table.tableCellProperties');
9234
+ const scopedHeaders = !!editor.config.get('table.tableCellProperties.scopedHeaders');
9073
9235
  const borderColorsConfig = normalizeColorOptions(config.borderColors);
9074
9236
  const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
9075
9237
  const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
@@ -9079,7 +9241,8 @@ const propertyToCommandMap$3 = {
9079
9241
  borderColors: localizedBorderColors,
9080
9242
  backgroundColors: localizedBackgroundColors,
9081
9243
  defaultTableCellProperties,
9082
- colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
9244
+ colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false,
9245
+ showScopedHeaderOptions: scopedHeaders
9083
9246
  });
9084
9247
  const t = editor.t;
9085
9248
  // Render the view so its #element is available for the clickOutsideHandler.
@@ -9154,6 +9317,11 @@ const propertyToCommandMap$3 = {
9154
9317
  }));
9155
9318
  view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
9156
9319
  view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
9320
+ const cellTypeCommand = editor.commands.get('tableCellType');
9321
+ if (cellTypeCommand) {
9322
+ view.cellTypeDropdown.bind('isEnabled').to(cellTypeCommand, 'isEnabled');
9323
+ view.on('change:cellType', this._getPropertyChangeCallback('tableCellType'));
9324
+ }
9157
9325
  return view;
9158
9326
  }
9159
9327
  /**
@@ -9166,12 +9334,24 @@ const propertyToCommandMap$3 = {
9166
9334
  */ _fillViewFormFromCommandValues() {
9167
9335
  const commands = this.editor.commands;
9168
9336
  const borderStyleCommand = commands.get('tableCellBorderStyle');
9169
- Object.entries(propertyToCommandMap$3).map(([property, commandName])=>{
9337
+ Object.entries(propertyToCommandMap$1).flatMap(([property, commandName])=>{
9338
+ const command = commands.get(commandName);
9339
+ if (!command) {
9340
+ return [];
9341
+ }
9170
9342
  const propertyKey = property;
9171
- const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
9172
- return [
9343
+ let defaultValue;
9344
+ if (propertyKey === 'cellType') {
9345
+ defaultValue = '';
9346
+ } else {
9347
+ defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
9348
+ }
9349
+ const entry = [
9173
9350
  property,
9174
- commands.get(commandName).value || defaultValue
9351
+ command.value || defaultValue
9352
+ ];
9353
+ return [
9354
+ entry
9175
9355
  ];
9176
9356
  }).forEach(([property, value])=>{
9177
9357
  // Do not set the `border-color` and `border-width` fields if `border-style:none`.
@@ -9272,7 +9452,7 @@ const propertyToCommandMap$3 = {
9272
9452
  const { commandName, viewField, validator, errorText } = options;
9273
9453
  const setErrorTextDebounced = debounce(()=>{
9274
9454
  viewField.errorText = errorText;
9275
- }, ERROR_TEXT_TIMEOUT$3);
9455
+ }, ERROR_TEXT_TIMEOUT$1);
9276
9456
  return (evt, propertyName, newValue)=>{
9277
9457
  setErrorTextDebounced.cancel();
9278
9458
  // Do not execute the command on initial call (opening the table properties view).
@@ -9932,7 +10112,7 @@ const propertyToCommandMap$3 = {
9932
10112
  // Check each cell in the current row/column.
9933
10113
  for (const { cell, row, column } of walker){
9934
10114
  // If we find a non-header cell, this row/column can't be part of the heading section.
9935
- if (cell.getAttribute('tableCellType') !== 'header') {
10115
+ if (!isTableHeaderCellType(cell.getAttribute('tableCellType'))) {
9936
10116
  allCellsAreHeaders = false;
9937
10117
  break;
9938
10118
  }
@@ -10058,10 +10238,8 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10058
10238
  editor.commands.add('tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand(editor, defaultTableCellProperties.horizontalAlignment));
10059
10239
  enableVerticalAlignmentProperty(schema, conversion, defaultTableCellProperties.verticalAlignment);
10060
10240
  editor.commands.add('tableCellVerticalAlignment', new TableCellVerticalAlignmentCommand(editor, defaultTableCellProperties.verticalAlignment));
10061
- if (editor.config.get('experimentalFlags.tableCellTypeSupport')) {
10062
- enableCellTypeProperty(editor);
10063
- editor.commands.add('tableCellType', new TableCellTypeCommand(editor));
10064
- }
10241
+ enableCellTypeProperty(editor);
10242
+ editor.commands.add('tableCellType', new TableCellTypeCommand(editor));
10065
10243
  }
10066
10244
  }
10067
10245
  /**
@@ -10251,8 +10429,9 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10251
10429
  /**
10252
10430
  * Enables the `tableCellType` attribute for table cells.
10253
10431
  */ function enableCellTypeProperty(editor) {
10254
- const { model, conversion, editing } = editor;
10432
+ const { model, conversion, editing, config } = editor;
10255
10433
  const { schema } = model;
10434
+ const scopedHeaders = !!config.get('table.tableCellProperties.scopedHeaders');
10256
10435
  const tableUtils = editor.plugins.get(TableUtils);
10257
10436
  schema.extend('tableCell', {
10258
10437
  allowAttributes: [
@@ -10275,7 +10454,7 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10275
10454
  const { writer } = conversionApi;
10276
10455
  const { modelRange } = data;
10277
10456
  const modelElement = modelRange?.start.nodeAfter;
10278
- if (modelElement?.is('element', 'tableCell')) {
10457
+ if (modelElement?.is('element', 'tableCell') && !modelElement.hasAttribute('tableCellType')) {
10279
10458
  writer.setAttribute('tableCellType', 'header', modelElement);
10280
10459
  }
10281
10460
  });
@@ -10287,7 +10466,8 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10287
10466
  const modelElement = modelRange?.start.nodeAfter;
10288
10467
  if (modelElement?.is('element', 'table') && modelElement.getAttribute('tableType') === 'layout') {
10289
10468
  for (const { cell } of new TableWalker(modelElement)){
10290
- if (cell.getAttribute('tableCellType') === 'header') {
10469
+ const tableCellType = cell.getAttribute('tableCellType');
10470
+ if (isTableHeaderCellType(tableCellType)) {
10291
10471
  writer.setAttribute('tableType', 'content', modelElement);
10292
10472
  break;
10293
10473
  }
@@ -10297,6 +10477,55 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10297
10477
  priority: priorities.low - 1
10298
10478
  });
10299
10479
  });
10480
+ // If scoped headers are enabled, add conversion for the `scope` attribute.
10481
+ if (scopedHeaders) {
10482
+ conversion.for('downcast').attributeToAttribute({
10483
+ model: {
10484
+ name: 'tableCell',
10485
+ key: 'tableCellType'
10486
+ },
10487
+ view: (modelAttributeValue)=>{
10488
+ switch(modelAttributeValue){
10489
+ case 'header-row':
10490
+ return {
10491
+ key: 'scope',
10492
+ value: 'row'
10493
+ };
10494
+ case 'header-column':
10495
+ return {
10496
+ key: 'scope',
10497
+ value: 'col'
10498
+ };
10499
+ }
10500
+ }
10501
+ });
10502
+ // Attribute to attribute conversion tend to not override existing `tableCellType` set by other converters.
10503
+ // However, in this scenario if the previous converter set `tableCellType` to `header`, we can adjust it
10504
+ // based on the `scope` attribute.
10505
+ conversion.for('upcast').add((dispatcher)=>{
10506
+ dispatcher.on('element:th', (_, data, conversionApi)=>{
10507
+ const { writer, consumable } = conversionApi;
10508
+ const { viewItem, modelRange } = data;
10509
+ const modelElement = modelRange.start.nodeAfter;
10510
+ const previousTableCellType = modelElement?.getAttribute('tableCellType');
10511
+ if (previousTableCellType === 'header' && consumable.consume(viewItem, {
10512
+ attributes: [
10513
+ 'scope'
10514
+ ]
10515
+ })) {
10516
+ const scope = viewItem.getAttribute('scope');
10517
+ switch(scope){
10518
+ case 'row':
10519
+ writer.setAttribute('tableCellType', 'header-row', modelElement);
10520
+ break;
10521
+ case 'col':
10522
+ writer.setAttribute('tableCellType', 'header-column', modelElement);
10523
+ break;
10524
+ }
10525
+ }
10526
+ });
10527
+ });
10528
+ }
10300
10529
  // Registers a post-fixer that ensures the `headingRows` and `headingColumns` attributes
10301
10530
  // are consistent with the `tableCellType` attribute of the cells. `tableCellType` has priority
10302
10531
  // over `headingRows` and `headingColumns` and we use it to adjust the heading sections of the table.
@@ -10354,7 +10583,7 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10354
10583
  for (const tableCell of cellsToReconvert){
10355
10584
  const viewElement = editing.mapper.toViewElement(tableCell);
10356
10585
  const cellType = tableCell.getAttribute('tableCellType');
10357
- const expectedElementName = cellType === 'header' ? 'th' : 'td';
10586
+ const expectedElementName = isTableHeaderCellType(cellType) ? 'th' : 'td';
10358
10587
  if (viewElement?.name !== expectedElementName) {
10359
10588
  editing.reconvertItem(tableCell);
10360
10589
  }
@@ -10485,14 +10714,10 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
10485
10714
  */ afterInit() {
10486
10715
  const { editor } = this;
10487
10716
  const { ui, plugins } = editor;
10488
- let tablePropertiesUI;
10489
- if (plugins.has('TablePropertiesUIExperimental')) {
10490
- tablePropertiesUI = plugins.get('TablePropertiesUIExperimental');
10491
- } else if (plugins.has('TablePropertiesUI')) {
10492
- tablePropertiesUI = plugins.get('TablePropertiesUI');
10493
- } else {
10717
+ if (!editor.plugins.has('TablePropertiesUI')) {
10494
10718
  return;
10495
10719
  }
10720
+ const tablePropertiesUI = plugins.get('TablePropertiesUI');
10496
10721
  // Override the default table properties button to include the table type dropdown.
10497
10722
  // It needs to be done in `afterInit()` to make sure that `tableProperties` button is
10498
10723
  // registered after the initialization of the `TablePropertiesUI`. Otherwise, the
@@ -12263,7 +12488,7 @@ const TABLE_TYPES = [
12263
12488
  const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
12264
12489
  includeAlignmentProperty: true
12265
12490
  });
12266
- const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') !== false;
12491
+ const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') === true;
12267
12492
  editor.data.addStyleProcessorRules(addMarginStylesRules);
12268
12493
  editor.data.addStyleProcessorRules(addBorderStylesRules);
12269
12494
  enableBorderProperties(editor, {
@@ -12274,11 +12499,7 @@ const TABLE_TYPES = [
12274
12499
  editor.commands.add('tableBorderColor', new TableBorderColorCommand(editor, defaultTableProperties.borderColor));
12275
12500
  editor.commands.add('tableBorderStyle', new TableBorderStyleCommand(editor, defaultTableProperties.borderStyle));
12276
12501
  editor.commands.add('tableBorderWidth', new TableBorderWidthCommand(editor, defaultTableProperties.borderWidth));
12277
- if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
12278
- enableExtendedAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
12279
- } else {
12280
- enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment);
12281
- }
12502
+ enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
12282
12503
  editor.commands.add('tableAlignment', new TableAlignmentCommand(editor, defaultTableProperties.alignment));
12283
12504
  enableTableToFigureProperty(schema, conversion, {
12284
12505
  modelAttribute: 'tableWidth',
@@ -12305,20 +12526,18 @@ const TABLE_TYPES = [
12305
12526
  defaultValue: defaultTableProperties.backgroundColor
12306
12527
  });
12307
12528
  editor.commands.add('tableBackgroundColor', new TableBackgroundColorCommand(editor, defaultTableProperties.backgroundColor));
12308
- if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
12309
- const viewDoc = editor.editing.view.document;
12310
- // Adjust clipboard output to wrap tables in divs if needed (for alignment).
12311
- this.listenTo(viewDoc, 'clipboardOutput', (evt, data)=>{
12312
- editor.editing.view.change((writer)=>{
12313
- for (const { item } of writer.createRangeIn(data.content)){
12314
- wrapInDivIfNeeded(item, writer);
12315
- }
12316
- data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
12317
- });
12318
- }, {
12319
- priority: 'lowest'
12529
+ const viewDoc = editor.editing.view.document;
12530
+ // Adjust clipboard output to wrap tables in divs if needed (for alignment).
12531
+ this.listenTo(viewDoc, 'clipboardOutput', (evt, data)=>{
12532
+ editor.editing.view.change((writer)=>{
12533
+ for (const { item } of writer.createRangeIn(data.content)){
12534
+ wrapInDivIfNeeded(item, writer);
12535
+ }
12536
+ data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
12320
12537
  });
12321
- }
12538
+ }, {
12539
+ priority: 'lowest'
12540
+ });
12322
12541
  }
12323
12542
  }
12324
12543
  /**
@@ -12388,10 +12607,10 @@ function insertWrapperWithAlignment(writer, align, table) {
12388
12607
  });
12389
12608
  }
12390
12609
  /**
12391
- * Enables the extended block`'alignment'` attribute for table.
12610
+ * Enables the `'alignment'` attribute for table.
12392
12611
  *
12393
12612
  * @param defaultValue The default alignment value.
12394
- */ function enableExtendedAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
12613
+ */ function enableAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
12395
12614
  schema.extend('table', {
12396
12615
  allowAttributes: [
12397
12616
  'tableAlignment'
@@ -12491,145 +12710,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12491
12710
  conversion.for('upcast').add(upcastTableAlignedDiv(defaultValue));
12492
12711
  }
12493
12712
  /**
12494
- * Enables the `'alignment'` attribute for table.
12495
- *
12496
- * @param defaultValue The default alignment value.
12497
- */ function enableAlignmentProperty(schema, conversion, defaultValue) {
12498
- const ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;
12499
- const FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;
12500
- schema.extend('table', {
12501
- allowAttributes: [
12502
- 'tableAlignment'
12503
- ]
12504
- });
12505
- schema.setAttributeProperties('tableAlignment', {
12506
- isFormatting: true
12507
- });
12508
- conversion.for('downcast').attributeToAttribute({
12509
- model: {
12510
- name: 'table',
12511
- key: 'tableAlignment',
12512
- values: [
12513
- 'left',
12514
- 'center',
12515
- 'right'
12516
- ]
12517
- },
12518
- view: {
12519
- left: {
12520
- key: 'style',
12521
- value: {
12522
- float: 'left'
12523
- }
12524
- },
12525
- right: {
12526
- key: 'style',
12527
- value: {
12528
- float: 'right'
12529
- }
12530
- },
12531
- center: (alignment, conversionApi, data)=>{
12532
- const value = data.item.getAttribute('tableType') !== 'layout' ? {
12533
- // Model: `alignment:center` => CSS: `float:none`.
12534
- float: 'none'
12535
- } : {
12536
- 'margin-left': 'auto',
12537
- 'margin-right': 'auto'
12538
- };
12539
- return {
12540
- key: 'style',
12541
- value
12542
- };
12543
- }
12544
- },
12545
- converterPriority: 'high'
12546
- });
12547
- conversion.for('upcast')// Support for the `float:*;` CSS definition for the table alignment.
12548
- .attributeToAttribute({
12549
- view: {
12550
- name: /^(table|figure)$/,
12551
- styles: {
12552
- float: FLOAT_VALUES_REG_EXP
12553
- }
12554
- },
12555
- model: {
12556
- key: 'tableAlignment',
12557
- value: (viewElement, conversionApi, data)=>{
12558
- // Ignore other figure elements.
12559
- if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
12560
- return;
12561
- }
12562
- const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
12563
- let align = viewElement.getStyle('float');
12564
- // CSS: `float:none` => Model: `alignment:center`.
12565
- if (align === 'none') {
12566
- align = 'center';
12567
- }
12568
- if (align !== localDefaultValue) {
12569
- return align;
12570
- }
12571
- // Consume the style even if not applied to the element so it won't be processed by other converters.
12572
- conversionApi.consumable.consume(viewElement, {
12573
- styles: 'float'
12574
- });
12575
- }
12576
- }
12577
- })// Support for the `margin-left:auto; margin-right:auto;` CSS definition for the table alignment.
12578
- .attributeToAttribute({
12579
- view: {
12580
- name: /^(table|figure)$/,
12581
- styles: {
12582
- 'margin-left': 'auto',
12583
- 'margin-right': 'auto'
12584
- }
12585
- },
12586
- model: {
12587
- key: 'tableAlignment',
12588
- value: (viewElement, conversionApi, data)=>{
12589
- // Ignore other figure elements.
12590
- if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
12591
- return;
12592
- }
12593
- const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
12594
- const align = 'center';
12595
- if (align !== localDefaultValue) {
12596
- return align;
12597
- }
12598
- // Consume the styles even if not applied to the element so it won't be processed by other converters.
12599
- conversionApi.consumable.consume(viewElement, {
12600
- styles: [
12601
- 'margin-left',
12602
- 'margin-right'
12603
- ]
12604
- });
12605
- }
12606
- }
12607
- })// Support for the `align` attribute as the backward compatibility while pasting from other sources.
12608
- .attributeToAttribute({
12609
- view: {
12610
- name: 'table',
12611
- attributes: {
12612
- align: ALIGN_VALUES_REG_EXP
12613
- }
12614
- },
12615
- model: {
12616
- key: 'tableAlignment',
12617
- value: (viewElement, conversionApi, data)=>{
12618
- const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
12619
- const align = viewElement.getAttribute('align');
12620
- if (align !== localDefaultValue) {
12621
- return align;
12622
- }
12623
- // Consume the attribute even if not applied to the element so it won't be processed by other converters.
12624
- conversionApi.consumable.consume(viewElement, {
12625
- attributes: 'align'
12626
- });
12627
- }
12628
- }
12629
- });
12630
- }
12631
- /**
12632
- * Returns a function that converts the table view representation:
12713
+ * Returns a function that converts the table view representation:
12633
12714
  *
12634
12715
  * ```html
12635
12716
  * <div align="right"><table>...</table></div>
@@ -12818,6 +12899,9 @@ function insertWrapperWithAlignment(writer, align, table) {
12818
12899
  /**
12819
12900
  * The "Cancel" button view.
12820
12901
  */ cancelButtonView;
12902
+ /**
12903
+ * The Back button view displayed in the header.
12904
+ */ backButtonView;
12821
12905
  /**
12822
12906
  * A collection of views that can be focused in the form.
12823
12907
  */ _focusables;
@@ -12859,6 +12943,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12859
12943
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
12860
12944
  this.saveButtonView = saveButtonView;
12861
12945
  this.cancelButtonView = cancelButtonView;
12946
+ this.backButtonView = this._createBackButton();
12862
12947
  this._focusables = new ViewCollection();
12863
12948
  this._focusCycler = new FocusCycler({
12864
12949
  focusables: this._focusables,
@@ -12872,29 +12957,22 @@ function insertWrapperWithAlignment(writer, align, table) {
12872
12957
  }
12873
12958
  });
12874
12959
  // Form header.
12875
- this.children.add(new FormHeaderView(locale, {
12960
+ const headerView = new FormHeaderView(locale, {
12876
12961
  label: this.t('Table properties')
12877
- }));
12962
+ });
12963
+ headerView.children.add(this.backButtonView, 0);
12964
+ this.children.add(headerView);
12878
12965
  // Border row.
12879
12966
  this.children.add(new FormRowView(locale, {
12880
12967
  labelView: borderRowLabel,
12881
12968
  children: [
12882
12969
  borderRowLabel,
12883
12970
  borderStyleDropdown,
12884
- borderColorInput,
12885
- borderWidthInput
12971
+ borderWidthInput,
12972
+ borderColorInput
12886
12973
  ],
12887
12974
  class: 'ck-table-form__border-row'
12888
12975
  }));
12889
- // Background row.
12890
- this.children.add(new FormRowView(locale, {
12891
- labelView: backgroundRowLabel,
12892
- children: [
12893
- backgroundRowLabel,
12894
- backgroundInput
12895
- ],
12896
- class: 'ck-table-form__background-row'
12897
- }));
12898
12976
  this.children.add(new FormRowView(locale, {
12899
12977
  children: [
12900
12978
  // Dimensions row.
@@ -12908,22 +12986,31 @@ function insertWrapperWithAlignment(writer, align, table) {
12908
12986
  ],
12909
12987
  class: 'ck-table-form__dimensions-row'
12910
12988
  }),
12911
- // Alignment row.
12989
+ // Background row.
12912
12990
  new FormRowView(locale, {
12913
- labelView: alignmentLabel,
12991
+ labelView: backgroundRowLabel,
12914
12992
  children: [
12915
- alignmentLabel,
12916
- alignmentToolbar
12993
+ backgroundRowLabel,
12994
+ backgroundInput
12917
12995
  ],
12918
- class: 'ck-table-properties-form__alignment-row'
12996
+ class: 'ck-table-form__background-row'
12919
12997
  })
12920
12998
  ]
12921
12999
  }));
13000
+ // Alignment row.
13001
+ this.children.add(new FormRowView(locale, {
13002
+ labelView: alignmentLabel,
13003
+ children: [
13004
+ alignmentLabel,
13005
+ alignmentToolbar
13006
+ ],
13007
+ class: 'ck-table-properties-form__alignment-row'
13008
+ }));
12922
13009
  // Action row.
12923
13010
  this.children.add(new FormRowView(locale, {
12924
13011
  children: [
12925
- this.saveButtonView,
12926
- this.cancelButtonView
13012
+ this.cancelButtonView,
13013
+ this.saveButtonView
12927
13014
  ],
12928
13015
  class: 'ck-table-form__action-row'
12929
13016
  }));
@@ -12960,14 +13047,15 @@ function insertWrapperWithAlignment(writer, align, table) {
12960
13047
  });
12961
13048
  [
12962
13049
  this.borderStyleDropdown,
12963
- this.borderColorInput,
12964
13050
  this.borderWidthInput,
12965
- this.backgroundInput,
13051
+ this.borderColorInput,
12966
13052
  this.widthInput,
12967
13053
  this.heightInput,
13054
+ this.backgroundInput,
12968
13055
  this.alignmentToolbar,
13056
+ this.cancelButtonView,
12969
13057
  this.saveButtonView,
12970
- this.cancelButtonView
13058
+ this.backButtonView
12971
13059
  ].forEach((view)=>{
12972
13060
  // Register the view as focusable.
12973
13061
  this._focusables.add(view);
@@ -13002,7 +13090,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13002
13090
  width: defaultTableProperties.borderWidth,
13003
13091
  color: defaultTableProperties.borderColor
13004
13092
  };
13005
- const colorInputCreator = getLabeledColorInputCreator$1({
13093
+ const colorInputCreator = getLabeledColorInputCreator({
13006
13094
  colorConfig: this.options.borderColors,
13007
13095
  columns: 5,
13008
13096
  defaultColorValue: defaultBorder.color,
@@ -13015,7 +13103,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13015
13103
  const borderRowLabel = new LabelView(locale);
13016
13104
  borderRowLabel.text = t('Border');
13017
13105
  // -- Style ---------------------------------------------------
13018
- const styleLabels = getBorderStyleLabels$1(t);
13106
+ const styleLabels = getBorderStyleLabels(t);
13019
13107
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
13020
13108
  borderStyleDropdown.set({
13021
13109
  label: accessibleLabel,
@@ -13035,7 +13123,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13035
13123
  this.borderStyle = evt.source._borderStyleValue;
13036
13124
  });
13037
13125
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
13038
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
13126
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
13039
13127
  role: 'menu',
13040
13128
  ariaLabel: accessibleLabel
13041
13129
  });
@@ -13046,7 +13134,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13046
13134
  class: 'ck-table-form__border-width'
13047
13135
  });
13048
13136
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
13049
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
13137
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
13050
13138
  borderWidthInput.fieldView.on('input', ()=>{
13051
13139
  this.borderWidth = borderWidthInput.fieldView.element.value;
13052
13140
  });
@@ -13057,7 +13145,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13057
13145
  class: 'ck-table-form__border-color'
13058
13146
  });
13059
13147
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
13060
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
13148
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
13061
13149
  borderColorInput.fieldView.on('input', ()=>{
13062
13150
  this.borderColor = borderColorInput.fieldView.value;
13063
13151
  });
@@ -13065,12 +13153,12 @@ function insertWrapperWithAlignment(writer, align, table) {
13065
13153
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
13066
13154
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
13067
13155
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
13068
- if (!isBorderStyleSet$2(newValue)) {
13156
+ if (!isBorderStyleSet(newValue)) {
13069
13157
  this.borderColor = '';
13070
13158
  this.borderWidth = '';
13071
13159
  }
13072
13160
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
13073
- if (!isBorderStyleSet$2(oldValue)) {
13161
+ if (!isBorderStyleSet(oldValue)) {
13074
13162
  this.borderColor = defaultBorder.color;
13075
13163
  this.borderWidth = defaultBorder.width;
13076
13164
  }
@@ -13093,7 +13181,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13093
13181
  const backgroundRowLabel = new LabelView(locale);
13094
13182
  backgroundRowLabel.text = t('Background');
13095
13183
  // -- Background color input -----------------------------------
13096
- const backgroundInputCreator = getLabeledColorInputCreator$1({
13184
+ const backgroundInputCreator = getLabeledColorInputCreator({
13097
13185
  colorConfig: this.options.backgroundColors,
13098
13186
  columns: 5,
13099
13187
  defaultColorValue: this.options.defaultTableProperties.backgroundColor,
@@ -13175,7 +13263,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13175
13263
  const t = this.t;
13176
13264
  // -- Label ---------------------------------------------------
13177
13265
  const alignmentLabel = new LabelView(locale);
13178
- alignmentLabel.text = t('Alignment');
13266
+ alignmentLabel.text = t('Table Alignment');
13179
13267
  // -- Toolbar ---------------------------------------------------
13180
13268
  const alignmentToolbar = new ToolbarView(locale);
13181
13269
  alignmentToolbar.set({
@@ -13183,12 +13271,14 @@ function insertWrapperWithAlignment(writer, align, table) {
13183
13271
  isCompact: true,
13184
13272
  ariaLabel: t('Table alignment toolbar')
13185
13273
  });
13186
- fillToolbar$1({
13274
+ fillToolbar({
13187
13275
  view: this,
13188
13276
  icons: {
13189
13277
  left: IconObjectInlineLeft,
13190
13278
  center: IconObjectCenter,
13191
- right: IconObjectInlineRight
13279
+ right: IconObjectInlineRight,
13280
+ blockLeft: IconObjectLeft,
13281
+ blockRight: IconObjectRight
13192
13282
  },
13193
13283
  toolbar: alignmentToolbar,
13194
13284
  labels: this._alignmentLabels,
@@ -13219,8 +13309,7 @@ function insertWrapperWithAlignment(writer, align, table) {
13219
13309
  ];
13220
13310
  saveButtonView.set({
13221
13311
  label: t('Save'),
13222
- icon: IconCheck,
13223
- class: 'ck-button-save',
13312
+ class: 'ck-button-action',
13224
13313
  type: 'submit',
13225
13314
  withText: true
13226
13315
  });
@@ -13229,8 +13318,6 @@ function insertWrapperWithAlignment(writer, align, table) {
13229
13318
  });
13230
13319
  cancelButtonView.set({
13231
13320
  label: t('Cancel'),
13232
- icon: IconCancel,
13233
- class: 'ck-button-cancel',
13234
13321
  withText: true
13235
13322
  });
13236
13323
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -13239,37 +13326,56 @@ function insertWrapperWithAlignment(writer, align, table) {
13239
13326
  cancelButtonView
13240
13327
  };
13241
13328
  }
13329
+ /**
13330
+ * Creates a back button view that cancels the form.
13331
+ */ _createBackButton() {
13332
+ const t = this.locale.t;
13333
+ const backButton = new ButtonView(this.locale);
13334
+ backButton.set({
13335
+ class: 'ck-button-back',
13336
+ label: t('Back'),
13337
+ icon: IconPreviousArrow,
13338
+ tooltip: true
13339
+ });
13340
+ backButton.delegate('execute').to(this, 'cancel');
13341
+ return backButton;
13342
+ }
13242
13343
  /**
13243
13344
  * Provides localized labels for {@link #alignmentToolbar} buttons.
13244
13345
  */ get _alignmentLabels() {
13245
13346
  const locale = this.locale;
13246
13347
  const t = this.t;
13247
- const left = t('Align table to the left');
13248
- const center = t('Center table');
13249
- const right = t('Align table to the right');
13348
+ const blockLeft = t('Align table to the left with no text wrapping');
13349
+ const blockRight = t('Align table to the right with no text wrapping');
13350
+ const left = t('Align table to the left with text wrapping');
13351
+ const center = t('Center table with no text wrapping');
13352
+ const right = t('Align table to the right with text wrapping');
13250
13353
  // Returns object with a proper order of labels.
13251
13354
  if (locale.uiLanguageDirection === 'rtl') {
13252
13355
  return {
13253
13356
  right,
13254
- center,
13255
- left
13256
- };
13257
- } else {
13258
- return {
13259
13357
  left,
13358
+ blockRight,
13260
13359
  center,
13261
- right
13360
+ blockLeft
13262
13361
  };
13263
13362
  }
13363
+ return {
13364
+ blockLeft,
13365
+ center,
13366
+ blockRight,
13367
+ left,
13368
+ right
13369
+ };
13264
13370
  }
13265
13371
  }
13266
- function isBorderStyleSet$2(value) {
13372
+ function isBorderStyleSet(value) {
13267
13373
  return value !== 'none';
13268
13374
  }
13269
13375
 
13270
- const ERROR_TEXT_TIMEOUT$2 = 500;
13376
+ const ERROR_TEXT_TIMEOUT = 500;
13271
13377
  // Map of view properties and related commands.
13272
- const propertyToCommandMap$2 = {
13378
+ const propertyToCommandMap = {
13273
13379
  borderStyle: 'tableBorderStyle',
13274
13380
  borderColor: 'tableBorderColor',
13275
13381
  borderWidth: 'tableBorderWidth',
@@ -13361,7 +13467,7 @@ const propertyToCommandMap$2 = {
13361
13467
  tooltip: true
13362
13468
  });
13363
13469
  this.listenTo(view, 'execute', ()=>this._showView());
13364
- const commands = Object.values(propertyToCommandMap$2).map((commandName)=>editor.commands.get(commandName));
13470
+ const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
13365
13471
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
13366
13472
  return view;
13367
13473
  }
@@ -13471,7 +13577,7 @@ const propertyToCommandMap$2 = {
13471
13577
  */ _fillViewFormFromCommandValues() {
13472
13578
  const commands = this.editor.commands;
13473
13579
  const borderStyleCommand = commands.get('tableBorderStyle');
13474
- Object.entries(propertyToCommandMap$2).map(([property, commandName])=>{
13580
+ Object.entries(propertyToCommandMap).map(([property, commandName])=>{
13475
13581
  const propertyKey = property;
13476
13582
  const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
13477
13583
  return [
@@ -13580,7 +13686,7 @@ const propertyToCommandMap$2 = {
13580
13686
  const { commandName, viewField, validator, errorText } = options;
13581
13687
  const setErrorTextDebounced = debounce(()=>{
13582
13688
  viewField.errorText = errorText;
13583
- }, ERROR_TEXT_TIMEOUT$2);
13689
+ }, ERROR_TEXT_TIMEOUT);
13584
13690
  return (evt, propertyName, newValue)=>{
13585
13691
  setErrorTextDebounced.cancel();
13586
13692
  // Do not execute the command on initial call (opening the table properties view).
@@ -14021,2096 +14127,5 @@ const propertyToCommandMap$2 = {
14021
14127
  }
14022
14128
  }
14023
14129
 
14024
- /**
14025
- * Returns an object containing pairs of CSS border style values and their localized UI
14026
- * labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}
14027
- * and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.
14028
- *
14029
- * @internal
14030
- * @param t The "t" function provided by the editor that is used to localize strings.
14031
- */ function getBorderStyleLabels(t) {
14032
- return {
14033
- none: t('None'),
14034
- solid: t('Solid'),
14035
- dotted: t('Dotted'),
14036
- dashed: t('Dashed'),
14037
- double: t('Double'),
14038
- groove: t('Groove'),
14039
- ridge: t('Ridge'),
14040
- inset: t('Inset'),
14041
- outset: t('Outset')
14042
- };
14043
- }
14044
- /**
14045
- * Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.
14046
- *
14047
- * @internal
14048
- * @param defaultStyle The default border.
14049
- */ function getBorderStyleDefinitions(view, defaultStyle) {
14050
- const itemDefinitions = new Collection();
14051
- const styleLabels = getBorderStyleLabels(view.t);
14052
- for(const style in styleLabels){
14053
- const definition = {
14054
- type: 'button',
14055
- model: new UIModel({
14056
- _borderStyleValue: style,
14057
- label: styleLabels[style],
14058
- role: 'menuitemradio',
14059
- withText: true
14060
- })
14061
- };
14062
- if (style === 'none') {
14063
- definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
14064
- if (defaultStyle === 'none') {
14065
- return !value;
14066
- }
14067
- return value === style;
14068
- });
14069
- } else {
14070
- definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
14071
- return value === style;
14072
- });
14073
- }
14074
- itemDefinitions.add(definition);
14075
- }
14076
- return itemDefinitions;
14077
- }
14078
- /**
14079
- * A helper that fills a toolbar with buttons that:
14080
- *
14081
- * * have some labels,
14082
- * * have some icons,
14083
- * * set a certain UI view property value upon execution.
14084
- *
14085
- * @internal
14086
- * @param options Configuration options
14087
- * @param options.view The view that has the observable property.
14088
- * @param options.icons Object with button icons.
14089
- * @param options.toolbar The toolbar to fill with buttons.
14090
- * @param options.labels Object with button labels.
14091
- * @param options.propertyName The name of the observable property in the view.
14092
- * @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
14093
- * @param options.defaultValue Default value for the property.
14094
- */ function fillToolbar(options) {
14095
- const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
14096
- for(const name in labels){
14097
- const button = new ButtonView(view.locale);
14098
- button.set({
14099
- role: 'radio',
14100
- isToggleable: true,
14101
- label: labels[name],
14102
- icon: icons[name],
14103
- tooltip: labels[name]
14104
- });
14105
- // If specified the `nameToValue()` callback, map the value based on the option's name.
14106
- const buttonValue = nameToValue ? nameToValue(name) : name;
14107
- button.bind('isOn').to(view, propertyName, (value)=>{
14108
- // `value` comes from `view[ propertyName ]`.
14109
- let valueToCompare = value;
14110
- // If it's empty, and the `defaultValue` is specified, use it instead.
14111
- if (value === '' && defaultValue) {
14112
- valueToCompare = defaultValue;
14113
- }
14114
- return buttonValue === valueToCompare;
14115
- });
14116
- button.on('execute', ()=>{
14117
- // Allow toggling alignment if there is no default value specified (especially for layout tables).
14118
- if (!defaultValue && buttonValue && view[propertyName] === buttonValue) {
14119
- view[propertyName] = undefined;
14120
- } else {
14121
- view[propertyName] = buttonValue;
14122
- }
14123
- });
14124
- toolbar.items.add(button);
14125
- }
14126
- }
14127
- /**
14128
- * Returns a creator for a color input with a label.
14129
- *
14130
- * For given options, it returns a function that creates an instance of a
14131
- * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to
14132
- * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.
14133
- *
14134
- * The helper does the following:
14135
- *
14136
- * * It sets the color input `id` and `ariaDescribedById` attributes.
14137
- * * It binds the color input `isReadOnly` to the labeled view.
14138
- * * It binds the color input `hasError` to the labeled view.
14139
- * * It enables a logic that cleans up the error when the user starts typing in the color input.
14140
- *
14141
- * Usage:
14142
- *
14143
- * ```ts
14144
- * const colorInputCreator = getLabeledColorInputCreator( {
14145
- * colorConfig: [ ... ],
14146
- * columns: 3,
14147
- * } );
14148
- *
14149
- * const labeledInputView = new LabeledFieldView( locale, colorInputCreator );
14150
- * console.log( labeledInputView.view ); // A color input instance.
14151
- * ```
14152
- *
14153
- * @internal
14154
- * @param options Color input options.
14155
- * @param options.colorConfig The configuration of the color palette displayed in the input's dropdown.
14156
- * @param options.columns The configuration of the number of columns the color palette consists of in the input's dropdown.
14157
- * @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
14158
- * the "Restore default" button. Instead of clearing the input field, the default color value will be set.
14159
- * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
14160
- */ function getLabeledColorInputCreator(options) {
14161
- return (labeledFieldView, viewUid, statusUid)=>{
14162
- const colorInputView = new ColorInputView(labeledFieldView.locale, {
14163
- colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
14164
- columns: options.columns,
14165
- defaultColorValue: options.defaultColorValue,
14166
- colorPickerConfig: options.colorPickerConfig
14167
- });
14168
- colorInputView.inputView.set({
14169
- id: viewUid,
14170
- ariaDescribedById: statusUid
14171
- });
14172
- colorInputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);
14173
- colorInputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);
14174
- colorInputView.on('input', ()=>{
14175
- // UX: Make the error text disappear and disable the error indicator as the user
14176
- // starts fixing the errors.
14177
- labeledFieldView.errorText = null;
14178
- });
14179
- labeledFieldView.bind('isEmpty', 'isFocused').to(colorInputView);
14180
- return colorInputView;
14181
- };
14182
- }
14183
- function colorConfigToColorGridDefinitions(colorConfig) {
14184
- return colorConfig.map((item)=>({
14185
- color: item.model,
14186
- label: item.label,
14187
- options: {
14188
- hasBorder: item.hasBorder
14189
- }
14190
- }));
14191
- }
14192
-
14193
- /**
14194
- * The class representing a table properties form, allowing users to customize
14195
- * certain style aspects of a table, for instance, border, background color, alignment, etc..
14196
- */ class TablePropertiesViewExperimental extends View {
14197
- /**
14198
- * Options passed to the view. See {@link #constructor} to learn more.
14199
- */ options;
14200
- /**
14201
- * Tracks information about the DOM focus in the form.
14202
- */ focusTracker;
14203
- /**
14204
- * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
14205
- */ keystrokes;
14206
- /**
14207
- * A collection of child views in the form.
14208
- */ children;
14209
- /**
14210
- * A dropdown that allows selecting the style of the table border.
14211
- */ borderStyleDropdown;
14212
- /**
14213
- * An input that allows specifying the width of the table border.
14214
- */ borderWidthInput;
14215
- /**
14216
- * An input that allows specifying the color of the table border.
14217
- */ borderColorInput;
14218
- /**
14219
- * An input that allows specifying the table background color.
14220
- */ backgroundInput;
14221
- /**
14222
- * An input that allows specifying the table width.
14223
- */ widthInput;
14224
- /**
14225
- * An input that allows specifying the table height.
14226
- */ heightInput;
14227
- /**
14228
- * A toolbar with buttons that allow changing the alignment of an entire table.
14229
- */ alignmentToolbar;
14230
- /**
14231
- * The "Save" button view.
14232
- */ saveButtonView;
14233
- /**
14234
- * The "Cancel" button view.
14235
- */ cancelButtonView;
14236
- /**
14237
- * The Back button view displayed in the header.
14238
- */ backButtonView;
14239
- /**
14240
- * A collection of views that can be focused in the form.
14241
- */ _focusables;
14242
- /**
14243
- * Helps cycling over {@link #_focusables} in the form.
14244
- */ _focusCycler;
14245
- /**
14246
- * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
14247
- * @param options Additional configuration of the view.
14248
- */ constructor(locale, options){
14249
- super(locale);
14250
- this.set({
14251
- borderStyle: '',
14252
- borderWidth: '',
14253
- borderColor: '',
14254
- backgroundColor: '',
14255
- width: '',
14256
- height: '',
14257
- alignment: ''
14258
- });
14259
- this.options = options;
14260
- const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
14261
- const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
14262
- const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
14263
- const { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();
14264
- this.focusTracker = new FocusTracker();
14265
- this.keystrokes = new KeystrokeHandler();
14266
- this.children = this.createCollection();
14267
- this.borderStyleDropdown = borderStyleDropdown;
14268
- this.borderWidthInput = borderWidthInput;
14269
- this.borderColorInput = borderColorInput;
14270
- this.backgroundInput = backgroundInput;
14271
- this.widthInput = widthInput;
14272
- this.heightInput = heightInput;
14273
- this.alignmentToolbar = alignmentToolbar;
14274
- // Defer creating to make sure other fields are present and the Save button can
14275
- // bind its #isEnabled to their error messages so there's no way to save unless all
14276
- // fields are valid.
14277
- const { saveButtonView, cancelButtonView } = this._createActionButtons();
14278
- this.saveButtonView = saveButtonView;
14279
- this.cancelButtonView = cancelButtonView;
14280
- this.backButtonView = this._createBackButton();
14281
- this._focusables = new ViewCollection();
14282
- this._focusCycler = new FocusCycler({
14283
- focusables: this._focusables,
14284
- focusTracker: this.focusTracker,
14285
- keystrokeHandler: this.keystrokes,
14286
- actions: {
14287
- // Navigate form fields backwards using the Shift + Tab keystroke.
14288
- focusPrevious: 'shift + tab',
14289
- // Navigate form fields forwards using the Tab key.
14290
- focusNext: 'tab'
14291
- }
14292
- });
14293
- // Form header.
14294
- const headerView = new FormHeaderView(locale, {
14295
- label: this.t('Table properties')
14296
- });
14297
- headerView.children.add(this.backButtonView, 0);
14298
- this.children.add(headerView);
14299
- // Border row.
14300
- this.children.add(new FormRowView(locale, {
14301
- labelView: borderRowLabel,
14302
- children: [
14303
- borderRowLabel,
14304
- borderStyleDropdown,
14305
- borderWidthInput,
14306
- borderColorInput
14307
- ],
14308
- class: 'ck-table-form__border-row'
14309
- }));
14310
- this.children.add(new FormRowView(locale, {
14311
- children: [
14312
- // Dimensions row.
14313
- new FormRowView(locale, {
14314
- labelView: dimensionsLabel,
14315
- children: [
14316
- dimensionsLabel,
14317
- widthInput,
14318
- operatorLabel,
14319
- heightInput
14320
- ],
14321
- class: 'ck-table-form__dimensions-row'
14322
- }),
14323
- // Background row.
14324
- new FormRowView(locale, {
14325
- labelView: backgroundRowLabel,
14326
- children: [
14327
- backgroundRowLabel,
14328
- backgroundInput
14329
- ],
14330
- class: 'ck-table-form__background-row'
14331
- })
14332
- ]
14333
- }));
14334
- // Alignment row.
14335
- this.children.add(new FormRowView(locale, {
14336
- labelView: alignmentLabel,
14337
- children: [
14338
- alignmentLabel,
14339
- alignmentToolbar
14340
- ],
14341
- class: 'ck-table-properties-form__alignment-row'
14342
- }));
14343
- // Action row.
14344
- this.children.add(new FormRowView(locale, {
14345
- children: [
14346
- this.cancelButtonView,
14347
- this.saveButtonView
14348
- ],
14349
- class: 'ck-table-form__action-row'
14350
- }));
14351
- this.setTemplate({
14352
- tag: 'form',
14353
- attributes: {
14354
- class: [
14355
- 'ck',
14356
- 'ck-form',
14357
- 'ck-table-form',
14358
- 'ck-table-properties-form',
14359
- 'ck-table-properties-form_experimental'
14360
- ],
14361
- // https://github.com/ckeditor/ckeditor5-link/issues/90
14362
- tabindex: '-1'
14363
- },
14364
- children: this.children
14365
- });
14366
- }
14367
- /**
14368
- * @inheritDoc
14369
- */ render() {
14370
- super.render();
14371
- // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
14372
- // which is of the "submit" DOM "type".
14373
- submitHandler({
14374
- view: this
14375
- });
14376
- // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
14377
- [
14378
- this.borderColorInput,
14379
- this.backgroundInput
14380
- ].forEach((view)=>{
14381
- this._focusCycler.chain(view.fieldView.focusCycler);
14382
- });
14383
- [
14384
- this.borderStyleDropdown,
14385
- this.borderWidthInput,
14386
- this.borderColorInput,
14387
- this.widthInput,
14388
- this.heightInput,
14389
- this.backgroundInput,
14390
- this.alignmentToolbar,
14391
- this.cancelButtonView,
14392
- this.saveButtonView,
14393
- this.backButtonView
14394
- ].forEach((view)=>{
14395
- // Register the view as focusable.
14396
- this._focusables.add(view);
14397
- // Register the view in the focus tracker.
14398
- this.focusTracker.add(view.element);
14399
- });
14400
- // Mainly for closing using "Esc" and navigation using "Tab".
14401
- this.keystrokes.listenTo(this.element);
14402
- }
14403
- /**
14404
- * @inheritDoc
14405
- */ destroy() {
14406
- super.destroy();
14407
- this.focusTracker.destroy();
14408
- this.keystrokes.destroy();
14409
- }
14410
- /**
14411
- * Focuses the fist focusable field in the form.
14412
- */ focus() {
14413
- this._focusCycler.focusFirst();
14414
- }
14415
- /**
14416
- * Creates the following form fields:
14417
- *
14418
- * * {@link #borderStyleDropdown},
14419
- * * {@link #borderWidthInput},
14420
- * * {@link #borderColorInput}.
14421
- */ _createBorderFields() {
14422
- const defaultTableProperties = this.options.defaultTableProperties;
14423
- const defaultBorder = {
14424
- style: defaultTableProperties.borderStyle,
14425
- width: defaultTableProperties.borderWidth,
14426
- color: defaultTableProperties.borderColor
14427
- };
14428
- const colorInputCreator = getLabeledColorInputCreator({
14429
- colorConfig: this.options.borderColors,
14430
- columns: 5,
14431
- defaultColorValue: defaultBorder.color,
14432
- colorPickerConfig: this.options.colorPickerConfig
14433
- });
14434
- const locale = this.locale;
14435
- const t = this.t;
14436
- const accessibleLabel = t('Style');
14437
- // -- Group label ---------------------------------------------
14438
- const borderRowLabel = new LabelView(locale);
14439
- borderRowLabel.text = t('Border');
14440
- // -- Style ---------------------------------------------------
14441
- const styleLabels = getBorderStyleLabels(t);
14442
- const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
14443
- borderStyleDropdown.set({
14444
- label: accessibleLabel,
14445
- class: 'ck-table-form__border-style'
14446
- });
14447
- borderStyleDropdown.fieldView.buttonView.set({
14448
- ariaLabel: accessibleLabel,
14449
- ariaLabelledBy: undefined,
14450
- isOn: false,
14451
- withText: true,
14452
- tooltip: accessibleLabel
14453
- });
14454
- borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
14455
- return styleLabels[value ? value : 'none'];
14456
- });
14457
- borderStyleDropdown.fieldView.on('execute', (evt)=>{
14458
- this.borderStyle = evt.source._borderStyleValue;
14459
- });
14460
- borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
14461
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
14462
- role: 'menu',
14463
- ariaLabel: accessibleLabel
14464
- });
14465
- // -- Width ---------------------------------------------------
14466
- const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
14467
- borderWidthInput.set({
14468
- label: t('Width'),
14469
- class: 'ck-table-form__border-width'
14470
- });
14471
- borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
14472
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
14473
- borderWidthInput.fieldView.on('input', ()=>{
14474
- this.borderWidth = borderWidthInput.fieldView.element.value;
14475
- });
14476
- // -- Color ---------------------------------------------------
14477
- const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
14478
- borderColorInput.set({
14479
- label: t('Color'),
14480
- class: 'ck-table-form__border-color'
14481
- });
14482
- borderColorInput.fieldView.bind('value').to(this, 'borderColor');
14483
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
14484
- borderColorInput.fieldView.on('input', ()=>{
14485
- this.borderColor = borderColorInput.fieldView.value;
14486
- });
14487
- // Reset the border color and width fields depending on the `border-style` value.
14488
- this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
14489
- // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
14490
- // See: https://github.com/ckeditor/ckeditor5/issues/6227.
14491
- if (!isBorderStyleSet$1(newValue)) {
14492
- this.borderColor = '';
14493
- this.borderWidth = '';
14494
- }
14495
- // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
14496
- if (!isBorderStyleSet$1(oldValue)) {
14497
- this.borderColor = defaultBorder.color;
14498
- this.borderWidth = defaultBorder.width;
14499
- }
14500
- });
14501
- return {
14502
- borderRowLabel,
14503
- borderStyleDropdown,
14504
- borderColorInput,
14505
- borderWidthInput
14506
- };
14507
- }
14508
- /**
14509
- * Creates the following form fields:
14510
- *
14511
- * * {@link #backgroundInput}.
14512
- */ _createBackgroundFields() {
14513
- const locale = this.locale;
14514
- const t = this.t;
14515
- // -- Group label ---------------------------------------------
14516
- const backgroundRowLabel = new LabelView(locale);
14517
- backgroundRowLabel.text = t('Background');
14518
- // -- Background color input -----------------------------------
14519
- const backgroundInputCreator = getLabeledColorInputCreator({
14520
- colorConfig: this.options.backgroundColors,
14521
- columns: 5,
14522
- defaultColorValue: this.options.defaultTableProperties.backgroundColor,
14523
- colorPickerConfig: this.options.colorPickerConfig
14524
- });
14525
- const backgroundInput = new LabeledFieldView(locale, backgroundInputCreator);
14526
- backgroundInput.set({
14527
- label: t('Color'),
14528
- class: 'ck-table-properties-form__background'
14529
- });
14530
- backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
14531
- backgroundInput.fieldView.on('input', ()=>{
14532
- this.backgroundColor = backgroundInput.fieldView.value;
14533
- });
14534
- return {
14535
- backgroundRowLabel,
14536
- backgroundInput
14537
- };
14538
- }
14539
- /**
14540
- * Creates the following form fields:
14541
- *
14542
- * * {@link #widthInput},
14543
- * * {@link #heightInput}.
14544
- */ _createDimensionFields() {
14545
- const locale = this.locale;
14546
- const t = this.t;
14547
- // -- Label ---------------------------------------------------
14548
- const dimensionsLabel = new LabelView(locale);
14549
- dimensionsLabel.text = t('Dimensions');
14550
- // -- Width ---------------------------------------------------
14551
- const widthInput = new LabeledFieldView(locale, createLabeledInputText);
14552
- widthInput.set({
14553
- label: t('Width'),
14554
- class: 'ck-table-form__dimensions-row__width'
14555
- });
14556
- widthInput.fieldView.bind('value').to(this, 'width');
14557
- widthInput.fieldView.on('input', ()=>{
14558
- this.width = widthInput.fieldView.element.value;
14559
- });
14560
- // -- Operator ---------------------------------------------------
14561
- const operatorLabel = new View(locale);
14562
- operatorLabel.setTemplate({
14563
- tag: 'span',
14564
- attributes: {
14565
- class: [
14566
- 'ck-table-form__dimension-operator'
14567
- ]
14568
- },
14569
- children: [
14570
- {
14571
- text: '×'
14572
- }
14573
- ]
14574
- });
14575
- // -- Height ---------------------------------------------------
14576
- const heightInput = new LabeledFieldView(locale, createLabeledInputText);
14577
- heightInput.set({
14578
- label: t('Height'),
14579
- class: 'ck-table-form__dimensions-row__height'
14580
- });
14581
- heightInput.fieldView.bind('value').to(this, 'height');
14582
- heightInput.fieldView.on('input', ()=>{
14583
- this.height = heightInput.fieldView.element.value;
14584
- });
14585
- return {
14586
- dimensionsLabel,
14587
- widthInput,
14588
- operatorLabel,
14589
- heightInput
14590
- };
14591
- }
14592
- /**
14593
- * Creates the following form fields:
14594
- *
14595
- * * {@link #alignmentToolbar}.
14596
- */ _createAlignmentFields() {
14597
- const locale = this.locale;
14598
- const t = this.t;
14599
- // -- Label ---------------------------------------------------
14600
- const alignmentLabel = new LabelView(locale);
14601
- alignmentLabel.text = t('Table Alignment');
14602
- // -- Toolbar ---------------------------------------------------
14603
- const alignmentToolbar = new ToolbarView(locale);
14604
- alignmentToolbar.set({
14605
- role: 'radiogroup',
14606
- isCompact: true,
14607
- ariaLabel: t('Table alignment toolbar')
14608
- });
14609
- fillToolbar({
14610
- view: this,
14611
- icons: {
14612
- left: IconObjectInlineLeft,
14613
- center: IconObjectCenter,
14614
- right: IconObjectInlineRight,
14615
- blockLeft: IconObjectLeft,
14616
- blockRight: IconObjectRight
14617
- },
14618
- toolbar: alignmentToolbar,
14619
- labels: this._alignmentLabels,
14620
- propertyName: 'alignment',
14621
- defaultValue: this.options.defaultTableProperties.alignment
14622
- });
14623
- return {
14624
- alignmentLabel,
14625
- alignmentToolbar
14626
- };
14627
- }
14628
- /**
14629
- * Creates the following form controls:
14630
- *
14631
- * * {@link #saveButtonView},
14632
- * * {@link #cancelButtonView}.
14633
- */ _createActionButtons() {
14634
- const locale = this.locale;
14635
- const t = this.t;
14636
- const saveButtonView = new ButtonView(locale);
14637
- const cancelButtonView = new ButtonView(locale);
14638
- const fieldsThatShouldValidateToSave = [
14639
- this.borderWidthInput,
14640
- this.borderColorInput,
14641
- this.backgroundInput,
14642
- this.widthInput,
14643
- this.heightInput
14644
- ];
14645
- saveButtonView.set({
14646
- label: t('Save'),
14647
- class: 'ck-button-action',
14648
- type: 'submit',
14649
- withText: true
14650
- });
14651
- saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
14652
- return errorTexts.every((errorText)=>!errorText);
14653
- });
14654
- cancelButtonView.set({
14655
- label: t('Cancel'),
14656
- withText: true
14657
- });
14658
- cancelButtonView.delegate('execute').to(this, 'cancel');
14659
- return {
14660
- saveButtonView,
14661
- cancelButtonView
14662
- };
14663
- }
14664
- /**
14665
- * Creates a back button view that cancels the form.
14666
- */ _createBackButton() {
14667
- const t = this.locale.t;
14668
- const backButton = new ButtonView(this.locale);
14669
- backButton.set({
14670
- class: 'ck-button-back',
14671
- label: t('Back'),
14672
- icon: IconPreviousArrow,
14673
- tooltip: true
14674
- });
14675
- backButton.delegate('execute').to(this, 'cancel');
14676
- return backButton;
14677
- }
14678
- /**
14679
- * Provides localized labels for {@link #alignmentToolbar} buttons.
14680
- */ get _alignmentLabels() {
14681
- const locale = this.locale;
14682
- const t = this.t;
14683
- const blockLeft = t('Align table to the left with no text wrapping');
14684
- const blockRight = t('Align table to the right with no text wrapping');
14685
- const left = t('Align table to the left with text wrapping');
14686
- const center = t('Center table with no text wrapping');
14687
- const right = t('Align table to the right with text wrapping');
14688
- // Returns object with a proper order of labels.
14689
- if (locale.uiLanguageDirection === 'rtl') {
14690
- return {
14691
- right,
14692
- left,
14693
- blockRight,
14694
- center,
14695
- blockLeft
14696
- };
14697
- }
14698
- return {
14699
- blockLeft,
14700
- center,
14701
- blockRight,
14702
- left,
14703
- right
14704
- };
14705
- }
14706
- }
14707
- function isBorderStyleSet$1(value) {
14708
- return value !== 'none';
14709
- }
14710
-
14711
- const ERROR_TEXT_TIMEOUT$1 = 500;
14712
- // Map of view properties and related commands.
14713
- const propertyToCommandMap$1 = {
14714
- borderStyle: 'tableBorderStyle',
14715
- borderColor: 'tableBorderColor',
14716
- borderWidth: 'tableBorderWidth',
14717
- backgroundColor: 'tableBackgroundColor',
14718
- width: 'tableWidth',
14719
- height: 'tableHeight',
14720
- alignment: 'tableAlignment'
14721
- };
14722
- /**
14723
- * The table properties UI plugin. It introduces the `'tableProperties'` button
14724
- * that opens a form allowing to specify visual styling of an entire table.
14725
- *
14726
- * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
14727
- */ class TablePropertiesUIExperimental extends Plugin {
14728
- /**
14729
- * The default table properties.
14730
- */ _defaultContentTableProperties;
14731
- /**
14732
- * The default layout table properties.
14733
- */ _defaultLayoutTableProperties;
14734
- /**
14735
- * The contextual balloon plugin instance.
14736
- */ _balloon;
14737
- /**
14738
- * The properties form view displayed inside the balloon.
14739
- */ view = null;
14740
- /**
14741
- * The properties form view displayed inside the balloon (content table).
14742
- */ _viewWithContentTableDefaults = null;
14743
- /**
14744
- * The properties form view displayed inside the balloon (layout table).
14745
- */ _viewWithLayoutTableDefaults = null;
14746
- /**
14747
- * The batch used to undo all changes made by the form (which are live, as the user types)
14748
- * when "Cancel" was pressed. Each time the view is shown, a new batch is created.
14749
- */ _undoStepBatch;
14750
- /**
14751
- * Flag used to indicate whether view is ready to execute update commands
14752
- * (it finished loading initial data).
14753
- */ _isReady;
14754
- /**
14755
- * @inheritDoc
14756
- */ static get requires() {
14757
- return [
14758
- ContextualBalloon
14759
- ];
14760
- }
14761
- /**
14762
- * @inheritDoc
14763
- */ static get pluginName() {
14764
- return 'TablePropertiesUIExperimental';
14765
- }
14766
- /**
14767
- * @inheritDoc
14768
- */ static get isOfficialPlugin() {
14769
- return true;
14770
- }
14771
- /**
14772
- * @inheritDoc
14773
- */ constructor(editor){
14774
- super(editor);
14775
- editor.config.define('table.tableProperties', {
14776
- borderColors: defaultColors,
14777
- backgroundColors: defaultColors
14778
- });
14779
- }
14780
- /**
14781
- * @inheritDoc
14782
- */ init() {
14783
- const editor = this.editor;
14784
- this._defaultContentTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
14785
- includeAlignmentProperty: true
14786
- });
14787
- this._defaultLayoutTableProperties = getNormalizedDefaultProperties();
14788
- this._balloon = editor.plugins.get(ContextualBalloon);
14789
- editor.ui.componentFactory.add('tableProperties', ()=>this._createTablePropertiesButton());
14790
- }
14791
- /**
14792
- * Creates the table properties button.
14793
- *
14794
- * @internal
14795
- */ _createTablePropertiesButton() {
14796
- const editor = this.editor;
14797
- const t = editor.t;
14798
- const view = new ButtonView(editor.locale);
14799
- view.set({
14800
- label: t('Table properties'),
14801
- icon: IconTableProperties,
14802
- tooltip: true
14803
- });
14804
- this.listenTo(view, 'execute', ()=>this._showView());
14805
- const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));
14806
- view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
14807
- return view;
14808
- }
14809
- /**
14810
- * @inheritDoc
14811
- */ destroy() {
14812
- super.destroy();
14813
- // Destroy created UI components as they are not automatically destroyed.
14814
- // See https://github.com/ckeditor/ckeditor5/issues/1341.
14815
- if (this.view) {
14816
- this.view.destroy();
14817
- }
14818
- }
14819
- /**
14820
- * Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.
14821
- *
14822
- * @returns The table properties form view instance.
14823
- */ _createPropertiesView(defaultTableProperties) {
14824
- const editor = this.editor;
14825
- const config = editor.config.get('table.tableProperties');
14826
- const borderColorsConfig = normalizeColorOptions(config.borderColors);
14827
- const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
14828
- const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
14829
- const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
14830
- const hasColorPicker = config.colorPicker !== false;
14831
- const view = new TablePropertiesViewExperimental(editor.locale, {
14832
- borderColors: localizedBorderColors,
14833
- backgroundColors: localizedBackgroundColors,
14834
- defaultTableProperties,
14835
- colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
14836
- });
14837
- const t = editor.t;
14838
- // Render the view so its #element is available for the clickOutsideHandler.
14839
- view.render();
14840
- this.listenTo(view, 'submit', ()=>{
14841
- this._hideView();
14842
- });
14843
- this.listenTo(view, 'cancel', ()=>{
14844
- // https://github.com/ckeditor/ckeditor5/issues/6180
14845
- if (this._undoStepBatch.operations.length) {
14846
- editor.execute('undo', this._undoStepBatch);
14847
- }
14848
- this._hideView();
14849
- });
14850
- // Close the balloon on Esc key press.
14851
- view.keystrokes.set('Esc', (data, cancel)=>{
14852
- this._hideView();
14853
- cancel();
14854
- });
14855
- // Close on click outside of balloon panel element.
14856
- clickOutsideHandler({
14857
- emitter: view,
14858
- activator: ()=>this._isViewInBalloon,
14859
- contextElements: [
14860
- this._balloon.view.element
14861
- ],
14862
- callback: ()=>this._hideView()
14863
- });
14864
- const colorErrorText = getLocalizedColorErrorText(t);
14865
- const lengthErrorText = getLocalizedLengthErrorText(t);
14866
- // Create the "UI -> editor data" binding.
14867
- // These listeners update the editor data (via table commands) when any observable
14868
- // property of the view has changed. They also validate the value and display errors in the UI
14869
- // when necessary. This makes the view live, which means the changes are
14870
- // visible in the editing as soon as the user types or changes fields' values.
14871
- view.on('change:borderStyle', this._getPropertyChangeCallback('tableBorderStyle'));
14872
- view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
14873
- viewField: view.borderColorInput,
14874
- commandName: 'tableBorderColor',
14875
- errorText: colorErrorText,
14876
- validator: colorFieldValidator
14877
- }));
14878
- view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
14879
- viewField: view.borderWidthInput,
14880
- commandName: 'tableBorderWidth',
14881
- errorText: lengthErrorText,
14882
- validator: lineWidthFieldValidator
14883
- }));
14884
- view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
14885
- viewField: view.backgroundInput,
14886
- commandName: 'tableBackgroundColor',
14887
- errorText: colorErrorText,
14888
- validator: colorFieldValidator
14889
- }));
14890
- view.on('change:width', this._getValidatedPropertyChangeCallback({
14891
- viewField: view.widthInput,
14892
- commandName: 'tableWidth',
14893
- errorText: lengthErrorText,
14894
- validator: lengthFieldValidator
14895
- }));
14896
- view.on('change:height', this._getValidatedPropertyChangeCallback({
14897
- viewField: view.heightInput,
14898
- commandName: 'tableHeight',
14899
- errorText: lengthErrorText,
14900
- validator: lengthFieldValidator
14901
- }));
14902
- view.on('change:alignment', this._getPropertyChangeCallback('tableAlignment'));
14903
- return view;
14904
- }
14905
- /**
14906
- * In this method the "editor data -> UI" binding is happening.
14907
- *
14908
- * When executed, this method obtains selected table property values from various table commands
14909
- * and passes them to the {@link #view}.
14910
- *
14911
- * This way, the UI stays up–to–date with the editor data.
14912
- */ _fillViewFormFromCommandValues() {
14913
- const commands = this.editor.commands;
14914
- const borderStyleCommand = commands.get('tableBorderStyle');
14915
- Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{
14916
- const propertyKey = property;
14917
- const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
14918
- return [
14919
- propertyKey,
14920
- commands.get(commandName).value || defaultValue
14921
- ];
14922
- }).forEach(([property, value])=>{
14923
- // Do not set the `border-color` and `border-width` fields if `border-style:none`.
14924
- if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
14925
- return;
14926
- }
14927
- this.view.set(property, value);
14928
- });
14929
- this._isReady = true;
14930
- }
14931
- /**
14932
- * Shows the {@link #view} in the {@link #_balloon}.
14933
- *
14934
- * **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains
14935
- * all changes made to the document when the view is visible, allowing a single undo step
14936
- * for all of them.
14937
- */ _showView() {
14938
- const editor = this.editor;
14939
- const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
14940
- const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
14941
- const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
14942
- if (useDefaults && !this._viewWithContentTableDefaults) {
14943
- this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableProperties);
14944
- } else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
14945
- this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableProperties);
14946
- }
14947
- this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
14948
- this.listenTo(editor.ui, 'update', ()=>{
14949
- this._updateView();
14950
- });
14951
- // Update the view with the model values.
14952
- this._fillViewFormFromCommandValues();
14953
- this._balloon.add({
14954
- view: this.view,
14955
- position: getBalloonTablePositionData(editor)
14956
- });
14957
- // Create a new batch. Clicking "Cancel" will undo this batch.
14958
- this._undoStepBatch = editor.model.createBatch();
14959
- // Basic a11y.
14960
- this.view.focus();
14961
- }
14962
- /**
14963
- * Removes the {@link #view} from the {@link #_balloon}.
14964
- */ _hideView() {
14965
- const editor = this.editor;
14966
- this.stopListening(editor.ui, 'update');
14967
- this._isReady = false;
14968
- // Blur any input element before removing it from DOM to prevent issues in some browsers.
14969
- // See https://github.com/ckeditor/ckeditor5/issues/1501.
14970
- this.view.saveButtonView.focus();
14971
- this._balloon.remove(this.view);
14972
- // Make sure the focus is not lost in the process by putting it directly
14973
- // into the editing view.
14974
- this.editor.editing.view.focus();
14975
- }
14976
- /**
14977
- * Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.
14978
- */ _updateView() {
14979
- const editor = this.editor;
14980
- const viewDocument = editor.editing.view.document;
14981
- if (!getSelectionAffectedTableWidget(viewDocument.selection)) {
14982
- this._hideView();
14983
- } else if (this._isViewVisible) {
14984
- repositionContextualBalloon(editor, 'table');
14985
- }
14986
- }
14987
- /**
14988
- * Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.
14989
- */ get _isViewVisible() {
14990
- return !!this.view && this._balloon.visibleView === this.view;
14991
- }
14992
- /**
14993
- * Returns `true` when the {@link #view} is in the {@link #_balloon}.
14994
- */ get _isViewInBalloon() {
14995
- return !!this.view && this._balloon.hasView(this.view);
14996
- }
14997
- /**
14998
- * Creates a callback that when executed upon {@link #view view's} property change
14999
- * executes a related editor command with the new property value.
15000
- *
15001
- * If new value will be set to the default value, the command will not be executed.
15002
- *
15003
- * @param commandName The command that will be executed.
15004
- */ _getPropertyChangeCallback(commandName) {
15005
- return (evt, propertyName, newValue)=>{
15006
- // Do not execute the command on initial call (opening the table properties view).
15007
- if (!this._isReady) {
15008
- return;
15009
- }
15010
- this.editor.execute(commandName, {
15011
- value: newValue,
15012
- batch: this._undoStepBatch
15013
- });
15014
- };
15015
- }
15016
- /**
15017
- * Creates a callback that when executed upon {@link #view view's} property change:
15018
- * * executes a related editor command with the new property value if the value is valid,
15019
- * * or sets the error text next to the invalid field, if the value did not pass the validation.
15020
- */ _getValidatedPropertyChangeCallback(options) {
15021
- const { commandName, viewField, validator, errorText } = options;
15022
- const setErrorTextDebounced = debounce(()=>{
15023
- viewField.errorText = errorText;
15024
- }, ERROR_TEXT_TIMEOUT$1);
15025
- return (evt, propertyName, newValue)=>{
15026
- setErrorTextDebounced.cancel();
15027
- // Do not execute the command on initial call (opening the table properties view).
15028
- if (!this._isReady) {
15029
- return;
15030
- }
15031
- if (validator(newValue)) {
15032
- this.editor.execute(commandName, {
15033
- value: newValue,
15034
- batch: this._undoStepBatch
15035
- });
15036
- viewField.errorText = null;
15037
- } else {
15038
- setErrorTextDebounced();
15039
- }
15040
- };
15041
- }
15042
- }
15043
-
15044
- /**
15045
- * The class representing a table cell properties form, allowing users to customize
15046
- * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..
15047
- */ class TableCellPropertiesViewExperimental extends View {
15048
- /**
15049
- * Options passed to the view. See {@link #constructor} to learn more.
15050
- */ options;
15051
- /**
15052
- * Tracks information about the DOM focus in the form.
15053
- */ focusTracker;
15054
- /**
15055
- * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
15056
- */ keystrokes;
15057
- /**
15058
- * A collection of child views in the form.
15059
- */ children;
15060
- /**
15061
- * A dropdown that allows selecting the style of the table cell border.
15062
- */ borderStyleDropdown;
15063
- /**
15064
- * An input that allows specifying the width of the table cell border.
15065
- */ borderWidthInput;
15066
- /**
15067
- * An input that allows specifying the color of the table cell border.
15068
- */ borderColorInput;
15069
- /**
15070
- * An input that allows specifying the table cell background color.
15071
- */ backgroundInput;
15072
- /**
15073
- * A dropdown that allows selecting the type of the table cell (data or header).
15074
- */ cellTypeDropdown;
15075
- /**
15076
- * An input that allows specifying the table cell padding.
15077
- */ paddingInput;
15078
- /**
15079
- * An input that allows specifying the table cell width.
15080
- */ widthInput;
15081
- /**
15082
- * An input that allows specifying the table cell height.
15083
- */ heightInput;
15084
- /**
15085
- * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.
15086
- */ horizontalAlignmentToolbar;
15087
- /**
15088
- * A toolbar with buttons that allow changing the vertical text alignment in a table cell.
15089
- */ verticalAlignmentToolbar;
15090
- /**
15091
- * The "Save" button view.
15092
- */ saveButtonView;
15093
- /**
15094
- * The "Cancel" button view.
15095
- */ cancelButtonView;
15096
- /**
15097
- * The "Back" button view.
15098
- */ backButtonView;
15099
- /**
15100
- * A collection of views that can be focused in the form.
15101
- */ _focusables;
15102
- /**
15103
- * Helps cycling over {@link #_focusables} in the form.
15104
- */ _focusCycler;
15105
- /**
15106
- * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
15107
- * @param options Additional configuration of the view.
15108
- * @param options.borderColors A configuration of the border color palette used by the
15109
- * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.
15110
- * @param options.backgroundColors A configuration of the background color palette used by the
15111
- * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.
15112
- * @param options.defaultTableCellProperties The default table cell properties.
15113
- * @param options.isTableCellTypeSupported A flag indicating whether the table cell type is supported.
15114
- */ constructor(locale, options){
15115
- super(locale);
15116
- this.set({
15117
- borderStyle: '',
15118
- borderWidth: '',
15119
- borderColor: '',
15120
- padding: '',
15121
- backgroundColor: '',
15122
- width: '',
15123
- height: '',
15124
- horizontalAlignment: '',
15125
- verticalAlignment: '',
15126
- cellType: ''
15127
- });
15128
- this.options = options;
15129
- const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
15130
- const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
15131
- const { cellTypeRowLabel, cellTypeDropdown } = this._createCellTypeField();
15132
- const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
15133
- const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
15134
- this.focusTracker = new FocusTracker();
15135
- this.keystrokes = new KeystrokeHandler();
15136
- this.children = this.createCollection();
15137
- this.borderStyleDropdown = borderStyleDropdown;
15138
- this.borderWidthInput = borderWidthInput;
15139
- this.borderColorInput = borderColorInput;
15140
- this.backgroundInput = backgroundInput;
15141
- this.cellTypeDropdown = cellTypeDropdown;
15142
- this.paddingInput = this._createPaddingField();
15143
- this.widthInput = widthInput;
15144
- this.heightInput = heightInput;
15145
- this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;
15146
- this.verticalAlignmentToolbar = verticalAlignmentToolbar;
15147
- // Defer creating to make sure other fields are present and the Save button can
15148
- // bind its #isEnabled to their error messages so there's no way to save unless all
15149
- // fields are valid.
15150
- const { saveButtonView, cancelButtonView } = this._createActionButtons();
15151
- this.saveButtonView = saveButtonView;
15152
- this.cancelButtonView = cancelButtonView;
15153
- this.backButtonView = this._createBackButton();
15154
- this._focusables = new ViewCollection();
15155
- this._focusCycler = new FocusCycler({
15156
- focusables: this._focusables,
15157
- focusTracker: this.focusTracker,
15158
- keystrokeHandler: this.keystrokes,
15159
- actions: {
15160
- // Navigate form fields backwards using the Shift + Tab keystroke.
15161
- focusPrevious: 'shift + tab',
15162
- // Navigate form fields forwards using the Tab key.
15163
- focusNext: 'tab'
15164
- }
15165
- });
15166
- // Form header.
15167
- const header = new FormHeaderView(locale, {
15168
- label: this.t('Cell properties')
15169
- });
15170
- header.children.add(this.backButtonView, 0);
15171
- this.children.add(header);
15172
- // Border row.
15173
- this.children.add(new FormRowView(locale, {
15174
- labelView: borderRowLabel,
15175
- children: this.options.isTableCellTypeSupported ? [
15176
- borderRowLabel,
15177
- borderStyleDropdown,
15178
- borderWidthInput,
15179
- borderColorInput
15180
- ] : [
15181
- borderRowLabel,
15182
- borderStyleDropdown,
15183
- borderColorInput,
15184
- borderWidthInput
15185
- ],
15186
- class: `ck-table-form__border-row${this.options.isTableCellTypeSupported ? ' ck-table-form__border-row_experimental' : ''}`
15187
- }));
15188
- // Background and cell type.
15189
- this.children.add(new FormRowView(locale, {
15190
- children: this.options.isTableCellTypeSupported ? [
15191
- new FormRowView(locale, {
15192
- labelView: cellTypeRowLabel,
15193
- children: [
15194
- cellTypeRowLabel,
15195
- cellTypeDropdown
15196
- ],
15197
- class: 'ck-table-form__cell-type-row'
15198
- }),
15199
- new FormRowView(locale, {
15200
- labelView: backgroundRowLabel,
15201
- children: [
15202
- backgroundRowLabel,
15203
- backgroundInput
15204
- ],
15205
- class: 'ck-table-form__background-row'
15206
- })
15207
- ] : [
15208
- new FormRowView(locale, {
15209
- labelView: backgroundRowLabel,
15210
- children: [
15211
- backgroundRowLabel,
15212
- backgroundInput
15213
- ],
15214
- class: 'ck-table-form__background-row'
15215
- })
15216
- ]
15217
- }));
15218
- // Dimensions row and padding.
15219
- this.children.add(new FormRowView(locale, {
15220
- children: [
15221
- // Dimensions row.
15222
- new FormRowView(locale, {
15223
- labelView: dimensionsLabel,
15224
- children: [
15225
- dimensionsLabel,
15226
- widthInput,
15227
- operatorLabel,
15228
- heightInput
15229
- ],
15230
- class: 'ck-table-form__dimensions-row'
15231
- }),
15232
- // Padding row.
15233
- new FormRowView(locale, {
15234
- children: [
15235
- this.paddingInput
15236
- ],
15237
- class: 'ck-table-cell-properties-form__padding-row'
15238
- })
15239
- ]
15240
- }));
15241
- // Text alignment row.
15242
- this.children.add(new FormRowView(locale, {
15243
- labelView: alignmentLabel,
15244
- children: [
15245
- alignmentLabel,
15246
- horizontalAlignmentToolbar,
15247
- verticalAlignmentToolbar
15248
- ],
15249
- class: 'ck-table-cell-properties-form__alignment-row'
15250
- }));
15251
- // Action row.
15252
- this.children.add(new FormRowView(locale, {
15253
- children: [
15254
- this.cancelButtonView,
15255
- this.saveButtonView
15256
- ],
15257
- class: 'ck-table-form__action-row'
15258
- }));
15259
- this.setTemplate({
15260
- tag: 'form',
15261
- attributes: {
15262
- class: [
15263
- 'ck',
15264
- 'ck-form',
15265
- 'ck-table-form',
15266
- 'ck-table-cell-properties-form',
15267
- 'ck-table-cell-properties-form_experimental',
15268
- this.options.isTableCellTypeSupported ? 'ck-table-cell-properties-form_experimental-no-cell-type' : ''
15269
- ],
15270
- // https://github.com/ckeditor/ckeditor5-link/issues/90
15271
- tabindex: '-1'
15272
- },
15273
- children: this.children
15274
- });
15275
- }
15276
- /**
15277
- * @inheritDoc
15278
- */ render() {
15279
- super.render();
15280
- // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
15281
- // which is of the "submit" DOM "type".
15282
- submitHandler({
15283
- view: this
15284
- });
15285
- // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
15286
- [
15287
- this.borderColorInput,
15288
- this.backgroundInput
15289
- ].forEach((view)=>{
15290
- this._focusCycler.chain(view.fieldView.focusCycler);
15291
- });
15292
- [
15293
- this.borderStyleDropdown,
15294
- this.borderColorInput,
15295
- this.borderWidthInput,
15296
- this.cellTypeDropdown,
15297
- this.backgroundInput,
15298
- this.widthInput,
15299
- this.heightInput,
15300
- this.paddingInput,
15301
- this.horizontalAlignmentToolbar,
15302
- this.verticalAlignmentToolbar,
15303
- this.cancelButtonView,
15304
- this.saveButtonView,
15305
- this.backButtonView
15306
- ].forEach((view)=>{
15307
- // Register the view as focusable.
15308
- this._focusables.add(view);
15309
- // Register the view in the focus tracker.
15310
- this.focusTracker.add(view.element);
15311
- });
15312
- // Mainly for closing using "Esc" and navigation using "Tab".
15313
- this.keystrokes.listenTo(this.element);
15314
- }
15315
- /**
15316
- * @inheritDoc
15317
- */ destroy() {
15318
- super.destroy();
15319
- this.focusTracker.destroy();
15320
- this.keystrokes.destroy();
15321
- }
15322
- /**
15323
- * Focuses the fist focusable field in the form.
15324
- */ focus() {
15325
- this._focusCycler.focusFirst();
15326
- }
15327
- /**
15328
- * Creates the following form fields:
15329
- *
15330
- * * {@link #borderStyleDropdown},
15331
- * * {@link #borderWidthInput},
15332
- * * {@link #borderColorInput}.
15333
- */ _createBorderFields() {
15334
- const defaultTableCellProperties = this.options.defaultTableCellProperties;
15335
- const defaultBorder = {
15336
- style: defaultTableCellProperties.borderStyle,
15337
- width: defaultTableCellProperties.borderWidth,
15338
- color: defaultTableCellProperties.borderColor
15339
- };
15340
- const colorInputCreator = getLabeledColorInputCreator({
15341
- colorConfig: this.options.borderColors,
15342
- columns: 5,
15343
- defaultColorValue: defaultBorder.color,
15344
- colorPickerConfig: this.options.colorPickerConfig
15345
- });
15346
- const locale = this.locale;
15347
- const t = this.t;
15348
- const accessibleLabel = t('Style');
15349
- // -- Group label ---------------------------------------------
15350
- const borderRowLabel = new LabelView(locale);
15351
- borderRowLabel.text = t('Border');
15352
- // -- Style ---------------------------------------------------
15353
- const styleLabels = getBorderStyleLabels(t);
15354
- const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
15355
- borderStyleDropdown.set({
15356
- label: accessibleLabel,
15357
- class: 'ck-table-form__border-style'
15358
- });
15359
- borderStyleDropdown.fieldView.buttonView.set({
15360
- ariaLabel: accessibleLabel,
15361
- ariaLabelledBy: undefined,
15362
- isOn: false,
15363
- withText: true,
15364
- tooltip: accessibleLabel
15365
- });
15366
- borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
15367
- return styleLabels[value ? value : 'none'];
15368
- });
15369
- borderStyleDropdown.fieldView.on('execute', (evt)=>{
15370
- this.borderStyle = evt.source._borderStyleValue;
15371
- });
15372
- borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
15373
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
15374
- role: 'menu',
15375
- ariaLabel: accessibleLabel
15376
- });
15377
- // -- Width ---------------------------------------------------
15378
- const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
15379
- borderWidthInput.set({
15380
- label: t('Width'),
15381
- class: 'ck-table-form__border-width'
15382
- });
15383
- borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
15384
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
15385
- borderWidthInput.fieldView.on('input', ()=>{
15386
- this.borderWidth = borderWidthInput.fieldView.element.value;
15387
- });
15388
- // -- Color ---------------------------------------------------
15389
- const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
15390
- borderColorInput.set({
15391
- label: t('Color'),
15392
- class: 'ck-table-form__border-color'
15393
- });
15394
- borderColorInput.fieldView.bind('value').to(this, 'borderColor');
15395
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
15396
- borderColorInput.fieldView.on('input', ()=>{
15397
- this.borderColor = borderColorInput.fieldView.value;
15398
- });
15399
- // Reset the border color and width fields depending on the `border-style` value.
15400
- this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
15401
- // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
15402
- // See: https://github.com/ckeditor/ckeditor5/issues/6227.
15403
- if (!isBorderStyleSet(newValue)) {
15404
- this.borderColor = '';
15405
- this.borderWidth = '';
15406
- }
15407
- // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
15408
- if (!isBorderStyleSet(oldValue)) {
15409
- this.borderColor = defaultBorder.color;
15410
- this.borderWidth = defaultBorder.width;
15411
- }
15412
- });
15413
- return {
15414
- borderRowLabel,
15415
- borderStyleDropdown,
15416
- borderColorInput,
15417
- borderWidthInput
15418
- };
15419
- }
15420
- /**
15421
- * Creates the following form fields:
15422
- *
15423
- * * {@link #backgroundInput}.
15424
- */ _createBackgroundFields() {
15425
- const locale = this.locale;
15426
- const t = this.t;
15427
- // -- Group label ---------------------------------------------
15428
- const backgroundRowLabel = new LabelView(locale);
15429
- backgroundRowLabel.text = t('Background');
15430
- // -- Background color input -----------------------------------
15431
- const colorInputCreator = getLabeledColorInputCreator({
15432
- colorConfig: this.options.backgroundColors,
15433
- columns: 5,
15434
- defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
15435
- colorPickerConfig: this.options.colorPickerConfig
15436
- });
15437
- const backgroundInput = new LabeledFieldView(locale, colorInputCreator);
15438
- backgroundInput.set({
15439
- label: t('Color'),
15440
- class: 'ck-table-cell-properties-form__background'
15441
- });
15442
- backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
15443
- backgroundInput.fieldView.on('input', ()=>{
15444
- this.backgroundColor = backgroundInput.fieldView.value;
15445
- });
15446
- return {
15447
- backgroundRowLabel,
15448
- backgroundInput
15449
- };
15450
- }
15451
- /**
15452
- * Create cell type field.
15453
- *
15454
- * * {@link #cellTypeDropdown}.
15455
- *
15456
- * @internal
15457
- */ _createCellTypeField() {
15458
- const locale = this.locale;
15459
- const t = this.t;
15460
- const cellTypeRowLabel = new LabelView(locale);
15461
- cellTypeRowLabel.text = t('Cell type');
15462
- const cellTypeLabels = this._cellTypeLabels;
15463
- const cellTypeDropdown = new LabeledFieldView(locale, createLabeledDropdown);
15464
- cellTypeDropdown.set({
15465
- label: t('Cell type'),
15466
- class: 'ck-table-cell-properties-form__cell-type'
15467
- });
15468
- cellTypeDropdown.fieldView.buttonView.set({
15469
- ariaLabel: t('Cell type'),
15470
- ariaLabelledBy: undefined,
15471
- isOn: false,
15472
- withText: true,
15473
- tooltip: t('Cell type')
15474
- });
15475
- cellTypeDropdown.fieldView.buttonView.bind('label').to(this, 'cellType', (value)=>{
15476
- return cellTypeLabels[value || 'data'];
15477
- });
15478
- cellTypeDropdown.fieldView.on('execute', (evt)=>{
15479
- this.cellType = evt.source._cellTypeValue;
15480
- });
15481
- cellTypeDropdown.bind('isEmpty').to(this, 'cellType', (value)=>!value);
15482
- addListToDropdown(cellTypeDropdown.fieldView, this._getCellTypeDefinitions(), {
15483
- role: 'menu',
15484
- ariaLabel: t('Cell type')
15485
- });
15486
- return {
15487
- cellTypeRowLabel,
15488
- cellTypeDropdown
15489
- };
15490
- }
15491
- /**
15492
- * Creates the following form fields:
15493
- *
15494
- * * {@link #widthInput}.
15495
- * * {@link #heightInput}.
15496
- */ _createDimensionFields() {
15497
- const locale = this.locale;
15498
- const t = this.t;
15499
- // -- Label ---------------------------------------------------
15500
- const dimensionsLabel = new LabelView(locale);
15501
- dimensionsLabel.text = t('Dimensions');
15502
- // -- Width ---------------------------------------------------
15503
- const widthInput = new LabeledFieldView(locale, createLabeledInputText);
15504
- widthInput.set({
15505
- label: t('Width'),
15506
- class: 'ck-table-form__dimensions-row__width'
15507
- });
15508
- widthInput.fieldView.bind('value').to(this, 'width');
15509
- widthInput.fieldView.on('input', ()=>{
15510
- this.width = widthInput.fieldView.element.value;
15511
- });
15512
- // -- Operator ---------------------------------------------------
15513
- const operatorLabel = new View(locale);
15514
- operatorLabel.setTemplate({
15515
- tag: 'span',
15516
- attributes: {
15517
- class: [
15518
- 'ck-table-form__dimension-operator'
15519
- ]
15520
- },
15521
- children: [
15522
- {
15523
- text: '×'
15524
- }
15525
- ]
15526
- });
15527
- // -- Height ---------------------------------------------------
15528
- const heightInput = new LabeledFieldView(locale, createLabeledInputText);
15529
- heightInput.set({
15530
- label: t('Height'),
15531
- class: 'ck-table-form__dimensions-row__height'
15532
- });
15533
- heightInput.fieldView.bind('value').to(this, 'height');
15534
- heightInput.fieldView.on('input', ()=>{
15535
- this.height = heightInput.fieldView.element.value;
15536
- });
15537
- return {
15538
- dimensionsLabel,
15539
- widthInput,
15540
- operatorLabel,
15541
- heightInput
15542
- };
15543
- }
15544
- /**
15545
- * Creates the following form fields:
15546
- *
15547
- * * {@link #paddingInput}.
15548
- */ _createPaddingField() {
15549
- const locale = this.locale;
15550
- const t = this.t;
15551
- const paddingInput = new LabeledFieldView(locale, createLabeledInputText);
15552
- paddingInput.set({
15553
- label: t('Padding'),
15554
- class: 'ck-table-cell-properties-form__padding'
15555
- });
15556
- paddingInput.fieldView.bind('value').to(this, 'padding');
15557
- paddingInput.fieldView.on('input', ()=>{
15558
- this.padding = paddingInput.fieldView.element.value;
15559
- });
15560
- return paddingInput;
15561
- }
15562
- /**
15563
- * Creates the following form fields:
15564
- *
15565
- * * {@link #horizontalAlignmentToolbar},
15566
- * * {@link #verticalAlignmentToolbar}.
15567
- */ _createAlignmentFields() {
15568
- const locale = this.locale;
15569
- const t = this.t;
15570
- const alignmentLabel = new LabelView(locale);
15571
- const ALIGNMENT_ICONS = {
15572
- left: IconAlignLeft,
15573
- center: IconAlignCenter,
15574
- right: IconAlignRight,
15575
- justify: IconAlignJustify,
15576
- top: IconAlignTop,
15577
- middle: IconAlignMiddle,
15578
- bottom: IconAlignBottom
15579
- };
15580
- alignmentLabel.text = t('Table cell text alignment');
15581
- // -- Horizontal ---------------------------------------------------
15582
- const horizontalAlignmentToolbar = new ToolbarView(locale);
15583
- const isContentRTL = locale.contentLanguageDirection === 'rtl';
15584
- horizontalAlignmentToolbar.set({
15585
- isCompact: true,
15586
- role: 'radiogroup',
15587
- ariaLabel: t('Horizontal text alignment toolbar'),
15588
- class: 'ck-table-cell-properties-form__horizontal-alignment-toolbar'
15589
- });
15590
- fillToolbar({
15591
- view: this,
15592
- icons: ALIGNMENT_ICONS,
15593
- toolbar: horizontalAlignmentToolbar,
15594
- labels: this._horizontalAlignmentLabels,
15595
- propertyName: 'horizontalAlignment',
15596
- nameToValue: (name)=>{
15597
- // For the RTL content, we want to swap the buttons "align to the left" and "align to the right".
15598
- if (isContentRTL) {
15599
- if (name === 'left') {
15600
- return 'right';
15601
- } else if (name === 'right') {
15602
- return 'left';
15603
- }
15604
- }
15605
- return name;
15606
- },
15607
- defaultValue: this.options.defaultTableCellProperties.horizontalAlignment
15608
- });
15609
- // -- Vertical -----------------------------------------------------
15610
- const verticalAlignmentToolbar = new ToolbarView(locale);
15611
- verticalAlignmentToolbar.set({
15612
- isCompact: true,
15613
- role: 'radiogroup',
15614
- ariaLabel: t('Vertical text alignment toolbar'),
15615
- class: 'ck-table-cell-properties-form__vertical-alignment-toolbar'
15616
- });
15617
- fillToolbar({
15618
- view: this,
15619
- icons: ALIGNMENT_ICONS,
15620
- toolbar: verticalAlignmentToolbar,
15621
- labels: this._verticalAlignmentLabels,
15622
- propertyName: 'verticalAlignment',
15623
- defaultValue: this.options.defaultTableCellProperties.verticalAlignment
15624
- });
15625
- return {
15626
- horizontalAlignmentToolbar,
15627
- verticalAlignmentToolbar,
15628
- alignmentLabel
15629
- };
15630
- }
15631
- /**
15632
- * Creates the following form controls:
15633
- *
15634
- * * {@link #saveButtonView},
15635
- * * {@link #cancelButtonView}.
15636
- */ _createActionButtons() {
15637
- const locale = this.locale;
15638
- const t = this.t;
15639
- const saveButtonView = new ButtonView(locale);
15640
- const cancelButtonView = new ButtonView(locale);
15641
- const fieldsThatShouldValidateToSave = [
15642
- this.borderWidthInput,
15643
- this.borderColorInput,
15644
- this.backgroundInput,
15645
- this.paddingInput
15646
- ];
15647
- saveButtonView.set({
15648
- label: t('Save'),
15649
- class: 'ck-button-action',
15650
- type: 'submit',
15651
- withText: true
15652
- });
15653
- saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
15654
- return errorTexts.every((errorText)=>!errorText);
15655
- });
15656
- cancelButtonView.set({
15657
- label: t('Cancel'),
15658
- withText: true
15659
- });
15660
- cancelButtonView.delegate('execute').to(this, 'cancel');
15661
- return {
15662
- saveButtonView,
15663
- cancelButtonView
15664
- };
15665
- }
15666
- /**
15667
- * Creates a back button view that cancels the form.
15668
- */ _createBackButton() {
15669
- const t = this.locale.t;
15670
- const backButton = new ButtonView(this.locale);
15671
- backButton.set({
15672
- class: 'ck-button-back',
15673
- label: t('Back'),
15674
- icon: IconPreviousArrow,
15675
- tooltip: true
15676
- });
15677
- backButton.delegate('execute').to(this, 'cancel');
15678
- return backButton;
15679
- }
15680
- /**
15681
- * Creates the cell type dropdown definitions.
15682
- */ _getCellTypeDefinitions() {
15683
- const itemDefinitions = new Collection();
15684
- const cellTypeLabels = this._cellTypeLabels;
15685
- for (const type of [
15686
- 'data',
15687
- 'header'
15688
- ]){
15689
- const definition = {
15690
- type: 'button',
15691
- model: new UIModel({
15692
- _cellTypeValue: type,
15693
- label: cellTypeLabels[type],
15694
- role: 'menuitemradio',
15695
- withText: true
15696
- })
15697
- };
15698
- definition.model.bind('isOn').to(this, 'cellType', (value)=>value === type);
15699
- itemDefinitions.add(definition);
15700
- }
15701
- return itemDefinitions;
15702
- }
15703
- /**
15704
- * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
15705
- */ get _horizontalAlignmentLabels() {
15706
- const locale = this.locale;
15707
- const t = this.t;
15708
- const left = t('Align cell text to the left');
15709
- const center = t('Align cell text to the center');
15710
- const right = t('Align cell text to the right');
15711
- const justify = t('Justify cell text');
15712
- // Returns object with a proper order of labels.
15713
- if (locale.uiLanguageDirection === 'rtl') {
15714
- return {
15715
- right,
15716
- center,
15717
- left,
15718
- justify
15719
- };
15720
- } else {
15721
- return {
15722
- left,
15723
- center,
15724
- right,
15725
- justify
15726
- };
15727
- }
15728
- }
15729
- /**
15730
- * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.
15731
- */ get _verticalAlignmentLabels() {
15732
- const t = this.t;
15733
- return {
15734
- top: t('Align cell text to the top'),
15735
- middle: t('Align cell text to the middle'),
15736
- bottom: t('Align cell text to the bottom')
15737
- };
15738
- }
15739
- /**
15740
- * Provides localized labels for {@link #cellTypeDropdown}.
15741
- */ get _cellTypeLabels() {
15742
- const t = this.t;
15743
- return {
15744
- data: t('Data cell'),
15745
- header: t('Header cell')
15746
- };
15747
- }
15748
- }
15749
- function isBorderStyleSet(value) {
15750
- return value !== 'none';
15751
- }
15752
-
15753
- const ERROR_TEXT_TIMEOUT = 500;
15754
- // Map of view properties and related commands.
15755
- const propertyToCommandMap = {
15756
- borderStyle: 'tableCellBorderStyle',
15757
- borderColor: 'tableCellBorderColor',
15758
- borderWidth: 'tableCellBorderWidth',
15759
- height: 'tableCellHeight',
15760
- width: 'tableCellWidth',
15761
- padding: 'tableCellPadding',
15762
- backgroundColor: 'tableCellBackgroundColor',
15763
- horizontalAlignment: 'tableCellHorizontalAlignment',
15764
- verticalAlignment: 'tableCellVerticalAlignment',
15765
- cellType: 'tableCellType'
15766
- };
15767
- /**
15768
- * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
15769
- * that opens a form allowing to specify the visual styling of a table cell.
15770
- *
15771
- * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
15772
- */ class TableCellPropertiesUIExperimental extends Plugin {
15773
- /**
15774
- * The default table cell properties.
15775
- */ _defaultContentTableCellProperties;
15776
- /**
15777
- * The default layout table cell properties.
15778
- */ _defaultLayoutTableCellProperties;
15779
- /**
15780
- * The contextual balloon plugin instance.
15781
- */ _balloon;
15782
- /**
15783
- * The cell properties form view displayed inside the balloon.
15784
- */ view;
15785
- /**
15786
- * The cell properties form view displayed inside the balloon (content table).
15787
- */ _viewWithContentTableDefaults;
15788
- /**
15789
- * The cell properties form view displayed inside the balloon (layout table).
15790
- */ _viewWithLayoutTableDefaults;
15791
- /**
15792
- * The batch used to undo all changes made by the form (which are live, as the user types)
15793
- * when "Cancel" was pressed. Each time the view is shown, a new batch is created.
15794
- */ _undoStepBatch;
15795
- /**
15796
- * Flag used to indicate whether view is ready to execute update commands
15797
- * (it finished loading initial data).
15798
- */ _isReady;
15799
- /**
15800
- * @inheritDoc
15801
- */ static get requires() {
15802
- return [
15803
- ContextualBalloon
15804
- ];
15805
- }
15806
- /**
15807
- * @inheritDoc
15808
- */ static get pluginName() {
15809
- return 'TableCellPropertiesUIExperimental';
15810
- }
15811
- /**
15812
- * @inheritDoc
15813
- */ static get isOfficialPlugin() {
15814
- return true;
15815
- }
15816
- /**
15817
- * @inheritDoc
15818
- */ constructor(editor){
15819
- super(editor);
15820
- editor.config.define('table.tableCellProperties', {
15821
- borderColors: defaultColors,
15822
- backgroundColors: defaultColors
15823
- });
15824
- }
15825
- /**
15826
- * @inheritDoc
15827
- */ init() {
15828
- const editor = this.editor;
15829
- const t = editor.t;
15830
- this._defaultContentTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
15831
- includeVerticalAlignmentProperty: true,
15832
- includeHorizontalAlignmentProperty: true,
15833
- includePaddingProperty: true,
15834
- isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
15835
- });
15836
- this._defaultLayoutTableCellProperties = getNormalizedDefaultProperties(undefined, {
15837
- includeVerticalAlignmentProperty: true,
15838
- includeHorizontalAlignmentProperty: true,
15839
- isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
15840
- });
15841
- this._balloon = editor.plugins.get(ContextualBalloon);
15842
- this.view = null;
15843
- this._isReady = false;
15844
- editor.ui.componentFactory.add('tableCellProperties', (locale)=>{
15845
- const view = new ButtonView(locale);
15846
- view.set({
15847
- label: t('Cell properties'),
15848
- icon: IconTableCellProperties,
15849
- tooltip: true
15850
- });
15851
- this.listenTo(view, 'execute', ()=>this._showView());
15852
- const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName)).filter((val)=>!!val);
15853
- view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
15854
- return view;
15855
- });
15856
- }
15857
- /**
15858
- * @inheritDoc
15859
- */ destroy() {
15860
- super.destroy();
15861
- // Destroy created UI components as they are not automatically destroyed.
15862
- // See https://github.com/ckeditor/ckeditor5/issues/1341.
15863
- if (this.view) {
15864
- this.view.destroy();
15865
- }
15866
- }
15867
- /**
15868
- * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
15869
- *
15870
- * @returns The cell properties form view instance.
15871
- */ _createPropertiesView(defaultTableCellProperties) {
15872
- const editor = this.editor;
15873
- const config = editor.config.get('table.tableCellProperties');
15874
- const borderColorsConfig = normalizeColorOptions(config.borderColors);
15875
- const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
15876
- const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
15877
- const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
15878
- const hasColorPicker = config.colorPicker !== false;
15879
- const isTableCellTypeSupported = !!editor.config.get('experimentalFlags.tableCellTypeSupport');
15880
- const view = new TableCellPropertiesViewExperimental(editor.locale, {
15881
- borderColors: localizedBorderColors,
15882
- backgroundColors: localizedBackgroundColors,
15883
- defaultTableCellProperties,
15884
- colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false,
15885
- isTableCellTypeSupported
15886
- });
15887
- const t = editor.t;
15888
- // Render the view so its #element is available for the clickOutsideHandler.
15889
- view.render();
15890
- this.listenTo(view, 'submit', ()=>{
15891
- this._hideView();
15892
- });
15893
- this.listenTo(view, 'cancel', ()=>{
15894
- // https://github.com/ckeditor/ckeditor5/issues/6180
15895
- if (this._undoStepBatch.operations.length) {
15896
- editor.execute('undo', this._undoStepBatch);
15897
- }
15898
- this._hideView();
15899
- });
15900
- // Close the balloon on Esc key press.
15901
- view.keystrokes.set('Esc', (data, cancel)=>{
15902
- this._hideView();
15903
- cancel();
15904
- });
15905
- // Close on click outside of balloon panel element.
15906
- clickOutsideHandler({
15907
- emitter: view,
15908
- activator: ()=>this._isViewInBalloon,
15909
- contextElements: [
15910
- this._balloon.view.element
15911
- ],
15912
- callback: ()=>this._hideView()
15913
- });
15914
- const colorErrorText = getLocalizedColorErrorText(t);
15915
- const lengthErrorText = getLocalizedLengthErrorText(t);
15916
- // Create the "UI -> editor data" binding.
15917
- // These listeners update the editor data (via table commands) when any observable
15918
- // property of the view has changed. They also validate the value and display errors in the UI
15919
- // when necessary. This makes the view live, which means the changes are
15920
- // visible in the editing as soon as the user types or changes fields' values.
15921
- view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
15922
- view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
15923
- viewField: view.borderColorInput,
15924
- commandName: 'tableCellBorderColor',
15925
- errorText: colorErrorText,
15926
- validator: colorFieldValidator
15927
- }));
15928
- view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
15929
- viewField: view.borderWidthInput,
15930
- commandName: 'tableCellBorderWidth',
15931
- errorText: lengthErrorText,
15932
- validator: lineWidthFieldValidator
15933
- }));
15934
- view.on('change:padding', this._getValidatedPropertyChangeCallback({
15935
- viewField: view.paddingInput,
15936
- commandName: 'tableCellPadding',
15937
- errorText: lengthErrorText,
15938
- validator: lengthFieldValidator
15939
- }));
15940
- view.on('change:width', this._getValidatedPropertyChangeCallback({
15941
- viewField: view.widthInput,
15942
- commandName: 'tableCellWidth',
15943
- errorText: lengthErrorText,
15944
- validator: lengthFieldValidator
15945
- }));
15946
- view.on('change:height', this._getValidatedPropertyChangeCallback({
15947
- viewField: view.heightInput,
15948
- commandName: 'tableCellHeight',
15949
- errorText: lengthErrorText,
15950
- validator: lengthFieldValidator
15951
- }));
15952
- view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
15953
- viewField: view.backgroundInput,
15954
- commandName: 'tableCellBackgroundColor',
15955
- errorText: colorErrorText,
15956
- validator: colorFieldValidator
15957
- }));
15958
- view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
15959
- view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
15960
- const cellTypeCommand = editor.commands.get('tableCellType');
15961
- if (cellTypeCommand) {
15962
- view.cellTypeDropdown.bind('isEnabled').to(cellTypeCommand, 'isEnabled');
15963
- view.on('change:cellType', this._getPropertyChangeCallback('tableCellType'));
15964
- }
15965
- return view;
15966
- }
15967
- /**
15968
- * In this method the "editor data -> UI" binding is happening.
15969
- *
15970
- * When executed, this method obtains selected cell property values from various table commands
15971
- * and passes them to the {@link #view}.
15972
- *
15973
- * This way, the UI stays up–to–date with the editor data.
15974
- */ _fillViewFormFromCommandValues() {
15975
- const commands = this.editor.commands;
15976
- const borderStyleCommand = commands.get('tableCellBorderStyle');
15977
- Object.entries(propertyToCommandMap).flatMap(([property, commandName])=>{
15978
- const command = commands.get(commandName);
15979
- if (!command) {
15980
- return [];
15981
- }
15982
- const propertyKey = property;
15983
- let defaultValue;
15984
- if (propertyKey === 'cellType') {
15985
- defaultValue = '';
15986
- } else {
15987
- defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
15988
- }
15989
- const entry = [
15990
- property,
15991
- command.value || defaultValue
15992
- ];
15993
- return [
15994
- entry
15995
- ];
15996
- }).forEach(([property, value])=>{
15997
- // Do not set the `border-color` and `border-width` fields if `border-style:none`.
15998
- if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
15999
- return;
16000
- }
16001
- this.view.set(property, value);
16002
- });
16003
- this._isReady = true;
16004
- }
16005
- /**
16006
- * Shows the {@link #view} in the {@link #_balloon}.
16007
- *
16008
- * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
16009
- * all changes made to the document when the view is visible, allowing a single undo step
16010
- * for all of them.
16011
- */ _showView() {
16012
- const editor = this.editor;
16013
- const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
16014
- const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
16015
- const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
16016
- if (useDefaults && !this._viewWithContentTableDefaults) {
16017
- this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableCellProperties);
16018
- } else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
16019
- this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableCellProperties);
16020
- }
16021
- this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
16022
- this.listenTo(editor.ui, 'update', ()=>{
16023
- this._updateView();
16024
- });
16025
- // Update the view with the model values.
16026
- this._fillViewFormFromCommandValues();
16027
- this._balloon.add({
16028
- view: this.view,
16029
- position: getBalloonCellPositionData(editor)
16030
- });
16031
- // Create a new batch. Clicking "Cancel" will undo this batch.
16032
- this._undoStepBatch = editor.model.createBatch();
16033
- // Basic a11y.
16034
- this.view.focus();
16035
- }
16036
- /**
16037
- * Removes the {@link #view} from the {@link #_balloon}.
16038
- */ _hideView() {
16039
- const editor = this.editor;
16040
- this.stopListening(editor.ui, 'update');
16041
- this._isReady = false;
16042
- // Blur any input element before removing it from DOM to prevent issues in some browsers.
16043
- // See https://github.com/ckeditor/ckeditor5/issues/1501.
16044
- this.view.saveButtonView.focus();
16045
- this._balloon.remove(this.view);
16046
- // Make sure the focus is not lost in the process by putting it directly
16047
- // into the editing view.
16048
- this.editor.editing.view.focus();
16049
- }
16050
- /**
16051
- * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
16052
- */ _updateView() {
16053
- const editor = this.editor;
16054
- const viewDocument = editor.editing.view.document;
16055
- if (!getTableWidgetAncestor(viewDocument.selection)) {
16056
- this._hideView();
16057
- } else if (this._isViewVisible) {
16058
- repositionContextualBalloon(editor, 'cell');
16059
- }
16060
- }
16061
- /**
16062
- * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
16063
- */ get _isViewVisible() {
16064
- return !!this.view && this._balloon.visibleView === this.view;
16065
- }
16066
- /**
16067
- * Returns `true` when the {@link #view} is in the {@link #_balloon}.
16068
- */ get _isViewInBalloon() {
16069
- return !!this.view && this._balloon.hasView(this.view);
16070
- }
16071
- /**
16072
- * Creates a callback that when executed upon the {@link #view view's} property change
16073
- * executes a related editor command with the new property value.
16074
- *
16075
- * @param commandName The default value of the command.
16076
- */ _getPropertyChangeCallback(commandName) {
16077
- return (evt, propertyName, newValue)=>{
16078
- if (!this._isReady) {
16079
- return;
16080
- }
16081
- this.editor.execute(commandName, {
16082
- value: newValue,
16083
- batch: this._undoStepBatch
16084
- });
16085
- };
16086
- }
16087
- /**
16088
- * Creates a callback that when executed upon the {@link #view view's} property change:
16089
- * * Executes a related editor command with the new property value if the value is valid,
16090
- * * Or sets the error text next to the invalid field, if the value did not pass the validation.
16091
- */ _getValidatedPropertyChangeCallback(options) {
16092
- const { commandName, viewField, validator, errorText } = options;
16093
- const setErrorTextDebounced = debounce(()=>{
16094
- viewField.errorText = errorText;
16095
- }, ERROR_TEXT_TIMEOUT);
16096
- return (evt, propertyName, newValue)=>{
16097
- setErrorTextDebounced.cancel();
16098
- // Do not execute the command on initial call (opening the table properties view).
16099
- if (!this._isReady) {
16100
- return;
16101
- }
16102
- if (validator(newValue)) {
16103
- this.editor.execute(commandName, {
16104
- value: newValue,
16105
- batch: this._undoStepBatch
16106
- });
16107
- viewField.errorText = null;
16108
- } else {
16109
- setErrorTextDebounced();
16110
- }
16111
- };
16112
- }
16113
- }
16114
-
16115
- export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesUIExperimental, TableCellPropertiesView, TableCellPropertiesViewExperimental, TableCellPropertyCommand, TableCellTypeCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesUIExperimental, TablePropertiesView, TablePropertiesViewExperimental, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar$1 as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels$1 as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator$1 as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions$1 as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute };
14130
+ export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesView, TableCellPropertyCommand, TableCellTypeCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesView, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute, isTableHeaderCellType };
16116
14131
  //# sourceMappingURL=index.js.map