@ckeditor/ckeditor5-table 47.2.0 → 47.3.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/LICENSE.md +4 -4
  2. package/build/table.js +2 -2
  3. package/build/translations/af.js +1 -1
  4. package/build/translations/ar.js +1 -1
  5. package/build/translations/ast.js +1 -1
  6. package/build/translations/az.js +1 -1
  7. package/build/translations/be.js +1 -1
  8. package/build/translations/bg.js +1 -1
  9. package/build/translations/bn.js +1 -1
  10. package/build/translations/bs.js +1 -1
  11. package/build/translations/ca.js +1 -1
  12. package/build/translations/cs.js +1 -1
  13. package/build/translations/da.js +1 -1
  14. package/build/translations/de-ch.js +1 -1
  15. package/build/translations/de.js +1 -1
  16. package/build/translations/el.js +1 -1
  17. package/build/translations/en-au.js +1 -1
  18. package/build/translations/en-gb.js +1 -1
  19. package/build/translations/eo.js +1 -1
  20. package/build/translations/es-co.js +1 -1
  21. package/build/translations/es.js +1 -1
  22. package/build/translations/et.js +1 -1
  23. package/build/translations/eu.js +1 -1
  24. package/build/translations/fa.js +1 -1
  25. package/build/translations/fi.js +1 -1
  26. package/build/translations/fr.js +1 -1
  27. package/build/translations/gl.js +1 -1
  28. package/build/translations/gu.js +1 -1
  29. package/build/translations/he.js +1 -1
  30. package/build/translations/hi.js +1 -1
  31. package/build/translations/hr.js +1 -1
  32. package/build/translations/hu.js +1 -1
  33. package/build/translations/hy.js +1 -1
  34. package/build/translations/id.js +1 -1
  35. package/build/translations/it.js +1 -1
  36. package/build/translations/ja.js +1 -1
  37. package/build/translations/jv.js +1 -1
  38. package/build/translations/kk.js +1 -1
  39. package/build/translations/km.js +1 -1
  40. package/build/translations/kn.js +1 -1
  41. package/build/translations/ko.js +1 -1
  42. package/build/translations/ku.js +1 -1
  43. package/build/translations/lt.js +1 -1
  44. package/build/translations/lv.js +1 -1
  45. package/build/translations/ms.js +1 -1
  46. package/build/translations/nb.js +1 -1
  47. package/build/translations/ne.js +1 -1
  48. package/build/translations/nl.js +1 -1
  49. package/build/translations/no.js +1 -1
  50. package/build/translations/oc.js +1 -1
  51. package/build/translations/pl.js +1 -1
  52. package/build/translations/pt-br.js +1 -1
  53. package/build/translations/pt.js +1 -1
  54. package/build/translations/ro.js +1 -1
  55. package/build/translations/ru.js +1 -1
  56. package/build/translations/si.js +1 -1
  57. package/build/translations/sk.js +1 -1
  58. package/build/translations/sl.js +1 -1
  59. package/build/translations/sq.js +1 -1
  60. package/build/translations/sr-latn.js +1 -1
  61. package/build/translations/sr.js +1 -1
  62. package/build/translations/sv.js +1 -1
  63. package/build/translations/th.js +1 -1
  64. package/build/translations/ti.js +1 -1
  65. package/build/translations/tk.js +1 -1
  66. package/build/translations/tr.js +1 -1
  67. package/build/translations/tt.js +1 -1
  68. package/build/translations/ug.js +1 -1
  69. package/build/translations/uk.js +1 -1
  70. package/build/translations/ur.js +1 -1
  71. package/build/translations/uz.js +1 -1
  72. package/build/translations/vi.js +1 -1
  73. package/build/translations/zh-cn.js +1 -1
  74. package/build/translations/zh.js +1 -1
  75. package/dist/index-content.css +32 -3
  76. package/dist/index-editor.css +181 -88
  77. package/dist/index.css +302 -160
  78. package/dist/index.css.map +1 -1
  79. package/dist/index.js +11215 -8546
  80. package/dist/index.js.map +1 -1
  81. package/dist/translations/af.js +1 -1
  82. package/dist/translations/af.umd.js +1 -1
  83. package/dist/translations/ar.js +1 -1
  84. package/dist/translations/ar.umd.js +1 -1
  85. package/dist/translations/ast.js +1 -1
  86. package/dist/translations/ast.umd.js +1 -1
  87. package/dist/translations/az.js +1 -1
  88. package/dist/translations/az.umd.js +1 -1
  89. package/dist/translations/be.js +1 -1
  90. package/dist/translations/be.umd.js +1 -1
  91. package/dist/translations/bg.js +1 -1
  92. package/dist/translations/bg.umd.js +1 -1
  93. package/dist/translations/bn.js +1 -1
  94. package/dist/translations/bn.umd.js +1 -1
  95. package/dist/translations/bs.js +1 -1
  96. package/dist/translations/bs.umd.js +1 -1
  97. package/dist/translations/ca.js +1 -1
  98. package/dist/translations/ca.umd.js +1 -1
  99. package/dist/translations/cs.js +1 -1
  100. package/dist/translations/cs.umd.js +1 -1
  101. package/dist/translations/da.js +1 -1
  102. package/dist/translations/da.umd.js +1 -1
  103. package/dist/translations/de-ch.js +1 -1
  104. package/dist/translations/de-ch.umd.js +1 -1
  105. package/dist/translations/de.js +1 -1
  106. package/dist/translations/de.umd.js +1 -1
  107. package/dist/translations/el.js +1 -1
  108. package/dist/translations/el.umd.js +1 -1
  109. package/dist/translations/en-au.js +1 -1
  110. package/dist/translations/en-au.umd.js +1 -1
  111. package/dist/translations/en-gb.js +1 -1
  112. package/dist/translations/en-gb.umd.js +1 -1
  113. package/dist/translations/en.js +1 -1
  114. package/dist/translations/en.umd.js +1 -1
  115. package/dist/translations/eo.js +1 -1
  116. package/dist/translations/eo.umd.js +1 -1
  117. package/dist/translations/es-co.js +1 -1
  118. package/dist/translations/es-co.umd.js +1 -1
  119. package/dist/translations/es.js +1 -1
  120. package/dist/translations/es.umd.js +1 -1
  121. package/dist/translations/et.js +1 -1
  122. package/dist/translations/et.umd.js +1 -1
  123. package/dist/translations/eu.js +1 -1
  124. package/dist/translations/eu.umd.js +1 -1
  125. package/dist/translations/fa.js +1 -1
  126. package/dist/translations/fa.umd.js +1 -1
  127. package/dist/translations/fi.js +1 -1
  128. package/dist/translations/fi.umd.js +1 -1
  129. package/dist/translations/fr.js +1 -1
  130. package/dist/translations/fr.umd.js +1 -1
  131. package/dist/translations/gl.js +1 -1
  132. package/dist/translations/gl.umd.js +1 -1
  133. package/dist/translations/gu.js +1 -1
  134. package/dist/translations/gu.umd.js +1 -1
  135. package/dist/translations/he.js +1 -1
  136. package/dist/translations/he.umd.js +1 -1
  137. package/dist/translations/hi.js +1 -1
  138. package/dist/translations/hi.umd.js +1 -1
  139. package/dist/translations/hr.js +1 -1
  140. package/dist/translations/hr.umd.js +1 -1
  141. package/dist/translations/hu.js +1 -1
  142. package/dist/translations/hu.umd.js +1 -1
  143. package/dist/translations/hy.js +1 -1
  144. package/dist/translations/hy.umd.js +1 -1
  145. package/dist/translations/id.js +1 -1
  146. package/dist/translations/id.umd.js +1 -1
  147. package/dist/translations/it.js +1 -1
  148. package/dist/translations/it.umd.js +1 -1
  149. package/dist/translations/ja.js +1 -1
  150. package/dist/translations/ja.umd.js +1 -1
  151. package/dist/translations/jv.js +1 -1
  152. package/dist/translations/jv.umd.js +1 -1
  153. package/dist/translations/kk.js +1 -1
  154. package/dist/translations/kk.umd.js +1 -1
  155. package/dist/translations/km.js +1 -1
  156. package/dist/translations/km.umd.js +1 -1
  157. package/dist/translations/kn.js +1 -1
  158. package/dist/translations/kn.umd.js +1 -1
  159. package/dist/translations/ko.js +1 -1
  160. package/dist/translations/ko.umd.js +1 -1
  161. package/dist/translations/ku.js +1 -1
  162. package/dist/translations/ku.umd.js +1 -1
  163. package/dist/translations/lt.js +1 -1
  164. package/dist/translations/lt.umd.js +1 -1
  165. package/dist/translations/lv.js +1 -1
  166. package/dist/translations/lv.umd.js +1 -1
  167. package/dist/translations/ms.js +1 -1
  168. package/dist/translations/ms.umd.js +1 -1
  169. package/dist/translations/nb.js +1 -1
  170. package/dist/translations/nb.umd.js +1 -1
  171. package/dist/translations/ne.js +1 -1
  172. package/dist/translations/ne.umd.js +1 -1
  173. package/dist/translations/nl.js +1 -1
  174. package/dist/translations/nl.umd.js +1 -1
  175. package/dist/translations/no.js +1 -1
  176. package/dist/translations/no.umd.js +1 -1
  177. package/dist/translations/oc.js +1 -1
  178. package/dist/translations/oc.umd.js +1 -1
  179. package/dist/translations/pl.js +1 -1
  180. package/dist/translations/pl.umd.js +1 -1
  181. package/dist/translations/pt-br.js +1 -1
  182. package/dist/translations/pt-br.umd.js +1 -1
  183. package/dist/translations/pt.js +1 -1
  184. package/dist/translations/pt.umd.js +1 -1
  185. package/dist/translations/ro.js +1 -1
  186. package/dist/translations/ro.umd.js +1 -1
  187. package/dist/translations/ru.js +1 -1
  188. package/dist/translations/ru.umd.js +1 -1
  189. package/dist/translations/si.js +1 -1
  190. package/dist/translations/si.umd.js +1 -1
  191. package/dist/translations/sk.js +1 -1
  192. package/dist/translations/sk.umd.js +1 -1
  193. package/dist/translations/sl.js +1 -1
  194. package/dist/translations/sl.umd.js +1 -1
  195. package/dist/translations/sq.js +1 -1
  196. package/dist/translations/sq.umd.js +1 -1
  197. package/dist/translations/sr-latn.js +1 -1
  198. package/dist/translations/sr-latn.umd.js +1 -1
  199. package/dist/translations/sr.js +1 -1
  200. package/dist/translations/sr.umd.js +1 -1
  201. package/dist/translations/sv.js +1 -1
  202. package/dist/translations/sv.umd.js +1 -1
  203. package/dist/translations/th.js +1 -1
  204. package/dist/translations/th.umd.js +1 -1
  205. package/dist/translations/ti.js +1 -1
  206. package/dist/translations/ti.umd.js +1 -1
  207. package/dist/translations/tk.js +1 -1
  208. package/dist/translations/tk.umd.js +1 -1
  209. package/dist/translations/tr.js +1 -1
  210. package/dist/translations/tr.umd.js +1 -1
  211. package/dist/translations/tt.js +1 -1
  212. package/dist/translations/tt.umd.js +1 -1
  213. package/dist/translations/ug.js +1 -1
  214. package/dist/translations/ug.umd.js +1 -1
  215. package/dist/translations/uk.js +1 -1
  216. package/dist/translations/uk.umd.js +1 -1
  217. package/dist/translations/ur.js +1 -1
  218. package/dist/translations/ur.umd.js +1 -1
  219. package/dist/translations/uz.js +1 -1
  220. package/dist/translations/uz.umd.js +1 -1
  221. package/dist/translations/vi.js +1 -1
  222. package/dist/translations/vi.umd.js +1 -1
  223. package/dist/translations/zh-cn.js +1 -1
  224. package/dist/translations/zh-cn.umd.js +1 -1
  225. package/dist/translations/zh.js +1 -1
  226. package/dist/translations/zh.umd.js +1 -1
  227. package/lang/contexts.json +6 -0
  228. package/lang/translations/af.po +24 -0
  229. package/lang/translations/ar.po +24 -0
  230. package/lang/translations/ast.po +24 -0
  231. package/lang/translations/az.po +24 -0
  232. package/lang/translations/be.po +24 -0
  233. package/lang/translations/bg.po +24 -0
  234. package/lang/translations/bn.po +24 -0
  235. package/lang/translations/bs.po +24 -0
  236. package/lang/translations/ca.po +24 -0
  237. package/lang/translations/cs.po +24 -0
  238. package/lang/translations/da.po +24 -0
  239. package/lang/translations/de-ch.po +24 -0
  240. package/lang/translations/de.po +24 -0
  241. package/lang/translations/el.po +24 -0
  242. package/lang/translations/en-au.po +24 -0
  243. package/lang/translations/en-gb.po +24 -0
  244. package/lang/translations/en.po +24 -0
  245. package/lang/translations/eo.po +24 -0
  246. package/lang/translations/es-co.po +24 -0
  247. package/lang/translations/es.po +24 -0
  248. package/lang/translations/et.po +24 -0
  249. package/lang/translations/eu.po +24 -0
  250. package/lang/translations/fa.po +24 -0
  251. package/lang/translations/fi.po +24 -0
  252. package/lang/translations/fr.po +24 -0
  253. package/lang/translations/gl.po +24 -0
  254. package/lang/translations/gu.po +24 -0
  255. package/lang/translations/he.po +24 -0
  256. package/lang/translations/hi.po +24 -0
  257. package/lang/translations/hr.po +24 -0
  258. package/lang/translations/hu.po +24 -0
  259. package/lang/translations/hy.po +24 -0
  260. package/lang/translations/id.po +24 -0
  261. package/lang/translations/it.po +24 -0
  262. package/lang/translations/ja.po +24 -0
  263. package/lang/translations/jv.po +24 -0
  264. package/lang/translations/kk.po +24 -0
  265. package/lang/translations/km.po +24 -0
  266. package/lang/translations/kn.po +24 -0
  267. package/lang/translations/ko.po +24 -0
  268. package/lang/translations/ku.po +24 -0
  269. package/lang/translations/lt.po +24 -0
  270. package/lang/translations/lv.po +24 -0
  271. package/lang/translations/ms.po +24 -0
  272. package/lang/translations/nb.po +24 -0
  273. package/lang/translations/ne.po +24 -0
  274. package/lang/translations/nl.po +24 -0
  275. package/lang/translations/no.po +24 -0
  276. package/lang/translations/oc.po +24 -0
  277. package/lang/translations/pl.po +24 -0
  278. package/lang/translations/pt-br.po +24 -0
  279. package/lang/translations/pt.po +24 -0
  280. package/lang/translations/ro.po +24 -0
  281. package/lang/translations/ru.po +24 -0
  282. package/lang/translations/si.po +24 -0
  283. package/lang/translations/sk.po +24 -0
  284. package/lang/translations/sl.po +24 -0
  285. package/lang/translations/sq.po +24 -0
  286. package/lang/translations/sr-latn.po +24 -0
  287. package/lang/translations/sr.po +24 -0
  288. package/lang/translations/sv.po +24 -0
  289. package/lang/translations/th.po +24 -0
  290. package/lang/translations/ti.po +24 -0
  291. package/lang/translations/tk.po +24 -0
  292. package/lang/translations/tr.po +24 -0
  293. package/lang/translations/tt.po +24 -0
  294. package/lang/translations/ug.po +24 -0
  295. package/lang/translations/uk.po +24 -0
  296. package/lang/translations/ur.po +24 -0
  297. package/lang/translations/uz.po +24 -0
  298. package/lang/translations/vi.po +24 -0
  299. package/lang/translations/zh-cn.po +24 -0
  300. package/lang/translations/zh.po +24 -0
  301. package/package.json +9 -9
  302. package/src/augmentation.d.ts +21 -0
  303. package/src/converters/downcast.d.ts +26 -1
  304. package/src/converters/downcast.js +129 -3
  305. package/src/converters/tableproperties.d.ts +46 -2
  306. package/src/converters/tableproperties.js +218 -1
  307. package/src/converters/upcasttable.js +147 -36
  308. package/src/index.d.ts +5 -1
  309. package/src/index.js +5 -0
  310. package/src/plaintableoutput.js +0 -91
  311. package/src/tablecellproperties/tablecellpropertiesediting.js +7 -4
  312. package/src/tablecellproperties/tablecellpropertiesuiexperimental.d.ts +128 -0
  313. package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +386 -0
  314. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts +237 -0
  315. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +633 -0
  316. package/src/tableconfig.d.ts +187 -10
  317. package/src/tableediting.d.ts +5 -0
  318. package/src/tableediting.js +28 -1
  319. package/src/tablelayout/tablelayoutediting.js +8 -2
  320. package/src/tableproperties/tablepropertiesediting.js +255 -8
  321. package/src/tableproperties/tablepropertiesuiexperimental.d.ts +136 -0
  322. package/src/tableproperties/tablepropertiesuiexperimental.js +375 -0
  323. package/src/tableproperties/ui/tablepropertiesviewexperimental.d.ts +216 -0
  324. package/src/tableproperties/ui/tablepropertiesviewexperimental.js +544 -0
  325. package/src/utils/structure.d.ts +5 -1
  326. package/src/utils/structure.js +10 -0
  327. package/src/utils/ui/table-propertiesexperimental.d.ts +215 -0
  328. package/src/utils/ui/table-propertiesexperimental.js +391 -0
  329. package/theme/formrow-experimental.css +15 -0
  330. package/theme/table.css +2 -2
  331. package/theme/tableform-experimental.css +61 -0
  332. package/theme/tableproperties-experimental.css +78 -0
