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

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