@ckeditor/ckeditor5-table 36.0.1 → 37.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/build/table.js +1 -1
  2. package/package.json +34 -29
  3. package/src/commands/insertcolumncommand.d.ts +61 -0
  4. package/src/commands/insertcolumncommand.js +45 -60
  5. package/src/commands/insertrowcommand.d.ts +60 -0
  6. package/src/commands/insertrowcommand.js +44 -59
  7. package/src/commands/inserttablecommand.d.ts +50 -0
  8. package/src/commands/inserttablecommand.js +51 -68
  9. package/src/commands/mergecellcommand.d.ts +76 -0
  10. package/src/commands/mergecellcommand.js +169 -244
  11. package/src/commands/mergecellscommand.d.ts +33 -0
  12. package/src/commands/mergecellscommand.js +72 -101
  13. package/src/commands/removecolumncommand.d.ts +34 -0
  14. package/src/commands/removecolumncommand.js +88 -102
  15. package/src/commands/removerowcommand.d.ts +34 -0
  16. package/src/commands/removerowcommand.js +63 -80
  17. package/src/commands/selectcolumncommand.d.ts +38 -0
  18. package/src/commands/selectcolumncommand.js +41 -54
  19. package/src/commands/selectrowcommand.d.ts +38 -0
  20. package/src/commands/selectrowcommand.js +38 -48
  21. package/src/commands/setheadercolumncommand.d.ts +55 -0
  22. package/src/commands/setheadercolumncommand.js +48 -73
  23. package/src/commands/setheaderrowcommand.d.ts +58 -0
  24. package/src/commands/setheaderrowcommand.js +56 -85
  25. package/src/commands/splitcellcommand.d.ts +49 -0
  26. package/src/commands/splitcellcommand.js +35 -49
  27. package/src/converters/downcast.d.ts +63 -0
  28. package/src/converters/downcast.js +98 -130
  29. package/src/converters/table-caption-post-fixer.d.ts +20 -0
  30. package/src/converters/table-caption-post-fixer.js +36 -52
  31. package/src/converters/table-cell-paragraph-post-fixer.d.ts +32 -0
  32. package/src/converters/table-cell-paragraph-post-fixer.js +88 -119
  33. package/src/converters/table-cell-refresh-handler.d.ts +18 -0
  34. package/src/converters/table-cell-refresh-handler.js +29 -48
  35. package/src/converters/table-headings-refresh-handler.d.ts +17 -0
  36. package/src/converters/table-headings-refresh-handler.js +35 -54
  37. package/src/converters/table-layout-post-fixer.d.ts +226 -0
  38. package/src/converters/table-layout-post-fixer.js +276 -313
  39. package/src/converters/tableproperties.d.ts +54 -0
  40. package/src/converters/tableproperties.js +136 -168
  41. package/src/converters/upcasttable.d.ts +49 -0
  42. package/src/converters/upcasttable.js +196 -251
  43. package/src/index.d.ts +29 -0
  44. package/src/index.js +0 -2
  45. package/src/plaintableoutput.d.ts +30 -0
  46. package/src/plaintableoutput.js +107 -135
  47. package/src/table.d.ts +38 -0
  48. package/src/table.js +12 -88
  49. package/src/tablecaption/tablecaptionediting.d.ts +68 -0
  50. package/src/tablecaption/tablecaptionediting.js +104 -135
  51. package/src/tablecaption/tablecaptionui.d.ts +26 -0
  52. package/src/tablecaption/tablecaptionui.js +42 -58
  53. package/src/tablecaption/toggletablecaptioncommand.d.ts +73 -0
  54. package/src/tablecaption/toggletablecaptioncommand.js +77 -92
  55. package/src/tablecaption/utils.d.ts +42 -0
  56. package/src/tablecaption/utils.js +35 -61
  57. package/src/tablecaption.d.ts +27 -0
  58. package/src/tablecaption.js +12 -19
  59. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.d.ts +37 -0
  60. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js +14 -20
  61. package/src/tablecellproperties/commands/tablecellbordercolorcommand.d.ts +42 -0
  62. package/src/tablecellproperties/commands/tablecellbordercolorcommand.js +27 -37
  63. package/src/tablecellproperties/commands/tablecellborderstylecommand.d.ts +42 -0
  64. package/src/tablecellproperties/commands/tablecellborderstylecommand.js +27 -37
  65. package/src/tablecellproperties/commands/tablecellborderwidthcommand.d.ts +56 -0
  66. package/src/tablecellproperties/commands/tablecellborderwidthcommand.js +42 -53
  67. package/src/tablecellproperties/commands/tablecellheightcommand.d.ts +51 -0
  68. package/src/tablecellproperties/commands/tablecellheightcommand.js +29 -36
  69. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.d.ts +37 -0
  70. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js +14 -20
  71. package/src/tablecellproperties/commands/tablecellpaddingcommand.d.ts +56 -0
  72. package/src/tablecellproperties/commands/tablecellpaddingcommand.js +42 -53
  73. package/src/tablecellproperties/commands/tablecellpropertycommand.d.ts +62 -0
  74. package/src/tablecellproperties/commands/tablecellpropertycommand.js +77 -122
  75. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.d.ts +45 -0
  76. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.js +14 -20
  77. package/src/tablecellproperties/tablecellpropertiesediting.d.ts +47 -0
  78. package/src/tablecellproperties/tablecellpropertiesediting.js +194 -236
  79. package/src/tablecellproperties/tablecellpropertiesui.d.ts +117 -0
  80. package/src/tablecellproperties/tablecellpropertiesui.js +303 -456
  81. package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +227 -0
  82. package/src/tablecellproperties/ui/tablecellpropertiesview.js +509 -844
  83. package/src/tablecellproperties.d.ts +33 -0
  84. package/src/tablecellproperties.js +12 -98
  85. package/src/tablecellwidth/commands/tablecellwidthcommand.d.ts +51 -0
  86. package/src/tablecellwidth/commands/tablecellwidthcommand.js +29 -35
  87. package/src/tablecellwidth/tablecellwidthediting.d.ts +34 -0
  88. package/src/tablecellwidth/tablecellwidthediting.js +26 -38
  89. package/src/tableclipboard.d.ts +68 -0
  90. package/src/tableclipboard.js +429 -568
  91. package/src/tablecolumnresize/constants.d.ts +20 -0
  92. package/src/tablecolumnresize/constants.js +0 -10
  93. package/src/tablecolumnresize/converters.d.ts +18 -0
  94. package/src/tablecolumnresize/converters.js +35 -119
  95. package/src/tablecolumnresize/tablecolumnresizeediting.d.ts +142 -0
  96. package/src/tablecolumnresize/tablecolumnresizeediting.js +545 -711
  97. package/src/tablecolumnresize/tablewidthscommand.d.ts +38 -0
  98. package/src/tablecolumnresize/tablewidthscommand.js +61 -0
  99. package/src/tablecolumnresize/utils.d.ts +141 -0
  100. package/src/tablecolumnresize/utils.js +256 -233
  101. package/src/tablecolumnresize.d.ts +29 -0
  102. package/src/tablecolumnresize.js +12 -19
  103. package/src/tableconfig.d.ts +341 -0
  104. package/src/tableconfig.js +5 -0
  105. package/src/tableediting.d.ts +102 -0
  106. package/src/tableediting.js +157 -176
  107. package/src/tablekeyboard.d.ts +68 -0
  108. package/src/tablekeyboard.js +261 -344
  109. package/src/tablemouse/mouseeventsobserver.d.ts +62 -0
  110. package/src/tablemouse/mouseeventsobserver.js +12 -49
  111. package/src/tablemouse.d.ts +51 -0
  112. package/src/tablemouse.js +154 -202
  113. package/src/tableproperties/commands/tablealignmentcommand.d.ts +37 -0
  114. package/src/tableproperties/commands/tablealignmentcommand.js +14 -20
  115. package/src/tableproperties/commands/tablebackgroundcolorcommand.d.ts +37 -0
  116. package/src/tableproperties/commands/tablebackgroundcolorcommand.js +14 -20
  117. package/src/tableproperties/commands/tablebordercolorcommand.d.ts +42 -0
  118. package/src/tableproperties/commands/tablebordercolorcommand.js +27 -37
  119. package/src/tableproperties/commands/tableborderstylecommand.d.ts +42 -0
  120. package/src/tableproperties/commands/tableborderstylecommand.js +27 -37
  121. package/src/tableproperties/commands/tableborderwidthcommand.d.ts +56 -0
  122. package/src/tableproperties/commands/tableborderwidthcommand.js +42 -53
  123. package/src/tableproperties/commands/tableheightcommand.d.ts +51 -0
  124. package/src/tableproperties/commands/tableheightcommand.js +29 -33
  125. package/src/tableproperties/commands/tablepropertycommand.d.ts +61 -0
  126. package/src/tableproperties/commands/tablepropertycommand.js +68 -112
  127. package/src/tableproperties/commands/tablewidthcommand.d.ts +51 -0
  128. package/src/tableproperties/commands/tablewidthcommand.js +29 -33
  129. package/src/tableproperties/tablepropertiesediting.d.ts +45 -0
  130. package/src/tableproperties/tablepropertiesediting.js +164 -210
  131. package/src/tableproperties/tablepropertiesui.d.ts +119 -0
  132. package/src/tableproperties/tablepropertiesui.js +294 -439
  133. package/src/tableproperties/ui/tablepropertiesview.d.ts +203 -0
  134. package/src/tableproperties/ui/tablepropertiesview.js +427 -718
  135. package/src/tableproperties.d.ts +33 -0
  136. package/src/tableproperties.js +12 -95
  137. package/src/tableselection.d.ts +111 -0
  138. package/src/tableselection.js +279 -376
  139. package/src/tabletoolbar.d.ts +37 -0
  140. package/src/tabletoolbar.js +39 -92
  141. package/src/tableui.d.ts +58 -0
  142. package/src/tableui.js +281 -338
  143. package/src/tableutils.d.ts +453 -0
  144. package/src/tableutils.js +1015 -1229
  145. package/src/tablewalker.d.ts +323 -0
  146. package/src/tablewalker.js +308 -548
  147. package/src/ui/colorinputview.d.ts +143 -0
  148. package/src/ui/colorinputview.js +229 -366
  149. package/src/ui/formrowview.d.ts +61 -0
  150. package/src/ui/formrowview.js +38 -84
  151. package/src/ui/inserttableview.d.ts +77 -0
  152. package/src/ui/inserttableview.js +152 -242
  153. package/src/utils/common.d.ts +42 -0
  154. package/src/utils/common.js +33 -57
  155. package/src/utils/structure.d.ts +245 -0
  156. package/src/utils/structure.js +261 -379
  157. package/src/utils/table-properties.d.ts +67 -0
  158. package/src/utils/table-properties.js +60 -81
  159. package/src/utils/ui/contextualballoon.d.ts +34 -0
  160. package/src/utils/ui/contextualballoon.js +70 -89
  161. package/src/utils/ui/table-properties.d.ts +193 -0
  162. package/src/utils/ui/table-properties.js +259 -319
  163. package/src/utils/ui/widget.d.ts +16 -0
  164. package/src/utils/ui/widget.js +24 -46
  165. package/src/tablecolumnresize/tablecolumnwidthscommand.js +0 -55
  166. package/src/tablecolumnresize/tablewidthresizecommand.js +0 -65