@@ -2,11 +2,10 @@
2
2
  * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
- /**
6
- * @module table/converters/downcast
7
- */
8
5
  import { toWidget, toWidgetEditable } from 'ckeditor5/src/widget.js';
9
6
  import { TableWalker } from './../tablewalker.js';
7
+ import { downcastTableAlignmentConfig } from './tableproperties.js';
8
+ import { getNormalizedDefaultTableProperties } from '../utils/table-properties.js';
10
9
  /**
11
10
  * Model table element to view table element conversion helper.
12
11
  *
@@ -158,3 +157,130 @@ function hasAnyAttribute(element) {
158
157
  }
159
158
  return false;
160
159
  }
160
+ /**
161
+ * Downcasts a plain table (also used in the clipboard pipeline).
162
+ */
163
+ export function convertPlainTable(editor) {
164
+ return (table, conversionApi) => {
165
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
166
+ const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
167
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
168
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
169
+ return null;
170
+ }
171
+ return downcastPlainTable(table, conversionApi, editor);
172
+ };
173
+ }
174
+ /**
175
+ * Downcasts a plain table caption (also used in the clipboard pipeline).
176
+ */
177
+ export function convertPlainTableCaption(editor) {
178
+ return (modelElement, { writer, options }) => {
179
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
180
+ const isClipboardPipeline = options.isClipboardPipeline;
181
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
182
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
183
+ return null;
184
+ }
185
+ if (modelElement.parent.name === 'table') {
186
+ return writer.createContainerElement('caption');
187
+ }
188
+ return null;
189
+ };
190
+ }
191
+ /**
192
+ * Downcasts a plain table.
193
+ *
194
+ * @param table Table model element.
195
+ * @param conversionApi The conversion API object.
196
+ * @param defaultTableProperties Normalized default table properties.
197
+ * @returns Created element.
198
+ */
199
+ export function downcastPlainTable(table, conversionApi, editor) {
200
+ const writer = conversionApi.writer;
201
+ const headingRows = table.getAttribute('headingRows') || 0;
202
+ // Table head rows slot.
203
+ const headRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index < headingRows);
204
+ // Table body rows slot.
205
+ const bodyRowsSlot = writer.createSlot((element) => element.is('element', 'tableRow') && element.index >= headingRows);
206
+ // Table children slot.
207
+ const childrenSlot = writer.createSlot((element) => !element.is('element', 'tableRow'));
208
+ // Table <thead> element with all the heading rows.
209
+ const theadElement = writer.createContainerElement('thead', null, headRowsSlot);
210
+ // Table <tbody> element with all the body rows.
211
+ const tbodyElement = writer.createContainerElement('tbody', null, bodyRowsSlot);
212
+ // Table contents element containing <thead> and <tbody> when necessary.
213
+ const tableContentElements = [];
214
+ if (headingRows) {
215
+ tableContentElements.push(theadElement);
216
+ }
217
+ if (headingRows < table.childCount) {
218
+ tableContentElements.push(tbodyElement);
219
+ }
220
+ const tableAttributes = { class: 'table' };
221
+ if (editor.plugins.has('TableProperties') && conversionApi.options.isClipboardPipeline) {
222
+ const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
223
+ includeAlignmentProperty: true
224
+ });
225
+ const tableAlignment = table.getAttribute('tableAlignment');
226
+ let localDefaultValue = defaultTableProperties.alignment;
227
+ if (table.getAttribute('tableType') === 'layout') {
228
+ localDefaultValue = '';
229
+ }
230
+ const tableAlignmentValue = tableAlignment || localDefaultValue;
231
+ if (tableAlignmentValue) {
232
+ tableAttributes.class += ' ' + downcastTableAlignmentConfig[tableAlignmentValue].className;
233
+ tableAttributes.style = downcastTableAlignmentConfig[tableAlignmentValue].style;
234
+ if (downcastTableAlignmentConfig[tableAlignmentValue].align !== undefined) {
235
+ tableAttributes.align = downcastTableAlignmentConfig[tableAlignmentValue].align;
236
+ }
237
+ }
238
+ }
239
+ // Create table structure.
240
+ //
241
+ // <table>
242
+ // {children-slot-like-caption}
243
+ // <thead>
244
+ // {table-head-rows-slot}
245
+ // </thead>
246
+ // <tbody>
247
+ // {table-body-rows-slot}
248
+ // </tbody>
249
+ // </table>
250
+ return writer.createContainerElement('table', tableAttributes, [childrenSlot, ...tableContentElements]);
251
+ }
252
+ /**
253
+ * Registers border and background attributes converters for plain tables or when the clipboard pipeline is used.
254
+ */
255
+ export function downcastTableBorderAndBackgroundAttributes(editor) {
256
+ const modelAttributes = {
257
+ 'border-width': 'tableBorderWidth',
258
+ 'border-color': 'tableBorderColor',
259
+ 'border-style': 'tableBorderStyle',
260
+ 'background-color': 'tableBackgroundColor'
261
+ };
262
+ for (const [styleName, modelAttribute] of Object.entries(modelAttributes)) {
263
+ editor.conversion.for('dataDowncast').add(dispatcher => {
264
+ return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi) => {
265
+ const { item, attributeNewValue } = data;
266
+ const { mapper, writer } = conversionApi;
267
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
268
+ const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
269
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
270
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
271
+ return;
272
+ }
273
+ if (!conversionApi.consumable.consume(item, evt.name)) {
274
+ return;
275
+ }
276
+ const table = mapper.toViewElement(item);
277
+ if (attributeNewValue) {
278
+ writer.setStyle(styleName, attributeNewValue, table);
279
+ }
280
+ else {
281
+ writer.removeStyle(styleName, table);
282
+ }
283
+ }, { priority: 'high' });
284
+ });
285
+ }
286
+ }
@@ -5,7 +5,8 @@
5
5
  /**
6
6
  * @module table/converters/tableproperties
7
7
  */
