@ckeditor/ckeditor5-table 27.1.0 → 29.2.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 (156) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -3
  3. package/build/table.js +1 -1
  4. package/build/translations/ar.js +1 -0
  5. package/build/translations/az.js +1 -0
  6. package/build/translations/bg.js +1 -0
  7. package/build/translations/cs.js +1 -0
  8. package/build/translations/da.js +1 -0
  9. package/build/translations/de-ch.js +1 -0
  10. package/build/translations/de.js +1 -0
  11. package/build/translations/en-au.js +1 -0
  12. package/build/translations/en-gb.js +1 -0
  13. package/build/translations/es.js +1 -0
  14. package/build/translations/et.js +1 -0
  15. package/build/translations/fa.js +1 -0
  16. package/build/translations/fi.js +1 -0
  17. package/build/translations/fr.js +1 -0
  18. package/build/translations/gl.js +1 -0
  19. package/build/translations/hi.js +1 -0
  20. package/build/translations/hr.js +1 -0
  21. package/build/translations/hu.js +1 -0
  22. package/build/translations/id.js +1 -0
  23. package/build/translations/it.js +1 -0
  24. package/build/translations/ja.js +1 -0
  25. package/build/translations/ko.js +1 -0
  26. package/build/translations/ku.js +1 -0
  27. package/build/translations/lt.js +1 -0
  28. package/build/translations/lv.js +1 -0
  29. package/build/translations/nb.js +1 -0
  30. package/build/translations/ne.js +1 -0
  31. package/build/translations/nl.js +1 -0
  32. package/build/translations/no.js +1 -0
  33. package/build/translations/pl.js +1 -0
  34. package/build/translations/pt-br.js +1 -0
  35. package/build/translations/ro.js +1 -0
  36. package/build/translations/ru.js +1 -0
  37. package/build/translations/sk.js +1 -0
  38. package/build/translations/sq.js +1 -0
  39. package/build/translations/sr-latn.js +1 -0
  40. package/build/translations/sr.js +1 -0
  41. package/build/translations/sv.js +1 -0
  42. package/build/translations/th.js +1 -0
  43. package/build/translations/tk.js +1 -0
  44. package/build/translations/tr.js +1 -0
  45. package/build/translations/ug.js +1 -0
  46. package/build/translations/uk.js +1 -0
  47. package/build/translations/vi.js +1 -0
  48. package/build/translations/zh-cn.js +1 -0
  49. package/build/translations/zh.js +1 -0
  50. package/ckeditor5-metadata.json +174 -0
  51. package/lang/contexts.json +4 -1
  52. package/lang/translations/ar.po +12 -0
  53. package/lang/translations/az.po +12 -0
  54. package/lang/translations/bg.po +12 -0
  55. package/lang/translations/cs.po +12 -0
  56. package/lang/translations/da.po +12 -0
  57. package/lang/translations/de-ch.po +12 -0
  58. package/lang/translations/de.po +12 -0
  59. package/lang/translations/en-au.po +12 -0
  60. package/lang/translations/en-gb.po +12 -0
  61. package/lang/translations/en.po +12 -0
  62. package/lang/translations/es.po +12 -0
  63. package/lang/translations/et.po +12 -0
  64. package/lang/translations/fa.po +12 -0
  65. package/lang/translations/fi.po +12 -0
  66. package/lang/translations/fr.po +12 -0
  67. package/lang/translations/gl.po +12 -0
  68. package/lang/translations/hi.po +12 -0
  69. package/lang/translations/hr.po +12 -0
  70. package/lang/translations/hu.po +23 -11
  71. package/lang/translations/id.po +23 -11
  72. package/lang/translations/it.po +12 -0
  73. package/lang/translations/ja.po +12 -0
  74. package/lang/translations/ko.po +12 -0
  75. package/lang/translations/ku.po +12 -0
  76. package/lang/translations/lt.po +12 -0
  77. package/lang/translations/lv.po +12 -0
  78. package/lang/translations/nb.po +12 -0
  79. package/lang/translations/ne.po +12 -0
  80. package/lang/translations/nl.po +12 -0
  81. package/lang/translations/no.po +12 -0
  82. package/lang/translations/pl.po +12 -0
  83. package/lang/translations/pt-br.po +12 -0
  84. package/lang/translations/ro.po +51 -39
  85. package/lang/translations/ru.po +12 -0
  86. package/lang/translations/sk.po +12 -0
  87. package/lang/translations/sq.po +12 -0
  88. package/lang/translations/sr-latn.po +12 -0
  89. package/lang/translations/sr.po +12 -0
  90. package/lang/translations/sv.po +12 -0
  91. package/lang/translations/th.po +12 -0
  92. package/lang/translations/tk.po +12 -0
  93. package/lang/translations/tr.po +12 -0
  94. package/lang/translations/ug.po +12 -0
  95. package/lang/translations/uk.po +12 -0
  96. package/lang/translations/vi.po +12 -0
  97. package/lang/translations/zh-cn.po +12 -0
  98. package/lang/translations/zh.po +12 -0
  99. package/package.json +25 -23
  100. package/src/commands/insertcolumncommand.js +2 -3
  101. package/src/commands/insertrowcommand.js +2 -3
  102. package/src/commands/inserttablecommand.js +22 -7
  103. package/src/commands/mergecellcommand.js +5 -3
  104. package/src/commands/removerowcommand.js +8 -5
  105. package/src/converters/downcast.js +4 -5
  106. package/src/converters/table-caption-post-fixer.js +69 -0
  107. package/src/converters/table-cell-paragraph-post-fixer.js +3 -1
  108. package/src/converters/table-layout-post-fixer.js +13 -8
  109. package/src/converters/tableproperties.js +82 -23
  110. package/src/converters/upcasttable.js +63 -0
  111. package/src/index.js +18 -33
  112. package/src/table.js +17 -0
  113. package/src/tablecaption/tablecaptionediting.js +153 -0
  114. package/src/tablecaption/tablecaptionui.js +71 -0
  115. package/src/tablecaption/toggletablecaptioncommand.js +120 -0
  116. package/src/tablecaption/utils.js +93 -0
  117. package/src/tablecaption.js +35 -0
  118. package/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js +3 -2
  119. package/src/tablecellproperties/commands/tablecellbordercolorcommand.js +10 -3
  120. package/src/tablecellproperties/commands/tablecellborderstylecommand.js +10 -3
  121. package/src/tablecellproperties/commands/tablecellborderwidthcommand.js +17 -4
  122. package/src/tablecellproperties/commands/tablecellheightcommand.js +10 -3
  123. package/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js +3 -2
  124. package/src/tablecellproperties/commands/tablecellpaddingcommand.js +17 -4
  125. package/src/tablecellproperties/commands/tablecellpropertycommand.js +28 -2
  126. package/src/tablecellproperties/commands/tablecellverticalalignmentcommand.js +3 -2
  127. package/src/tablecellproperties/commands/tablecellwidthcommand.js +10 -3
  128. package/src/tablecellproperties/tablecellpropertiesediting.js +164 -65
  129. package/src/tablecellproperties/tablecellpropertiesui.js +76 -16
  130. package/src/tablecellproperties/ui/tablecellpropertiesview.js +39 -13
  131. package/src/tablecellproperties.js +42 -2
  132. package/src/tableediting.js +76 -6
  133. package/src/tablekeyboard.js +3 -2
  134. package/src/tableproperties/commands/tablealignmentcommand.js +3 -2
  135. package/src/tableproperties/commands/tablebackgroundcolorcommand.js +3 -2
  136. package/src/tableproperties/commands/tablebordercolorcommand.js +10 -3
  137. package/src/tableproperties/commands/tableborderstylecommand.js +10 -3
  138. package/src/tableproperties/commands/tableborderwidthcommand.js +17 -4
  139. package/src/tableproperties/commands/tableheightcommand.js +10 -3
  140. package/src/tableproperties/commands/tablepropertycommand.js +28 -2
  141. package/src/tableproperties/commands/tablewidthcommand.js +10 -3
  142. package/src/tableproperties/tablepropertiesediting.js +104 -47
  143. package/src/tableproperties/tablepropertiesui.js +68 -15
  144. package/src/tableproperties/ui/tablepropertiesview.js +26 -11
  145. package/src/tableproperties.js +38 -2
  146. package/src/tableui.js +10 -1
  147. package/src/tableutils.js +41 -5
  148. package/src/tablewalker.js +36 -1
  149. package/src/ui/colorinputview.js +11 -7
  150. package/src/utils/structure.js +4 -3
  151. package/src/utils/table-properties.js +41 -0
  152. package/src/utils/ui/table-properties.js +29 -7
  153. package/src/utils/ui/widget.js +7 -15
  154. package/theme/table.css +17 -1
  155. package/theme/tablecaption.css +53 -0
  156. package/build/table.js.map +0 -1
