@ckeditor/ckeditor5-table 39.0.1 → 40.0.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 (229) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -3
  3. package/build/table.js +1 -1
  4. package/build/table.js.map +1 -0
  5. package/build/translations/hy.js +1 -0
  6. package/lang/translations/ar.po +1 -0
  7. package/lang/translations/az.po +1 -0
  8. package/lang/translations/bg.po +1 -0
  9. package/lang/translations/bn.po +1 -0
  10. package/lang/translations/ca.po +1 -0
  11. package/lang/translations/cs.po +1 -0
  12. package/lang/translations/da.po +1 -0
  13. package/lang/translations/de-ch.po +1 -0
  14. package/lang/translations/de.po +1 -0
  15. package/lang/translations/el.po +1 -0
  16. package/lang/translations/en-au.po +1 -0
  17. package/lang/translations/en-gb.po +1 -0
  18. package/lang/translations/en.po +1 -0
  19. package/lang/translations/es.po +1 -0
  20. package/lang/translations/et.po +1 -0
  21. package/lang/translations/fa.po +1 -0
  22. package/lang/translations/fi.po +1 -0
  23. package/lang/translations/fr.po +1 -0
  24. package/lang/translations/gl.po +1 -0
  25. package/lang/translations/he.po +1 -0
  26. package/lang/translations/hi.po +1 -0
  27. package/lang/translations/hr.po +1 -0
  28. package/lang/translations/hu.po +1 -0
  29. package/lang/translations/hy.po +262 -0
  30. package/lang/translations/id.po +1 -0
  31. package/lang/translations/it.po +1 -0
  32. package/lang/translations/ja.po +1 -0
  33. package/lang/translations/ko.po +1 -0
  34. package/lang/translations/ku.po +1 -0
  35. package/lang/translations/lt.po +1 -0
  36. package/lang/translations/lv.po +1 -0
  37. package/lang/translations/ms.po +1 -0
  38. package/lang/translations/nb.po +1 -0
  39. package/lang/translations/ne.po +1 -0
  40. package/lang/translations/nl.po +1 -0
  41. package/lang/translations/no.po +1 -0
  42. package/lang/translations/pl.po +1 -0
  43. package/lang/translations/pt-br.po +1 -0
  44. package/lang/translations/pt.po +1 -0
  45. package/lang/translations/ro.po +1 -0
  46. package/lang/translations/ru.po +1 -0
  47. package/lang/translations/sk.po +1 -0
  48. package/lang/translations/sl.po +1 -0
  49. package/lang/translations/sq.po +1 -0
  50. package/lang/translations/sr-latn.po +1 -0
  51. package/lang/translations/sr.po +1 -0
  52. package/lang/translations/sv.po +1 -0
  53. package/lang/translations/th.po +1 -0
  54. package/lang/translations/tk.po +1 -0
  55. package/lang/translations/tr.po +1 -0
  56. package/lang/translations/tt.po +1 -0
  57. package/lang/translations/ug.po +1 -0
  58. package/lang/translations/uk.po +1 -0
  59. package/lang/translations/ur.po +1 -0
  60. package/lang/translations/uz.po +1 -0
  61. package/lang/translations/vi.po +1 -0
  62. package/lang/translations/zh-cn.po +1 -0
  63. package/lang/translations/zh.po +1 -0
  64. package/package.json +2 -6
  65. package/src/augmentation.d.ts +76 -76
  66. package/src/augmentation.js +5 -5
  67. package/src/commands/insertcolumncommand.d.ts +55 -55
  68. package/src/commands/insertcolumncommand.js +67 -67
  69. package/src/commands/insertrowcommand.d.ts +54 -54
  70. package/src/commands/insertrowcommand.js +66 -66
  71. package/src/commands/inserttablecommand.d.ts +44 -44
  72. package/src/commands/inserttablecommand.js +69 -69
  73. package/src/commands/mergecellcommand.d.ts +68 -68
  74. package/src/commands/mergecellcommand.js +198 -198
  75. package/src/commands/mergecellscommand.d.ts +28 -28
  76. package/src/commands/mergecellscommand.js +94 -94
  77. package/src/commands/removecolumncommand.d.ts +29 -29
  78. package/src/commands/removecolumncommand.js +109 -109
  79. package/src/commands/removerowcommand.d.ts +29 -29
  80. package/src/commands/removerowcommand.js +82 -82
  81. package/src/commands/selectcolumncommand.d.ts +33 -33
  82. package/src/commands/selectcolumncommand.js +60 -60
  83. package/src/commands/selectrowcommand.d.ts +33 -33
  84. package/src/commands/selectrowcommand.js +56 -56
  85. package/src/commands/setheadercolumncommand.d.ts +50 -50
  86. package/src/commands/setheadercolumncommand.js +71 -71
  87. package/src/commands/setheaderrowcommand.d.ts +53 -53
  88. package/src/commands/setheaderrowcommand.js +79 -79
  89. package/src/commands/splitcellcommand.d.ts +43 -43
  90. package/src/commands/splitcellcommand.js +54 -54
  91. package/src/converters/downcast.d.ts +63 -63
  92. package/src/converters/downcast.js +146 -146
  93. package/src/converters/table-caption-post-fixer.d.ts +20 -20
  94. package/src/converters/table-caption-post-fixer.js +53 -53
  95. package/src/converters/table-cell-paragraph-post-fixer.d.ts +32 -32
  96. package/src/converters/table-cell-paragraph-post-fixer.js +107 -107
  97. package/src/converters/table-cell-refresh-handler.d.ts +18 -18
  98. package/src/converters/table-cell-refresh-handler.js +45 -45
  99. package/src/converters/table-headings-refresh-handler.d.ts +17 -17
  100. package/src/converters/table-headings-refresh-handler.js +49 -49
  101. package/src/converters/table-layout-post-fixer.d.ts +226 -226
  102. package/src/converters/table-layout-post-fixer.js +367 -367
  103. package/src/converters/tableproperties.d.ts +54 -54
  104. package/src/converters/tableproperties.js +159 -159
  105. package/src/converters/upcasttable.d.ts +49 -49
  106. package/src/converters/upcasttable.js +243 -243
  107. package/src/index.d.ts +60 -60
  108. package/src/index.js +30 -30
  109. package/src/plaintableoutput.d.ts +26 -26
  110. package/src/plaintableoutput.js +123 -123
  111. package/src/table.d.ts +40 -40
  112. package/src/table.js +44 -44
  113. package/src/tablecaption/tablecaptionediting.d.ts +63 -63
  114. package/src/tablecaption/tablecaptionediting.js +122 -122
  115. package/src/tablecaption/tablecaptionui.d.ts +21 -21
  116. package/src/tablecaption/tablecaptionui.js +57 -57
  117. package/src/tablecaption/toggletablecaptioncommand.d.ts +68 -68
  118. package/src/tablecaption/toggletablecaptioncommand.js +104 -104
  119. package/src/tablecaption/utils.d.ts +42 -42
  120. package/src/tablecaption/utils.js +67 -67
  121. package/src/tablecaption.d.ts +24 -24
  122. package/src/tablecaption.js +28 -28
  123. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.d.ts +32 -32
  124. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js +30 -30
  125. package/src/tablecellproperties/commands/tablecellbordercolorcommand.d.ts +37 -37
  126. package/src/tablecellproperties/commands/tablecellbordercolorcommand.js +44 -44
  127. package/src/tablecellproperties/commands/tablecellborderstylecommand.d.ts +37 -37
  128. package/src/tablecellproperties/commands/tablecellborderstylecommand.js +44 -44
  129. package/src/tablecellproperties/commands/tablecellborderwidthcommand.d.ts +51 -51
  130. package/src/tablecellproperties/commands/tablecellborderwidthcommand.js +64 -64
  131. package/src/tablecellproperties/commands/tablecellheightcommand.d.ts +46 -46
  132. package/src/tablecellproperties/commands/tablecellheightcommand.js +51 -51
  133. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.d.ts +32 -32
  134. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js +30 -30
  135. package/src/tablecellproperties/commands/tablecellpaddingcommand.d.ts +51 -51
  136. package/src/tablecellproperties/commands/tablecellpaddingcommand.js +64 -64
  137. package/src/tablecellproperties/commands/tablecellpropertycommand.d.ts +62 -62
  138. package/src/tablecellproperties/commands/tablecellpropertycommand.js +92 -92
  139. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.d.ts +40 -40
  140. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.js +38 -38
  141. package/src/tablecellproperties/tablecellpropertiesediting.d.ts +43 -43
  142. package/src/tablecellproperties/tablecellpropertiesediting.js +241 -241
  143. package/src/tablecellproperties/tablecellpropertiesui.d.ts +112 -112
  144. package/src/tablecellproperties/tablecellpropertiesui.js +330 -330
  145. package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +228 -228
  146. package/src/tablecellproperties/ui/tablecellpropertiesview.js +548 -539
  147. package/src/tablecellproperties.d.ts +30 -30
  148. package/src/tablecellproperties.js +34 -34
  149. package/src/tablecellwidth/commands/tablecellwidthcommand.d.ts +46 -46
  150. package/src/tablecellwidth/commands/tablecellwidthcommand.js +51 -51
  151. package/src/tablecellwidth/tablecellwidthediting.d.ts +29 -29
  152. package/src/tablecellwidth/tablecellwidthediting.js +45 -45
  153. package/src/tableclipboard.d.ts +65 -65
  154. package/src/tableclipboard.js +450 -450
  155. package/src/tablecolumnresize/constants.d.ts +20 -20
  156. package/src/tablecolumnresize/constants.js +20 -20
  157. package/src/tablecolumnresize/converters.d.ts +18 -18
  158. package/src/tablecolumnresize/converters.js +46 -45
  159. package/src/tablecolumnresize/tablecolumnresizeediting.d.ts +139 -139
  160. package/src/tablecolumnresize/tablecolumnresizeediting.js +583 -571
  161. package/src/tablecolumnresize/tablewidthscommand.d.ts +38 -38
  162. package/src/tablecolumnresize/tablewidthscommand.js +61 -61
  163. package/src/tablecolumnresize/utils.d.ts +148 -141
  164. package/src/tablecolumnresize/utils.js +358 -330
  165. package/src/tablecolumnresize.d.ts +26 -26
  166. package/src/tablecolumnresize.js +30 -30
  167. package/src/tableconfig.d.ts +343 -343
  168. package/src/tableconfig.js +5 -5
  169. package/src/tableediting.d.ts +98 -98
  170. package/src/tableediting.js +191 -191
  171. package/src/tablekeyboard.d.ts +68 -68
  172. package/src/tablekeyboard.js +279 -279
  173. package/src/tablemouse/mouseeventsobserver.d.ts +62 -62
  174. package/src/tablemouse/mouseeventsobserver.js +35 -35
  175. package/src/tablemouse.d.ts +48 -48
  176. package/src/tablemouse.js +172 -172
  177. package/src/tableproperties/commands/tablealignmentcommand.d.ts +32 -32
  178. package/src/tableproperties/commands/tablealignmentcommand.js +30 -30
  179. package/src/tableproperties/commands/tablebackgroundcolorcommand.d.ts +32 -32
  180. package/src/tableproperties/commands/tablebackgroundcolorcommand.js +30 -30
  181. package/src/tableproperties/commands/tablebordercolorcommand.d.ts +37 -37
  182. package/src/tableproperties/commands/tablebordercolorcommand.js +44 -44
  183. package/src/tableproperties/commands/tableborderstylecommand.d.ts +37 -37
  184. package/src/tableproperties/commands/tableborderstylecommand.js +44 -44
  185. package/src/tableproperties/commands/tableborderwidthcommand.d.ts +51 -51
  186. package/src/tableproperties/commands/tableborderwidthcommand.js +64 -64
  187. package/src/tableproperties/commands/tableheightcommand.d.ts +46 -46
  188. package/src/tableproperties/commands/tableheightcommand.js +54 -54
  189. package/src/tableproperties/commands/tablepropertycommand.d.ts +61 -61
  190. package/src/tableproperties/commands/tablepropertycommand.js +80 -80
  191. package/src/tableproperties/commands/tablewidthcommand.d.ts +46 -46
  192. package/src/tableproperties/commands/tablewidthcommand.js +54 -54
  193. package/src/tableproperties/tablepropertiesediting.d.ts +40 -40
  194. package/src/tableproperties/tablepropertiesediting.js +206 -206
  195. package/src/tableproperties/tablepropertiesui.d.ts +114 -114
  196. package/src/tableproperties/tablepropertiesui.js +321 -321
  197. package/src/tableproperties/ui/tablepropertiesview.d.ts +207 -207
  198. package/src/tableproperties/ui/tablepropertiesview.js +466 -457
  199. package/src/tableproperties.d.ts +30 -30
  200. package/src/tableproperties.js +34 -34
  201. package/src/tableselection.d.ts +107 -107
  202. package/src/tableselection.js +297 -297
  203. package/src/tabletoolbar.d.ts +32 -32
  204. package/src/tabletoolbar.js +57 -57
  205. package/src/tableui.d.ts +53 -53
  206. package/src/tableui.js +309 -309
  207. package/src/tableutils.d.ts +448 -448
  208. package/src/tableutils.js +1055 -1041
  209. package/src/tablewalker.d.ts +362 -323
  210. package/src/tablewalker.js +393 -333
  211. package/src/ui/colorinputview.d.ts +140 -140
  212. package/src/ui/colorinputview.js +271 -265
  213. package/src/ui/formrowview.d.ts +61 -61
  214. package/src/ui/formrowview.js +57 -57
  215. package/src/ui/inserttableview.d.ts +77 -77
  216. package/src/ui/inserttableview.js +169 -169
  217. package/src/utils/common.d.ts +42 -42
  218. package/src/utils/common.js +57 -57
  219. package/src/utils/structure.d.ts +245 -245
  220. package/src/utils/structure.js +426 -426
  221. package/src/utils/table-properties.d.ts +67 -67
  222. package/src/utils/table-properties.js +86 -86
  223. package/src/utils/ui/contextualballoon.d.ts +34 -34
  224. package/src/utils/ui/contextualballoon.js +106 -106
  225. package/src/utils/ui/table-properties.d.ts +195 -195
  226. package/src/utils/ui/table-properties.js +362 -362
  227. package/src/utils/ui/widget.d.ts +16 -16
  228. package/src/utils/ui/widget.js +38 -38
  229. package/theme/tablecolumnresize.css +8 -6