8
- import type { Conversion, UpcastConversionData, ViewElement } from 'ckeditor5/src/engine.js';
8
+ import type { Editor } from 'ckeditor5/src/core.js';
9
+ import type { Conversion, UpcastConversionData, ViewElement, Consumables } from 'ckeditor5/src/engine.js';
9
10
  /**
10
11
  * Conversion helper for upcasting attributes using normalized styles.
11
12
  *
@@ -41,13 +42,14 @@ export interface StyleValues {
41
42
  /**
42
43
  * Conversion helper for upcasting border styles for view elements.
43
44
  *
45
+ * @param editor The editor instance.
44
46
  * @param defaultBorder The default border values.
45
47
  * @param defaultBorder.color The default `borderColor` value.
46
48
  * @param defaultBorder.style The default `borderStyle` value.
47
49
  * @param defaultBorder.width The default `borderWidth` value.
48
50
  * @internal
49
51
  */
50
- export declare function upcastBorderStyles(conversion: Conversion, viewElementName: string, modelAttributes: StyleValues, defaultBorder: StyleValues): void;
52
+ export declare function upcastBorderStyles(editor: Editor, viewElementName: string, modelAttributes: StyleValues, defaultBorder: StyleValues): void;
51
53
  /**
52
54
  * Conversion helper for downcasting an attribute to a style.
53
55
  *
@@ -73,3 +75,45 @@ export declare function downcastTableAttribute(conversion: Conversion, options:
73
75
  * @internal
74
76
  */
