@ckeditor/ckeditor5-table 0.0.0-nightly-next-20251209.0 → 0.0.0-nightly-20251210.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 (108) hide show
  1. package/build/table.js +2 -2
  2. package/build/translations/af.js +1 -1
  3. package/build/translations/ar.js +1 -1
  4. package/build/translations/ast.js +1 -1
  5. package/build/translations/az.js +1 -1
  6. package/build/translations/be.js +1 -1
  7. package/build/translations/bg.js +1 -1
  8. package/build/translations/bn.js +1 -1
  9. package/build/translations/bs.js +1 -1
  10. package/build/translations/ca.js +1 -1
  11. package/build/translations/cs.js +1 -1
  12. package/build/translations/da.js +1 -1
  13. package/build/translations/de-ch.js +1 -1
  14. package/build/translations/de.js +1 -1
  15. package/build/translations/el.js +1 -1
  16. package/build/translations/en-au.js +1 -1
  17. package/build/translations/en-gb.js +1 -1
  18. package/build/translations/eo.js +1 -1
  19. package/build/translations/es-co.js +1 -1
  20. package/build/translations/es.js +1 -1
  21. package/build/translations/et.js +1 -1
  22. package/build/translations/eu.js +1 -1
  23. package/build/translations/fa.js +1 -1
  24. package/build/translations/fi.js +1 -1
  25. package/build/translations/fr.js +1 -1
  26. package/build/translations/gl.js +1 -1
  27. package/build/translations/gu.js +1 -1
  28. package/build/translations/he.js +1 -1
  29. package/build/translations/hi.js +1 -1
  30. package/build/translations/hr.js +1 -1
  31. package/build/translations/hu.js +1 -1
  32. package/build/translations/hy.js +1 -1
  33. package/build/translations/id.js +1 -1
  34. package/build/translations/it.js +1 -1
  35. package/build/translations/ja.js +1 -1
  36. package/build/translations/jv.js +1 -1
  37. package/build/translations/kk.js +1 -1
  38. package/build/translations/km.js +1 -1
  39. package/build/translations/kn.js +1 -1
  40. package/build/translations/ko.js +1 -1
  41. package/build/translations/ku.js +1 -1
  42. package/build/translations/lt.js +1 -1
  43. package/build/translations/lv.js +1 -1
  44. package/build/translations/ms.js +1 -1
  45. package/build/translations/nb.js +1 -1
  46. package/build/translations/ne.js +1 -1
  47. package/build/translations/nl.js +1 -1
  48. package/build/translations/no.js +1 -1
  49. package/build/translations/oc.js +1 -1
  50. package/build/translations/pl.js +1 -1
  51. package/build/translations/pt-br.js +1 -1
  52. package/build/translations/pt.js +1 -1
  53. package/build/translations/ro.js +1 -1
  54. package/build/translations/ru.js +1 -1
  55. package/build/translations/si.js +1 -1
  56. package/build/translations/sk.js +1 -1
  57. package/build/translations/sl.js +1 -1
  58. package/build/translations/sq.js +1 -1
  59. package/build/translations/sr-latn.js +1 -1
  60. package/build/translations/sr.js +1 -1
  61. package/build/translations/sv.js +1 -1
  62. package/build/translations/th.js +1 -1
  63. package/build/translations/ti.js +1 -1
  64. package/build/translations/tk.js +1 -1
  65. package/build/translations/tr.js +1 -1
  66. package/build/translations/tt.js +1 -1
  67. package/build/translations/ug.js +1 -1
  68. package/build/translations/uk.js +1 -1
  69. package/build/translations/ur.js +1 -1
  70. package/build/translations/uz.js +1 -1
  71. package/build/translations/vi.js +1 -1
  72. package/build/translations/zh-cn.js +1 -1
  73. package/build/translations/zh.js +1 -1
  74. package/ckeditor5-metadata.json +1 -10
  75. package/dist/index-content.css +30 -30
  76. package/dist/index-editor.css +194 -120
  77. package/dist/index.css +265 -167
  78. package/dist/index.css.map +1 -1
  79. package/dist/index.js +2219 -148
  80. package/dist/index.js.map +1 -1
  81. package/lang/contexts.json +4 -0
  82. package/package.json +9 -9
  83. package/src/augmentation.d.ts +7 -0
  84. package/src/converters/downcast.js +12 -3
  85. package/src/index.d.ts +4 -0
  86. package/src/index.js +5 -0
  87. package/src/tablecellproperties/tablecellpropertiesuiexperimental.d.ts +128 -0
  88. package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +386 -0
  89. package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +0 -8
  90. package/src/tablecellproperties/ui/tablecellpropertiesview.js +10 -30
  91. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts +237 -0
  92. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +633 -0
  93. package/src/tableconfig.d.ts +4 -4
  94. package/src/tableproperties/tablepropertiesediting.js +147 -14
  95. package/src/tableproperties/tablepropertiesuiexperimental.d.ts +136 -0
  96. package/src/tableproperties/tablepropertiesuiexperimental.js +375 -0
  97. package/src/tableproperties/ui/tablepropertiesview.d.ts +0 -8
  98. package/src/tableproperties/ui/tablepropertiesview.js +37 -59
  99. package/src/tableproperties/ui/tablepropertiesviewexperimental.d.ts +216 -0
  100. package/src/tableproperties/ui/tablepropertiesviewexperimental.js +544 -0
  101. package/src/utils/ui/table-propertiesexperimental.d.ts +215 -0
  102. package/src/utils/ui/table-propertiesexperimental.js +391 -0
  103. package/theme/formrow-experimental.css +15 -0
  104. package/theme/formrow.css +0 -2
  105. package/theme/tableform-experimental.css +73 -0
  106. package/theme/tableform.css +5 -1
  107. package/theme/tableproperties-experimental.css +78 -0
  108. package/theme/tableproperties.css +0 -60
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
6
  import { toWidgetEditable, toWidget, Widget, isWidget, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';
7
7
  import { first, global, CKEditorError, KeystrokeHandler, FocusTracker, Collection, getLocalizedArrowKeyCodeDirection, Rect, DomEmitterMixin, toUnit } from '@ckeditor/ckeditor5-utils/dist/index.js';
8
8
  import { isObject, debounce, isEqual, throttle } from 'es-toolkit/compat';
9
- import { IconTable, IconTableColumn, IconTableRow, IconTableMergeCell, IconPreviousArrow, IconAlignBottom, IconAlignMiddle, IconAlignTop, IconAlignJustify, IconAlignRight, IconAlignCenter, IconAlignLeft, IconTableCellProperties, IconTableLayout, IconTableProperties, IconObjectRight, IconObjectLeft, IconObjectInlineRight, IconObjectCenter, IconObjectInlineLeft, IconCaption } from '@ckeditor/ckeditor5-icons/dist/index.js';
9
+ import { IconTable, IconTableColumn, IconTableRow, IconTableMergeCell, IconCheck, IconCancel, IconAlignBottom, IconAlignMiddle, IconAlignTop, IconAlignJustify, IconAlignRight, IconAlignCenter, IconAlignLeft, IconTableCellProperties, IconTableLayout, IconTableProperties, IconObjectInlineRight, IconObjectCenter, IconObjectInlineLeft, IconCaption, IconPreviousArrow, IconObjectRight, IconObjectLeft } from '@ckeditor/ckeditor5-icons/dist/index.js';
10
10
  import { View, addKeyboardHandlingForGrid, ButtonView, createDropdown, MenuBarMenuView, SwitchButtonView, SplitButtonView, addListToDropdown, UIModel, ViewCollection, FocusCycler, InputTextView, ColorSelectorView, FormHeaderView, FormRowView, submitHandler, LabelView, LabeledFieldView, createLabeledDropdown, createLabeledInputText, ToolbarView, BalloonPanelView, ContextualBalloon, normalizeColorOptions, getLocalizedColorOptions, clickOutsideHandler, DropdownButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
11
11
  import { ClipboardMarkersUtils, ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';
12
12
  import { DomEventObserver, isColorStyleValue, isLengthStyleValue, isPercentageStyleValue, addBorderStylesRules, addPaddingStylesRules, addBackgroundStylesRules, addMarginStylesRules, enableViewPlaceholder, ModelElement } from '@ckeditor/ckeditor5-engine/dist/index.js';
@@ -2119,7 +2119,10 @@ const downcastTableAlignmentConfig = {
2119
2119
  * Downcasts a plain table (also used in the clipboard pipeline).
2120
2120
  */ function convertPlainTable(editor) {
2121
2121
  return (table, conversionApi)=>{
2122
- if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2122
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2123
+ const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
2124
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2125
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2123
2126
  return null;
2124
2127
  }
2125
2128
  return downcastPlainTable(table, conversionApi, editor);
@@ -2129,7 +2132,10 @@ const downcastTableAlignmentConfig = {
2129
2132
  * Downcasts a plain table caption (also used in the clipboard pipeline).
2130
2133
  */ function convertPlainTableCaption(editor) {
2131
2134
  return (modelElement, { writer, options })=>{
2132
- if (!options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2135
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2136
+ const isClipboardPipeline = options.isClipboardPipeline;
2137
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2138
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2133
2139
  return null;
2134
2140
  }
2135
2141
  if (modelElement.parent.name === 'table') {
@@ -2217,7 +2223,10 @@ const downcastTableAlignmentConfig = {
2217
2223
  return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{
2218
2224
  const { item, attributeNewValue } = data;
2219
2225
  const { mapper, writer } = conversionApi;
2220
- if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2226
+ const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
2227
+ const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
2228
+ const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
2229
+ if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
2221
2230
  return;
2222
2231
  }
2223
2232
  if (!conversionApi.consumable.consume(item, evt.name)) {
@@ -7603,7 +7612,7 @@ const isEmpty = (val)=>val === '';
7603
7612
  *
7604
7613
  * @internal
7605
7614
  * @param t The "t" function provided by the editor that is used to localize strings.
7606
- */ function getBorderStyleLabels(t) {
7615
+ */ function getBorderStyleLabels$1(t) {
7607
7616
  return {
7608
7617
  none: t('None'),
7609
7618
  solid: t('Solid'),
@@ -7673,9 +7682,9 @@ const isEmpty = (val)=>val === '';
7673
7682
  *
7674
7683
  * @internal
7675
7684
  * @param defaultStyle The default border.
7676
- */ function getBorderStyleDefinitions(view, defaultStyle) {
7685
+ */ function getBorderStyleDefinitions$1(view, defaultStyle) {
7677
7686
  const itemDefinitions = new Collection();
7678
- const styleLabels = getBorderStyleLabels(view.t);
7687
+ const styleLabels = getBorderStyleLabels$1(view.t);
7679
7688
  for(const style in styleLabels){
7680
7689
  const definition = {
7681
7690
  type: 'button',
@@ -7718,7 +7727,7 @@ const isEmpty = (val)=>val === '';
7718
7727
  * @param options.propertyName The name of the observable property in the view.
7719
7728
  * @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
7720
7729
  * @param options.defaultValue Default value for the property.
7721
- */ function fillToolbar(options) {
7730
+ */ function fillToolbar$1(options) {
7722
7731
  const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
7723
7732
  for(const name in labels){
7724
7733
  const button = new ButtonView(view.locale);
@@ -7922,10 +7931,10 @@ const isEmpty = (val)=>val === '';
7922
7931
  * @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
7923
7932
  * the "Restore default" button. Instead of clearing the input field, the default color value will be set.
7924
7933
  * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
7925
- */ function getLabeledColorInputCreator(options) {
7934
+ */ function getLabeledColorInputCreator$1(options) {
7926
7935
  return (labeledFieldView, viewUid, statusUid)=>{
7927
7936
  const colorInputView = new ColorInputView(labeledFieldView.locale, {
7928
- colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
7937
+ colorDefinitions: colorConfigToColorGridDefinitions$1(options.colorConfig),
7929
7938
  columns: options.columns,
7930
7939
  defaultColorValue: options.defaultColorValue,
7931
7940
  colorPickerConfig: options.colorPickerConfig
@@ -7952,7 +7961,7 @@ const isEmpty = (val)=>val === '';
7952
7961
  const parsedValue = parseFloat(value);
7953
7962
  return !Number.isNaN(parsedValue) && value === String(parsedValue);
7954
7963
  }
7955
- function colorConfigToColorGridDefinitions(colorConfig) {
7964
+ function colorConfigToColorGridDefinitions$1(colorConfig) {
7956
7965
  return colorConfig.map((item)=>({
7957
7966
  color: item.model,
7958
7967
  label: item.label,
@@ -8011,9 +8020,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8011
8020
  /**
8012
8021
  * The "Cancel" button view.
8013
8022
  */ cancelButtonView;
8014
- /**
8015
- * The "Back" button view.
8016
- */ backButtonView;
8017
8023
  /**
8018
8024
  * A collection of views that can be focused in the form.
8019
8025
  */ _focusables;
@@ -8064,7 +8070,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8064
8070
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
8065
8071
  this.saveButtonView = saveButtonView;
8066
8072
  this.cancelButtonView = cancelButtonView;
8067
- this.backButtonView = this._createBackButton();
8068
8073
  this._focusables = new ViewCollection();
8069
8074
  this._focusCycler = new FocusCycler({
8070
8075
  focusables: this._focusables,
@@ -8078,11 +8083,9 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8078
8083
  }
8079
8084
  });
8080
8085
  // Form header.
8081
- const header = new FormHeaderView(locale, {
8086
+ this.children.add(new FormHeaderView(locale, {
8082
8087
  label: this.t('Cell properties')
8083
- });
8084
- header.children.add(this.backButtonView, 0);
8085
- this.children.add(header);
8088
+ }));
8086
8089
  // Border row.
8087
8090
  this.children.add(new FormRowView(locale, {
8088
8091
  labelView: borderRowLabel,
@@ -8139,8 +8142,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8139
8142
  // Action row.
8140
8143
  this.children.add(new FormRowView(locale, {
8141
8144
  children: [
8142
- this.cancelButtonView,
8143
- this.saveButtonView
8145
+ this.saveButtonView,
8146
+ this.cancelButtonView
8144
8147
  ],
8145
8148
  class: 'ck-table-form__action-row'
8146
8149
  }));
@@ -8185,9 +8188,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8185
8188
  this.paddingInput,
8186
8189
  this.horizontalAlignmentToolbar,
8187
8190
  this.verticalAlignmentToolbar,
8188
- this.cancelButtonView,
8189
8191
  this.saveButtonView,
8190
- this.backButtonView
8192
+ this.cancelButtonView
8191
8193
  ].forEach((view)=>{
8192
8194
  // Register the view as focusable.
8193
8195
  this._focusables.add(view);
@@ -8222,7 +8224,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8222
8224
  width: defaultTableCellProperties.borderWidth,
8223
8225
  color: defaultTableCellProperties.borderColor
8224
8226
  };
8225
- const colorInputCreator = getLabeledColorInputCreator({
8227
+ const colorInputCreator = getLabeledColorInputCreator$1({
8226
8228
  colorConfig: this.options.borderColors,
8227
8229
  columns: 5,
8228
8230
  defaultColorValue: defaultBorder.color,
@@ -8235,7 +8237,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8235
8237
  const borderRowLabel = new LabelView(locale);
8236
8238
  borderRowLabel.text = t('Border');
8237
8239
  // -- Style ---------------------------------------------------
8238
- const styleLabels = getBorderStyleLabels(t);
8240
+ const styleLabels = getBorderStyleLabels$1(t);
8239
8241
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
8240
8242
  borderStyleDropdown.set({
8241
8243
  label: accessibleLabel,
@@ -8255,7 +8257,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8255
8257
  this.borderStyle = evt.source._borderStyleValue;
8256
8258
  });
8257
8259
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
8258
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
8260
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
8259
8261
  role: 'menu',
8260
8262
  ariaLabel: accessibleLabel
8261
8263
  });
@@ -8266,7 +8268,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8266
8268
  class: 'ck-table-form__border-width'
8267
8269
  });
8268
8270
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
8269
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8271
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8270
8272
  borderWidthInput.fieldView.on('input', ()=>{
8271
8273
  this.borderWidth = borderWidthInput.fieldView.element.value;
8272
8274
  });
@@ -8277,7 +8279,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8277
8279
  class: 'ck-table-form__border-color'
8278
8280
  });
8279
8281
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
8280
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8282
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8281
8283
  borderColorInput.fieldView.on('input', ()=>{
8282
8284
  this.borderColor = borderColorInput.fieldView.value;
8283
8285
  });
@@ -8285,12 +8287,12 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8285
8287
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
8286
8288
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
8287
8289
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
8288
- if (!isBorderStyleSet$1(newValue)) {
8290
+ if (!isBorderStyleSet$3(newValue)) {
8289
8291
  this.borderColor = '';
8290
8292
  this.borderWidth = '';
8291
8293
  }
8292
8294
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
8293
- if (!isBorderStyleSet$1(oldValue)) {
8295
+ if (!isBorderStyleSet$3(oldValue)) {
8294
8296
  this.borderColor = defaultBorder.color;
8295
8297
  this.borderWidth = defaultBorder.width;
8296
8298
  }
@@ -8313,7 +8315,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8313
8315
  const backgroundRowLabel = new LabelView(locale);
8314
8316
  backgroundRowLabel.text = t('Background');
8315
8317
  // -- Background color input -----------------------------------
8316
- const colorInputCreator = getLabeledColorInputCreator({
8318
+ const colorInputCreator = getLabeledColorInputCreator$1({
8317
8319
  colorConfig: this.options.backgroundColors,
8318
8320
  columns: 5,
8319
8321
  defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
@@ -8431,7 +8433,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8431
8433
  role: 'radiogroup',
8432
8434
  ariaLabel: t('Horizontal text alignment toolbar')
8433
8435
  });
8434
- fillToolbar({
8436
+ fillToolbar$1({
8435
8437
  view: this,
8436
8438
  icons: ALIGNMENT_ICONS,
8437
8439
  toolbar: horizontalAlignmentToolbar,
@@ -8457,7 +8459,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8457
8459
  role: 'radiogroup',
8458
8460
  ariaLabel: t('Vertical text alignment toolbar')
8459
8461
  });
8460
- fillToolbar({
8462
+ fillToolbar$1({
8461
8463
  view: this,
8462
8464
  icons: ALIGNMENT_ICONS,
8463
8465
  toolbar: verticalAlignmentToolbar,
@@ -8489,7 +8491,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8489
8491
  ];
8490
8492
  saveButtonView.set({
8491
8493
  label: t('Save'),
8492
- class: 'ck-button-action',
8494
+ icon: IconCheck,
8495
+ class: 'ck-button-save',
8493
8496
  type: 'submit',
8494
8497
  withText: true
8495
8498
  });
@@ -8498,6 +8501,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8498
8501
  });
8499
8502
  cancelButtonView.set({
8500
8503
  label: t('Cancel'),
8504
+ icon: IconCancel,
8505
+ class: 'ck-button-cancel',
8501
8506
  withText: true
8502
8507
  });
8503
8508
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -8506,20 +8511,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8506
8511
  cancelButtonView
8507
8512
  };
8508
8513
  }
8509
- /**
8510
- * Creates a back button view that cancels the form.
8511
- */ _createBackButton() {
8512
- const t = this.locale.t;
8513
- const backButton = new ButtonView(this.locale);
8514
- backButton.set({
8515
- class: 'ck-button-back',
8516
- label: t('Back'),
8517
- icon: IconPreviousArrow,
8518
- tooltip: true
8519
- });
8520
- backButton.delegate('execute').to(this, 'cancel');
8521
- return backButton;
8522
- }
8523
8514
  /**
8524
8515
  * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
8525
8516
  */ get _horizontalAlignmentLabels() {
@@ -8557,7 +8548,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
8557
8548
  };
8558
8549
  }
8559
8550
  }
8560
- function isBorderStyleSet$1(value) {
8551
+ function isBorderStyleSet$3(value) {
8561
8552
  return value !== 'none';
8562
8553
  }
8563
8554
 
@@ -8656,9 +8647,9 @@ const BALLOON_POSITIONS = /* #__PURE__ */ (()=>[
8656
8647
  return Rect.getBoundingRect(rects);
8657
8648
  }
8658
8649
 
8659
- const ERROR_TEXT_TIMEOUT$1 = 500;
8650
+ const ERROR_TEXT_TIMEOUT$3 = 500;
8660
8651
  // Map of view properties and related commands.
8661
- const propertyToCommandMap$1 = {
8652
+ const propertyToCommandMap$3 = {
8662
8653
  borderStyle: 'tableCellBorderStyle',
8663
8654
  borderColor: 'tableCellBorderColor',
8664
8655
  borderWidth: 'tableCellBorderWidth',
@@ -8754,7 +8745,7 @@ const propertyToCommandMap$1 = {
8754
8745
  tooltip: true
8755
8746
  });
8756
8747
  this.listenTo(view, 'execute', ()=>this._showView());
8757
- const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));
8748
+ const commands = Object.values(propertyToCommandMap$3).map((commandName)=>editor.commands.get(commandName));
8758
8749
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
8759
8750
  return view;
8760
8751
  });
@@ -8872,7 +8863,7 @@ const propertyToCommandMap$1 = {
8872
8863
  */ _fillViewFormFromCommandValues() {
8873
8864
  const commands = this.editor.commands;
8874
8865
  const borderStyleCommand = commands.get('tableCellBorderStyle');
8875
- Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{
8866
+ Object.entries(propertyToCommandMap$3).map(([property, commandName])=>{
8876
8867
  const propertyKey = property;
8877
8868
  const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
8878
8869
  return [
@@ -8978,7 +8969,7 @@ const propertyToCommandMap$1 = {
8978
8969
  const { commandName, viewField, validator, errorText } = options;
8979
8970
  const setErrorTextDebounced = debounce(()=>{
8980
8971
  viewField.errorText = errorText;
8981
- }, ERROR_TEXT_TIMEOUT$1);
8972
+ }, ERROR_TEXT_TIMEOUT$3);
8982
8973
  return (evt, propertyName, newValue)=>{
8983
8974
  setErrorTextDebounced.cancel();
8984
8975
  // Do not execute the command on initial call (opening the table properties view).
@@ -11672,7 +11663,7 @@ const TABLE_TYPES = [
11672
11663
  const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
11673
11664
  includeAlignmentProperty: true
11674
11665
  });
11675
- const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') === true;
11666
+ const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') !== false;
11676
11667
  editor.data.addStyleProcessorRules(addMarginStylesRules);
11677
11668
  editor.data.addStyleProcessorRules(addBorderStylesRules);
11678
11669
  enableBorderProperties(editor, {
@@ -11683,7 +11674,11 @@ const TABLE_TYPES = [
11683
11674
  editor.commands.add('tableBorderColor', new TableBorderColorCommand(editor, defaultTableProperties.borderColor));
11684
11675
  editor.commands.add('tableBorderStyle', new TableBorderStyleCommand(editor, defaultTableProperties.borderStyle));
11685
11676
  editor.commands.add('tableBorderWidth', new TableBorderWidthCommand(editor, defaultTableProperties.borderWidth));
11686
- enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
11677
+ if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
11678
+ enableExtendedAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
11679
+ } else {
11680
+ enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment);
11681
+ }
11687
11682
  editor.commands.add('tableAlignment', new TableAlignmentCommand(editor, defaultTableProperties.alignment));
11688
11683
  enableTableToFigureProperty(schema, conversion, {
11689
11684
  modelAttribute: 'tableWidth',
@@ -11710,18 +11705,20 @@ const TABLE_TYPES = [
11710
11705
  defaultValue: defaultTableProperties.backgroundColor
11711
11706
  });
11712
11707
  editor.commands.add('tableBackgroundColor', new TableBackgroundColorCommand(editor, defaultTableProperties.backgroundColor));
11713
- const viewDoc = editor.editing.view.document;
11714
- // Adjust clipboard output to wrap tables in divs if needed (for alignment).
11715
- this.listenTo(viewDoc, 'clipboardOutput', (evt, data)=>{
11716
- editor.editing.view.change((writer)=>{
11717
- for (const { item } of writer.createRangeIn(data.content)){
11718
- wrapInDivIfNeeded(item, writer);
11719
- }
11720
- data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
11708
+ if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
11709
+ const viewDoc = editor.editing.view.document;
11710
+ // Adjust clipboard output to wrap tables in divs if needed (for alignment).
11711
+ this.listenTo(viewDoc, 'clipboardOutput', (evt, data)=>{
11712
+ editor.editing.view.change((writer)=>{
11713
+ for (const { item } of writer.createRangeIn(data.content)){
11714
+ wrapInDivIfNeeded(item, writer);
11715
+ }
11716
+ data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
11717
+ });
11718
+ }, {
11719
+ priority: 'lowest'
11721
11720
  });
11722
- }, {
11723
- priority: 'lowest'
11724
- });
11721
+ }
11725
11722
  }
11726
11723
  }
11727
11724
  /**
@@ -11791,10 +11788,10 @@ function insertWrapperWithAlignment(writer, align, table) {
11791
11788
  });
11792
11789
  }
11793
11790
  /**
11794
- * Enables the `'alignment'` attribute for table.
11791
+ * Enables the extended block`'alignment'` attribute for table.
11795
11792
  *
11796
11793
  * @param defaultValue The default alignment value.
11797
- */ function enableAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
11794
+ */ function enableExtendedAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
11798
11795
  schema.extend('table', {
11799
11796
  allowAttributes: [
11800
11797
  'tableAlignment'
@@ -11893,6 +11890,144 @@ function insertWrapperWithAlignment(writer, align, table) {
11893
11890
  });
11894
11891
  conversion.for('upcast').add(upcastTableAlignedDiv(defaultValue));
11895
11892
  }
11893
+ /**
11894
+ * Enables the `'alignment'` attribute for table.
11895
+ *
11896
+ * @param defaultValue The default alignment value.
11897
+ */ function enableAlignmentProperty(schema, conversion, defaultValue) {
11898
+ const ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;
11899
+ const FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;
11900
+ schema.extend('table', {
11901
+ allowAttributes: [
11902
+ 'tableAlignment'
11903
+ ]
11904
+ });
11905
+ schema.setAttributeProperties('tableAlignment', {
11906
+ isFormatting: true
11907
+ });
11908
+ conversion.for('downcast').attributeToAttribute({
11909
+ model: {
11910
+ name: 'table',
11911
+ key: 'tableAlignment',
11912
+ values: [
11913
+ 'left',
11914
+ 'center',
11915
+ 'right'
11916
+ ]
11917
+ },
11918
+ view: {
11919
+ left: {
11920
+ key: 'style',
11921
+ value: {
11922
+ float: 'left'
11923
+ }
11924
+ },
11925
+ right: {
11926
+ key: 'style',
11927
+ value: {
11928
+ float: 'right'
11929
+ }
11930
+ },
11931
+ center: (alignment, conversionApi, data)=>{
11932
+ const value = data.item.getAttribute('tableType') !== 'layout' ? {
11933
+ // Model: `alignment:center` => CSS: `float:none`.
11934
+ float: 'none'
11935
+ } : {
11936
+ 'margin-left': 'auto',
11937
+ 'margin-right': 'auto'
11938
+ };
11939
+ return {
11940
+ key: 'style',
11941
+ value
11942
+ };
11943
+ }
11944
+ },
11945
+ converterPriority: 'high'
11946
+ });
11947
+ conversion.for('upcast')// Support for the `float:*;` CSS definition for the table alignment.
11948
+ .attributeToAttribute({
11949
+ view: {
11950
+ name: /^(table|figure)$/,
11951
+ styles: {
11952
+ float: FLOAT_VALUES_REG_EXP
11953
+ }
11954
+ },
11955
+ model: {
11956
+ key: 'tableAlignment',
11957
+ value: (viewElement, conversionApi, data)=>{
11958
+ // Ignore other figure elements.
11959
+ if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
11960
+ return;
11961
+ }
11962
+ const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
11963
+ let align = viewElement.getStyle('float');
11964
+ // CSS: `float:none` => Model: `alignment:center`.
11965
+ if (align === 'none') {
11966
+ align = 'center';
11967
+ }
11968
+ if (align !== localDefaultValue) {
11969
+ return align;
11970
+ }
11971
+ // Consume the style even if not applied to the element so it won't be processed by other converters.
11972
+ conversionApi.consumable.consume(viewElement, {
11973
+ styles: 'float'
11974
+ });
11975
+ }
11976
+ }
11977
+ })// Support for the `margin-left:auto; margin-right:auto;` CSS definition for the table alignment.
11978
+ .attributeToAttribute({
11979
+ view: {
11980
+ name: /^(table|figure)$/,
11981
+ styles: {
11982
+ 'margin-left': 'auto',
11983
+ 'margin-right': 'auto'
11984
+ }
11985
+ },
11986
+ model: {
11987
+ key: 'tableAlignment',
11988
+ value: (viewElement, conversionApi, data)=>{
11989
+ // Ignore other figure elements.
11990
+ if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
11991
+ return;
11992
+ }
11993
+ const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
11994
+ const align = 'center';
11995
+ if (align !== localDefaultValue) {
11996
+ return align;
11997
+ }
11998
+ // Consume the styles even if not applied to the element so it won't be processed by other converters.
11999
+ conversionApi.consumable.consume(viewElement, {
12000
+ styles: [
12001
+ 'margin-left',
12002
+ 'margin-right'
12003
+ ]
12004
+ });
12005
+ }
12006
+ }
12007
+ })// Support for the `align` attribute as the backward compatibility while pasting from other sources.
12008
+ .attributeToAttribute({
12009
+ view: {
12010
+ name: 'table',
12011
+ attributes: {
12012
+ align: ALIGN_VALUES_REG_EXP
12013
+ }
12014
+ },
12015
+ model: {
12016
+ key: 'tableAlignment',
12017
+ value: (viewElement, conversionApi, data)=>{
12018
+ const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
12019
+ const align = viewElement.getAttribute('align');
12020
+ if (align !== localDefaultValue) {
12021
+ return align;
12022
+ }
12023
+ // Consume the attribute even if not applied to the element so it won't be processed by other converters.
12024
+ conversionApi.consumable.consume(viewElement, {
12025
+ attributes: 'align'
12026
+ });
12027
+ }
12028
+ }
12029
+ });
12030
+ }
11896
12031
  /**
11897
12032
  * Returns a function that converts the table view representation:
11898
12033
  *
@@ -12083,9 +12218,6 @@ function insertWrapperWithAlignment(writer, align, table) {
12083
12218
  /**
12084
12219
  * The "Cancel" button view.
12085
12220
  */ cancelButtonView;
12086
- /**
12087
- * The Back button view displayed in the header.
12088
- */ backButtonView;
12089
12221
  /**
12090
12222
  * A collection of views that can be focused in the form.
12091
12223
  */ _focusables;
@@ -12127,7 +12259,6 @@ function insertWrapperWithAlignment(writer, align, table) {
12127
12259
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
12128
12260
  this.saveButtonView = saveButtonView;
12129
12261
  this.cancelButtonView = cancelButtonView;
12130
- this.backButtonView = this._createBackButton();
12131
12262
  this._focusables = new ViewCollection();
12132
12263
  this._focusCycler = new FocusCycler({
12133
12264
  focusables: this._focusables,
@@ -12141,22 +12272,29 @@ function insertWrapperWithAlignment(writer, align, table) {
12141
12272
  }
12142
12273
  });
12143
12274
  // Form header.
12144
- const headerView = new FormHeaderView(locale, {
12275
+ this.children.add(new FormHeaderView(locale, {
12145
12276
  label: this.t('Table properties')
12146
- });
12147
- headerView.children.add(this.backButtonView, 0);
12148
- this.children.add(headerView);
12277
+ }));
12149
12278
  // Border row.
12150
12279
  this.children.add(new FormRowView(locale, {
12151
12280
  labelView: borderRowLabel,
12152
12281
  children: [
12153
12282
  borderRowLabel,
12154
12283
  borderStyleDropdown,
12155
- borderWidthInput,
12156
- borderColorInput
12284
+ borderColorInput,
12285
+ borderWidthInput
12157
12286
  ],
12158
12287
  class: 'ck-table-form__border-row'
12159
12288
  }));
12289
+ // Background row.
12290
+ this.children.add(new FormRowView(locale, {
12291
+ labelView: backgroundRowLabel,
12292
+ children: [
12293
+ backgroundRowLabel,
12294
+ backgroundInput
12295
+ ],
12296
+ class: 'ck-table-form__background-row'
12297
+ }));
12160
12298
  this.children.add(new FormRowView(locale, {
12161
12299
  children: [
12162
12300
  // Dimensions row.
@@ -12170,31 +12308,22 @@ function insertWrapperWithAlignment(writer, align, table) {
12170
12308
  ],
12171
12309
  class: 'ck-table-form__dimensions-row'
12172
12310
  }),
12173
- // Background row.
12311
+ // Alignment row.
12174
12312
  new FormRowView(locale, {
12175
- labelView: backgroundRowLabel,
12313
+ labelView: alignmentLabel,
12176
12314
  children: [
12177
- backgroundRowLabel,
12178
- backgroundInput
12315
+ alignmentLabel,
12316
+ alignmentToolbar
12179
12317
  ],
12180
- class: 'ck-table-form__background-row'
12318
+ class: 'ck-table-properties-form__alignment-row'
12181
12319
  })
12182
12320
  ]
12183
12321
  }));
12184
- // Alignment row.
12185
- this.children.add(new FormRowView(locale, {
12186
- labelView: alignmentLabel,
12187
- children: [
12188
- alignmentLabel,
12189
- alignmentToolbar
12190
- ],
12191
- class: 'ck-table-properties-form__alignment-row'
12192
- }));
12193
12322
  // Action row.
12194
12323
  this.children.add(new FormRowView(locale, {
12195
12324
  children: [
12196
- this.cancelButtonView,
12197
- this.saveButtonView
12325
+ this.saveButtonView,
12326
+ this.cancelButtonView
12198
12327
  ],
12199
12328
  class: 'ck-table-form__action-row'
12200
12329
  }));
@@ -12231,15 +12360,14 @@ function insertWrapperWithAlignment(writer, align, table) {
12231
12360
  });
12232
12361
  [
12233
12362
  this.borderStyleDropdown,
12234
- this.borderWidthInput,
12235
12363
  this.borderColorInput,
12364
+ this.borderWidthInput,
12365
+ this.backgroundInput,
12236
12366
  this.widthInput,
12237
12367
  this.heightInput,
12238
- this.backgroundInput,
12239
12368
  this.alignmentToolbar,
12240
- this.cancelButtonView,
12241
12369
  this.saveButtonView,
12242
- this.backButtonView
12370
+ this.cancelButtonView
12243
12371
  ].forEach((view)=>{
12244
12372
  // Register the view as focusable.
12245
12373
  this._focusables.add(view);
@@ -12274,7 +12402,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12274
12402
  width: defaultTableProperties.borderWidth,
12275
12403
  color: defaultTableProperties.borderColor
12276
12404
  };
12277
- const colorInputCreator = getLabeledColorInputCreator({
12405
+ const colorInputCreator = getLabeledColorInputCreator$1({
12278
12406
  colorConfig: this.options.borderColors,
12279
12407
  columns: 5,
12280
12408
  defaultColorValue: defaultBorder.color,
@@ -12287,7 +12415,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12287
12415
  const borderRowLabel = new LabelView(locale);
12288
12416
  borderRowLabel.text = t('Border');
12289
12417
  // -- Style ---------------------------------------------------
12290
- const styleLabels = getBorderStyleLabels(t);
12418
+ const styleLabels = getBorderStyleLabels$1(t);
12291
12419
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
12292
12420
  borderStyleDropdown.set({
12293
12421
  label: accessibleLabel,
@@ -12307,7 +12435,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12307
12435
  this.borderStyle = evt.source._borderStyleValue;
12308
12436
  });
12309
12437
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
12310
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
12438
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
12311
12439
  role: 'menu',
12312
12440
  ariaLabel: accessibleLabel
12313
12441
  });
@@ -12318,7 +12446,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12318
12446
  class: 'ck-table-form__border-width'
12319
12447
  });
12320
12448
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
12321
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
12449
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
12322
12450
  borderWidthInput.fieldView.on('input', ()=>{
12323
12451
  this.borderWidth = borderWidthInput.fieldView.element.value;
12324
12452
  });
@@ -12329,7 +12457,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12329
12457
  class: 'ck-table-form__border-color'
12330
12458
  });
12331
12459
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
12332
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
12460
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
12333
12461
  borderColorInput.fieldView.on('input', ()=>{
12334
12462
  this.borderColor = borderColorInput.fieldView.value;
12335
12463
  });
@@ -12337,12 +12465,12 @@ function insertWrapperWithAlignment(writer, align, table) {
12337
12465
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
12338
12466
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
12339
12467
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
12340
- if (!isBorderStyleSet(newValue)) {
12468
+ if (!isBorderStyleSet$2(newValue)) {
12341
12469
  this.borderColor = '';
12342
12470
  this.borderWidth = '';
12343
12471
  }
12344
12472
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
12345
- if (!isBorderStyleSet(oldValue)) {
12473
+ if (!isBorderStyleSet$2(oldValue)) {
12346
12474
  this.borderColor = defaultBorder.color;
12347
12475
  this.borderWidth = defaultBorder.width;
12348
12476
  }
@@ -12365,7 +12493,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12365
12493
  const backgroundRowLabel = new LabelView(locale);
12366
12494
  backgroundRowLabel.text = t('Background');
12367
12495
  // -- Background color input -----------------------------------
12368
- const backgroundInputCreator = getLabeledColorInputCreator({
12496
+ const backgroundInputCreator = getLabeledColorInputCreator$1({
12369
12497
  colorConfig: this.options.backgroundColors,
12370
12498
  columns: 5,
12371
12499
  defaultColorValue: this.options.defaultTableProperties.backgroundColor,
@@ -12447,7 +12575,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12447
12575
  const t = this.t;
12448
12576
  // -- Label ---------------------------------------------------
12449
12577
  const alignmentLabel = new LabelView(locale);
12450
- alignmentLabel.text = t('Table Alignment');
12578
+ alignmentLabel.text = t('Alignment');
12451
12579
  // -- Toolbar ---------------------------------------------------
12452
12580
  const alignmentToolbar = new ToolbarView(locale);
12453
12581
  alignmentToolbar.set({
@@ -12455,14 +12583,12 @@ function insertWrapperWithAlignment(writer, align, table) {
12455
12583
  isCompact: true,
12456
12584
  ariaLabel: t('Table alignment toolbar')
12457
12585
  });
12458
- fillToolbar({
12586
+ fillToolbar$1({
12459
12587
  view: this,
12460
12588
  icons: {
12461
12589
  left: IconObjectInlineLeft,
12462
12590
  center: IconObjectCenter,
12463
- right: IconObjectInlineRight,
12464
- blockLeft: IconObjectLeft,
12465
- blockRight: IconObjectRight
12591
+ right: IconObjectInlineRight
12466
12592
  },
12467
12593
  toolbar: alignmentToolbar,
12468
12594
  labels: this._alignmentLabels,
@@ -12493,7 +12619,8 @@ function insertWrapperWithAlignment(writer, align, table) {
12493
12619
  ];
12494
12620
  saveButtonView.set({
12495
12621
  label: t('Save'),
12496
- class: 'ck-button-action',
12622
+ icon: IconCheck,
12623
+ class: 'ck-button-save',
12497
12624
  type: 'submit',
12498
12625
  withText: true
12499
12626
  });
@@ -12502,6 +12629,8 @@ function insertWrapperWithAlignment(writer, align, table) {
12502
12629
  });
12503
12630
  cancelButtonView.set({
12504
12631
  label: t('Cancel'),
12632
+ icon: IconCancel,
12633
+ class: 'ck-button-cancel',
12505
12634
  withText: true
12506
12635
  });
12507
12636
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -12510,56 +12639,37 @@ function insertWrapperWithAlignment(writer, align, table) {
12510
12639
  cancelButtonView
12511
12640
  };
12512
12641
  }
12513
- /**
12514
- * Creates a back button view that cancels the form.
12515
- */ _createBackButton() {
12516
- const t = this.locale.t;
12517
- const backButton = new ButtonView(this.locale);
12518
- backButton.set({
12519
- class: 'ck-button-back',
12520
- label: t('Back'),
12521
- icon: IconPreviousArrow,
12522
- tooltip: true
12523
- });
12524
- backButton.delegate('execute').to(this, 'cancel');
12525
- return backButton;
12526
- }
12527
12642
  /**
12528
12643
  * Provides localized labels for {@link #alignmentToolbar} buttons.
12529
12644
  */ get _alignmentLabels() {
12530
12645
  const locale = this.locale;
12531
12646
  const t = this.t;
12532
- const blockLeft = t('Align table to the left with no text wrapping');
12533
- const blockRight = t('Align table to the right with no text wrapping');
12534
- const left = t('Align table to the left with text wrapping');
12535
- const center = t('Center table with no text wrapping');
12536
- const right = t('Align table to the right with text wrapping');
12647
+ const left = t('Align table to the left');
12648
+ const center = t('Center table');
12649
+ const right = t('Align table to the right');
12537
12650
  // Returns object with a proper order of labels.
12538
12651
  if (locale.uiLanguageDirection === 'rtl') {
12539
12652
  return {
12540
12653
  right,
12654
+ center,
12655
+ left
12656
+ };
12657
+ } else {
12658
+ return {
12541
12659
  left,
12542
- blockRight,
12543
12660
  center,
12544
- blockLeft
12661
+ right
12545
12662
  };
12546
12663
  }
12547
- return {
12548
- blockLeft,
12549
- center,
12550
- blockRight,
12551
- left,
12552
- right
12553
- };
12554
12664
  }
12555
12665
  }
12556
- function isBorderStyleSet(value) {
12666
+ function isBorderStyleSet$2(value) {
12557
12667
  return value !== 'none';
12558
12668
  }
12559
12669
 
12560
- const ERROR_TEXT_TIMEOUT = 500;
12670
+ const ERROR_TEXT_TIMEOUT$2 = 500;
12561
12671
  // Map of view properties and related commands.
12562
- const propertyToCommandMap = {
12672
+ const propertyToCommandMap$2 = {
12563
12673
  borderStyle: 'tableBorderStyle',
12564
12674
  borderColor: 'tableBorderColor',
12565
12675
  borderWidth: 'tableBorderWidth',
@@ -12651,7 +12761,7 @@ const propertyToCommandMap = {
12651
12761
  tooltip: true
12652
12762
  });
12653
12763
  this.listenTo(view, 'execute', ()=>this._showView());
12654
- const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
12764
+ const commands = Object.values(propertyToCommandMap$2).map((commandName)=>editor.commands.get(commandName));
12655
12765
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
12656
12766
  return view;
12657
12767
  }
@@ -12761,7 +12871,7 @@ const propertyToCommandMap = {
12761
12871
  */ _fillViewFormFromCommandValues() {
12762
12872
  const commands = this.editor.commands;
12763
12873
  const borderStyleCommand = commands.get('tableBorderStyle');
12764
- Object.entries(propertyToCommandMap).map(([property, commandName])=>{
12874
+ Object.entries(propertyToCommandMap$2).map(([property, commandName])=>{
12765
12875
  const propertyKey = property;
12766
12876
  const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
12767
12877
  return [
@@ -12870,7 +12980,7 @@ const propertyToCommandMap = {
12870
12980
  const { commandName, viewField, validator, errorText } = options;
12871
12981
  const setErrorTextDebounced = debounce(()=>{
12872
12982
  viewField.errorText = errorText;
12873
- }, ERROR_TEXT_TIMEOUT);
12983
+ }, ERROR_TEXT_TIMEOUT$2);
12874
12984
  return (evt, propertyName, newValue)=>{
12875
12985
  setErrorTextDebounced.cancel();
12876
12986
  // Do not execute the command on initial call (opening the table properties view).
@@ -13311,5 +13421,1966 @@ const propertyToCommandMap = {
13311
13421
  }
13312
13422
  }
13313
13423
 
13314
- export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesView, TableCellPropertyCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesView, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute };
13424
+ /**
13425
+ * Returns an object containing pairs of CSS border style values and their localized UI
13426
+ * labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}
13427
+ * and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.
13428
+ *
13429
+ * @internal
13430
+ * @param t The "t" function provided by the editor that is used to localize strings.
13431
+ */ function getBorderStyleLabels(t) {
13432
+ return {
13433
+ none: t('None'),
13434
+ solid: t('Solid'),
13435
+ dotted: t('Dotted'),
13436
+ dashed: t('Dashed'),
13437
+ double: t('Double'),
13438
+ groove: t('Groove'),
13439
+ ridge: t('Ridge'),
13440
+ inset: t('Inset'),
13441
+ outset: t('Outset')
13442
+ };
13443
+ }
13444
+ /**
13445
+ * Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.
13446
+ *
13447
+ * @internal
13448
+ * @param defaultStyle The default border.
13449
+ */ function getBorderStyleDefinitions(view, defaultStyle) {
13450
+ const itemDefinitions = new Collection();
13451
+ const styleLabels = getBorderStyleLabels(view.t);
13452
+ for(const style in styleLabels){
13453
+ const definition = {
13454
+ type: 'button',
13455
+ model: new UIModel({
13456
+ _borderStyleValue: style,
13457
+ label: styleLabels[style],
13458
+ role: 'menuitemradio',
13459
+ withText: true
13460
+ })
13461
+ };
13462
+ if (style === 'none') {
13463
+ definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
13464
+ if (defaultStyle === 'none') {
13465
+ return !value;
13466
+ }
13467
+ return value === style;
13468
+ });
13469
+ } else {
13470
+ definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
13471
+ return value === style;
13472
+ });
13473
+ }
13474
+ itemDefinitions.add(definition);
13475
+ }
13476
+ return itemDefinitions;
13477
+ }
13478
+ /**
13479
+ * A helper that fills a toolbar with buttons that:
13480
+ *
13481
+ * * have some labels,
13482
+ * * have some icons,
13483
+ * * set a certain UI view property value upon execution.
13484
+ *
13485
+ * @internal
13486
+ * @param options Configuration options
13487
+ * @param options.view The view that has the observable property.
13488
+ * @param options.icons Object with button icons.
13489
+ * @param options.toolbar The toolbar to fill with buttons.
13490
+ * @param options.labels Object with button labels.
13491
+ * @param options.propertyName The name of the observable property in the view.
13492
+ * @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
13493
+ * @param options.defaultValue Default value for the property.
13494
+ */ function fillToolbar(options) {
13495
+ const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
13496
+ for(const name in labels){
13497
+ const button = new ButtonView(view.locale);
13498
+ button.set({
13499
+ role: 'radio',
13500
+ isToggleable: true,
13501
+ label: labels[name],
13502
+ icon: icons[name],
13503
+ tooltip: labels[name]
13504
+ });
13505
+ // If specified the `nameToValue()` callback, map the value based on the option's name.
13506
+ const buttonValue = nameToValue ? nameToValue(name) : name;
13507
+ button.bind('isOn').to(view, propertyName, (value)=>{
13508
+ // `value` comes from `view[ propertyName ]`.
13509
+ let valueToCompare = value;
13510
+ // If it's empty, and the `defaultValue` is specified, use it instead.
13511
+ if (value === '' && defaultValue) {
13512
+ valueToCompare = defaultValue;
13513
+ }
13514
+ return buttonValue === valueToCompare;
13515
+ });
13516
+ button.on('execute', ()=>{
13517
+ // Allow toggling alignment if there is no default value specified (especially for layout tables).
13518
+ if (!defaultValue && buttonValue && view[propertyName] === buttonValue) {
13519
+ view[propertyName] = undefined;
13520
+ } else {
13521
+ view[propertyName] = buttonValue;
13522
+ }
13523
+ });
13524
+ toolbar.items.add(button);
13525
+ }
13526
+ }
13527
+ /**
13528
+ * Returns a creator for a color input with a label.
13529
+ *
13530
+ * For given options, it returns a function that creates an instance of a
13531
+ * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to
13532
+ * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.
13533
+ *
13534
+ * The helper does the following:
13535
+ *
13536
+ * * It sets the color input `id` and `ariaDescribedById` attributes.
13537
+ * * It binds the color input `isReadOnly` to the labeled view.
13538
+ * * It binds the color input `hasError` to the labeled view.
13539
+ * * It enables a logic that cleans up the error when the user starts typing in the color input.
13540
+ *
13541
+ * Usage:
13542
+ *
13543
+ * ```ts
13544
+ * const colorInputCreator = getLabeledColorInputCreator( {
13545
+ * colorConfig: [ ... ],
13546
+ * columns: 3,
13547
+ * } );
13548
+ *
13549
+ * const labeledInputView = new LabeledFieldView( locale, colorInputCreator );
13550
+ * console.log( labeledInputView.view ); // A color input instance.
13551
+ * ```
13552
+ *
13553
+ * @internal
13554
+ * @param options Color input options.
13555
+ * @param options.colorConfig The configuration of the color palette displayed in the input's dropdown.
13556
+ * @param options.columns The configuration of the number of columns the color palette consists of in the input's dropdown.
13557
+ * @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
13558
+ * the "Restore default" button. Instead of clearing the input field, the default color value will be set.
13559
+ * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
13560
+ */ function getLabeledColorInputCreator(options) {
13561
+ return (labeledFieldView, viewUid, statusUid)=>{
13562
+ const colorInputView = new ColorInputView(labeledFieldView.locale, {
13563
+ colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
13564
+ columns: options.columns,
13565
+ defaultColorValue: options.defaultColorValue,
13566
+ colorPickerConfig: options.colorPickerConfig
13567
+ });
13568
+ colorInputView.inputView.set({
13569
+ id: viewUid,
13570
+ ariaDescribedById: statusUid
13571
+ });
13572
+ colorInputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);
13573
+ colorInputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);
13574
+ colorInputView.on('input', ()=>{
13575
+ // UX: Make the error text disappear and disable the error indicator as the user
13576
+ // starts fixing the errors.
13577
+ labeledFieldView.errorText = null;
13578
+ });
13579
+ labeledFieldView.bind('isEmpty', 'isFocused').to(colorInputView);
13580
+ return colorInputView;
13581
+ };
13582
+ }
13583
+ function colorConfigToColorGridDefinitions(colorConfig) {
13584
+ return colorConfig.map((item)=>({
13585
+ color: item.model,
13586
+ label: item.label,
13587
+ options: {
13588
+ hasBorder: item.hasBorder
13589
+ }
13590
+ }));
13591
+ }
13592
+
13593
+ /**
13594
+ * The class representing a table properties form, allowing users to customize
13595
+ * certain style aspects of a table, for instance, border, background color, alignment, etc..
13596
+ */ class TablePropertiesViewExperimental extends View {
13597
+ /**
13598
+ * Options passed to the view. See {@link #constructor} to learn more.
13599
+ */ options;
13600
+ /**
13601
+ * Tracks information about the DOM focus in the form.
13602
+ */ focusTracker;
13603
+ /**
13604
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
13605
+ */ keystrokes;
13606
+ /**
13607
+ * A collection of child views in the form.
13608
+ */ children;
13609
+ /**
13610
+ * A dropdown that allows selecting the style of the table border.
13611
+ */ borderStyleDropdown;
13612
+ /**
13613
+ * An input that allows specifying the width of the table border.
13614
+ */ borderWidthInput;
13615
+ /**
13616
+ * An input that allows specifying the color of the table border.
13617
+ */ borderColorInput;
13618
+ /**
13619
+ * An input that allows specifying the table background color.
13620
+ */ backgroundInput;
13621
+ /**
13622
+ * An input that allows specifying the table width.
13623
+ */ widthInput;
13624
+ /**
13625
+ * An input that allows specifying the table height.
13626
+ */ heightInput;
13627
+ /**
13628
+ * A toolbar with buttons that allow changing the alignment of an entire table.
13629
+ */ alignmentToolbar;
13630
+ /**
13631
+ * The "Save" button view.
13632
+ */ saveButtonView;
13633
+ /**
13634
+ * The "Cancel" button view.
13635
+ */ cancelButtonView;
13636
+ /**
13637
+ * The Back button view displayed in the header.
13638
+ */ backButtonView;
13639
+ /**
13640
+ * A collection of views that can be focused in the form.
13641
+ */ _focusables;
13642
+ /**
13643
+ * Helps cycling over {@link #_focusables} in the form.
13644
+ */ _focusCycler;
13645
+ /**
13646
+ * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
13647
+ * @param options Additional configuration of the view.
13648
+ */ constructor(locale, options){
13649
+ super(locale);
13650
+ this.set({
13651
+ borderStyle: '',
13652
+ borderWidth: '',
13653
+ borderColor: '',
13654
+ backgroundColor: '',
13655
+ width: '',
13656
+ height: '',
13657
+ alignment: ''
13658
+ });
13659
+ this.options = options;
13660
+ const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
13661
+ const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
13662
+ const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
13663
+ const { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();
13664
+ this.focusTracker = new FocusTracker();
13665
+ this.keystrokes = new KeystrokeHandler();
13666
+ this.children = this.createCollection();
13667
+ this.borderStyleDropdown = borderStyleDropdown;
13668
+ this.borderWidthInput = borderWidthInput;
13669
+ this.borderColorInput = borderColorInput;
13670
+ this.backgroundInput = backgroundInput;
13671
+ this.widthInput = widthInput;
13672
+ this.heightInput = heightInput;
13673
+ this.alignmentToolbar = alignmentToolbar;
13674
+ // Defer creating to make sure other fields are present and the Save button can
13675
+ // bind its #isEnabled to their error messages so there's no way to save unless all
13676
+ // fields are valid.
13677
+ const { saveButtonView, cancelButtonView } = this._createActionButtons();
13678
+ this.saveButtonView = saveButtonView;
13679
+ this.cancelButtonView = cancelButtonView;
13680
+ this.backButtonView = this._createBackButton();
13681
+ this._focusables = new ViewCollection();
13682
+ this._focusCycler = new FocusCycler({
13683
+ focusables: this._focusables,
13684
+ focusTracker: this.focusTracker,
13685
+ keystrokeHandler: this.keystrokes,
13686
+ actions: {
13687
+ // Navigate form fields backwards using the Shift + Tab keystroke.
13688
+ focusPrevious: 'shift + tab',
13689
+ // Navigate form fields forwards using the Tab key.
13690
+ focusNext: 'tab'
13691
+ }
13692
+ });
13693
+ // Form header.
13694
+ const headerView = new FormHeaderView(locale, {
13695
+ label: this.t('Table properties')
13696
+ });
13697
+ headerView.children.add(this.backButtonView, 0);
13698
+ this.children.add(headerView);
13699
+ // Border row.
13700
+ this.children.add(new FormRowView(locale, {
13701
+ labelView: borderRowLabel,
13702
+ children: [
13703
+ borderRowLabel,
13704
+ borderStyleDropdown,
13705
+ borderWidthInput,
13706
+ borderColorInput
13707
+ ],
13708
+ class: 'ck-table-form__border-row'
13709
+ }));
13710
+ this.children.add(new FormRowView(locale, {
13711
+ children: [
13712
+ // Dimensions row.
13713
+ new FormRowView(locale, {
13714
+ labelView: dimensionsLabel,
13715
+ children: [
13716
+ dimensionsLabel,
13717
+ widthInput,
13718
+ operatorLabel,
13719
+ heightInput
13720
+ ],
13721
+ class: 'ck-table-form__dimensions-row'
13722
+ }),
13723
+ // Background row.
13724
+ new FormRowView(locale, {
13725
+ labelView: backgroundRowLabel,
13726
+ children: [
13727
+ backgroundRowLabel,
13728
+ backgroundInput
13729
+ ],
13730
+ class: 'ck-table-form__background-row'
13731
+ })
13732
+ ]
13733
+ }));
13734
+ // Alignment row.
13735
+ this.children.add(new FormRowView(locale, {
13736
+ labelView: alignmentLabel,
13737
+ children: [
13738
+ alignmentLabel,
13739
+ alignmentToolbar
13740
+ ],
13741
+ class: 'ck-table-properties-form__alignment-row'
13742
+ }));
13743
+ // Action row.
13744
+ this.children.add(new FormRowView(locale, {
13745
+ children: [
13746
+ this.cancelButtonView,
13747
+ this.saveButtonView
13748
+ ],
13749
+ class: 'ck-table-form__action-row'
13750
+ }));
13751
+ this.setTemplate({
13752
+ tag: 'form',
13753
+ attributes: {
13754
+ class: [
13755
+ 'ck',
13756
+ 'ck-form',
13757
+ 'ck-table-form',
13758
+ 'ck-table-properties-form',
13759
+ 'ck-table-properties-form_experimental'
13760
+ ],
13761
+ // https://github.com/ckeditor/ckeditor5-link/issues/90
13762
+ tabindex: '-1'
13763
+ },
13764
+ children: this.children
13765
+ });
13766
+ }
13767
+ /**
13768
+ * @inheritDoc
13769
+ */ render() {
13770
+ super.render();
13771
+ // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
13772
+ // which is of the "submit" DOM "type".
13773
+ submitHandler({
13774
+ view: this
13775
+ });
13776
+ // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
13777
+ [
13778
+ this.borderColorInput,
13779
+ this.backgroundInput
13780
+ ].forEach((view)=>{
13781
+ this._focusCycler.chain(view.fieldView.focusCycler);
13782
+ });
13783
+ [
13784
+ this.borderStyleDropdown,
13785
+ this.borderWidthInput,
13786
+ this.borderColorInput,
13787
+ this.widthInput,
13788
+ this.heightInput,
13789
+ this.backgroundInput,
13790
+ this.alignmentToolbar,
13791
+ this.cancelButtonView,
13792
+ this.saveButtonView,
13793
+ this.backButtonView
13794
+ ].forEach((view)=>{
13795
+ // Register the view as focusable.
13796
+ this._focusables.add(view);
13797
+ // Register the view in the focus tracker.
13798
+ this.focusTracker.add(view.element);
13799
+ });
13800
+ // Mainly for closing using "Esc" and navigation using "Tab".
13801
+ this.keystrokes.listenTo(this.element);
13802
+ }
13803
+ /**
13804
+ * @inheritDoc
13805
+ */ destroy() {
13806
+ super.destroy();
13807
+ this.focusTracker.destroy();
13808
+ this.keystrokes.destroy();
13809
+ }
13810
+ /**
13811
+ * Focuses the fist focusable field in the form.
13812
+ */ focus() {
13813
+ this._focusCycler.focusFirst();
13814
+ }
13815
+ /**
13816
+ * Creates the following form fields:
13817
+ *
13818
+ * * {@link #borderStyleDropdown},
13819
+ * * {@link #borderWidthInput},
13820
+ * * {@link #borderColorInput}.
13821
+ */ _createBorderFields() {
13822
+ const defaultTableProperties = this.options.defaultTableProperties;
13823
+ const defaultBorder = {
13824
+ style: defaultTableProperties.borderStyle,
13825
+ width: defaultTableProperties.borderWidth,
13826
+ color: defaultTableProperties.borderColor
13827
+ };
13828
+ const colorInputCreator = getLabeledColorInputCreator({
13829
+ colorConfig: this.options.borderColors,
13830
+ columns: 5,
13831
+ defaultColorValue: defaultBorder.color,
13832
+ colorPickerConfig: this.options.colorPickerConfig
13833
+ });
13834
+ const locale = this.locale;
13835
+ const t = this.t;
13836
+ const accessibleLabel = t('Style');
13837
+ // -- Group label ---------------------------------------------
13838
+ const borderRowLabel = new LabelView(locale);
13839
+ borderRowLabel.text = t('Border');
13840
+ // -- Style ---------------------------------------------------
13841
+ const styleLabels = getBorderStyleLabels(t);
13842
+ const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
13843
+ borderStyleDropdown.set({
13844
+ label: accessibleLabel,
13845
+ class: 'ck-table-form__border-style'
13846
+ });
13847
+ borderStyleDropdown.fieldView.buttonView.set({
13848
+ ariaLabel: accessibleLabel,
13849
+ ariaLabelledBy: undefined,
13850
+ isOn: false,
13851
+ withText: true,
13852
+ tooltip: accessibleLabel
13853
+ });
13854
+ borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
13855
+ return styleLabels[value ? value : 'none'];
13856
+ });
13857
+ borderStyleDropdown.fieldView.on('execute', (evt)=>{
13858
+ this.borderStyle = evt.source._borderStyleValue;
13859
+ });
13860
+ borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
13861
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
13862
+ role: 'menu',
13863
+ ariaLabel: accessibleLabel
13864
+ });
13865
+ // -- Width ---------------------------------------------------
13866
+ const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
13867
+ borderWidthInput.set({
13868
+ label: t('Width'),
13869
+ class: 'ck-table-form__border-width'
13870
+ });
13871
+ borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
13872
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
13873
+ borderWidthInput.fieldView.on('input', ()=>{
13874
+ this.borderWidth = borderWidthInput.fieldView.element.value;
13875
+ });
13876
+ // -- Color ---------------------------------------------------
13877
+ const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
13878
+ borderColorInput.set({
13879
+ label: t('Color'),
13880
+ class: 'ck-table-form__border-color'
13881
+ });
13882
+ borderColorInput.fieldView.bind('value').to(this, 'borderColor');
13883
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
13884
+ borderColorInput.fieldView.on('input', ()=>{
13885
+ this.borderColor = borderColorInput.fieldView.value;
13886
+ });
13887
+ // Reset the border color and width fields depending on the `border-style` value.
13888
+ this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
13889
+ // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
13890
+ // See: https://github.com/ckeditor/ckeditor5/issues/6227.
13891
+ if (!isBorderStyleSet$1(newValue)) {
13892
+ this.borderColor = '';
13893
+ this.borderWidth = '';
13894
+ }
13895
+ // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
13896
+ if (!isBorderStyleSet$1(oldValue)) {
13897
+ this.borderColor = defaultBorder.color;
13898
+ this.borderWidth = defaultBorder.width;
13899
+ }
13900
+ });
13901
+ return {
13902
+ borderRowLabel,
13903
+ borderStyleDropdown,
13904
+ borderColorInput,
13905
+ borderWidthInput
13906
+ };
13907
+ }
13908
+ /**
13909
+ * Creates the following form fields:
13910
+ *
13911
+ * * {@link #backgroundInput}.
13912
+ */ _createBackgroundFields() {
13913
+ const locale = this.locale;
13914
+ const t = this.t;
13915
+ // -- Group label ---------------------------------------------
13916
+ const backgroundRowLabel = new LabelView(locale);
13917
+ backgroundRowLabel.text = t('Background');
13918
+ // -- Background color input -----------------------------------
13919
+ const backgroundInputCreator = getLabeledColorInputCreator({
13920
+ colorConfig: this.options.backgroundColors,
13921
+ columns: 5,
13922
+ defaultColorValue: this.options.defaultTableProperties.backgroundColor,
13923
+ colorPickerConfig: this.options.colorPickerConfig
13924
+ });
13925
+ const backgroundInput = new LabeledFieldView(locale, backgroundInputCreator);
13926
+ backgroundInput.set({
13927
+ label: t('Color'),
13928
+ class: 'ck-table-properties-form__background'
13929
+ });
13930
+ backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
13931
+ backgroundInput.fieldView.on('input', ()=>{
13932
+ this.backgroundColor = backgroundInput.fieldView.value;
13933
+ });
13934
+ return {
13935
+ backgroundRowLabel,
13936
+ backgroundInput
13937
+ };
13938
+ }
13939
+ /**
13940
+ * Creates the following form fields:
13941
+ *
13942
+ * * {@link #widthInput},
13943
+ * * {@link #heightInput}.
13944
+ */ _createDimensionFields() {
13945
+ const locale = this.locale;
13946
+ const t = this.t;
13947
+ // -- Label ---------------------------------------------------
13948
+ const dimensionsLabel = new LabelView(locale);
13949
+ dimensionsLabel.text = t('Dimensions');
13950
+ // -- Width ---------------------------------------------------
13951
+ const widthInput = new LabeledFieldView(locale, createLabeledInputText);
13952
+ widthInput.set({
13953
+ label: t('Width'),
13954
+ class: 'ck-table-form__dimensions-row__width'
13955
+ });
13956
+ widthInput.fieldView.bind('value').to(this, 'width');
13957
+ widthInput.fieldView.on('input', ()=>{
13958
+ this.width = widthInput.fieldView.element.value;
13959
+ });
13960
+ // -- Operator ---------------------------------------------------
13961
+ const operatorLabel = new View(locale);
13962
+ operatorLabel.setTemplate({
13963
+ tag: 'span',
13964
+ attributes: {
13965
+ class: [
13966
+ 'ck-table-form__dimension-operator'
13967
+ ]
13968
+ },
13969
+ children: [
13970
+ {
13971
+ text: '×'
13972
+ }
13973
+ ]
13974
+ });
13975
+ // -- Height ---------------------------------------------------
13976
+ const heightInput = new LabeledFieldView(locale, createLabeledInputText);
13977
+ heightInput.set({
13978
+ label: t('Height'),
13979
+ class: 'ck-table-form__dimensions-row__height'
13980
+ });
13981
+ heightInput.fieldView.bind('value').to(this, 'height');
13982
+ heightInput.fieldView.on('input', ()=>{
13983
+ this.height = heightInput.fieldView.element.value;
13984
+ });
13985
+ return {
13986
+ dimensionsLabel,
13987
+ widthInput,
13988
+ operatorLabel,
13989
+ heightInput
13990
+ };
13991
+ }
13992
+ /**
13993
+ * Creates the following form fields:
13994
+ *
13995
+ * * {@link #alignmentToolbar}.
13996
+ */ _createAlignmentFields() {
13997
+ const locale = this.locale;
13998
+ const t = this.t;
13999
+ // -- Label ---------------------------------------------------
14000
+ const alignmentLabel = new LabelView(locale);
14001
+ alignmentLabel.text = t('Table Alignment');
14002
+ // -- Toolbar ---------------------------------------------------
14003
+ const alignmentToolbar = new ToolbarView(locale);
14004
+ alignmentToolbar.set({
14005
+ role: 'radiogroup',
14006
+ isCompact: true,
14007
+ ariaLabel: t('Table alignment toolbar')
14008
+ });
14009
+ fillToolbar({
14010
+ view: this,
14011
+ icons: {
14012
+ left: IconObjectInlineLeft,
14013
+ center: IconObjectCenter,
14014
+ right: IconObjectInlineRight,
14015
+ blockLeft: IconObjectLeft,
14016
+ blockRight: IconObjectRight
14017
+ },
14018
+ toolbar: alignmentToolbar,
14019
+ labels: this._alignmentLabels,
14020
+ propertyName: 'alignment',
14021
+ defaultValue: this.options.defaultTableProperties.alignment
14022
+ });
14023
+ return {
14024
+ alignmentLabel,
14025
+ alignmentToolbar
14026
+ };
14027
+ }
14028
+ /**
14029
+ * Creates the following form controls:
14030
+ *
14031
+ * * {@link #saveButtonView},
14032
+ * * {@link #cancelButtonView}.
14033
+ */ _createActionButtons() {
14034
+ const locale = this.locale;
14035
+ const t = this.t;
14036
+ const saveButtonView = new ButtonView(locale);
14037
+ const cancelButtonView = new ButtonView(locale);
14038
+ const fieldsThatShouldValidateToSave = [
14039
+ this.borderWidthInput,
14040
+ this.borderColorInput,
14041
+ this.backgroundInput,
14042
+ this.widthInput,
14043
+ this.heightInput
14044
+ ];
14045
+ saveButtonView.set({
14046
+ label: t('Save'),
14047
+ class: 'ck-button-action',
14048
+ type: 'submit',
14049
+ withText: true
14050
+ });
14051
+ saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
14052
+ return errorTexts.every((errorText)=>!errorText);
14053
+ });
14054
+ cancelButtonView.set({
14055
+ label: t('Cancel'),
14056
+ withText: true
14057
+ });
14058
+ cancelButtonView.delegate('execute').to(this, 'cancel');
14059
+ return {
14060
+ saveButtonView,
14061
+ cancelButtonView
14062
+ };
14063
+ }
14064
+ /**
14065
+ * Creates a back button view that cancels the form.
14066
+ */ _createBackButton() {
14067
+ const t = this.locale.t;
14068
+ const backButton = new ButtonView(this.locale);
14069
+ backButton.set({
14070
+ class: 'ck-button-back',
14071
+ label: t('Back'),
14072
+ icon: IconPreviousArrow,
14073
+ tooltip: true
14074
+ });
14075
+ backButton.delegate('execute').to(this, 'cancel');
14076
+ return backButton;
14077
+ }
14078
+ /**
14079
+ * Provides localized labels for {@link #alignmentToolbar} buttons.
14080
+ */ get _alignmentLabels() {
14081
+ const locale = this.locale;
14082
+ const t = this.t;
14083
+ const blockLeft = t('Align table to the left with no text wrapping');
14084
+ const blockRight = t('Align table to the right with no text wrapping');
14085
+ const left = t('Align table to the left with text wrapping');
14086
+ const center = t('Center table with no text wrapping');
14087
+ const right = t('Align table to the right with text wrapping');
14088
+ // Returns object with a proper order of labels.
14089
+ if (locale.uiLanguageDirection === 'rtl') {
14090
+ return {
14091
+ right,
14092
+ left,
14093
+ blockRight,
14094
+ center,
14095
+ blockLeft
14096
+ };
14097
+ }
14098
+ return {
14099
+ blockLeft,
14100
+ center,
14101
+ blockRight,
14102
+ left,
14103
+ right
14104
+ };
14105
+ }
14106
+ }
14107
+ function isBorderStyleSet$1(value) {
14108
+ return value !== 'none';
14109
+ }
14110
+
14111
+ const ERROR_TEXT_TIMEOUT$1 = 500;
14112
+ // Map of view properties and related commands.
14113
+ const propertyToCommandMap$1 = {
14114
+ borderStyle: 'tableBorderStyle',
14115
+ borderColor: 'tableBorderColor',
14116
+ borderWidth: 'tableBorderWidth',
14117
+ backgroundColor: 'tableBackgroundColor',
14118
+ width: 'tableWidth',
14119
+ height: 'tableHeight',
14120
+ alignment: 'tableAlignment'
14121
+ };
14122
+ /**
14123
+ * The table properties UI plugin. It introduces the `'tableProperties'` button
14124
+ * that opens a form allowing to specify visual styling of an entire table.
14125
+ *
14126
+ * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
14127
+ */ class TablePropertiesUIExperimental extends Plugin {
14128
+ /**
14129
+ * The default table properties.
14130
+ */ _defaultContentTableProperties;
14131
+ /**
14132
+ * The default layout table properties.
14133
+ */ _defaultLayoutTableProperties;
14134
+ /**
14135
+ * The contextual balloon plugin instance.
14136
+ */ _balloon;
14137
+ /**
14138
+ * The properties form view displayed inside the balloon.
14139
+ */ view = null;
14140
+ /**
14141
+ * The properties form view displayed inside the balloon (content table).
14142
+ */ _viewWithContentTableDefaults = null;
14143
+ /**
14144
+ * The properties form view displayed inside the balloon (layout table).
14145
+ */ _viewWithLayoutTableDefaults = null;
14146
+ /**
14147
+ * The batch used to undo all changes made by the form (which are live, as the user types)
14148
+ * when "Cancel" was pressed. Each time the view is shown, a new batch is created.
14149
+ */ _undoStepBatch;
14150
+ /**
14151
+ * Flag used to indicate whether view is ready to execute update commands
14152
+ * (it finished loading initial data).
14153
+ */ _isReady;
14154
+ /**
14155
+ * @inheritDoc
14156
+ */ static get requires() {
14157
+ return [
14158
+ ContextualBalloon
14159
+ ];
14160
+ }
14161
+ /**
14162
+ * @inheritDoc
14163
+ */ static get pluginName() {
14164
+ return 'TablePropertiesUIExperimental';
14165
+ }
14166
+ /**
14167
+ * @inheritDoc
14168
+ */ static get isOfficialPlugin() {
14169
+ return true;
14170
+ }
14171
+ /**
14172
+ * @inheritDoc
14173
+ */ constructor(editor){
14174
+ super(editor);
14175
+ editor.config.define('table.tableProperties', {
14176
+ borderColors: defaultColors,
14177
+ backgroundColors: defaultColors
14178
+ });
14179
+ }
14180
+ /**
14181
+ * @inheritDoc
14182
+ */ init() {
14183
+ const editor = this.editor;
14184
+ this._defaultContentTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
14185
+ includeAlignmentProperty: true
14186
+ });
14187
+ this._defaultLayoutTableProperties = getNormalizedDefaultProperties();
14188
+ this._balloon = editor.plugins.get(ContextualBalloon);
14189
+ editor.ui.componentFactory.add('tableProperties', ()=>this._createTablePropertiesButton());
14190
+ }
14191
+ /**
14192
+ * Creates the table properties button.
14193
+ *
14194
+ * @internal
14195
+ */ _createTablePropertiesButton() {
14196
+ const editor = this.editor;
14197
+ const t = editor.t;
14198
+ const view = new ButtonView(editor.locale);
14199
+ view.set({
14200
+ label: t('Table properties'),
14201
+ icon: IconTableProperties,
14202
+ tooltip: true
14203
+ });
14204
+ this.listenTo(view, 'execute', ()=>this._showView());
14205
+ const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));
14206
+ view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
14207
+ return view;
14208
+ }
14209
+ /**
14210
+ * @inheritDoc
14211
+ */ destroy() {
14212
+ super.destroy();
14213
+ // Destroy created UI components as they are not automatically destroyed.
14214
+ // See https://github.com/ckeditor/ckeditor5/issues/1341.
14215
+ if (this.view) {
14216
+ this.view.destroy();
14217
+ }
14218
+ }
14219
+ /**
14220
+ * Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.
14221
+ *
14222
+ * @returns The table properties form view instance.
14223
+ */ _createPropertiesView(defaultTableProperties) {
14224
+ const editor = this.editor;
14225
+ const config = editor.config.get('table.tableProperties');
14226
+ const borderColorsConfig = normalizeColorOptions(config.borderColors);
14227
+ const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
14228
+ const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
14229
+ const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
14230
+ const hasColorPicker = config.colorPicker !== false;
14231
+ const view = new TablePropertiesViewExperimental(editor.locale, {
14232
+ borderColors: localizedBorderColors,
14233
+ backgroundColors: localizedBackgroundColors,
14234
+ defaultTableProperties,
14235
+ colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
14236
+ });
14237
+ const t = editor.t;
14238
+ // Render the view so its #element is available for the clickOutsideHandler.
14239
+ view.render();
14240
+ this.listenTo(view, 'submit', ()=>{
14241
+ this._hideView();
14242
+ });
14243
+ this.listenTo(view, 'cancel', ()=>{
14244
+ // https://github.com/ckeditor/ckeditor5/issues/6180
14245
+ if (this._undoStepBatch.operations.length) {
14246
+ editor.execute('undo', this._undoStepBatch);
14247
+ }
14248
+ this._hideView();
14249
+ });
14250
+ // Close the balloon on Esc key press.
14251
+ view.keystrokes.set('Esc', (data, cancel)=>{
14252
+ this._hideView();
14253
+ cancel();
14254
+ });
14255
+ // Close on click outside of balloon panel element.
14256
+ clickOutsideHandler({
14257
+ emitter: view,
14258
+ activator: ()=>this._isViewInBalloon,
14259
+ contextElements: [
14260
+ this._balloon.view.element
14261
+ ],
14262
+ callback: ()=>this._hideView()
14263
+ });
14264
+ const colorErrorText = getLocalizedColorErrorText(t);
14265
+ const lengthErrorText = getLocalizedLengthErrorText(t);
14266
+ // Create the "UI -> editor data" binding.
14267
+ // These listeners update the editor data (via table commands) when any observable
14268
+ // property of the view has changed. They also validate the value and display errors in the UI
14269
+ // when necessary. This makes the view live, which means the changes are
14270
+ // visible in the editing as soon as the user types or changes fields' values.
14271
+ view.on('change:borderStyle', this._getPropertyChangeCallback('tableBorderStyle'));
14272
+ view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
14273
+ viewField: view.borderColorInput,
14274
+ commandName: 'tableBorderColor',
14275
+ errorText: colorErrorText,
14276
+ validator: colorFieldValidator
14277
+ }));
14278
+ view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
14279
+ viewField: view.borderWidthInput,
14280
+ commandName: 'tableBorderWidth',
14281
+ errorText: lengthErrorText,
14282
+ validator: lineWidthFieldValidator
14283
+ }));
14284
+ view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
14285
+ viewField: view.backgroundInput,
14286
+ commandName: 'tableBackgroundColor',
14287
+ errorText: colorErrorText,
14288
+ validator: colorFieldValidator
14289
+ }));
14290
+ view.on('change:width', this._getValidatedPropertyChangeCallback({
14291
+ viewField: view.widthInput,
14292
+ commandName: 'tableWidth',
14293
+ errorText: lengthErrorText,
14294
+ validator: lengthFieldValidator
14295
+ }));
14296
+ view.on('change:height', this._getValidatedPropertyChangeCallback({
14297
+ viewField: view.heightInput,
14298
+ commandName: 'tableHeight',
14299
+ errorText: lengthErrorText,
14300
+ validator: lengthFieldValidator
14301
+ }));
14302
+ view.on('change:alignment', this._getPropertyChangeCallback('tableAlignment'));
14303
+ return view;
14304
+ }
14305
+ /**
14306
+ * In this method the "editor data -> UI" binding is happening.
14307
+ *
14308
+ * When executed, this method obtains selected table property values from various table commands
14309
+ * and passes them to the {@link #view}.
14310
+ *
14311
+ * This way, the UI stays up–to–date with the editor data.
14312
+ */ _fillViewFormFromCommandValues() {
14313
+ const commands = this.editor.commands;
14314
+ const borderStyleCommand = commands.get('tableBorderStyle');
14315
+ Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{
14316
+ const propertyKey = property;
14317
+ const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
14318
+ return [
14319
+ propertyKey,
14320
+ commands.get(commandName).value || defaultValue
14321
+ ];
14322
+ }).forEach(([property, value])=>{
14323
+ // Do not set the `border-color` and `border-width` fields if `border-style:none`.
14324
+ if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
14325
+ return;
14326
+ }
14327
+ this.view.set(property, value);
14328
+ });
14329
+ this._isReady = true;
14330
+ }
14331
+ /**
14332
+ * Shows the {@link #view} in the {@link #_balloon}.
14333
+ *
14334
+ * **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains
14335
+ * all changes made to the document when the view is visible, allowing a single undo step
14336
+ * for all of them.
14337
+ */ _showView() {
14338
+ const editor = this.editor;
14339
+ const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
14340
+ const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
14341
+ const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
14342
+ if (useDefaults && !this._viewWithContentTableDefaults) {
14343
+ this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableProperties);
14344
+ } else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
14345
+ this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableProperties);
14346
+ }
14347
+ this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
14348
+ this.listenTo(editor.ui, 'update', ()=>{
14349
+ this._updateView();
14350
+ });
14351
+ // Update the view with the model values.
14352
+ this._fillViewFormFromCommandValues();
14353
+ this._balloon.add({
14354
+ view: this.view,
14355
+ position: getBalloonTablePositionData(editor)
14356
+ });
14357
+ // Create a new batch. Clicking "Cancel" will undo this batch.
14358
+ this._undoStepBatch = editor.model.createBatch();
14359
+ // Basic a11y.
14360
+ this.view.focus();
14361
+ }
14362
+ /**
14363
+ * Removes the {@link #view} from the {@link #_balloon}.
14364
+ */ _hideView() {
14365
+ const editor = this.editor;
14366
+ this.stopListening(editor.ui, 'update');
14367
+ this._isReady = false;
14368
+ // Blur any input element before removing it from DOM to prevent issues in some browsers.
14369
+ // See https://github.com/ckeditor/ckeditor5/issues/1501.
14370
+ this.view.saveButtonView.focus();
14371
+ this._balloon.remove(this.view);
14372
+ // Make sure the focus is not lost in the process by putting it directly
14373
+ // into the editing view.
14374
+ this.editor.editing.view.focus();
14375
+ }
14376
+ /**
14377
+ * Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.
14378
+ */ _updateView() {
14379
+ const editor = this.editor;
14380
+ const viewDocument = editor.editing.view.document;
14381
+ if (!getSelectionAffectedTableWidget(viewDocument.selection)) {
14382
+ this._hideView();
14383
+ } else if (this._isViewVisible) {
14384
+ repositionContextualBalloon(editor, 'table');
14385
+ }
14386
+ }
14387
+ /**
14388
+ * Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.
14389
+ */ get _isViewVisible() {
14390
+ return !!this.view && this._balloon.visibleView === this.view;
14391
+ }
14392
+ /**
14393
+ * Returns `true` when the {@link #view} is in the {@link #_balloon}.
14394
+ */ get _isViewInBalloon() {
14395
+ return !!this.view && this._balloon.hasView(this.view);
14396
+ }
14397
+ /**
14398
+ * Creates a callback that when executed upon {@link #view view's} property change
14399
+ * executes a related editor command with the new property value.
14400
+ *
14401
+ * If new value will be set to the default value, the command will not be executed.
14402
+ *
14403
+ * @param commandName The command that will be executed.
14404
+ */ _getPropertyChangeCallback(commandName) {
14405
+ return (evt, propertyName, newValue)=>{
14406
+ // Do not execute the command on initial call (opening the table properties view).
14407
+ if (!this._isReady) {
14408
+ return;
14409
+ }
14410
+ this.editor.execute(commandName, {
14411
+ value: newValue,
14412
+ batch: this._undoStepBatch
14413
+ });
14414
+ };
14415
+ }
14416
+ /**
14417
+ * Creates a callback that when executed upon {@link #view view's} property change:
14418
+ * * executes a related editor command with the new property value if the value is valid,
14419
+ * * or sets the error text next to the invalid field, if the value did not pass the validation.
14420
+ */ _getValidatedPropertyChangeCallback(options) {
14421
+ const { commandName, viewField, validator, errorText } = options;
14422
+ const setErrorTextDebounced = debounce(()=>{
14423
+ viewField.errorText = errorText;
14424
+ }, ERROR_TEXT_TIMEOUT$1);
14425
+ return (evt, propertyName, newValue)=>{
14426
+ setErrorTextDebounced.cancel();
14427
+ // Do not execute the command on initial call (opening the table properties view).
14428
+ if (!this._isReady) {
14429
+ return;
14430
+ }
14431
+ if (validator(newValue)) {
14432
+ this.editor.execute(commandName, {
14433
+ value: newValue,
14434
+ batch: this._undoStepBatch
14435
+ });
14436
+ viewField.errorText = null;
14437
+ } else {
14438
+ setErrorTextDebounced();
14439
+ }
14440
+ };
14441
+ }
14442
+ }
14443
+
14444
+ /**
14445
+ * The class representing a table cell properties form, allowing users to customize
14446
+ * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..
14447
+ */ class TableCellPropertiesViewExperimental extends View {
14448
+ /**
14449
+ * Options passed to the view. See {@link #constructor} to learn more.
14450
+ */ options;
14451
+ /**
14452
+ * Tracks information about the DOM focus in the form.
14453
+ */ focusTracker;
14454
+ /**
14455
+ * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
14456
+ */ keystrokes;
14457
+ /**
14458
+ * A collection of child views in the form.
14459
+ */ children;
14460
+ /**
14461
+ * A dropdown that allows selecting the style of the table cell border.
14462
+ */ borderStyleDropdown;
14463
+ /**
14464
+ * An input that allows specifying the width of the table cell border.
14465
+ */ borderWidthInput;
14466
+ /**
14467
+ * An input that allows specifying the color of the table cell border.
14468
+ */ borderColorInput;
14469
+ /**
14470
+ * An input that allows specifying the table cell background color.
14471
+ */ backgroundInput;
14472
+ /**
14473
+ * An input that allows specifying the table cell padding.
14474
+ */ paddingInput;
14475
+ /**
14476
+ * An input that allows specifying the table cell width.
14477
+ */ widthInput;
14478
+ /**
14479
+ * An input that allows specifying the table cell height.
14480
+ */ heightInput;
14481
+ /**
14482
+ * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.
14483
+ */ horizontalAlignmentToolbar;
14484
+ /**
14485
+ * A toolbar with buttons that allow changing the vertical text alignment in a table cell.
14486
+ */ verticalAlignmentToolbar;
14487
+ /**
14488
+ * The "Save" button view.
14489
+ */ saveButtonView;
14490
+ /**
14491
+ * The "Cancel" button view.
14492
+ */ cancelButtonView;
14493
+ /**
14494
+ * The "Back" button view.
14495
+ */ backButtonView;
14496
+ /**
14497
+ * A collection of views that can be focused in the form.
14498
+ */ _focusables;
14499
+ /**
14500
+ * Helps cycling over {@link #_focusables} in the form.
14501
+ */ _focusCycler;
14502
+ /**
14503
+ * @param locale The {@link module:core/editor/editor~Editor#locale} instance.
14504
+ * @param options Additional configuration of the view.
14505
+ * @param options.borderColors A configuration of the border color palette used by the
14506
+ * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.
14507
+ * @param options.backgroundColors A configuration of the background color palette used by the
14508
+ * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.
14509
+ * @param options.defaultTableCellProperties The default table cell properties.
14510
+ */ constructor(locale, options){
14511
+ super(locale);
14512
+ this.set({
14513
+ borderStyle: '',
14514
+ borderWidth: '',
14515
+ borderColor: '',
14516
+ padding: '',
14517
+ backgroundColor: '',
14518
+ width: '',
14519
+ height: '',
14520
+ horizontalAlignment: '',
14521
+ verticalAlignment: ''
14522
+ });
14523
+ this.options = options;
14524
+ const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
14525
+ const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
14526
+ const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
14527
+ const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
14528
+ this.focusTracker = new FocusTracker();
14529
+ this.keystrokes = new KeystrokeHandler();
14530
+ this.children = this.createCollection();
14531
+ this.borderStyleDropdown = borderStyleDropdown;
14532
+ this.borderWidthInput = borderWidthInput;
14533
+ this.borderColorInput = borderColorInput;
14534
+ this.backgroundInput = backgroundInput;
14535
+ this.paddingInput = this._createPaddingField();
14536
+ this.widthInput = widthInput;
14537
+ this.heightInput = heightInput;
14538
+ this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;
14539
+ this.verticalAlignmentToolbar = verticalAlignmentToolbar;
14540
+ // Defer creating to make sure other fields are present and the Save button can
14541
+ // bind its #isEnabled to their error messages so there's no way to save unless all
14542
+ // fields are valid.
14543
+ const { saveButtonView, cancelButtonView } = this._createActionButtons();
14544
+ this.saveButtonView = saveButtonView;
14545
+ this.cancelButtonView = cancelButtonView;
14546
+ this.backButtonView = this._createBackButton();
14547
+ this._focusables = new ViewCollection();
14548
+ this._focusCycler = new FocusCycler({
14549
+ focusables: this._focusables,
14550
+ focusTracker: this.focusTracker,
14551
+ keystrokeHandler: this.keystrokes,
14552
+ actions: {
14553
+ // Navigate form fields backwards using the Shift + Tab keystroke.
14554
+ focusPrevious: 'shift + tab',
14555
+ // Navigate form fields forwards using the Tab key.
14556
+ focusNext: 'tab'
14557
+ }
14558
+ });
14559
+ // Form header.
14560
+ const header = new FormHeaderView(locale, {
14561
+ label: this.t('Cell properties')
14562
+ });
14563
+ header.children.add(this.backButtonView, 0);
14564
+ this.children.add(header);
14565
+ // Border row.
14566
+ this.children.add(new FormRowView(locale, {
14567
+ labelView: borderRowLabel,
14568
+ children: [
14569
+ borderRowLabel,
14570
+ borderStyleDropdown,
14571
+ borderColorInput,
14572
+ borderWidthInput
14573
+ ],
14574
+ class: 'ck-table-form__border-row'
14575
+ }));
14576
+ // Background.
14577
+ this.children.add(new FormRowView(locale, {
14578
+ labelView: backgroundRowLabel,
14579
+ children: [
14580
+ backgroundRowLabel,
14581
+ backgroundInput
14582
+ ],
14583
+ class: 'ck-table-form__background-row'
14584
+ }));
14585
+ // Dimensions row and padding.
14586
+ this.children.add(new FormRowView(locale, {
14587
+ children: [
14588
+ // Dimensions row.
14589
+ new FormRowView(locale, {
14590
+ labelView: dimensionsLabel,
14591
+ children: [
14592
+ dimensionsLabel,
14593
+ widthInput,
14594
+ operatorLabel,
14595
+ heightInput
14596
+ ],
14597
+ class: 'ck-table-form__dimensions-row'
14598
+ }),
14599
+ // Padding row.
14600
+ new FormRowView(locale, {
14601
+ children: [
14602
+ this.paddingInput
14603
+ ],
14604
+ class: 'ck-table-cell-properties-form__padding-row'
14605
+ })
14606
+ ]
14607
+ }));
14608
+ // Text alignment row.
14609
+ this.children.add(new FormRowView(locale, {
14610
+ labelView: alignmentLabel,
14611
+ children: [
14612
+ alignmentLabel,
14613
+ horizontalAlignmentToolbar,
14614
+ verticalAlignmentToolbar
14615
+ ],
14616
+ class: 'ck-table-cell-properties-form__alignment-row'
14617
+ }));
14618
+ // Action row.
14619
+ this.children.add(new FormRowView(locale, {
14620
+ children: [
14621
+ this.cancelButtonView,
14622
+ this.saveButtonView
14623
+ ],
14624
+ class: 'ck-table-form__action-row'
14625
+ }));
14626
+ this.setTemplate({
14627
+ tag: 'form',
14628
+ attributes: {
14629
+ class: [
14630
+ 'ck',
14631
+ 'ck-form',
14632
+ 'ck-table-form',
14633
+ 'ck-table-cell-properties-form'
14634
+ ],
14635
+ // https://github.com/ckeditor/ckeditor5-link/issues/90
14636
+ tabindex: '-1'
14637
+ },
14638
+ children: this.children
14639
+ });
14640
+ }
14641
+ /**
14642
+ * @inheritDoc
14643
+ */ render() {
14644
+ super.render();
14645
+ // Enable the "submit" event for this view. It can be triggered by the #saveButtonView
14646
+ // which is of the "submit" DOM "type".
14647
+ submitHandler({
14648
+ view: this
14649
+ });
14650
+ // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
14651
+ [
14652
+ this.borderColorInput,
14653
+ this.backgroundInput
14654
+ ].forEach((view)=>{
14655
+ this._focusCycler.chain(view.fieldView.focusCycler);
14656
+ });
14657
+ [
14658
+ this.borderStyleDropdown,
14659
+ this.borderColorInput,
14660
+ this.borderWidthInput,
14661
+ this.backgroundInput,
14662
+ this.widthInput,
14663
+ this.heightInput,
14664
+ this.paddingInput,
14665
+ this.horizontalAlignmentToolbar,
14666
+ this.verticalAlignmentToolbar,
14667
+ this.cancelButtonView,
14668
+ this.saveButtonView,
14669
+ this.backButtonView
14670
+ ].forEach((view)=>{
14671
+ // Register the view as focusable.
14672
+ this._focusables.add(view);
14673
+ // Register the view in the focus tracker.
14674
+ this.focusTracker.add(view.element);
14675
+ });
14676
+ // Mainly for closing using "Esc" and navigation using "Tab".
14677
+ this.keystrokes.listenTo(this.element);
14678
+ }
14679
+ /**
14680
+ * @inheritDoc
14681
+ */ destroy() {
14682
+ super.destroy();
14683
+ this.focusTracker.destroy();
14684
+ this.keystrokes.destroy();
14685
+ }
14686
+ /**
14687
+ * Focuses the fist focusable field in the form.
14688
+ */ focus() {
14689
+ this._focusCycler.focusFirst();
14690
+ }
14691
+ /**
14692
+ * Creates the following form fields:
14693
+ *
14694
+ * * {@link #borderStyleDropdown},
14695
+ * * {@link #borderWidthInput},
14696
+ * * {@link #borderColorInput}.
14697
+ */ _createBorderFields() {
14698
+ const defaultTableCellProperties = this.options.defaultTableCellProperties;
14699
+ const defaultBorder = {
14700
+ style: defaultTableCellProperties.borderStyle,
14701
+ width: defaultTableCellProperties.borderWidth,
14702
+ color: defaultTableCellProperties.borderColor
14703
+ };
14704
+ const colorInputCreator = getLabeledColorInputCreator({
14705
+ colorConfig: this.options.borderColors,
14706
+ columns: 5,
14707
+ defaultColorValue: defaultBorder.color,
14708
+ colorPickerConfig: this.options.colorPickerConfig
14709
+ });
14710
+ const locale = this.locale;
14711
+ const t = this.t;
14712
+ const accessibleLabel = t('Style');
14713
+ // -- Group label ---------------------------------------------
14714
+ const borderRowLabel = new LabelView(locale);
14715
+ borderRowLabel.text = t('Border');
14716
+ // -- Style ---------------------------------------------------
14717
+ const styleLabels = getBorderStyleLabels(t);
14718
+ const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
14719
+ borderStyleDropdown.set({
14720
+ label: accessibleLabel,
14721
+ class: 'ck-table-form__border-style'
14722
+ });
14723
+ borderStyleDropdown.fieldView.buttonView.set({
14724
+ ariaLabel: accessibleLabel,
14725
+ ariaLabelledBy: undefined,
14726
+ isOn: false,
14727
+ withText: true,
14728
+ tooltip: accessibleLabel
14729
+ });
14730
+ borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
14731
+ return styleLabels[value ? value : 'none'];
14732
+ });
14733
+ borderStyleDropdown.fieldView.on('execute', (evt)=>{
14734
+ this.borderStyle = evt.source._borderStyleValue;
14735
+ });
14736
+ borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
14737
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
14738
+ role: 'menu',
14739
+ ariaLabel: accessibleLabel
14740
+ });
14741
+ // -- Width ---------------------------------------------------
14742
+ const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
14743
+ borderWidthInput.set({
14744
+ label: t('Width'),
14745
+ class: 'ck-table-form__border-width'
14746
+ });
14747
+ borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
14748
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
14749
+ borderWidthInput.fieldView.on('input', ()=>{
14750
+ this.borderWidth = borderWidthInput.fieldView.element.value;
14751
+ });
14752
+ // -- Color ---------------------------------------------------
14753
+ const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
14754
+ borderColorInput.set({
14755
+ label: t('Color'),
14756
+ class: 'ck-table-form__border-color'
14757
+ });
14758
+ borderColorInput.fieldView.bind('value').to(this, 'borderColor');
14759
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
14760
+ borderColorInput.fieldView.on('input', ()=>{
14761
+ this.borderColor = borderColorInput.fieldView.value;
14762
+ });
14763
+ // Reset the border color and width fields depending on the `border-style` value.
14764
+ this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
14765
+ // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
14766
+ // See: https://github.com/ckeditor/ckeditor5/issues/6227.
14767
+ if (!isBorderStyleSet(newValue)) {
14768
+ this.borderColor = '';
14769
+ this.borderWidth = '';
14770
+ }
14771
+ // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
14772
+ if (!isBorderStyleSet(oldValue)) {
14773
+ this.borderColor = defaultBorder.color;
14774
+ this.borderWidth = defaultBorder.width;
14775
+ }
14776
+ });
14777
+ return {
14778
+ borderRowLabel,
14779
+ borderStyleDropdown,
14780
+ borderColorInput,
14781
+ borderWidthInput
14782
+ };
14783
+ }
14784
+ /**
14785
+ * Creates the following form fields:
14786
+ *
14787
+ * * {@link #backgroundInput}.
14788
+ */ _createBackgroundFields() {
14789
+ const locale = this.locale;
14790
+ const t = this.t;
14791
+ // -- Group label ---------------------------------------------
14792
+ const backgroundRowLabel = new LabelView(locale);
14793
+ backgroundRowLabel.text = t('Background');
14794
+ // -- Background color input -----------------------------------
14795
+ const colorInputCreator = getLabeledColorInputCreator({
14796
+ colorConfig: this.options.backgroundColors,
14797
+ columns: 5,
14798
+ defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
14799
+ colorPickerConfig: this.options.colorPickerConfig
14800
+ });
14801
+ const backgroundInput = new LabeledFieldView(locale, colorInputCreator);
14802
+ backgroundInput.set({
14803
+ label: t('Color'),
14804
+ class: 'ck-table-cell-properties-form__background'
14805
+ });
14806
+ backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
14807
+ backgroundInput.fieldView.on('input', ()=>{
14808
+ this.backgroundColor = backgroundInput.fieldView.value;
14809
+ });
14810
+ return {
14811
+ backgroundRowLabel,
14812
+ backgroundInput
14813
+ };
14814
+ }
14815
+ /**
14816
+ * Creates the following form fields:
14817
+ *
14818
+ * * {@link #widthInput}.
14819
+ * * {@link #heightInput}.
14820
+ */ _createDimensionFields() {
14821
+ const locale = this.locale;
14822
+ const t = this.t;
14823
+ // -- Label ---------------------------------------------------
14824
+ const dimensionsLabel = new LabelView(locale);
14825
+ dimensionsLabel.text = t('Dimensions');
14826
+ // -- Width ---------------------------------------------------
14827
+ const widthInput = new LabeledFieldView(locale, createLabeledInputText);
14828
+ widthInput.set({
14829
+ label: t('Width'),
14830
+ class: 'ck-table-form__dimensions-row__width'
14831
+ });
14832
+ widthInput.fieldView.bind('value').to(this, 'width');
14833
+ widthInput.fieldView.on('input', ()=>{
14834
+ this.width = widthInput.fieldView.element.value;
14835
+ });
14836
+ // -- Operator ---------------------------------------------------
14837
+ const operatorLabel = new View(locale);
14838
+ operatorLabel.setTemplate({
14839
+ tag: 'span',
14840
+ attributes: {
14841
+ class: [
14842
+ 'ck-table-form__dimension-operator'
14843
+ ]
14844
+ },
14845
+ children: [
14846
+ {
14847
+ text: '×'
14848
+ }
14849
+ ]
14850
+ });
14851
+ // -- Height ---------------------------------------------------
14852
+ const heightInput = new LabeledFieldView(locale, createLabeledInputText);
14853
+ heightInput.set({
14854
+ label: t('Height'),
14855
+ class: 'ck-table-form__dimensions-row__height'
14856
+ });
14857
+ heightInput.fieldView.bind('value').to(this, 'height');
14858
+ heightInput.fieldView.on('input', ()=>{
14859
+ this.height = heightInput.fieldView.element.value;
14860
+ });
14861
+ return {
14862
+ dimensionsLabel,
14863
+ widthInput,
14864
+ operatorLabel,
14865
+ heightInput
14866
+ };
14867
+ }
14868
+ /**
14869
+ * Creates the following form fields:
14870
+ *
14871
+ * * {@link #paddingInput}.
14872
+ */ _createPaddingField() {
14873
+ const locale = this.locale;
14874
+ const t = this.t;
14875
+ const paddingInput = new LabeledFieldView(locale, createLabeledInputText);
14876
+ paddingInput.set({
14877
+ label: t('Padding'),
14878
+ class: 'ck-table-cell-properties-form__padding'
14879
+ });
14880
+ paddingInput.fieldView.bind('value').to(this, 'padding');
14881
+ paddingInput.fieldView.on('input', ()=>{
14882
+ this.padding = paddingInput.fieldView.element.value;
14883
+ });
14884
+ return paddingInput;
14885
+ }
14886
+ /**
14887
+ * Creates the following form fields:
14888
+ *
14889
+ * * {@link #horizontalAlignmentToolbar},
14890
+ * * {@link #verticalAlignmentToolbar}.
14891
+ */ _createAlignmentFields() {
14892
+ const locale = this.locale;
14893
+ const t = this.t;
14894
+ const alignmentLabel = new LabelView(locale);
14895
+ const ALIGNMENT_ICONS = {
14896
+ left: IconAlignLeft,
14897
+ center: IconAlignCenter,
14898
+ right: IconAlignRight,
14899
+ justify: IconAlignJustify,
14900
+ top: IconAlignTop,
14901
+ middle: IconAlignMiddle,
14902
+ bottom: IconAlignBottom
14903
+ };
14904
+ alignmentLabel.text = t('Table cell text alignment');
14905
+ // -- Horizontal ---------------------------------------------------
14906
+ const horizontalAlignmentToolbar = new ToolbarView(locale);
14907
+ const isContentRTL = locale.contentLanguageDirection === 'rtl';
14908
+ horizontalAlignmentToolbar.set({
14909
+ isCompact: true,
14910
+ role: 'radiogroup',
14911
+ ariaLabel: t('Horizontal text alignment toolbar')
14912
+ });
14913
+ fillToolbar({
14914
+ view: this,
14915
+ icons: ALIGNMENT_ICONS,
14916
+ toolbar: horizontalAlignmentToolbar,
14917
+ labels: this._horizontalAlignmentLabels,
14918
+ propertyName: 'horizontalAlignment',
14919
+ nameToValue: (name)=>{
14920
+ // For the RTL content, we want to swap the buttons "align to the left" and "align to the right".
14921
+ if (isContentRTL) {
14922
+ if (name === 'left') {
14923
+ return 'right';
14924
+ } else if (name === 'right') {
14925
+ return 'left';
14926
+ }
14927
+ }
14928
+ return name;
14929
+ },
14930
+ defaultValue: this.options.defaultTableCellProperties.horizontalAlignment
14931
+ });
14932
+ // -- Vertical -----------------------------------------------------
14933
+ const verticalAlignmentToolbar = new ToolbarView(locale);
14934
+ verticalAlignmentToolbar.set({
14935
+ isCompact: true,
14936
+ role: 'radiogroup',
14937
+ ariaLabel: t('Vertical text alignment toolbar')
14938
+ });
14939
+ fillToolbar({
14940
+ view: this,
14941
+ icons: ALIGNMENT_ICONS,
14942
+ toolbar: verticalAlignmentToolbar,
14943
+ labels: this._verticalAlignmentLabels,
14944
+ propertyName: 'verticalAlignment',
14945
+ defaultValue: this.options.defaultTableCellProperties.verticalAlignment
14946
+ });
14947
+ return {
14948
+ horizontalAlignmentToolbar,
14949
+ verticalAlignmentToolbar,
14950
+ alignmentLabel
14951
+ };
14952
+ }
14953
+ /**
14954
+ * Creates the following form controls:
14955
+ *
14956
+ * * {@link #saveButtonView},
14957
+ * * {@link #cancelButtonView}.
14958
+ */ _createActionButtons() {
14959
+ const locale = this.locale;
14960
+ const t = this.t;
14961
+ const saveButtonView = new ButtonView(locale);
14962
+ const cancelButtonView = new ButtonView(locale);
14963
+ const fieldsThatShouldValidateToSave = [
14964
+ this.borderWidthInput,
14965
+ this.borderColorInput,
14966
+ this.backgroundInput,
14967
+ this.paddingInput
14968
+ ];
14969
+ saveButtonView.set({
14970
+ label: t('Save'),
14971
+ class: 'ck-button-action',
14972
+ type: 'submit',
14973
+ withText: true
14974
+ });
14975
+ saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
14976
+ return errorTexts.every((errorText)=>!errorText);
14977
+ });
14978
+ cancelButtonView.set({
14979
+ label: t('Cancel'),
14980
+ withText: true
14981
+ });
14982
+ cancelButtonView.delegate('execute').to(this, 'cancel');
14983
+ return {
14984
+ saveButtonView,
14985
+ cancelButtonView
14986
+ };
14987
+ }
14988
+ /**
14989
+ * Creates a back button view that cancels the form.
14990
+ */ _createBackButton() {
14991
+ const t = this.locale.t;
14992
+ const backButton = new ButtonView(this.locale);
14993
+ backButton.set({
14994
+ class: 'ck-button-back',
14995
+ label: t('Back'),
14996
+ icon: IconPreviousArrow,
14997
+ tooltip: true
14998
+ });
14999
+ backButton.delegate('execute').to(this, 'cancel');
15000
+ return backButton;
15001
+ }
15002
+ /**
15003
+ * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
15004
+ */ get _horizontalAlignmentLabels() {
15005
+ const locale = this.locale;
15006
+ const t = this.t;
15007
+ const left = t('Align cell text to the left');
15008
+ const center = t('Align cell text to the center');
15009
+ const right = t('Align cell text to the right');
15010
+ const justify = t('Justify cell text');
15011
+ // Returns object with a proper order of labels.
15012
+ if (locale.uiLanguageDirection === 'rtl') {
15013
+ return {
15014
+ right,
15015
+ center,
15016
+ left,
15017
+ justify
15018
+ };
15019
+ } else {
15020
+ return {
15021
+ left,
15022
+ center,
15023
+ right,
15024
+ justify
15025
+ };
15026
+ }
15027
+ }
15028
+ /**
15029
+ * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.
15030
+ */ get _verticalAlignmentLabels() {
15031
+ const t = this.t;
15032
+ return {
15033
+ top: t('Align cell text to the top'),
15034
+ middle: t('Align cell text to the middle'),
15035
+ bottom: t('Align cell text to the bottom')
15036
+ };
15037
+ }
15038
+ }
15039
+ function isBorderStyleSet(value) {
15040
+ return value !== 'none';
15041
+ }
15042
+
15043
+ const ERROR_TEXT_TIMEOUT = 500;
15044
+ // Map of view properties and related commands.
15045
+ const propertyToCommandMap = {
15046
+ borderStyle: 'tableCellBorderStyle',
15047
+ borderColor: 'tableCellBorderColor',
15048
+ borderWidth: 'tableCellBorderWidth',
15049
+ height: 'tableCellHeight',
15050
+ width: 'tableCellWidth',
15051
+ padding: 'tableCellPadding',
15052
+ backgroundColor: 'tableCellBackgroundColor',
15053
+ horizontalAlignment: 'tableCellHorizontalAlignment',
15054
+ verticalAlignment: 'tableCellVerticalAlignment'
15055
+ };
15056
+ /**
15057
+ * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
15058
+ * that opens a form allowing to specify the visual styling of a table cell.
15059
+ *
15060
+ * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
15061
+ */ class TableCellPropertiesUIExperimental extends Plugin {
15062
+ /**
15063
+ * The default table cell properties.
15064
+ */ _defaultContentTableCellProperties;
15065
+ /**
15066
+ * The default layout table cell properties.
15067
+ */ _defaultLayoutTableCellProperties;
15068
+ /**
15069
+ * The contextual balloon plugin instance.
15070
+ */ _balloon;
15071
+ /**
15072
+ * The cell properties form view displayed inside the balloon.
15073
+ */ view;
15074
+ /**
15075
+ * The cell properties form view displayed inside the balloon (content table).
15076
+ */ _viewWithContentTableDefaults;
15077
+ /**
15078
+ * The cell properties form view displayed inside the balloon (layout table).
15079
+ */ _viewWithLayoutTableDefaults;
15080
+ /**
15081
+ * The batch used to undo all changes made by the form (which are live, as the user types)
15082
+ * when "Cancel" was pressed. Each time the view is shown, a new batch is created.
15083
+ */ _undoStepBatch;
15084
+ /**
15085
+ * Flag used to indicate whether view is ready to execute update commands
15086
+ * (it finished loading initial data).
15087
+ */ _isReady;
15088
+ /**
15089
+ * @inheritDoc
15090
+ */ static get requires() {
15091
+ return [
15092
+ ContextualBalloon
15093
+ ];
15094
+ }
15095
+ /**
15096
+ * @inheritDoc
15097
+ */ static get pluginName() {
15098
+ return 'TableCellPropertiesUIExperimental';
15099
+ }
15100
+ /**
15101
+ * @inheritDoc
15102
+ */ static get isOfficialPlugin() {
15103
+ return true;
15104
+ }
15105
+ /**
15106
+ * @inheritDoc
15107
+ */ constructor(editor){
15108
+ super(editor);
15109
+ editor.config.define('table.tableCellProperties', {
15110
+ borderColors: defaultColors,
15111
+ backgroundColors: defaultColors
15112
+ });
15113
+ }
15114
+ /**
15115
+ * @inheritDoc
15116
+ */ init() {
15117
+ const editor = this.editor;
15118
+ const t = editor.t;
15119
+ this._defaultContentTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
15120
+ includeVerticalAlignmentProperty: true,
15121
+ includeHorizontalAlignmentProperty: true,
15122
+ includePaddingProperty: true,
15123
+ isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
15124
+ });
15125
+ this._defaultLayoutTableCellProperties = getNormalizedDefaultProperties(undefined, {
15126
+ includeVerticalAlignmentProperty: true,
15127
+ includeHorizontalAlignmentProperty: true,
15128
+ isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
15129
+ });
15130
+ this._balloon = editor.plugins.get(ContextualBalloon);
15131
+ this.view = null;
15132
+ this._isReady = false;
15133
+ editor.ui.componentFactory.add('tableCellProperties', (locale)=>{
15134
+ const view = new ButtonView(locale);
15135
+ view.set({
15136
+ label: t('Cell properties'),
15137
+ icon: IconTableCellProperties,
15138
+ tooltip: true
15139
+ });
15140
+ this.listenTo(view, 'execute', ()=>this._showView());
15141
+ const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
15142
+ view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
15143
+ return view;
15144
+ });
15145
+ }
15146
+ /**
15147
+ * @inheritDoc
15148
+ */ destroy() {
15149
+ super.destroy();
15150
+ // Destroy created UI components as they are not automatically destroyed.
15151
+ // See https://github.com/ckeditor/ckeditor5/issues/1341.
15152
+ if (this.view) {
15153
+ this.view.destroy();
15154
+ }
15155
+ }
15156
+ /**
15157
+ * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
15158
+ *
15159
+ * @returns The cell properties form view instance.
15160
+ */ _createPropertiesView(defaultTableCellProperties) {
15161
+ const editor = this.editor;
15162
+ const config = editor.config.get('table.tableCellProperties');
15163
+ const borderColorsConfig = normalizeColorOptions(config.borderColors);
15164
+ const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
15165
+ const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
15166
+ const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
15167
+ const hasColorPicker = config.colorPicker !== false;
15168
+ const view = new TableCellPropertiesViewExperimental(editor.locale, {
15169
+ borderColors: localizedBorderColors,
15170
+ backgroundColors: localizedBackgroundColors,
15171
+ defaultTableCellProperties,
15172
+ colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
15173
+ });
15174
+ const t = editor.t;
15175
+ // Render the view so its #element is available for the clickOutsideHandler.
15176
+ view.render();
15177
+ this.listenTo(view, 'submit', ()=>{
15178
+ this._hideView();
15179
+ });
15180
+ this.listenTo(view, 'cancel', ()=>{
15181
+ // https://github.com/ckeditor/ckeditor5/issues/6180
15182
+ if (this._undoStepBatch.operations.length) {
15183
+ editor.execute('undo', this._undoStepBatch);
15184
+ }
15185
+ this._hideView();
15186
+ });
15187
+ // Close the balloon on Esc key press.
15188
+ view.keystrokes.set('Esc', (data, cancel)=>{
15189
+ this._hideView();
15190
+ cancel();
15191
+ });
15192
+ // Close on click outside of balloon panel element.
15193
+ clickOutsideHandler({
15194
+ emitter: view,
15195
+ activator: ()=>this._isViewInBalloon,
15196
+ contextElements: [
15197
+ this._balloon.view.element
15198
+ ],
15199
+ callback: ()=>this._hideView()
15200
+ });
15201
+ const colorErrorText = getLocalizedColorErrorText(t);
15202
+ const lengthErrorText = getLocalizedLengthErrorText(t);
15203
+ // Create the "UI -> editor data" binding.
15204
+ // These listeners update the editor data (via table commands) when any observable
15205
+ // property of the view has changed. They also validate the value and display errors in the UI
15206
+ // when necessary. This makes the view live, which means the changes are
15207
+ // visible in the editing as soon as the user types or changes fields' values.
15208
+ view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
15209
+ view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
15210
+ viewField: view.borderColorInput,
15211
+ commandName: 'tableCellBorderColor',
15212
+ errorText: colorErrorText,
15213
+ validator: colorFieldValidator
15214
+ }));
15215
+ view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
15216
+ viewField: view.borderWidthInput,
15217
+ commandName: 'tableCellBorderWidth',
15218
+ errorText: lengthErrorText,
15219
+ validator: lineWidthFieldValidator
15220
+ }));
15221
+ view.on('change:padding', this._getValidatedPropertyChangeCallback({
15222
+ viewField: view.paddingInput,
15223
+ commandName: 'tableCellPadding',
15224
+ errorText: lengthErrorText,
15225
+ validator: lengthFieldValidator
15226
+ }));
15227
+ view.on('change:width', this._getValidatedPropertyChangeCallback({
15228
+ viewField: view.widthInput,
15229
+ commandName: 'tableCellWidth',
15230
+ errorText: lengthErrorText,
15231
+ validator: lengthFieldValidator
15232
+ }));
15233
+ view.on('change:height', this._getValidatedPropertyChangeCallback({
15234
+ viewField: view.heightInput,
15235
+ commandName: 'tableCellHeight',
15236
+ errorText: lengthErrorText,
15237
+ validator: lengthFieldValidator
15238
+ }));
15239
+ view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
15240
+ viewField: view.backgroundInput,
15241
+ commandName: 'tableCellBackgroundColor',
15242
+ errorText: colorErrorText,
15243
+ validator: colorFieldValidator
15244
+ }));
15245
+ view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
15246
+ view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
15247
+ return view;
15248
+ }
15249
+ /**
15250
+ * In this method the "editor data -> UI" binding is happening.
15251
+ *
15252
+ * When executed, this method obtains selected cell property values from various table commands
15253
+ * and passes them to the {@link #view}.
15254
+ *
15255
+ * This way, the UI stays up–to–date with the editor data.
15256
+ */ _fillViewFormFromCommandValues() {
15257
+ const commands = this.editor.commands;
15258
+ const borderStyleCommand = commands.get('tableCellBorderStyle');
15259
+ Object.entries(propertyToCommandMap).map(([property, commandName])=>{
15260
+ const propertyKey = property;
15261
+ const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
15262
+ return [
15263
+ property,
15264
+ commands.get(commandName).value || defaultValue
15265
+ ];
15266
+ }).forEach(([property, value])=>{
15267
+ // Do not set the `border-color` and `border-width` fields if `border-style:none`.
15268
+ if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
15269
+ return;
15270
+ }
15271
+ this.view.set(property, value);
15272
+ });
15273
+ this._isReady = true;
15274
+ }
15275
+ /**
15276
+ * Shows the {@link #view} in the {@link #_balloon}.
15277
+ *
15278
+ * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
15279
+ * all changes made to the document when the view is visible, allowing a single undo step
15280
+ * for all of them.
15281
+ */ _showView() {
15282
+ const editor = this.editor;
15283
+ const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
15284
+ const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
15285
+ const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
15286
+ if (useDefaults && !this._viewWithContentTableDefaults) {
15287
+ this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableCellProperties);
15288
+ } else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
15289
+ this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableCellProperties);
15290
+ }
15291
+ this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
15292
+ this.listenTo(editor.ui, 'update', ()=>{
15293
+ this._updateView();
15294
+ });
15295
+ // Update the view with the model values.
15296
+ this._fillViewFormFromCommandValues();
15297
+ this._balloon.add({
15298
+ view: this.view,
15299
+ position: getBalloonCellPositionData(editor)
15300
+ });
15301
+ // Create a new batch. Clicking "Cancel" will undo this batch.
15302
+ this._undoStepBatch = editor.model.createBatch();
15303
+ // Basic a11y.
15304
+ this.view.focus();
15305
+ }
15306
+ /**
15307
+ * Removes the {@link #view} from the {@link #_balloon}.
15308
+ */ _hideView() {
15309
+ const editor = this.editor;
15310
+ this.stopListening(editor.ui, 'update');
15311
+ this._isReady = false;
15312
+ // Blur any input element before removing it from DOM to prevent issues in some browsers.
15313
+ // See https://github.com/ckeditor/ckeditor5/issues/1501.
15314
+ this.view.saveButtonView.focus();
15315
+ this._balloon.remove(this.view);
15316
+ // Make sure the focus is not lost in the process by putting it directly
15317
+ // into the editing view.
15318
+ this.editor.editing.view.focus();
15319
+ }
15320
+ /**
15321
+ * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
15322
+ */ _updateView() {
15323
+ const editor = this.editor;
15324
+ const viewDocument = editor.editing.view.document;
15325
+ if (!getTableWidgetAncestor(viewDocument.selection)) {
15326
+ this._hideView();
15327
+ } else if (this._isViewVisible) {
15328
+ repositionContextualBalloon(editor, 'cell');
15329
+ }
15330
+ }
15331
+ /**
15332
+ * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
15333
+ */ get _isViewVisible() {
15334
+ return !!this.view && this._balloon.visibleView === this.view;
15335
+ }
15336
+ /**
15337
+ * Returns `true` when the {@link #view} is in the {@link #_balloon}.
15338
+ */ get _isViewInBalloon() {
15339
+ return !!this.view && this._balloon.hasView(this.view);
15340
+ }
15341
+ /**
15342
+ * Creates a callback that when executed upon the {@link #view view's} property change
15343
+ * executes a related editor command with the new property value.
15344
+ *
15345
+ * @param commandName The default value of the command.
15346
+ */ _getPropertyChangeCallback(commandName) {
15347
+ return (evt, propertyName, newValue)=>{
15348
+ if (!this._isReady) {
15349
+ return;
15350
+ }
15351
+ this.editor.execute(commandName, {
15352
+ value: newValue,
15353
+ batch: this._undoStepBatch
15354
+ });
15355
+ };
15356
+ }
15357
+ /**
15358
+ * Creates a callback that when executed upon the {@link #view view's} property change:
15359
+ * * Executes a related editor command with the new property value if the value is valid,
15360
+ * * Or sets the error text next to the invalid field, if the value did not pass the validation.
15361
+ */ _getValidatedPropertyChangeCallback(options) {
15362
+ const { commandName, viewField, validator, errorText } = options;
15363
+ const setErrorTextDebounced = debounce(()=>{
15364
+ viewField.errorText = errorText;
15365
+ }, ERROR_TEXT_TIMEOUT);
15366
+ return (evt, propertyName, newValue)=>{
15367
+ setErrorTextDebounced.cancel();
15368
+ // Do not execute the command on initial call (opening the table properties view).
15369
+ if (!this._isReady) {
15370
+ return;
15371
+ }
15372
+ if (validator(newValue)) {
15373
+ this.editor.execute(commandName, {
15374
+ value: newValue,
15375
+ batch: this._undoStepBatch
15376
+ });
15377
+ viewField.errorText = null;
15378
+ } else {
15379
+ setErrorTextDebounced();
15380
+ }
15381
+ };
15382
+ }
15383
+ }
15384
+
15385
+ export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesUIExperimental, TableCellPropertiesView, TableCellPropertiesViewExperimental, TableCellPropertyCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesUIExperimental, TablePropertiesView, TablePropertiesViewExperimental, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar$1 as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels$1 as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator$1 as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions$1 as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute };
13315
15386
  //# sourceMappingURL=index.js.map