@@ -1,330 +1,330 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module table/tablecellproperties/tablecellpropertiesui
7
- */
8
- import { Plugin } from 'ckeditor5/src/core';
9
- import { ButtonView, clickOutsideHandler, ContextualBalloon, getLocalizedColorOptions, normalizeColorOptions } from 'ckeditor5/src/ui';
10
- import TableCellPropertiesView from './ui/tablecellpropertiesview';
11
- import { colorFieldValidator, getLocalizedColorErrorText, getLocalizedLengthErrorText, defaultColors, lengthFieldValidator, lineWidthFieldValidator } from '../utils/ui/table-properties';
12
- import { debounce } from 'lodash-es';
13
- import { getTableWidgetAncestor } from '../utils/ui/widget';
14
- import { getBalloonCellPositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';
15
- import tableCellProperties from './../../theme/icons/table-cell-properties.svg';
16
- import { getNormalizedDefaultProperties } from '../utils/table-properties';
17
- const ERROR_TEXT_TIMEOUT = 500;
18
- // Map of view properties and related commands.
19
- const propertyToCommandMap = {
20
- borderStyle: 'tableCellBorderStyle',
21
- borderColor: 'tableCellBorderColor',
22
- borderWidth: 'tableCellBorderWidth',
23
- height: 'tableCellHeight',
24
- width: 'tableCellWidth',
25
- padding: 'tableCellPadding',
26
- backgroundColor: 'tableCellBackgroundColor',
27
- horizontalAlignment: 'tableCellHorizontalAlignment',
28
- verticalAlignment: 'tableCellVerticalAlignment'
29
- };
30
- /**
31
- * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
32
- * that opens a form allowing to specify the visual styling of a table cell.
33
- *
34
- * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
35
- */
36
- export default class TableCellPropertiesUI extends Plugin {
37
- /**
38
- * @inheritDoc
39
- */
40
- static get requires() {
41
- return [ContextualBalloon];
42
- }
43
- /**
44
- * @inheritDoc
45
- */
46
- static get pluginName() {
47
- return 'TableCellPropertiesUI';
48
- }
49
- /**
50
- * @inheritDoc
51
- */
52
- constructor(editor) {
53
- super(editor);
54
- editor.config.define('table.tableCellProperties', {
55
- borderColors: defaultColors,
56
- backgroundColors: defaultColors
57
- });
58
- }
59
- /**
60
- * @inheritDoc
61
- */
62
- init() {
63
- const editor = this.editor;
64
- const t = editor.t;
65
- this._defaultTableCellProperties = getNormalizedDefaultProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
66
- includeVerticalAlignmentProperty: true,
67
- includeHorizontalAlignmentProperty: true,
68
- includePaddingProperty: true,
69
- isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
70
- });
71
- this._balloon = editor.plugins.get(ContextualBalloon);
72
- this.view = null;
73
- this._isReady = false;
74
- editor.ui.componentFactory.add('tableCellProperties', locale => {
75
- const view = new ButtonView(locale);
76
- view.set({
77
- label: t('Cell properties'),
78
- icon: tableCellProperties,
79
- tooltip: true
80
- });
81
- this.listenTo(view, 'execute', () => this._showView());
82
- const commands = Object.values(propertyToCommandMap)
83
- .map(commandName => editor.commands.get(commandName));
84
- view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => (areEnabled.some(isCommandEnabled => isCommandEnabled)));
85
- return view;
86
- });
87
- }
88
- /**
89
- * @inheritDoc
90
- */
91
- destroy() {
92
- super.destroy();
93
- // Destroy created UI components as they are not automatically destroyed.
94
- // See https://github.com/ckeditor/ckeditor5/issues/1341.
95
- if (this.view) {
96
- this.view.destroy();
97
- }
98
- }
99
- /**
100
- * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
101
- *
102
- * @returns The cell properties form view instance.
103
- */
104
- _createPropertiesView() {
105
- const editor = this.editor;
106
- const config = editor.config.get('table.tableCellProperties');
107
- const borderColorsConfig = normalizeColorOptions(config.borderColors);
108
- const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
109
- const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
110
- const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
111
- const hasColorPicker = config.colorPicker !== false;
112
- const view = new TableCellPropertiesView(editor.locale, {
113
- borderColors: localizedBorderColors,
114
- backgroundColors: localizedBackgroundColors,
115
- defaultTableCellProperties: this._defaultTableCellProperties,
116
- colorPickerConfig: hasColorPicker ? (config.colorPicker || {}) : false
117
- });
118
- const t = editor.t;
119
- // Render the view so its #element is available for the clickOutsideHandler.
120
- view.render();
121
- this.listenTo(view, 'submit', () => {
122
- this._hideView();
123
- });
124
- this.listenTo(view, 'cancel', () => {
125
- // https://github.com/ckeditor/ckeditor5/issues/6180
126
- if (this._undoStepBatch.operations.length) {
127
- editor.execute('undo', this._undoStepBatch);
128
- }
129
- this._hideView();
130
- });
131
- // Close the balloon on Esc key press.
132
- view.keystrokes.set('Esc', (data, cancel) => {
133
- this._hideView();
134
- cancel();
135
- });
136
- // Close on click outside of balloon panel element.
137
- clickOutsideHandler({
138
- emitter: view,
139
- activator: () => this._isViewInBalloon,
140
- contextElements: [this._balloon.view.element],
141
- callback: () => this._hideView()
142
- });
143
- const colorErrorText = getLocalizedColorErrorText(t);
144
- const lengthErrorText = getLocalizedLengthErrorText(t);
145
- // Create the "UI -> editor data" binding.
146
- // These listeners update the editor data (via table commands) when any observable
147
- // property of the view has changed. They also validate the value and display errors in the UI
148
- // when necessary. This makes the view live, which means the changes are
149
- // visible in the editing as soon as the user types or changes fields' values.
150
- view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
151
- view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
152
- viewField: view.borderColorInput,
153
- commandName: 'tableCellBorderColor',
154
- errorText: colorErrorText,
155
- validator: colorFieldValidator
156
- }));
157
- view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
158
- viewField: view.borderWidthInput,
159
- commandName: 'tableCellBorderWidth',
160
- errorText: lengthErrorText,
161
- validator: lineWidthFieldValidator
162
- }));
163
- view.on('change:padding', this._getValidatedPropertyChangeCallback({
164
- viewField: view.paddingInput,
165
- commandName: 'tableCellPadding',
166
- errorText: lengthErrorText,
167
- validator: lengthFieldValidator
168
- }));
169
- view.on('change:width', this._getValidatedPropertyChangeCallback({
170
- viewField: view.widthInput,
171
- commandName: 'tableCellWidth',
172
- errorText: lengthErrorText,
173
- validator: lengthFieldValidator
174
- }));
175
- view.on('change:height', this._getValidatedPropertyChangeCallback({
176
- viewField: view.heightInput,
177
- commandName: 'tableCellHeight',
178
- errorText: lengthErrorText,
179
- validator: lengthFieldValidator
180
- }));
181
- view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
182
- viewField: view.backgroundInput,
183
- commandName: 'tableCellBackgroundColor',
184
- errorText: colorErrorText,
185
- validator: colorFieldValidator
186
- }));
187
- view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
188
- view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
189
- return view;
190
- }
191
- /**
192
- * In this method the "editor data -> UI" binding is happening.
193
- *
194
- * When executed, this method obtains selected cell property values from various table commands
195
- * and passes them to the {@link #view}.
196
- *
197
- * This way, the UI stays up–to–date with the editor data.
198
- */
199
- _fillViewFormFromCommandValues() {
200
- const commands = this.editor.commands;
201
- const borderStyleCommand = commands.get('tableCellBorderStyle');
202
- Object.entries(propertyToCommandMap)
203
- .map(([property, commandName]) => {
204
- const defaultValue = this._defaultTableCellProperties[property] || '';
205
- return [
206
- property,
207
- commands.get(commandName).value || defaultValue
208
- ];
209
- })
210
- .forEach(([property, value]) => {
211
- // Do not set the `border-color` and `border-width` fields if `border-style:none`.
212
- if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
213
- return;
214
- }
215
- this.view.set(property, value);
216
- });
217
- this._isReady = true;
218
- }
219
- /**
220
- * Shows the {@link #view} in the {@link #_balloon}.
221
- *
222
- * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
223
- * all changes made to the document when the view is visible, allowing a single undo step
224
- * for all of them.
225
- */
226
- _showView() {
227
- const editor = this.editor;
228
- if (!this.view) {
229
- this.view = this._createPropertiesView();
230
- }
231
- this.listenTo(editor.ui, 'update', () => {
232
- this._updateView();
233
- });
234
- // Update the view with the model values.
235
- this._fillViewFormFromCommandValues();
236
- this._balloon.add({
237
- view: this.view,
238
- position: getBalloonCellPositionData(editor)
239
- });
240
- // Create a new batch. Clicking "Cancel" will undo this batch.
241
- this._undoStepBatch = editor.model.createBatch();
242
- // Basic a11y.
243
- this.view.focus();
244
- }
245
- /**
246
- * Removes the {@link #view} from the {@link #_balloon}.
247
- */
248
- _hideView() {
249
- const editor = this.editor;
250
- this.stopListening(editor.ui, 'update');
251
- this._isReady = false;
252
- // Blur any input element before removing it from DOM to prevent issues in some browsers.
253
- // See https://github.com/ckeditor/ckeditor5/issues/1501.
254
- this.view.saveButtonView.focus();
255
- this._balloon.remove(this.view);
256
- // Make sure the focus is not lost in the process by putting it directly
257
- // into the editing view.
258
- this.editor.editing.view.focus();
259
- }
260
- /**
261
- * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
262
- */
263
- _updateView() {
264
- const editor = this.editor;
265
- const viewDocument = editor.editing.view.document;
266
- if (!getTableWidgetAncestor(viewDocument.selection)) {
267
- this._hideView();
268
- }
269
- else if (this._isViewVisible) {
270
- repositionContextualBalloon(editor, 'cell');
271
- }
272
- }
273
- /**
274
- * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
275
- */
276
- get _isViewVisible() {
277
- return !!this.view && this._balloon.visibleView === this.view;
278
- }
279
- /**
280
- * Returns `true` when the {@link #view} is in the {@link #_balloon}.
281
- */
282
- get _isViewInBalloon() {
283
- return !!this.view && this._balloon.hasView(this.view);
284
- }
285
- /**
286
- * Creates a callback that when executed upon the {@link #view view's} property change
287
- * executes a related editor command with the new property value.
288
- *
289
- * @param defaultValue The default value of the command.
290
- */
291
- _getPropertyChangeCallback(commandName) {
292
- return (evt, propertyName, newValue) => {
293
- if (!this._isReady) {
294
- return;
295
- }
296
- this.editor.execute(commandName, {
297
- value: newValue,
298
- batch: this._undoStepBatch
299
- });
300
- };
301
- }
302
- /**
303
- * Creates a callback that when executed upon the {@link #view view's} property change:
304
- * * Executes a related editor command with the new property value if the value is valid,
305
- * * Or sets the error text next to the invalid field, if the value did not pass the validation.
306
- */
307
- _getValidatedPropertyChangeCallback(options) {
308
- const { commandName, viewField, validator, errorText } = options;
309
- const setErrorTextDebounced = debounce(() => {
310
- viewField.errorText = errorText;
311
- }, ERROR_TEXT_TIMEOUT);
312
- return (evt, propertyName, newValue) => {
313
- setErrorTextDebounced.cancel();
314
- // Do not execute the command on initial call (opening the table properties view).
315
- if (!this._isReady) {
316
- return;
317
- }
318
- if (validator(newValue)) {
319
- this.editor.execute(commandName, {
320
- value: newValue,
321
- batch: this._undoStepBatch
322
- });
323
- viewField.errorText = null;
324
- }
325
- else {
326
- setErrorTextDebounced();
327
- }
328
- };
329
- }
330
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module table/tablecellproperties/tablecellpropertiesui
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core';
9
+ import { ButtonView, clickOutsideHandler, ContextualBalloon, getLocalizedColorOptions, normalizeColorOptions } from 'ckeditor5/src/ui';
10
+ import TableCellPropertiesView from './ui/tablecellpropertiesview';
11
+ import { colorFieldValidator, getLocalizedColorErrorText, getLocalizedLengthErrorText, defaultColors, lengthFieldValidator, lineWidthFieldValidator } from '../utils/ui/table-properties';
12
+ import { debounce } from 'lodash-es';
13
+ import { getTableWidgetAncestor } from '../utils/ui/widget';
14
+ import { getBalloonCellPositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';
15
+ import tableCellProperties from './../../theme/icons/table-cell-properties.svg';
16
+ import { getNormalizedDefaultProperties } from '../utils/table-properties';
17
+ const ERROR_TEXT_TIMEOUT = 500;
18
+ // Map of view properties and related commands.
19
+ const propertyToCommandMap = {
20
+ borderStyle: 'tableCellBorderStyle',
21
+ borderColor: 'tableCellBorderColor',
22
+ borderWidth: 'tableCellBorderWidth',
23
+ height: 'tableCellHeight',
24
+ width: 'tableCellWidth',
25
+ padding: 'tableCellPadding',
26
+ backgroundColor: 'tableCellBackgroundColor',
27
+ horizontalAlignment: 'tableCellHorizontalAlignment',
28
+ verticalAlignment: 'tableCellVerticalAlignment'
29
+ };
30
+ /**
31
+ * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
32
+ * that opens a form allowing to specify the visual styling of a table cell.
33
+ *
34
+ * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
35
+ */
36
+ export default class TableCellPropertiesUI extends Plugin {
37
+ /**
38
+ * @inheritDoc
39
+ */
40
+ static get requires() {
41
+ return [ContextualBalloon];
42
+ }
43
+ /**
44
+ * @inheritDoc
45
+ */
46
+ static get pluginName() {
47
+ return 'TableCellPropertiesUI';
48
+ }
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ constructor(editor) {
53
+ super(editor);
54
+ editor.config.define('table.tableCellProperties', {
55
+ borderColors: defaultColors,
56
+ backgroundColors: defaultColors
57
+ });
58
+ }
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ init() {
63
+ const editor = this.editor;
64
+ const t = editor.t;
65
+ this._defaultTableCellProperties = getNormalizedDefaultProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
66
+ includeVerticalAlignmentProperty: true,
67
+ includeHorizontalAlignmentProperty: true,
68
+ includePaddingProperty: true,
69
+ isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
70
+ });
71
+ this._balloon = editor.plugins.get(ContextualBalloon);
72
+ this.view = null;
73
+ this._isReady = false;
74
+ editor.ui.componentFactory.add('tableCellProperties', locale => {
75
+ const view = new ButtonView(locale);
76
+ view.set({
77
+ label: t('Cell properties'),
78
+ icon: tableCellProperties,
79
+ tooltip: true
80
+ });
81
+ this.listenTo(view, 'execute', () => this._showView());
82
+ const commands = Object.values(propertyToCommandMap)
83
+ .map(commandName => editor.commands.get(commandName));
84
+ view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => (areEnabled.some(isCommandEnabled => isCommandEnabled)));
85
+ return view;
86
+ });
87
+ }
88
+ /**
89
+ * @inheritDoc
90
+ */
91
+ destroy() {
92
+ super.destroy();
93
+ // Destroy created UI components as they are not automatically destroyed.
94
+ // See https://github.com/ckeditor/ckeditor5/issues/1341.
95
+ if (this.view) {
96
+ this.view.destroy();
97
+ }
98
+ }
99
+ /**
100
+ * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
101
+ *
102
+ * @returns The cell properties form view instance.
103
+ */
104
+ _createPropertiesView() {
105
+ const editor = this.editor;
106
+ const config = editor.config.get('table.tableCellProperties');
107
+ const borderColorsConfig = normalizeColorOptions(config.borderColors);
108
+ const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
109
+ const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
110
+ const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
111
+ const hasColorPicker = config.colorPicker !== false;
112
+ const view = new TableCellPropertiesView(editor.locale, {
113
+ borderColors: localizedBorderColors,
114
+ backgroundColors: localizedBackgroundColors,
115
+ defaultTableCellProperties: this._defaultTableCellProperties,
116
+ colorPickerConfig: hasColorPicker ? (config.colorPicker || {}) : false
117
+ });
118
+ const t = editor.t;
119
+ // Render the view so its #element is available for the clickOutsideHandler.
120
+ view.render();
121
+ this.listenTo(view, 'submit', () => {
122
+ this._hideView();
123
+ });
124
+ this.listenTo(view, 'cancel', () => {
125
+ // https://github.com/ckeditor/ckeditor5/issues/6180
126
+ if (this._undoStepBatch.operations.length) {
127
+ editor.execute('undo', this._undoStepBatch);
128
+ }
129
+ this._hideView();
130
+ });
131
+ // Close the balloon on Esc key press.
132
+ view.keystrokes.set('Esc', (data, cancel) => {
133
+ this._hideView();
134
+ cancel();
135
+ });
136
+ // Close on click outside of balloon panel element.
137
+ clickOutsideHandler({
138
+ emitter: view,
139
+ activator: () => this._isViewInBalloon,
140
+ contextElements: [this._balloon.view.element],
141
+ callback: () => this._hideView()
142
+ });
143
+ const colorErrorText = getLocalizedColorErrorText(t);
144
+ const lengthErrorText = getLocalizedLengthErrorText(t);
145
+ // Create the "UI -> editor data" binding.
146
+ // These listeners update the editor data (via table commands) when any observable
147
+ // property of the view has changed. They also validate the value and display errors in the UI
148
+ // when necessary. This makes the view live, which means the changes are
149
+ // visible in the editing as soon as the user types or changes fields' values.
150
+ view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
151
+ view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
152
+ viewField: view.borderColorInput,
153
+ commandName: 'tableCellBorderColor',
154
+ errorText: colorErrorText,
155
+ validator: colorFieldValidator
156
+ }));
157
+ view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
158
+ viewField: view.borderWidthInput,
159
+ commandName: 'tableCellBorderWidth',
160
+ errorText: lengthErrorText,
161
+ validator: lineWidthFieldValidator
162
+ }));
163
+ view.on('change:padding', this._getValidatedPropertyChangeCallback({
164
+ viewField: view.paddingInput,
165
+ commandName: 'tableCellPadding',
166
+ errorText: lengthErrorText,
167
+ validator: lengthFieldValidator
168
+ }));
169
+ view.on('change:width', this._getValidatedPropertyChangeCallback({
170
+ viewField: view.widthInput,
171
+ commandName: 'tableCellWidth',
172
+ errorText: lengthErrorText,
173
+ validator: lengthFieldValidator
174
+ }));
175
+ view.on('change:height', this._getValidatedPropertyChangeCallback({
176
+ viewField: view.heightInput,
177
+ commandName: 'tableCellHeight',
178
+ errorText: lengthErrorText,
179
+ validator: lengthFieldValidator
180
+ }));
181
+ view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
182
+ viewField: view.backgroundInput,
183
+ commandName: 'tableCellBackgroundColor',
184
+ errorText: colorErrorText,
185
+ validator: colorFieldValidator
186
+ }));
187
+ view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
188
+ view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
189
+ return view;
190
+ }
191
+ /**
192
+ * In this method the "editor data -> UI" binding is happening.
193
+ *
194
+ * When executed, this method obtains selected cell property values from various table commands
195
+ * and passes them to the {@link #view}.
196
+ *
197
+ * This way, the UI stays up–to–date with the editor data.
198
+ */
199
+ _fillViewFormFromCommandValues() {
200
+ const commands = this.editor.commands;
201
+ const borderStyleCommand = commands.get('tableCellBorderStyle');
202
+ Object.entries(propertyToCommandMap)
203
+ .map(([property, commandName]) => {
204
+ const defaultValue = this._defaultTableCellProperties[property] || '';
205
+ return [
206
+ property,
207
+ commands.get(commandName).value || defaultValue
208
+ ];
209
+ })
210
+ .forEach(([property, value]) => {
211
+ // Do not set the `border-color` and `border-width` fields if `border-style:none`.
212
+ if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
213
+ return;
214
+ }
215
+ this.view.set(property, value);
216
+ });
217
+ this._isReady = true;
218
+ }
219
+ /**
220
+ * Shows the {@link #view} in the {@link #_balloon}.
221
+ *
222
+ * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
223
+ * all changes made to the document when the view is visible, allowing a single undo step
224
+ * for all of them.
225
+ */
226
+ _showView() {
227
+ const editor = this.editor;
228
+ if (!this.view) {
229
+ this.view = this._createPropertiesView();
230
+ }
231
+ this.listenTo(editor.ui, 'update', () => {
232
+ this._updateView();
233
+ });
234
+ // Update the view with the model values.
235
+ this._fillViewFormFromCommandValues();
236
+ this._balloon.add({
237
+ view: this.view,
238
+ position: getBalloonCellPositionData(editor)
239
+ });
240
+ // Create a new batch. Clicking "Cancel" will undo this batch.
241
+ this._undoStepBatch = editor.model.createBatch();
242
+ // Basic a11y.
243
+ this.view.focus();
244
+ }
245
+ /**
246
+ * Removes the {@link #view} from the {@link #_balloon}.
247
+ */
248
+ _hideView() {
249
+ const editor = this.editor;
250
+ this.stopListening(editor.ui, 'update');
251
+ this._isReady = false;
252
+ // Blur any input element before removing it from DOM to prevent issues in some browsers.
253
+ // See https://github.com/ckeditor/ckeditor5/issues/1501.
254
+ this.view.saveButtonView.focus();
255
+ this._balloon.remove(this.view);
256
+ // Make sure the focus is not lost in the process by putting it directly
257
+ // into the editing view.
258
+ this.editor.editing.view.focus();
259
+ }
260
+ /**
261
+ * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
262
+ */
263
+ _updateView() {
264
+ const editor = this.editor;
265
+ const viewDocument = editor.editing.view.document;
266
+ if (!getTableWidgetAncestor(viewDocument.selection)) {
267
+ this._hideView();
268
+ }
269
+ else if (this._isViewVisible) {
270
+ repositionContextualBalloon(editor, 'cell');
271
+ }
272
+ }
273
+ /**
274
+ * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
275
+ */
276
+ get _isViewVisible() {
277
+ return !!this.view && this._balloon.visibleView === this.view;
278
+ }
279
+ /**
280
+ * Returns `true` when the {@link #view} is in the {@link #_balloon}.
281
+ */
282
+ get _isViewInBalloon() {
283
+ return !!this.view && this._balloon.hasView(this.view);
284
+ }
285
+ /**
286
+ * Creates a callback that when executed upon the {@link #view view's} property change
287
+ * executes a related editor command with the new property value.
288
+ *
289
+ * @param defaultValue The default value of the command.
290
+ */
291
+ _getPropertyChangeCallback(commandName) {
292
+ return (evt, propertyName, newValue) => {
293
+ if (!this._isReady) {
294
+ return;
295
+ }
296
+ this.editor.execute(commandName, {
297
+ value: newValue,
298
+ batch: this._undoStepBatch
299
+ });
300
+ };
301
+ }
302
+ /**
303
+ * Creates a callback that when executed upon the {@link #view view's} property change:
304
+ * * Executes a related editor command with the new property value if the value is valid,
305
+ * * Or sets the error text next to the invalid field, if the value did not pass the validation.
306
+ */
307
+ _getValidatedPropertyChangeCallback(options) {
308
+ const { commandName, viewField, validator, errorText } = options;
309
+ const setErrorTextDebounced = debounce(() => {
310
+ viewField.errorText = errorText;
311
+ }, ERROR_TEXT_TIMEOUT);
312
+ return (evt, propertyName, newValue) => {
313
+ setErrorTextDebounced.cancel();
314
+ // Do not execute the command on initial call (opening the table properties view).
315
+ if (!this._isReady) {
316
+ return;
317
+ }
318
+ if (validator(newValue)) {
319
+ this.editor.execute(commandName, {
320
+ value: newValue,
321
+ batch: this._undoStepBatch
322
+ });
323
+ viewField.errorText = null;
324
+ }
325
+ else {
326
+ setErrorTextDebounced();
327
+ }
328
+ };
329
+ }
330
+ }