75
77
  export declare function getDefaultValueAdjusted(defaultValue: string, layoutTableDefault: string, data: UpcastConversionData<ViewElement>): string;
78
+ /**
79
+ * Default table alignment options.
80
+ */
81
+ export declare const DEFAULT_TABLE_ALIGNMENT_OPTIONS: {
82
+ left: {
83
+ className: string;
84
+ };
85
+ center: {
86
+ className: string;
87
+ };
88
+ right: {
89
+ className: string;
90
+ };
91
+ blockLeft: {
92
+ className: string;
93
+ };
94
+ blockRight: {
95
+ className: string;
96
+ };
97
+ };
98
+ /**
99
+ * Configuration for upcasting table alignment from view to model.
100
+ */
101
+ export declare const upcastTableAlignmentConfig: Array<UpcastTableAlignmentConfig>;
102
+ export declare const downcastTableAlignmentConfig: Record<TableAlignmentValues, {
103
+ align: string | undefined;
104
+ style: string;
105
+ className: string;
106
+ }>;
107
+ type UpcastTableAlignmentConfig = {
108
+ view: {
109
+ name: RegExp | string;
110
+ styles?: Record<string, RegExp | string>;
111
+ attributes?: Record<string, RegExp | string>;
112
+ key?: string;
113
+ value?: RegExp | string;
114
+ };
115
+ getAlign: ((viewElement: ViewElement) => string | undefined) | (() => string);
116
+ getConsumables: (viewElement: ViewElement) => Consumables;
117
+ };
118
+ export type TableAlignmentValues = 'left' | 'center' | 'right' | 'blockLeft' | 'blockRight';
119
+ export {};
@@ -3,6 +3,8 @@
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
5
  import { first } from 'ckeditor5/src/utils.js';