@@ -22,11 +22,27 @@ export default class TablePropertyCommand extends Command {
22
22
  *
23
23
  * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.
24
24
  * @param {String} attributeName Table cell attribute name.
25
+ * @param {String} defaultValue The default value of the attribute.
25
26
  */
26
- constructor( editor, attributeName ) {
27
+ constructor( editor, attributeName, defaultValue ) {
27
28
  super( editor );
28
29
 
30
+ /**
31
+ * The attribute that will be set by the command.
32
+ *
33
+ * @readonly
34
+ * @member {String}
35
+ */
29
36
  this.attributeName = attributeName;
37
+
38
+ /**
39
+ * The default value for the attribute.
40
+ *
41
+ * @readonly
42
+ * @protected
43
+ * @member {String}
44
+ */
45
+ this._defaultValue = defaultValue;
30
46
  }
31
47
 
32
48
  /**
@@ -82,7 +98,13 @@ export default class TablePropertyCommand extends Command {
82
98
  return;
83
99
  }
84
100
 
85
- return table.getAttribute( this.attributeName );
101
+ const value = table.getAttribute( this.attributeName );
102
+
103
+ if ( value === this._defaultValue ) {
104
+ return;
105
+ }
106
+
107
+ return value;
86
108
  }
87
109
 
88
110
  /**
@@ -93,6 +115,10 @@ export default class TablePropertyCommand extends Command {
93
115
  * @returns {*}
94
116
  */
95
117
  _getValueToSet( value ) {
118
+ if ( value === this._defaultValue ) {
119
+ return;
120
+ }
121
+
96
122
  return value;
97
123
  }
98
124
  }
@@ -37,15 +37,22 @@ export default class TableWidthCommand extends TablePropertyCommand {
37
37
  * Creates a new `TableWidthCommand` instance.
38
38
  *
39
39
  * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.
40
+ * @param {String} defaultValue The default value of the attribute.
40
41
  */
41
- constructor( editor ) {
42
- super( editor, 'width' );
42
+ constructor( editor, defaultValue ) {
43
+ super( editor, 'width', defaultValue );
43
44
  }
44
45
 
45
46
  /**
46
47
  * @inheritDoc
47
48
  */
48
49
  _getValueToSet( value ) {
49
- return addDefaultUnitToNumericValue( value, 'px' );
50
+ value = addDefaultUnitToNumericValue( value, 'px' );
51
+
52
+ if ( value === this._defaultValue ) {
53
+ return;
54
+ }
55
+
56
+ return value;
50
57
  }
51
58
  }
@@ -24,8 +24,10 @@ import TableBorderWidthCommand from './commands/tableborderwidthcommand';
24
24
  import TableWidthCommand from './commands/tablewidthcommand';
25
25
  import TableHeightCommand from './commands/tableheightcommand';
26
26
  import TableAlignmentCommand from './commands/tablealignmentcommand';
27
+ import { getNormalizedDefaultProperties } from '../utils/table-properties';
27
28
 
28
- const ALIGN_VALUES_REG_EXP = /^(left|right)$/;
29
+ const ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;
30
+ const FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;
29
31
 
30
32
  /**
31
33
  * The table properties editing feature.
@@ -69,24 +71,49 @@ export default class TablePropertiesEditing extends Plugin {
69
71
  const schema = editor.model.schema;
70
72
  const conversion = editor.conversion;
71
73
 
74
+ editor.config.define( 'table.tableProperties.defaultProperties', {} );
75
+
76
+ const defaultTableProperties = getNormalizedDefaultProperties( editor.config.get( 'table.tableProperties.defaultProperties' ), {
77
+ includeAlignmentProperty: true
78
+ } );
79
+
72
80
  editor.data.addStyleProcessorRules( addBorderRules );
73
- enableBorderProperties( schema, conversion );
74
- editor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor ) );
75
- editor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor ) );
76
- editor.commands.add( 'tableBorderWidth', new TableBorderWidthCommand( editor ) );
81
+ enableBorderProperties( schema, conversion, {
82
+ color: defaultTableProperties.borderColor,
83
+ style: defaultTableProperties.borderStyle,
84
+ width: defaultTableProperties.borderWidth
85
+ } );
86
+ editor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor, defaultTableProperties.borderColor ) );
87
+ editor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor, defaultTableProperties.borderStyle ) );
88
+ editor.commands.add( 'tableBorderWidth', new TableBorderWidthCommand( editor, defaultTableProperties.borderWidth ) );
77
89
 
78
- enableAlignmentProperty( schema, conversion );
79
- editor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor ) );
90
+ enableAlignmentProperty( schema, conversion, defaultTableProperties.alignment );
91
+ editor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor, defaultTableProperties.alignment ) );
80
92
 
81
- enableTableToFigureProperty( schema, conversion, 'width', 'width' );
82
- editor.commands.add( 'tableWidth', new TableWidthCommand( editor ) );
93
+ enableTableToFigureProperty( schema, conversion, {
94
+ modelAttribute: 'width',
95
+ styleName: 'width',
96
+ defaultValue: defaultTableProperties.width
97
+ } );
98
+ editor.commands.add( 'tableWidth', new TableWidthCommand( editor, defaultTableProperties.width ) );
83
99
 
84
- enableTableToFigureProperty( schema, conversion, 'height', 'height' );
85
- editor.commands.add( 'tableHeight', new TableHeightCommand( editor ) );
100
+ enableTableToFigureProperty( schema, conversion, {
101
+ modelAttribute: 'height',
102
+ styleName: 'height',
103
+ defaultValue: defaultTableProperties.height
104
+ } );
105
+ editor.commands.add( 'tableHeight', new TableHeightCommand( editor, defaultTableProperties.height ) );
86
106
 
87
107
  editor.data.addStyleProcessorRules( addBackgroundRules );
88
- enableProperty( schema, conversion, 'backgroundColor', 'background-color' );
89
- editor.commands.add( 'tableBackgroundColor', new TableBackgroundColorCommand( editor ) );
108
+ enableProperty( schema, conversion, {
109
+ modelAttribute: 'backgroundColor',
110
+ styleName: 'background-color',
111
+ defaultValue: defaultTableProperties.backgroundColor
112
+ } );
113
+ editor.commands.add(
114
+ 'tableBackgroundColor',
115
+ new TableBackgroundColorCommand( editor, defaultTableProperties.backgroundColor )
116
+ );
90
117
  }
91
118
  }
92
119
 
@@ -94,51 +121,70 @@ export default class TablePropertiesEditing extends Plugin {
94
121
  //
95
122
  // @param {module:engine/model/schema~Schema} schema
96
123
  // @param {module:engine/conversion/conversion~Conversion} conversion
97
- function enableBorderProperties( schema, conversion ) {
124
+ // @param {Object} defaultBorder The default border values.
125
+ // @param {String} defaultBorder.color The default `borderColor` value.
126
+ // @param {String} defaultBorder.style The default `borderStyle` value.
127
+ // @param {String} defaultBorder.width The default `borderWidth` value.
128
+ function enableBorderProperties( schema, conversion, defaultBorder ) {
98
129
  schema.extend( 'table', {
99
130
  allowAttributes: [ 'borderWidth', 'borderColor', 'borderStyle' ]
100
131
  } );
101
- upcastBorderStyles( conversion, 'table' );
102
- downcastTableAttribute( conversion, 'borderColor', 'border-color' );
103
- downcastTableAttribute( conversion, 'borderStyle', 'border-style' );
104
- downcastTableAttribute( conversion, 'borderWidth', 'border-width' );
132
+ upcastBorderStyles( conversion, 'table', defaultBorder );
133
+ downcastTableAttribute( conversion, { modelAttribute: 'borderColor', styleName: 'border-color' } );
134
+ downcastTableAttribute( conversion, { modelAttribute: 'borderStyle', styleName: 'border-style' } );
135
+ downcastTableAttribute( conversion, { modelAttribute: 'borderWidth', styleName: 'border-width' } );
105
136
  }
106
137
 
107
138
  // Enables the `'alignment'` attribute for table.
108
139
  //
109
140
  // @param {module:engine/model/schema~Schema} schema
110
141
  // @param {module:engine/conversion/conversion~Conversion} conversion
111
- function enableAlignmentProperty( schema, conversion ) {
142
+ // @param {String} defaultValue The default alignment value.
143
+ function enableAlignmentProperty( schema, conversion, defaultValue ) {
112
144
  schema.extend( 'table', {
113
145
  allowAttributes: [ 'alignment' ]
114
146
  } );
115
147
 
116
- conversion
148
+ conversion.for( 'downcast' )
117
149
  .attributeToAttribute( {
118
150
  model: {
119
151
  name: 'table',
120
- key: 'alignment',
121
- values: [ 'left', 'right' ]
152
+ key: 'alignment'
122
153
  },
123
- view: {
124
- left: {
125
- key: 'style',
126
- value: {
127
- float: 'left'
128
- }
129
- },
130
- right: {
131
- key: 'style',
132
- value: {
133
- float: 'right'
134
- }
154
+ view: alignment => ( {
155
+ key: 'style',
156
+ value: {
157
+ // Model: `alignment:center` => CSS: `float:none`.
158
+ float: alignment === 'center' ? 'none' : alignment
135
159
  }
136
- },
160
+ } ),
137
161
  converterPriority: 'high'
138
162
  } );
139
163
 
140
164
  conversion.for( 'upcast' )
141
- // Support for backwards compatibility and pasting from other sources.
165
+ // Support for the `float:*;` CSS definition for the table alignment.
166
+ .attributeToAttribute( {
167
+ view: {
168
+ name: /^(table|figure)$/,
169
+ styles: {
170
+ float: FLOAT_VALUES_REG_EXP
171
+ }
172
+ },
173
+ model: {
174
+ key: 'alignment',
175
+ value: viewElement => {
176
+ let align = viewElement.getStyle( 'float' );
177
+
178
+ // CSS: `float:none` => Model: `alignment:center`.
179
+ if ( align === 'none' ) {
180
+ align = 'center';
181
+ }
182
+
183
+ return align === defaultValue ? null : align;
184
+ }
185
+ }
186
+ } )
187
+ // Support for the `align` attribute as the backward compatibility while pasting from other sources.
142
188
  .attributeToAttribute( {
143
189
  view: {
144
190
  attributes: {
@@ -148,35 +194,46 @@ function enableAlignmentProperty( schema, conversion ) {
148
194
  model: {
149
195
  name: 'table',
150
196
  key: 'alignment',
151
- value: viewElement => viewElement.getAttribute( 'align' )
197
+ value: viewElement => {
198
+ const align = viewElement.getAttribute( 'align' );
199
+
200
+ return align === defaultValue ? null : align;
201
+ }
152
202
  }
153
203
  } );
154
204
  }
155
205
 
156
206
  // Enables conversion for an attribute for simple view-model mappings.
157
207
  //
158
- // @param {String} modelAttribute
159
- // @param {String} styleName
160
208
  // @param {module:engine/model/schema~Schema} schema
161
209
  // @param {module:engine/conversion/conversion~Conversion} conversion
162
- function enableProperty( schema, conversion, modelAttribute, styleName ) {
210
+ // @param {Object} options
211
+ // @param {String} options.modelAttribute
212
+ // @param {String} options.styleName
213
+ // @param {String} options.defaultValue The default value for the specified `modelAttribute`.
214
+ function enableProperty( schema, conversion, options ) {
215
+ const { modelAttribute } = options;
216
+
163
217
  schema.extend( 'table', {
164
218
  allowAttributes: [ modelAttribute ]
165
219
  } );
166
- upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
167
- downcastTableAttribute( conversion, modelAttribute, styleName );
220
+ upcastStyleToAttribute( conversion, { viewElement: 'table', ...options } );
221
+ downcastTableAttribute( conversion, options );
168
222
  }
169
223
 
170
224
  // Enables conversion for an attribute for simple view (figure) to model (table) mappings.
171
225
  //
172
- // @param {String} modelAttribute
173
- // @param {String} styleName
174
226
  // @param {module:engine/model/schema~Schema} schema
175
227
  // @param {module:engine/conversion/conversion~Conversion} conversion
176
- function enableTableToFigureProperty( schema, conversion, modelAttribute, styleName ) {
228
+ // @param {Object} options
229
+ // @param {String} options.modelAttribute
230
+ // @param {String} options.styleName
231
+ function enableTableToFigureProperty( schema, conversion, options ) {
232
+ const { modelAttribute } = options;
233
+
177
234
  schema.extend( 'table', {
178
235
  allowAttributes: [ modelAttribute ]
179
236
  } );
180
- upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
181
- downcastAttributeToStyle( conversion, 'table', modelAttribute, styleName );
237
+ upcastStyleToAttribute( conversion, { viewElement: /^(table|figure)$/, ...options } );
238
+ downcastAttributeToStyle( conversion, { modelElement: 'table', ...options } );
182
239
  }
@@ -24,6 +24,7 @@ import {
24
24
  } from '../utils/ui/table-properties';
25
25
  import { getTableWidgetAncestor } from '../utils/ui/widget';
26
26
  import { getBalloonTablePositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';
27
+ import { getNormalizedDefaultProperties } from '../utils/table-properties';
27
28
 
28
29
  const ERROR_TEXT_TIMEOUT = 500;
29
30
 
@@ -81,6 +82,16 @@ export default class TablePropertiesUI extends Plugin {
81
82
  const editor = this.editor;
82
83
  const t = editor.t;
83
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
+
84
95
  /**
85
96
  * The contextual balloon plugin instance.
86
97
  *
@@ -152,9 +163,11 @@ export default class TablePropertiesUI extends Plugin {
152
163
  const localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );
153
164
  const backgroundColorsConfig = normalizeColorOptions( config.backgroundColors );
154
165
  const localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );
166
+
155
167
  const view = new TablePropertiesView( editor.locale, {
156
168
  borderColors: localizedBorderColors,
157
- backgroundColors: localizedBackgroundColors
169
+ backgroundColors: localizedBackgroundColors,
170
+ defaultTableProperties: this._defaultTableProperties
158
171
  } );
159
172
  const t = editor.t;
160
173
 
@@ -196,44 +209,55 @@ export default class TablePropertiesUI extends Plugin {
196
209
  // property of the view has changed. They also validate the value and display errors in the UI
197
210
  // when necessary. This makes the view live, which means the changes are
198
211
  // visible in the editing as soon as the user types or changes fields' values.
199
- view.on( 'change:borderStyle', this._getPropertyChangeCallback( 'tableBorderStyle' ) );
212
+ view.on(
213
+ 'change:borderStyle',
214
+ this._getPropertyChangeCallback( 'tableBorderStyle', this._defaultTableProperties.borderStyle )
215
+ );
200
216
 
201
217
  view.on( 'change:borderColor', this._getValidatedPropertyChangeCallback( {
202
218
  viewField: view.borderColorInput,
203
219
  commandName: 'tableBorderColor',
204
220
  errorText: colorErrorText,
205
- validator: colorFieldValidator
221
+ validator: colorFieldValidator,
222
+ defaultValue: this._defaultTableProperties.borderColor
206
223
  } ) );
207
224
 
208
225
  view.on( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {
209
226
  viewField: view.borderWidthInput,
210
227
  commandName: 'tableBorderWidth',
211
228
  errorText: lengthErrorText,
212
- validator: lineWidthFieldValidator
229
+ validator: lineWidthFieldValidator,
230
+ defaultValue: this._defaultTableProperties.borderWidth
213
231
  } ) );
214
232
 
215
233
  view.on( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {
216
234
  viewField: view.backgroundInput,
217
235
  commandName: 'tableBackgroundColor',
218
236
  errorText: colorErrorText,
219
- validator: colorFieldValidator
237
+ validator: colorFieldValidator,
238
+ defaultValue: this._defaultTableProperties.backgroundColor
220
239
  } ) );
221
240
 
222
241
  view.on( 'change:width', this._getValidatedPropertyChangeCallback( {
223
242
  viewField: view.widthInput,
224
243
  commandName: 'tableWidth',
225
244
  errorText: lengthErrorText,
226
- validator: lengthFieldValidator
245
+ validator: lengthFieldValidator,
246
+ defaultValue: this._defaultTableProperties.width
227
247
  } ) );
228
248
 
229
249
  view.on( 'change:height', this._getValidatedPropertyChangeCallback( {
230
250
  viewField: view.heightInput,
231
251
  commandName: 'tableHeight',
232
252
  errorText: lengthErrorText,
233
- validator: lengthFieldValidator
253
+ validator: lengthFieldValidator,
254
+ defaultValue: this._defaultTableProperties.height
234
255
  } ) );
235
256
 
236
- view.on( 'change:alignment', this._getPropertyChangeCallback( 'tableAlignment' ) );
257
+ view.on(
258
+ 'change:alignment',
259
+ this._getPropertyChangeCallback( 'tableAlignment', this._defaultTableProperties.alignment )
260
+ );
237
261
 
238
262
  return view;
239
263
  }
@@ -250,10 +274,22 @@ export default class TablePropertiesUI extends Plugin {
250
274
  */
251
275
  _fillViewFormFromCommandValues() {
252
276
  const commands = this.editor.commands;
277
+ const borderStyleCommand = commands.get( 'tableBorderStyle' );
253
278
 
254
279
  Object.entries( propertyToCommandMap )
255
- .map( ( [ property, commandName ] ) => [ property, commands.get( commandName ).value || '' ] )
256
- .forEach( ( [ property, value ] ) => this.view.set( property, value ) );
280
+ .map( ( [ property, commandName ] ) => {
281
+ const defaultValue = this._defaultTableProperties[ property ] || '';
282
+
283
+ return [ property, commands.get( commandName ).value || defaultValue ];
284
+ } )
285
+ .forEach( ( [ property, value ] ) => {
286
+ // Do not set the `border-color` and `border-width` fields if `border-style:none`.
287
+ if ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {
288
+ return;
289
+ }
290
+
291
+ this.view.set( property, value );
292
+ } );
257
293
  }
258
294
 
259
295
  /**
@@ -348,12 +384,21 @@ export default class TablePropertiesUI extends Plugin {
348
384
  * Creates a callback that when executed upon {@link #view view's} property change
349
385
  * executes a related editor command with the new property value.
350
386
  *
387
+ * If new value will be set to the default value, the command will not be executed.
388
+ *
351
389
  * @private
352
- * @param {String} commandName
390
+ * @param {String} commandName The command that will be executed.
391
+ * @param {String} defaultValue The default value of the command.
353
392
  * @returns {Function}
354
393
  */
355
- _getPropertyChangeCallback( commandName ) {
356
- return ( evt, propertyName, newValue ) => {
394
+ _getPropertyChangeCallback( commandName, defaultValue ) {
395
+ return ( evt, propertyName, newValue, oldValue ) => {
396
+ // If the "oldValue" is missing and "newValue" is set to the default value, do not execute the command.
397
+ // It is an initial call (when opening the table properties view).
398
+ if ( !oldValue && defaultValue === newValue ) {
399
+ return;
400
+ }
401
+
357
402
  this.editor.execute( commandName, {
358
403
  value: newValue,
359
404
  batch: this._undoStepBatch
@@ -372,16 +417,24 @@ export default class TablePropertiesUI extends Plugin {
372
417
  * @param {module:ui/view~View} options.viewField
373
418
  * @param {Function} options.validator
374
419
  * @param {String} options.errorText
420
+ * @param {String} options.defaultValue
375
421
  * @returns {Function}
376
422
  */
377
- _getValidatedPropertyChangeCallback( { commandName, viewField, validator, errorText } ) {
423
+ _getValidatedPropertyChangeCallback( options ) {
424
+ const { commandName, viewField, validator, errorText, defaultValue } = options;
378
425
  const setErrorTextDebounced = debounce( () => {
379
426
  viewField.errorText = errorText;
380
427
  }, ERROR_TEXT_TIMEOUT );
381
428
 
382
- return ( evt, propertyName, newValue ) => {
429
+ return ( evt, propertyName, newValue, oldValue ) => {
383
430
  setErrorTextDebounced.cancel();
384
431
 
432
+ // If the "oldValue" is missing and "newValue" is set to the default value, do not execute the command.
433
+ // It is an initial call (when opening the table properties view).
434
+ if ( !oldValue && defaultValue === newValue ) {
435
+ return;
436
+ }
437
+
385
438
  if ( validator( newValue ) ) {
386
439
  this.editor.execute( commandName, {
387
440
  value: newValue,
@@ -58,6 +58,7 @@ export default class TablePropertiesView extends View {
58
58
  * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background
59
59
  * color palette used by the
60
60
  * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#backgroundInput}.
61
+ * @param {module:table/tableproperties~TablePropertiesOptions} options.defaultTableProperties The default table properties.
61
62
  */
62
63
  constructor( locale, options ) {
63
64
  super( locale );
@@ -396,9 +397,17 @@ export default class TablePropertiesView extends View {
396
397
  * @returns {Object.<String,module:ui/view~View>}
397
398
  */
398
399
  _createBorderFields() {
400
+ const defaultTableProperties = this.options.defaultTableProperties;
401
+ const defaultBorder = {
402
+ style: defaultTableProperties.borderStyle,
403
+ width: defaultTableProperties.borderWidth,
404
+ color: defaultTableProperties.borderColor
405
+ };
406
+
399
407
  const colorInputCreator = getLabeledColorInputCreator( {
400
408
  colorConfig: this.options.borderColors,
401
- columns: 5
409
+ columns: 5,
410
+ defaultColorValue: defaultBorder.color
402
411
  } );
403
412
  const locale = this.locale;
404
413
  const t = this.t;
@@ -433,7 +442,7 @@ export default class TablePropertiesView extends View {
433
442
 
434
443
  borderStyleDropdown.bind( 'isEmpty' ).to( this, 'borderStyle', value => !value );
435
444
 
436
- addListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this ) );
445
+ addListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this, defaultBorder.style ) );
437
446
 
438
447
  // -- Width ---------------------------------------------------
439
448
 
@@ -466,13 +475,20 @@ export default class TablePropertiesView extends View {
466
475
  this.borderColor = borderColorInput.fieldView.value;
467
476
  } );
468
477
 
469
- // Reset the border color and width fields when style is "none".
470
- // https://github.com/ckeditor/ckeditor5/issues/6227
471
- this.on( 'change:borderStyle', ( evt, name, value ) => {
472
- if ( !isBorderStyleSet( value ) ) {
478
+ // Reset the border color and width fields depending on the `border-style` value.
479
+ this.on( 'change:borderStyle', ( evt, name, newValue, oldValue ) => {
480
+ // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
481
+ // See: https://github.com/ckeditor/ckeditor5/issues/6227.
482
+ if ( !isBorderStyleSet( newValue ) ) {
473
483
  this.borderColor = '';
474
484
  this.borderWidth = '';
475
485
  }
486
+
487
+ // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
488
+ if ( !isBorderStyleSet( oldValue ) ) {
489
+ this.borderColor = defaultBorder.color;
490
+ this.borderWidth = defaultBorder.width;
491
+ }
476
492
  } );
477
493
 
478
494
  return {
@@ -504,7 +520,8 @@ export default class TablePropertiesView extends View {
504
520
 
505
521
  const backgroundInputCreator = getLabeledColorInputCreator( {
506
522
  colorConfig: this.options.backgroundColors,
507
- columns: 5
523
+ columns: 5,
524
+ defaultColorValue: this.options.defaultTableProperties.backgroundColor
508
525
  } );
509
526
 
510
527
  const backgroundInput = new LabeledFieldView( locale, backgroundInputCreator );
@@ -625,9 +642,7 @@ export default class TablePropertiesView extends View {
625
642
  toolbar: alignmentToolbar,
626
643
  labels: this._alignmentLabels,
627
644
  propertyName: 'alignment',
628
- nameToValue: name => {
629
- return name === 'center' ? '' : name;
630
- }
645
+ defaultValue: this.options.defaultTableProperties.alignment
631
646
  } );
632
647
 
633
648
  return {
@@ -710,5 +725,5 @@ export default class TablePropertiesView extends View {
710
725
  }
711
726
 
712
727
  function isBorderStyleSet( value ) {
713
- return !!value;
728
+ return value !== 'none';
714
729
  }
@@ -65,9 +65,25 @@ export default class TableProperties extends Plugin {
65
65
  * }
66
66
  * };
67
67
  *
68
- * **Note**: The configurations do not impact the data loaded into the editor,
68
+ * * The default styles for tables (`tableProperties.defaultProperties`):
69
+ *
70
+ * const tableConfig = {
71
+ * tableProperties: {
72
+ * defaultProperties: {
73
+ * borderStyle: 'dashed',
74
+ * borderColor: 'hsl(0, 0%, 90%)',
75
+ * borderWidth: '3px',
76
+ * alignment: 'left'
77
+ * }
78
+ * }
79
+ * }
80
+ *
81
+ * {@link module:table/tableproperties~TablePropertiesOptions Read more about the supported properties.}
82
+ *
83
+ * **Note**: The `borderColors` and `backgroundColors` options do not impact the data loaded into the editor,
69
84
  * i.e. they do not limit or filter the colors in the data. They are used only in the user interface
70
- * allowing users to pick colors in a more convenient way.
85
+ * allowing users to pick colors in a more convenient way. The `defaultProperties` option does impact the data.
86
+ * Default values will not be kept in the editor model.
71
87
  *
72
88
  * The default color palettes for the table background and the table border are the same
73
89
  * ({@link module:table/utils/ui/table-properties~defaultColors check out their content}).
@@ -79,3 +95,23 @@ export default class TableProperties extends Plugin {
79
95
  *
80
96
  * @member {Object} module:table/table~TableConfig#tableProperties
81
97
  */
98
+
99
+ /**
100
+ * The configuration of the table default properties feature.
101
+ *
102
+ * @typedef {Object} module:table/tableproperties~TablePropertiesOptions
103
+ *
104
+ * @property {String} width The default `width` of the table.
105
+ *
106
+ * @property {String} height The default `height` of the table.
107
+ *
108
+ * @property {String} backgroundColor The default `background-color` of the table.
109
+ *
110
+ * @property {String} borderColor The default `border-color` of the table.
111
+ *
112
+ * @property {String} borderWidth The default `border-width` of the table.
113
+ *
114
+ * @property {String} [borderStyle='none'] The default `border-style` of the table.
115
+ *
116
+ * @property {String} [alignment='center'] The default `alignment` of the table.
117
+ */
package/src/tableui.js CHANGED
@@ -278,7 +278,11 @@ export default class TableUI extends Plugin {
278
278
  const dropdownView = createDropdown( locale, SplitButtonView );
279
279
  const mergeCommandName = 'mergeTableCells';
280
280
 
281
- this._fillDropdownWithListOptions( dropdownView, options );
281
+ // Main command.
282
+ const mergeCommand = editor.commands.get( mergeCommandName );
283
+
284
+ // Subcommands in the dropdown.
285
+ const commands = this._fillDropdownWithListOptions( dropdownView, options );
282
286
 
283
287
  dropdownView.buttonView.set( {
284
288
  label,
@@ -287,6 +291,11 @@ export default class TableUI extends Plugin {
287
291
  isEnabled: true
288
292
  } );
289
293
 
294
+ // Make dropdown button disabled when all options are disabled together with the main command.
295
+ dropdownView.bind( 'isEnabled' ).toMany( [ mergeCommand, ...commands ], 'isEnabled', ( ...areEnabled ) => {
296
+ return areEnabled.some( isEnabled => isEnabled );
297
+ } );
298
+
290
299
  // Merge selected table cells when the main part of the split button is clicked.
291
300
  this.listenTo( dropdownView.buttonView, 'execute', () => {
292
301
  editor.execute( mergeCommandName );