@@ -2,481 +2,328 @@
2
2
  * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
-
6
5
  /**
7
6
  * @module table/tablecellproperties/tablecellpropertiesui
8
7
  */
9
-
10
8
  import { Plugin } from 'ckeditor5/src/core';
11
9
  import { ButtonView, clickOutsideHandler, ContextualBalloon, getLocalizedColorOptions, normalizeColorOptions } from 'ckeditor5/src/ui';
12
-
13
10
  import TableCellPropertiesView from './ui/tablecellpropertiesview';
14
- import {
15
- colorFieldValidator,
16
- getLocalizedColorErrorText,
17
- getLocalizedLengthErrorText,
18
- defaultColors,
19
- lengthFieldValidator,
20
- lineWidthFieldValidator
21
- } from '../utils/ui/table-properties';
11
+ import { colorFieldValidator, getLocalizedColorErrorText, getLocalizedLengthErrorText, defaultColors, lengthFieldValidator, lineWidthFieldValidator } from '../utils/ui/table-properties';
22
12
  import { debounce } from 'lodash-es';
23
13
  import { getTableWidgetAncestor } from '../utils/ui/widget';
24
14
  import { getBalloonCellPositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';
25
-
26
15
  import tableCellProperties from './../../theme/icons/table-cell-properties.svg';
27
16
  import { getNormalizedDefaultProperties } from '../utils/table-properties';
28
-
17
+ import '../tableconfig';
29
18
  const ERROR_TEXT_TIMEOUT = 500;
30
-
31
19
  // Map of view properties and related commands.
32
20
  const propertyToCommandMap = {
33
- borderStyle: 'tableCellBorderStyle',
34
- borderColor: 'tableCellBorderColor',
35
- borderWidth: 'tableCellBorderWidth',
36
- height: 'tableCellHeight',
37
- width: 'tableCellWidth',
38
- padding: 'tableCellPadding',
39
- backgroundColor: 'tableCellBackgroundColor',
40
- horizontalAlignment: 'tableCellHorizontalAlignment',
41
- verticalAlignment: 'tableCellVerticalAlignment'
21
+ borderStyle: 'tableCellBorderStyle',
22
+ borderColor: 'tableCellBorderColor',
23
+ borderWidth: 'tableCellBorderWidth',
24
+ height: 'tableCellHeight',
25
+ width: 'tableCellWidth',
26
+ padding: 'tableCellPadding',
27
+ backgroundColor: 'tableCellBackgroundColor',
28
+ horizontalAlignment: 'tableCellHorizontalAlignment',
29
+ verticalAlignment: 'tableCellVerticalAlignment'
42
30
  };
43
-
44
31
  /**
45
32
  * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
46
33
  * that opens a form allowing to specify the visual styling of a table cell.
47
34
  *
48
- * It uses the
49
- * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
50
- *
51
- * @extends module:core/plugin~Plugin
35
+ * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
52
36
  */
53
37
  export default class TableCellPropertiesUI extends Plugin {
54
- /**
55
- * @inheritDoc
56
- */
57
- static get requires() {
58
- return [ ContextualBalloon ];
59
- }
60
-
61
- /**
62
- * @inheritDoc
63
- */
64
- static get pluginName() {
65
- return 'TableCellPropertiesUI';
66
- }
67
-
68
- /**
69
- * @inheritDoc
70
- */
71
- constructor( editor ) {
72
- super( editor );
73
-
74
- editor.config.define( 'table.tableCellProperties', {
75
- borderColors: defaultColors,
76
- backgroundColors: defaultColors
77
- } );
78
- }
79
-
80
- /**
81
- * @inheritDoc
82
- */
83
- init() {
84
- const editor = this.editor;
85
- const t = editor.t;
86
-
87
- /**
88
- * The default table cell properties.
89
- *
90
- * @protected
91
- * @member {module:table/tablecellproperties~TableCellPropertiesOptions}
92
- */
93
- this._defaultTableCellProperties = getNormalizedDefaultProperties(
94
- editor.config.get( 'table.tableCellProperties.defaultProperties' ),
95
- {
96
- includeVerticalAlignmentProperty: true,
97
- includeHorizontalAlignmentProperty: true,
98
- includePaddingProperty: true,
99
- isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
100
- }
101
- );
102
-
103
- /**
104
- * The contextual balloon plugin instance.
105
- *
106
- * @private
107
- * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}
108
- */
109
- this._balloon = editor.plugins.get( ContextualBalloon );
110
-
111
- /**
112
- * The cell properties form view displayed inside the balloon.
113
- *
114
- * @member {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}
115
- */
116
- this.view = null;
117
-
118
- /**
119
- * The batch used to undo all changes made by the form (which are live, as the user types)
120
- * when "Cancel" was pressed. Each time the view is shown, a new batch is created.
121
- *
122
- * @protected
123
- * @member {module:engine/model/batch~Batch}
124
- */
125
- this._undoStepBatch = null;
126
-
127
- /**
128
- * Flag used to indicate whether view is ready to execute update commands
129
- * (it finished loading initial data).
130
- *
131
- * @private
132
- * @member {Boolean}
133
- */
134
- this._isReady = false;
135
-
136
- editor.ui.componentFactory.add( 'tableCellProperties', locale => {
137
- const view = new ButtonView( locale );
138
-
139
- view.set( {
140
- label: t( 'Cell properties' ),
141
- icon: tableCellProperties,
142
- tooltip: true
143
- } );
144
-
145
- this.listenTo( view, 'execute', () => this._showView() );
146
-
147
- const commands = Object.values( propertyToCommandMap )
148
- .map( commandName => editor.commands.get( commandName ) );
149
-
150
- view.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => (
151
- areEnabled.some( isCommandEnabled => isCommandEnabled )
152
- ) );
153
-
154
- return view;
155
- } );
156
- }
157
-
158
- /**
159
- * @inheritDoc
160
- */
161
- destroy() {
162
- super.destroy();
163
-
164
- // Destroy created UI components as they are not automatically destroyed.
165
- // See https://github.com/ckeditor/ckeditor5/issues/1341.
166
- if ( this.view ) {
167
- this.view.destroy();
168
- }
169
- }
170
-
171
- /**
172
- * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
173
- *
174
- * @private
175
- * @returns {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} The cell
176
- * properties form view instance.
177
- */
178
- _createPropertiesView() {
179
- const editor = this.editor;
180
- const config = editor.config.get( 'table.tableCellProperties' );
181
- const borderColorsConfig = normalizeColorOptions( config.borderColors );
182
- const localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );
183
- const backgroundColorsConfig = normalizeColorOptions( config.backgroundColors );
184
- const localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );
185
-
186
- const view = new TableCellPropertiesView( editor.locale, {
187
- borderColors: localizedBorderColors,
188
- backgroundColors: localizedBackgroundColors,
189
- defaultTableCellProperties: this._defaultTableCellProperties
190
- } );
191
- const t = editor.t;
192
-
193
- // Render the view so its #element is available for the clickOutsideHandler.
194
- view.render();
195
-
196
- this.listenTo( view, 'submit', () => {
197
- this._hideView();
198
- } );
199
-
200
- this.listenTo( view, 'cancel', () => {
201
- // https://github.com/ckeditor/ckeditor5/issues/6180
202
- if ( this._undoStepBatch.operations.length ) {
203
- editor.execute( 'undo', this._undoStepBatch );
204
- }
205
-
206
- this._hideView();
207
- } );
208
-
209
- // Close the balloon on Esc key press.
210
- view.keystrokes.set( 'Esc', ( data, cancel ) => {
211
- this._hideView();
212
- cancel();
213
- } );
214
-
215
- // Close on click outside of balloon panel element.
216
- clickOutsideHandler( {
217
- emitter: view,
218
- activator: () => this._isViewInBalloon,
219
- contextElements: [ this._balloon.view.element ],
220
- callback: () => this._hideView()
221
- } );
222
-
223
- const colorErrorText = getLocalizedColorErrorText( t );
224
- const lengthErrorText = getLocalizedLengthErrorText( t );
225
-
226
- // Create the "UI -> editor data" binding.
227
- // These listeners update the editor data (via table commands) when any observable
228
- // property of the view has changed. They also validate the value and display errors in the UI
229
- // when necessary. This makes the view live, which means the changes are
230
- // visible in the editing as soon as the user types or changes fields' values.
231
- view.on(
232
- 'change:borderStyle',
233
- this._getPropertyChangeCallback( 'tableCellBorderStyle', this._defaultTableCellProperties.borderStyle )
234
- );
235
-
236
- view.on( 'change:borderColor', this._getValidatedPropertyChangeCallback( {
237
- viewField: view.borderColorInput,
238
- commandName: 'tableCellBorderColor',
239
- errorText: colorErrorText,
240
- validator: colorFieldValidator,
241
- defaultValue: this._defaultTableCellProperties.borderColor
242
- } ) );
243
-
244
- view.on( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {
245
- viewField: view.borderWidthInput,
246
- commandName: 'tableCellBorderWidth',
247
- errorText: lengthErrorText,
248
- validator: lineWidthFieldValidator,
249
- defaultValue: this._defaultTableCellProperties.borderWidth
250
- } ) );
251
-
252
- view.on( 'change:padding', this._getValidatedPropertyChangeCallback( {
253
- viewField: view.paddingInput,
254
- commandName: 'tableCellPadding',
255
- errorText: lengthErrorText,
256
- validator: lengthFieldValidator,
257
- defaultValue: this._defaultTableCellProperties.padding
258
- } ) );
259
-
260
- view.on( 'change:width', this._getValidatedPropertyChangeCallback( {
261
- viewField: view.widthInput,
262
- commandName: 'tableCellWidth',
263
- errorText: lengthErrorText,
264
- validator: lengthFieldValidator,
265
- defaultValue: this._defaultTableCellProperties.width
266
- } ) );
267
-
268
- view.on( 'change:height', this._getValidatedPropertyChangeCallback( {
269
- viewField: view.heightInput,
270
- commandName: 'tableCellHeight',
271
- errorText: lengthErrorText,
272
- validator: lengthFieldValidator,
273
- defaultValue: this._defaultTableCellProperties.height
274
- } ) );
275
-
276
- view.on( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {
277
- viewField: view.backgroundInput,
278
- commandName: 'tableCellBackgroundColor',
279
- errorText: colorErrorText,
280
- validator: colorFieldValidator,
281
- defaultValue: this._defaultTableCellProperties.backgroundColor
282
- } ) );
283
-
284
- view.on(
285
- 'change:horizontalAlignment',
286
- this._getPropertyChangeCallback( 'tableCellHorizontalAlignment', this._defaultTableCellProperties.horizontalAlignment )
287
- );
288
- view.on(
289
- 'change:verticalAlignment',
290
- this._getPropertyChangeCallback( 'tableCellVerticalAlignment', this._defaultTableCellProperties.verticalAlignment )
291
- );
292
-
293
- return view;
294
- }
295
-
296
- /**
297
- * In this method the "editor data -> UI" binding is happening.
298
- *
299
- * When executed, this method obtains selected cell property values from various table commands
300
- * and passes them to the {@link #view}.
301
- *
302
- * This way, the UI stays up–to–date with the editor data.
303
- *
304
- * @private
305
- */
306
- _fillViewFormFromCommandValues() {
307
- const commands = this.editor.commands;
308
- const borderStyleCommand = commands.get( 'tableCellBorderStyle' );
309
-
310
- Object.entries( propertyToCommandMap )
311
- .map( ( [ property, commandName ] ) => {
312
- const defaultValue = this._defaultTableCellProperties[ property ] || '';
313
-
314
- return [ property, commands.get( commandName ).value || defaultValue ];
315
- } )
316
- .forEach( ( [ property, value ] ) => {
317
- // Do not set the `border-color` and `border-width` fields if `border-style:none`.
318
- if ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {
319
- return;
320
- }
321
-
322
- this.view.set( property, value );
323
- } );
324
-
325
- this._isReady = true;
326
- }
327
-
328
- /**
329
- * Shows the {@link #view} in the {@link #_balloon}.
330
- *
331
- * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
332
- * all changes made to the document when the view is visible, allowing a single undo step
333
- * for all of them.
334
- *
335
- * @protected
336
- */
337
- _showView() {
338
- const editor = this.editor;
339
-
340
- if ( !this.view ) {
341
- this.view = this._createPropertiesView();
342
- }
343
-
344
- this.listenTo( editor.ui, 'update', () => {
345
- this._updateView();
346
- } );
347
-
348
- // Update the view with the model values.
349
- this._fillViewFormFromCommandValues();
350
-
351
- this._balloon.add( {
352
- view: this.view,
353
- position: getBalloonCellPositionData( editor )
354
- } );
355
-
356
- // Create a new batch. Clicking "Cancel" will undo this batch.
357
- this._undoStepBatch = editor.model.createBatch();
358
-
359
- // Basic a11y.
360
- this.view.focus();
361
- }
362
-
363
- /**
364
- * Removes the {@link #view} from the {@link #_balloon}.
365
- *
366
- * @protected
367
- */
368
- _hideView() {
369
- const editor = this.editor;
370
-
371
- this.stopListening( editor.ui, 'update' );
372
-
373
- this._isReady = false;
374
-
375
- // Blur any input element before removing it from DOM to prevent issues in some browsers.
376
- // See https://github.com/ckeditor/ckeditor5/issues/1501.
377
- this.view.saveButtonView.focus();
378
-
379
- this._balloon.remove( this.view );
380
-
381
- // Make sure the focus is not lost in the process by putting it directly
382
- // into the editing view.
383
- this.editor.editing.view.focus();
384
- }
385
-
386
- /**
387
- * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
388
- *
389
- * @protected
390
- */
391
- _updateView() {
392
- const editor = this.editor;
393
- const viewDocument = editor.editing.view.document;
394
-
395
- if ( !getTableWidgetAncestor( viewDocument.selection ) ) {
396
- this._hideView();
397
- } else if ( this._isViewVisible ) {
398
- repositionContextualBalloon( editor, 'cell' );
399
- }
400
- }
401
-
402
- /**
403
- * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
404
- *
405
- * @private
406
- * @type {Boolean}
407
- */
408
- get _isViewVisible() {
409
- return !!this.view && this._balloon.visibleView === this.view;
410
- }
411
-
412
- /**
413
- * Returns `true` when the {@link #view} is in the {@link #_balloon}.
414
- *
415
- * @private
416
- * @type {Boolean}
417
- */
418
- get _isViewInBalloon() {
419
- return !!this.view && this._balloon.hasView( this.view );
420
- }
421
-
422
- /**
423
- * Creates a callback that when executed upon the {@link #view view's} property change
424
- * executes a related editor command with the new property value.
425
- *
426
- * @private
427
- * @param {String} commandName
428
- * @returns {Function}
429
- */
430
- _getPropertyChangeCallback( commandName ) {
431
- return ( evt, propertyName, newValue ) => {
432
- // Do not execute the command on initial call (opening the table properties view).
433
- if ( !this._isReady ) {
434
- return;
435
- }
436
-
437
- this.editor.execute( commandName, {
438
- value: newValue,
439
- batch: this._undoStepBatch
440
- } );
441
- };
442
- }
443
-
444
- /**
445
- * Creates a callback that when executed upon the {@link #view view's} property change:
446
- * * Executes a related editor command with the new property value if the value is valid,
447
- * * Or sets the error text next to the invalid field, if the value did not pass the validation.
448
- *
449
- * @private
450
- * @param {Object} options
451
- * @param {String} options.commandName
452
- * @param {module:ui/view~View} options.viewField
453
- * @param {Function} options.validator
454
- * @param {String} options.errorText
455
- * @returns {Function}
456
- */
457
- _getValidatedPropertyChangeCallback( options ) {
458
- const { commandName, viewField, validator, errorText } = options;
459
- const setErrorTextDebounced = debounce( () => {
460
- viewField.errorText = errorText;
461
- }, ERROR_TEXT_TIMEOUT );
462
-
463
- return ( evt, propertyName, newValue ) => {
464
- setErrorTextDebounced.cancel();
465
- // Do not execute the command on initial call (opening the table properties view).
466
- if ( !this._isReady ) {
467
- return;
468
- }
469
-
470
- if ( validator( newValue ) ) {
471
- this.editor.execute( commandName, {
472
- value: newValue,
473
- batch: this._undoStepBatch
474
- } );
475
-
476
- viewField.errorText = null;
477
- } else {
478
- setErrorTextDebounced();
479
- }
480
- };
481
- }
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ static get requires() {
42
+ return [ContextualBalloon];
43
+ }
44
+ /**
45
+ * @inheritDoc
46
+ */
47
+ static get pluginName() {
48
+ return 'TableCellPropertiesUI';
49
+ }
50
+ /**
51
+ * @inheritDoc
52
+ */
53
+ constructor(editor) {
54
+ super(editor);
55
+ editor.config.define('table.tableCellProperties', {
56
+ borderColors: defaultColors,
57
+ backgroundColors: defaultColors
58
+ });
59
+ }
60
+ /**
61
+ * @inheritDoc
62
+ */
63
+ init() {
64
+ const editor = this.editor;
65
+ const t = editor.t;
66
+ this._defaultTableCellProperties = getNormalizedDefaultProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
67
+ includeVerticalAlignmentProperty: true,
68
+ includeHorizontalAlignmentProperty: true,
69
+ includePaddingProperty: true,
70
+ isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
71
+ });
72
+ this._balloon = editor.plugins.get(ContextualBalloon);
73
+ this.view = null;
74
+ this._isReady = false;
75
+ editor.ui.componentFactory.add('tableCellProperties', locale => {
76
+ const view = new ButtonView(locale);
77
+ view.set({
78
+ label: t('Cell properties'),
79
+ icon: tableCellProperties,
80
+ tooltip: true
81
+ });
82
+ this.listenTo(view, 'execute', () => this._showView());
83
+ const commands = Object.values(propertyToCommandMap)
84
+ .map(commandName => editor.commands.get(commandName));
85
+ view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled) => (areEnabled.some(isCommandEnabled => isCommandEnabled)));
86
+ return view;
87
+ });
88
+ }
89
+ /**
90
+ * @inheritDoc
91
+ */
92
+ destroy() {
93
+ super.destroy();
94
+ // Destroy created UI components as they are not automatically destroyed.
95
+ // See https://github.com/ckeditor/ckeditor5/issues/1341.
96
+ if (this.view) {
97
+ this.view.destroy();
98
+ }
99
+ }
100
+ /**
101
+ * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
102
+ *
103
+ * @returns The cell properties form view instance.
104
+ */
105
+ _createPropertiesView() {
106
+ const editor = this.editor;
107
+ const config = editor.config.get('table.tableCellProperties');
108
+ const borderColorsConfig = normalizeColorOptions(config.borderColors);
109
+ const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
110
+ const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
111
+ const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
112
+ const view = new TableCellPropertiesView(editor.locale, {
113
+ borderColors: localizedBorderColors,
114
+ backgroundColors: localizedBackgroundColors,
115
+ defaultTableCellProperties: this._defaultTableCellProperties
116
+ });
117
+ const t = editor.t;
118
+ // Render the view so its #element is available for the clickOutsideHandler.
119
+ view.render();
120
+ this.listenTo(view, 'submit', () => {
121
+ this._hideView();
122
+ });
123
+ this.listenTo(view, 'cancel', () => {
124
+ // https://github.com/ckeditor/ckeditor5/issues/6180
125
+ if (this._undoStepBatch.operations.length) {
126
+ editor.execute('undo', this._undoStepBatch);
127
+ }
128
+ this._hideView();
129
+ });
130
+ // Close the balloon on Esc key press.
131
+ view.keystrokes.set('Esc', (data, cancel) => {
132
+ this._hideView();
133
+ cancel();
134
+ });
135
+ // Close on click outside of balloon panel element.
136
+ clickOutsideHandler({
137
+ emitter: view,
138
+ activator: () => this._isViewInBalloon,
139
+ contextElements: [this._balloon.view.element],
140
+ callback: () => this._hideView()
141
+ });
142
+ const colorErrorText = getLocalizedColorErrorText(t);
143
+ const lengthErrorText = getLocalizedLengthErrorText(t);
144
+ // Create the "UI -> editor data" binding.
145
+ // These listeners update the editor data (via table commands) when any observable
146
+ // property of the view has changed. They also validate the value and display errors in the UI
147
+ // when necessary. This makes the view live, which means the changes are
148
+ // visible in the editing as soon as the user types or changes fields' values.
149
+ view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
150
+ view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
151
+ viewField: view.borderColorInput,
152
+ commandName: 'tableCellBorderColor',
153
+ errorText: colorErrorText,
154
+ validator: colorFieldValidator
155
+ }));
156
+ view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
157
+ viewField: view.borderWidthInput,
158
+ commandName: 'tableCellBorderWidth',
159
+ errorText: lengthErrorText,
160
+ validator: lineWidthFieldValidator
161
+ }));
162
+ view.on('change:padding', this._getValidatedPropertyChangeCallback({
163
+ viewField: view.paddingInput,
164
+ commandName: 'tableCellPadding',
165
+ errorText: lengthErrorText,
166
+ validator: lengthFieldValidator
167
+ }));
168
+ view.on('change:width', this._getValidatedPropertyChangeCallback({
169
+ viewField: view.widthInput,
170
+ commandName: 'tableCellWidth',
171
+ errorText: lengthErrorText,
172
+ validator: lengthFieldValidator
173
+ }));
174
+ view.on('change:height', this._getValidatedPropertyChangeCallback({
175
+ viewField: view.heightInput,
176
+ commandName: 'tableCellHeight',
177
+ errorText: lengthErrorText,
178
+ validator: lengthFieldValidator
179
+ }));
180
+ view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
181
+ viewField: view.backgroundInput,
182
+ commandName: 'tableCellBackgroundColor',
183
+ errorText: colorErrorText,
184
+ validator: colorFieldValidator
185
+ }));
186
+ view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
187
+ view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
188
+ return view;
189
+ }
190
+ /**
191
+ * In this method the "editor data -> UI" binding is happening.
192
+ *
193
+ * When executed, this method obtains selected cell property values from various table commands
194
+ * and passes them to the {@link #view}.
195
+ *
196
+ * This way, the UI stays up–to–date with the editor data.
197
+ */
198
+ _fillViewFormFromCommandValues() {
199
+ const commands = this.editor.commands;
200
+ const borderStyleCommand = commands.get('tableCellBorderStyle');
201
+ Object.entries(propertyToCommandMap)
202
+ .map(([property, commandName]) => {
203
+ const defaultValue = this._defaultTableCellProperties[property] || '';
204
+ return [
205
+ property,
206
+ commands.get(commandName).value || defaultValue
207
+ ];
208
+ })
209
+ .forEach(([property, value]) => {
210
+ // Do not set the `border-color` and `border-width` fields if `border-style:none`.
211
+ if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
212
+ return;
213
+ }
214
+ this.view.set(property, value);
215
+ });
216
+ this._isReady = true;
217
+ }
218
+ /**
219
+ * Shows the {@link #view} in the {@link #_balloon}.
220
+ *
221
+ * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
222
+ * all changes made to the document when the view is visible, allowing a single undo step
223
+ * for all of them.
224
+ */
225
+ _showView() {
226
+ const editor = this.editor;
227
+ if (!this.view) {
228
+ this.view = this._createPropertiesView();
229
+ }
230
+ this.listenTo(editor.ui, 'update', () => {
231
+ this._updateView();
232
+ });
233
+ // Update the view with the model values.
234
+ this._fillViewFormFromCommandValues();
235
+ this._balloon.add({
236
+ view: this.view,
237
+ position: getBalloonCellPositionData(editor)
238
+ });
239
+ // Create a new batch. Clicking "Cancel" will undo this batch.
240
+ this._undoStepBatch = editor.model.createBatch();
241
+ // Basic a11y.
242
+ this.view.focus();
243
+ }
244
+ /**
245
+ * Removes the {@link #view} from the {@link #_balloon}.
246
+ */
247
+ _hideView() {
248
+ const editor = this.editor;
249
+ this.stopListening(editor.ui, 'update');
250
+ this._isReady = false;
251
+ // Blur any input element before removing it from DOM to prevent issues in some browsers.
252
+ // See https://github.com/ckeditor/ckeditor5/issues/1501.
253
+ this.view.saveButtonView.focus();
254
+ this._balloon.remove(this.view);
255
+ // Make sure the focus is not lost in the process by putting it directly
256
+ // into the editing view.
257
+ this.editor.editing.view.focus();
258
+ }
259
+ /**
260
+ * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
261
+ */
262
+ _updateView() {
263
+ const editor = this.editor;
264
+ const viewDocument = editor.editing.view.document;
265
+ if (!getTableWidgetAncestor(viewDocument.selection)) {
266
+ this._hideView();
267
+ }
268
+ else if (this._isViewVisible) {
269
+ repositionContextualBalloon(editor, 'cell');
270
+ }
271
+ }
272
+ /**
273
+ * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
274
+ */
275
+ get _isViewVisible() {
276
+ return !!this.view && this._balloon.visibleView === this.view;
277
+ }
278
+ /**
279
+ * Returns `true` when the {@link #view} is in the {@link #_balloon}.
280
+ */
281
+ get _isViewInBalloon() {
282
+ return !!this.view && this._balloon.hasView(this.view);
283
+ }
284
+ /**
285
+ * Creates a callback that when executed upon the {@link #view view's} property change
286
+ * executes a related editor command with the new property value.
287
+ *
288
+ * @param defaultValue The default value of the command.
289
+ */
290
+ _getPropertyChangeCallback(commandName) {
291
+ return (evt, propertyName, newValue) => {
292
+ if (!this._isReady) {
293
+ return;
294
+ }
295
+ this.editor.execute(commandName, {
296
+ value: newValue,
297
+ batch: this._undoStepBatch
298
+ });
299
+ };
300
+ }
301
+ /**
302
+ * Creates a callback that when executed upon the {@link #view view's} property change:
303
+ * * Executes a related editor command with the new property value if the value is valid,
304
+ * * Or sets the error text next to the invalid field, if the value did not pass the validation.
305
+ */
306
+ _getValidatedPropertyChangeCallback(options) {
307
+ const { commandName, viewField, validator, errorText } = options;
308
+ const setErrorTextDebounced = debounce(() => {
309
+ viewField.errorText = errorText;
310
+ }, ERROR_TEXT_TIMEOUT);
311
+ return (evt, propertyName, newValue) => {
312
+ setErrorTextDebounced.cancel();
313
+ // Do not execute the command on initial call (opening the table properties view).
314
+ if (!this._isReady) {
315
+ return;
316
+ }
317
+ if (validator(newValue)) {
318
+ this.editor.execute(commandName, {
319
+ value: newValue,
320
+ batch: this._undoStepBatch
321
+ });
322
+ viewField.errorText = null;
323
+ }
324
+ else {
325
+ setErrorTextDebounced();
326
+ }
327
+ };
328
+ }
482
329
  }