6
+ const ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;
7
+ const FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;
6
8
  /**
7
9
  * Conversion helper for upcasting attributes using normalized styles.
8
10
  *
@@ -79,13 +81,15 @@ export function upcastStyleToAttribute(conversion, options) {
79
81
  /**
80
82
  * Conversion helper for upcasting border styles for view elements.
81
83
  *
84
+ * @param editor The editor instance.
82
85
  * @param defaultBorder The default border values.
83
86
  * @param defaultBorder.color The default `borderColor` value.
84
87
  * @param defaultBorder.style The default `borderStyle` value.
85
88
  * @param defaultBorder.width The default `borderWidth` value.
86
89
  * @internal
87
90
  */
88
- export function upcastBorderStyles(conversion, viewElementName, modelAttributes, defaultBorder) {
91
+ export function upcastBorderStyles(editor, viewElementName, modelAttributes, defaultBorder) {
92
+ const { conversion } = editor;
89
93
  conversion.for('upcast').add(dispatcher => dispatcher.on('element:' + viewElementName, (evt, data, conversionApi) => {
90
94
  // If the element was not converted by element-to-element converter,
91
95
  // we should not try to convert the style. See #8393.
@@ -149,6 +153,35 @@ export function upcastBorderStyles(conversion, viewElementName, modelAttributes,
149
153
  conversionApi.writer.setAttribute(modelAttributes.width, reducedBorder.width, modelElement);
150
154
  }
151
155
  }));
156
+ if (editor.config.get('experimentalFlags.upcastTableBorderZeroAttributes')) {
157
+ // If parent table has `border="0"` attribute then set border style to `none`
158
+ // all table cells of that table and table itself.
159
+ conversion.for('upcast').add(dispatcher => {
160
+ dispatcher.on(`element:${viewElementName}`, (evt, data, conversionApi) => {
161
+ const { modelRange, viewItem } = data;
162
+ const viewTable = (viewItem.is('element', 'table') ?
163
+ viewItem :
164
+ viewItem.findAncestor('table'));
165
+ // If something already consumed the border attribute on the nearest table element, skip the conversion.
166
+ if (!conversionApi.consumable.test(viewTable, { attributes: 'border' })) {
167
+ return;
168
+ }
169
+ // Ignore tables with border different than "0".
170
+ if (viewTable.getAttribute('border') !== '0') {
171
+ return;
172
+ }
173
+ const modelElement = modelRange?.start?.nodeAfter;
174
+ // If model element has already border style attribute, skip the conversion.
175
+ if (!modelElement || modelElement.hasAttribute(modelAttributes.style)) {
176
+ return;
177
+ }
178
+ conversionApi.writer.setAttribute(modelAttributes.style, 'none', modelElement);
179
+ if (viewItem.is('element', 'table')) {
180
+ conversionApi.consumable.consume(viewItem, { attributes: 'border' });
181
+ }
182
+ });
183
+ });
184
+ }
152
185
  }
153
186
  /**
154
187
  * Conversion helper for downcasting an attribute to a style.
@@ -225,3 +258,187 @@ function reduceBoxSidesValue(style) {
225
258
  }
226
259
  return topSideStyle;
227
260
  }
261
+ /**
262
+ * Default table alignment options.
263
+ */
264
+ export const DEFAULT_TABLE_ALIGNMENT_OPTIONS = {
265
+ left: { className: 'table-style-align-left' },
266
+ center: { className: 'table-style-align-center' },
267
+ right: { className: 'table-style-align-right' },
268
+ blockLeft: { className: 'table-style-block-align-left' },
269
+ blockRight: { className: 'table-style-block-align-right' }
270
+ };
271
+ /**
272
+ * Configuration for upcasting table alignment from view to model.
273
+ */
274
+ export const upcastTableAlignmentConfig = [
275
+ // Support for the `float:*;` CSS definition for the table alignment.
276
+ {
277
+ view: {
278
+ name: /^(table|figure)$/,
279
+ styles: {
280
+ float: FLOAT_VALUES_REG_EXP
281
+ }
282
+ },
283
+ getAlign: (viewElement) => {
284
+ let align = viewElement.getStyle('float');
285
+ if (align === 'none') {
286
+ align = 'center';
287
+ }
288
+ return align;
289
+ },
290
+ getConsumables(viewElement) {
291
+ const float = viewElement.getStyle('float');
292
+ const styles = ['float'];
293
+ if (float === 'left' && viewElement.hasStyle('margin-right')) {
294
+ styles.push('margin-right');
295
+ }
296
+ else if (float === 'right' && viewElement.hasStyle('margin-left')) {
297
+ styles.push('margin-left');
298
+ }
299
+ return { styles };
300
+ }
301
+ },
302
+ // Support for the `margin-left:auto; margin-right:auto;` CSS definition for the table alignment.
303
+ {
304
+ view: {
305
+ name: /^(table|figure)$/,
306
+ styles: {
307
+ 'margin-left': 'auto',
308
+ 'margin-right': 'auto'
309
+ }
310
+ },
311
+ getAlign: () => 'center',
312
+ getConsumables: () => {
313
+ return { styles: ['margin-left', 'margin-right'] };
314
+ }
315
+ },
316
+ // Support for the left alignment using CSS classes.
317
+ {
318
+ view: {
319
+ name: /^(table|figure)$/,
320
+ key: 'class',
321
+ value: 'table-style-align-left'
322
+ },
323
+ getAlign: () => 'left',
324
+ getConsumables() {
325
+ return { classes: DEFAULT_TABLE_ALIGNMENT_OPTIONS.left.className };
326
+ }
327
+ },
328
+ // Support for the right alignment using CSS classes.
329
+ {
330
+ view: {
331
+ name: /^(table|figure)$/,
332
+ key: 'class',
333
+ value: DEFAULT_TABLE_ALIGNMENT_OPTIONS.right.className
334
+ },
335
+ getAlign: () => 'right',
336
+ getConsumables() {
337
+ return { classes: DEFAULT_TABLE_ALIGNMENT_OPTIONS.right.className };
338
+ }
339
+ },
340
+ // Support for the center alignment using CSS classes.
341
+ {
342
+ view: {
343
+ name: /^(table|figure)$/,
344
+ key: 'class',
345
+ value: DEFAULT_TABLE_ALIGNMENT_OPTIONS.center.className
346
+ },
347
+ getAlign: () => 'center',
348
+ getConsumables() {
349
+ return { classes: DEFAULT_TABLE_ALIGNMENT_OPTIONS.center.className };
350
+ }
351
+ },
352
+ // Support for the block alignment left using CSS classes.
353
+ {
354
+ view: {
355
+ name: /^(table|figure)$/,
356
+ key: 'class',
357
+ value: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockLeft.className
358
+ },
359
+ getAlign: () => 'blockLeft',
360
+ getConsumables() {
361
+ return { classes: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockLeft.className };
362
+ }
363
+ },
364
+ // Support for the block alignment right using CSS classes.
365
+ {
366
+ view: {
367
+ name: /^(table|figure)$/,
368
+ key: 'class',
369
+ value: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockRight.className
370
+ },
371
+ getAlign: () => 'blockRight',
372
+ getConsumables() {
373
+ return { classes: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockRight.className };
374
+ }
375
+ },
376
+ // Support for the block alignment left using margin CSS styles.
377
+ {
378
+ view: {
379
+ name: /^(table|figure)$/,
380
+ styles: {
381
+ 'margin-left': '0',
382
+ 'margin-right': 'auto'
383
+ }
384
+ },
385
+ getAlign: () => 'blockLeft',
386
+ getConsumables() {
387
+ return { styles: ['margin-left', 'margin-right'] };
388
+ }
389
+ },
390
+ // Support for the block alignment right using margin CSS styles.
391
+ {
392
+ view: {
393
+ name: /^(table|figure)$/,
394
+ styles: {
395
+ 'margin-left': 'auto',
396
+ 'margin-right': '0'
397
+ }
398
+ },
399
+ getAlign: () => 'blockRight',
400
+ getConsumables() {
401
+ return { styles: ['margin-left', 'margin-right'] };
402
+ }
403
+ },
404
+ // Support for the `align` attribute as the backward compatibility while pasting from other sources.
405
+ {
406
+ view: {
407
+ name: 'table',
408
+ attributes: {
409
+ align: ALIGN_VALUES_REG_EXP
410
+ }
411
+ },
412
+ getAlign: (viewElement) => viewElement.getAttribute('align'),
413
+ getConsumables() {
414
+ return { attributes: 'align' };
415
+ }
416
+ }
417
+ ];
418
+ export const downcastTableAlignmentConfig = {
419
+ center: {
420
+ align: 'center',
421
+ style: 'margin-left: auto; margin-right: auto;',
422
+ className: 'table-style-align-center'
423
+ },
424
+ left: {
425
+ align: 'left',
426
+ style: 'float: left;',
427
+ className: 'table-style-align-left'
428
+ },
429
+ right: {
430
+ align: 'right',
431
+ style: 'float: right;',
432
+ className: 'table-style-align-right'
433
+ },
434
+ blockLeft: {
435
+ align: undefined,
436
+ style: 'margin-left: 0; margin-right: auto;',
437
+ className: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockLeft.className
438
+ },
439
+ blockRight: {
440
+ align: undefined,
441
+ style: 'margin-left: auto; margin-right: 0;',
442
+ className: DEFAULT_TABLE_ALIGNMENT_OPTIONS.blockRight.className
443
+ }
444
+ };