@ckeditor/ckeditor5-table 0.0.0-nightly-20251215.0 → 0.0.0-nightly-next-20251215.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 +10 -1
  75. package/dist/index-content.css +30 -30
  76. package/dist/index-editor.css +120 -194
  77. package/dist/index.css +167 -265
  78. package/dist/index.css.map +1 -1
  79. package/dist/index.js +150 -2221
  80. package/dist/index.js.map +1 -1
  81. package/lang/contexts.json +0 -4
  82. package/package.json +9 -9
  83. package/src/augmentation.d.ts +0 -7
  84. package/src/converters/downcast.js +3 -12
  85. package/src/index.d.ts +0 -4
  86. package/src/index.js +0 -5
  87. package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +8 -0
  88. package/src/tablecellproperties/ui/tablecellpropertiesview.js +30 -10
  89. package/src/tableconfig.d.ts +4 -4
  90. package/src/tableproperties/tablepropertiesediting.js +14 -147
  91. package/src/tableproperties/ui/tablepropertiesview.d.ts +8 -0
  92. package/src/tableproperties/ui/tablepropertiesview.js +59 -37
  93. package/theme/formrow.css +2 -0
  94. package/theme/tableform.css +1 -5
  95. package/theme/tableproperties.css +60 -0
  96. package/src/tablecellproperties/tablecellpropertiesuiexperimental.d.ts +0 -128
  97. package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +0 -386
  98. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts +0 -237
  99. package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +0 -633
  100. package/src/tableproperties/tablepropertiesuiexperimental.d.ts +0 -136
  101. package/src/tableproperties/tablepropertiesuiexperimental.js +0 -375
  102. package/src/tableproperties/ui/tablepropertiesviewexperimental.d.ts +0 -216
  103. package/src/tableproperties/ui/tablepropertiesviewexperimental.js +0 -544
  104. package/src/utils/ui/table-propertiesexperimental.d.ts +0 -215
  105. package/src/utils/ui/table-propertiesexperimental.js +0 -391
  106. package/theme/formrow-experimental.css +0 -15
  107. package/theme/tableform-experimental.css +0 -73
  108. package/theme/tableproperties-experimental.css +0 -78
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, 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';
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';
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,10 +2119,7 @@ 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
- 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)) {
2122
+ if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2126
2123
  return null;
2127
2124
  }
2128
2125
  return downcastPlainTable(table, conversionApi, editor);
@@ -2132,10 +2129,7 @@ const downcastTableAlignmentConfig = {
2132
2129
  * Downcasts a plain table caption (also used in the clipboard pipeline).
2133
2130
  */ function convertPlainTableCaption(editor) {
2134
2131
  return (modelElement, { writer, options })=>{
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)) {
2132
+ if (!options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2139
2133
  return null;
2140
2134
  }
2141
2135
  if (modelElement.parent.name === 'table') {
@@ -2223,10 +2217,7 @@ const downcastTableAlignmentConfig = {
2223
2217
  return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{
2224
2218
  const { item, attributeNewValue } = data;
2225
2219
  const { mapper, writer } = conversionApi;
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)) {
2220
+ if (!conversionApi.options.isClipboardPipeline && !editor.plugins.has('PlainTableOutput')) {
2230
2221
  return;
2231
2222
  }
2232
2223
  if (!conversionApi.consumable.consume(item, evt.name)) {
@@ -7612,7 +7603,7 @@ const isEmpty = (val)=>val === '';
7612
7603
  *
7613
7604
  * @internal
7614
7605
  * @param t The "t" function provided by the editor that is used to localize strings.
7615
- */ function getBorderStyleLabels$1(t) {
7606
+ */ function getBorderStyleLabels(t) {
7616
7607
  return {
7617
7608
  none: t('None'),
7618
7609
  solid: t('Solid'),
@@ -7682,9 +7673,9 @@ const isEmpty = (val)=>val === '';
7682
7673
  *
7683
7674
  * @internal
7684
7675
  * @param defaultStyle The default border.
7685
- */ function getBorderStyleDefinitions$1(view, defaultStyle) {
7676
+ */ function getBorderStyleDefinitions(view, defaultStyle) {
7686
7677
  const itemDefinitions = new Collection();
7687
- const styleLabels = getBorderStyleLabels$1(view.t);
7678
+ const styleLabels = getBorderStyleLabels(view.t);
7688
7679
  for(const style in styleLabels){
7689
7680
  const definition = {
7690
7681
  type: 'button',
@@ -7727,7 +7718,7 @@ const isEmpty = (val)=>val === '';
7727
7718
  * @param options.propertyName The name of the observable property in the view.
7728
7719
  * @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
7729
7720
  * @param options.defaultValue Default value for the property.
7730
- */ function fillToolbar$1(options) {
7721
+ */ function fillToolbar(options) {
7731
7722
  const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
7732
7723
  for(const name in labels){
7733
7724
  const button = new ButtonView(view.locale);
@@ -7931,10 +7922,10 @@ const isEmpty = (val)=>val === '';
7931
7922
  * @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
7932
7923
  * the "Restore default" button. Instead of clearing the input field, the default color value will be set.
7933
7924
  * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
7934
- */ function getLabeledColorInputCreator$1(options) {
7925
+ */ function getLabeledColorInputCreator(options) {
7935
7926
  return (labeledFieldView, viewUid, statusUid)=>{
7936
7927
  const colorInputView = new ColorInputView(labeledFieldView.locale, {
7937
- colorDefinitions: colorConfigToColorGridDefinitions$1(options.colorConfig),
7928
+ colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
7938
7929
  columns: options.columns,
7939
7930
  defaultColorValue: options.defaultColorValue,
7940
7931
  colorPickerConfig: options.colorPickerConfig
@@ -7961,7 +7952,7 @@ const isEmpty = (val)=>val === '';
7961
7952
  const parsedValue = parseFloat(value);
7962
7953
  return !Number.isNaN(parsedValue) && value === String(parsedValue);
7963
7954
  }
7964
- function colorConfigToColorGridDefinitions$1(colorConfig) {
7955
+ function colorConfigToColorGridDefinitions(colorConfig) {
7965
7956
  return colorConfig.map((item)=>({
7966
7957
  color: item.model,
7967
7958
  label: item.label,
@@ -8020,6 +8011,9 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8020
8011
  /**
8021
8012
  * The "Cancel" button view.
8022
8013
  */ cancelButtonView;
8014
+ /**
8015
+ * The "Back" button view.
8016
+ */ backButtonView;
8023
8017
  /**
8024
8018
  * A collection of views that can be focused in the form.
8025
8019
  */ _focusables;
@@ -8070,6 +8064,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8070
8064
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
8071
8065
  this.saveButtonView = saveButtonView;
8072
8066
  this.cancelButtonView = cancelButtonView;
8067
+ this.backButtonView = this._createBackButton();
8073
8068
  this._focusables = new ViewCollection();
8074
8069
  this._focusCycler = new FocusCycler({
8075
8070
  focusables: this._focusables,
@@ -8083,9 +8078,11 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8083
8078
  }
8084
8079
  });
8085
8080
  // Form header.
8086
- this.children.add(new FormHeaderView(locale, {
8081
+ const header = new FormHeaderView(locale, {
8087
8082
  label: this.t('Cell properties')
8088
- }));
8083
+ });
8084
+ header.children.add(this.backButtonView, 0);
8085
+ this.children.add(header);
8089
8086
  // Border row.
8090
8087
  this.children.add(new FormRowView(locale, {
8091
8088
  labelView: borderRowLabel,
@@ -8142,8 +8139,8 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8142
8139
  // Action row.
8143
8140
  this.children.add(new FormRowView(locale, {
8144
8141
  children: [
8145
- this.saveButtonView,
8146
- this.cancelButtonView
8142
+ this.cancelButtonView,
8143
+ this.saveButtonView
8147
8144
  ],
8148
8145
  class: 'ck-table-form__action-row'
8149
8146
  }));
@@ -8188,8 +8185,9 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8188
8185
  this.paddingInput,
8189
8186
  this.horizontalAlignmentToolbar,
8190
8187
  this.verticalAlignmentToolbar,
8188
+ this.cancelButtonView,
8191
8189
  this.saveButtonView,
8192
- this.cancelButtonView
8190
+ this.backButtonView
8193
8191
  ].forEach((view)=>{
8194
8192
  // Register the view as focusable.
8195
8193
  this._focusables.add(view);
@@ -8224,7 +8222,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8224
8222
  width: defaultTableCellProperties.borderWidth,
8225
8223
  color: defaultTableCellProperties.borderColor
8226
8224
  };
8227
- const colorInputCreator = getLabeledColorInputCreator$1({
8225
+ const colorInputCreator = getLabeledColorInputCreator({
8228
8226
  colorConfig: this.options.borderColors,
8229
8227
  columns: 5,
8230
8228
  defaultColorValue: defaultBorder.color,
@@ -8237,7 +8235,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8237
8235
  const borderRowLabel = new LabelView(locale);
8238
8236
  borderRowLabel.text = t('Border');
8239
8237
  // -- Style ---------------------------------------------------
8240
- const styleLabels = getBorderStyleLabels$1(t);
8238
+ const styleLabels = getBorderStyleLabels(t);
8241
8239
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
8242
8240
  borderStyleDropdown.set({
8243
8241
  label: accessibleLabel,
@@ -8257,7 +8255,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8257
8255
  this.borderStyle = evt.source._borderStyleValue;
8258
8256
  });
8259
8257
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
8260
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
8258
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
8261
8259
  role: 'menu',
8262
8260
  ariaLabel: accessibleLabel
8263
8261
  });
@@ -8268,7 +8266,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8268
8266
  class: 'ck-table-form__border-width'
8269
8267
  });
8270
8268
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
8271
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8269
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8272
8270
  borderWidthInput.fieldView.on('input', ()=>{
8273
8271
  this.borderWidth = borderWidthInput.fieldView.element.value;
8274
8272
  });
@@ -8279,7 +8277,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8279
8277
  class: 'ck-table-form__border-color'
8280
8278
  });
8281
8279
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
8282
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
8280
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
8283
8281
  borderColorInput.fieldView.on('input', ()=>{
8284
8282
  this.borderColor = borderColorInput.fieldView.value;
8285
8283
  });
@@ -8287,12 +8285,12 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8287
8285
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
8288
8286
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
8289
8287
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
8290
- if (!isBorderStyleSet$3(newValue)) {
8288
+ if (!isBorderStyleSet$1(newValue)) {
8291
8289
  this.borderColor = '';
8292
8290
  this.borderWidth = '';
8293
8291
  }
8294
8292
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
8295
- if (!isBorderStyleSet$3(oldValue)) {
8293
+ if (!isBorderStyleSet$1(oldValue)) {
8296
8294
  this.borderColor = defaultBorder.color;
8297
8295
  this.borderWidth = defaultBorder.width;
8298
8296
  }
@@ -8315,7 +8313,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8315
8313
  const backgroundRowLabel = new LabelView(locale);
8316
8314
  backgroundRowLabel.text = t('Background');
8317
8315
  // -- Background color input -----------------------------------
8318
- const colorInputCreator = getLabeledColorInputCreator$1({
8316
+ const colorInputCreator = getLabeledColorInputCreator({
8319
8317
  colorConfig: this.options.backgroundColors,
8320
8318
  columns: 5,
8321
8319
  defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
@@ -8433,7 +8431,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8433
8431
  role: 'radiogroup',
8434
8432
  ariaLabel: t('Horizontal text alignment toolbar')
8435
8433
  });
8436
- fillToolbar$1({
8434
+ fillToolbar({
8437
8435
  view: this,
8438
8436
  icons: ALIGNMENT_ICONS,
8439
8437
  toolbar: horizontalAlignmentToolbar,
@@ -8459,7 +8457,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8459
8457
  role: 'radiogroup',
8460
8458
  ariaLabel: t('Vertical text alignment toolbar')
8461
8459
  });
8462
- fillToolbar$1({
8460
+ fillToolbar({
8463
8461
  view: this,
8464
8462
  icons: ALIGNMENT_ICONS,
8465
8463
  toolbar: verticalAlignmentToolbar,
@@ -8491,8 +8489,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8491
8489
  ];
8492
8490
  saveButtonView.set({
8493
8491
  label: t('Save'),
8494
- icon: IconCheck,
8495
- class: 'ck-button-save',
8492
+ class: 'ck-button-action',
8496
8493
  type: 'submit',
8497
8494
  withText: true
8498
8495
  });
@@ -8501,8 +8498,6 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8501
8498
  });
8502
8499
  cancelButtonView.set({
8503
8500
  label: t('Cancel'),
8504
- icon: IconCancel,
8505
- class: 'ck-button-cancel',
8506
8501
  withText: true
8507
8502
  });
8508
8503
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -8511,6 +8506,20 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8511
8506
  cancelButtonView
8512
8507
  };
8513
8508
  }
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
+ }
8514
8523
  /**
8515
8524
  * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
8516
8525
  */ get _horizontalAlignmentLabels() {
@@ -8548,7 +8557,7 @@ function colorConfigToColorGridDefinitions$1(colorConfig) {
8548
8557
  };
8549
8558
  }
8550
8559
  }
8551
- function isBorderStyleSet$3(value) {
8560
+ function isBorderStyleSet$1(value) {
8552
8561
  return value !== 'none';
8553
8562
  }
8554
8563
 
@@ -8647,9 +8656,9 @@ const BALLOON_POSITIONS = /* #__PURE__ */ (()=>[
8647
8656
  return Rect.getBoundingRect(rects);
8648
8657
  }
8649
8658
 
8650
- const ERROR_TEXT_TIMEOUT$3 = 500;
8659
+ const ERROR_TEXT_TIMEOUT$1 = 500;
8651
8660
  // Map of view properties and related commands.
8652
- const propertyToCommandMap$3 = {
8661
+ const propertyToCommandMap$1 = {
8653
8662
  borderStyle: 'tableCellBorderStyle',
8654
8663
  borderColor: 'tableCellBorderColor',
8655
8664
  borderWidth: 'tableCellBorderWidth',
@@ -8745,7 +8754,7 @@ const propertyToCommandMap$3 = {
8745
8754
  tooltip: true
8746
8755
  });
8747
8756
  this.listenTo(view, 'execute', ()=>this._showView());
8748
- const commands = Object.values(propertyToCommandMap$3).map((commandName)=>editor.commands.get(commandName));
8757
+ const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));
8749
8758
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
8750
8759
  return view;
8751
8760
  });
@@ -8863,7 +8872,7 @@ const propertyToCommandMap$3 = {
8863
8872
  */ _fillViewFormFromCommandValues() {
8864
8873
  const commands = this.editor.commands;
8865
8874
  const borderStyleCommand = commands.get('tableCellBorderStyle');
8866
- Object.entries(propertyToCommandMap$3).map(([property, commandName])=>{
8875
+ Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{
8867
8876
  const propertyKey = property;
8868
8877
  const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
8869
8878
  return [
@@ -8969,7 +8978,7 @@ const propertyToCommandMap$3 = {
8969
8978
  const { commandName, viewField, validator, errorText } = options;
8970
8979
  const setErrorTextDebounced = debounce(()=>{
8971
8980
  viewField.errorText = errorText;
8972
- }, ERROR_TEXT_TIMEOUT$3);
8981
+ }, ERROR_TEXT_TIMEOUT$1);
8973
8982
  return (evt, propertyName, newValue)=>{
8974
8983
  setErrorTextDebounced.cancel();
8975
8984
  // Do not execute the command on initial call (opening the table properties view).
@@ -11663,7 +11672,7 @@ const TABLE_TYPES = [
11663
11672
  const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
11664
11673
  includeAlignmentProperty: true
11665
11674
  });
11666
- const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') !== false;
11675
+ const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') === true;
11667
11676
  editor.data.addStyleProcessorRules(addMarginStylesRules);
11668
11677
  editor.data.addStyleProcessorRules(addBorderStylesRules);
11669
11678
  enableBorderProperties(editor, {
@@ -11674,11 +11683,7 @@ const TABLE_TYPES = [
11674
11683
  editor.commands.add('tableBorderColor', new TableBorderColorCommand(editor, defaultTableProperties.borderColor));
11675
11684
  editor.commands.add('tableBorderStyle', new TableBorderStyleCommand(editor, defaultTableProperties.borderStyle));
11676
11685
  editor.commands.add('tableBorderWidth', new TableBorderWidthCommand(editor, defaultTableProperties.borderWidth));
11677
- if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
11678
- enableExtendedAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
11679
- } else {
11680
- enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment);
11681
- }
11686
+ enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
11682
11687
  editor.commands.add('tableAlignment', new TableAlignmentCommand(editor, defaultTableProperties.alignment));
11683
11688
  enableTableToFigureProperty(schema, conversion, {
11684
11689
  modelAttribute: 'tableWidth',
@@ -11705,20 +11710,18 @@ const TABLE_TYPES = [
11705
11710
  defaultValue: defaultTableProperties.backgroundColor
11706
11711
  });
11707
11712
  editor.commands.add('tableBackgroundColor', new TableBackgroundColorCommand(editor, defaultTableProperties.backgroundColor));
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'
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));
11720
11721
  });
11721
- }
11722
+ }, {
11723
+ priority: 'lowest'
11724
+ });
11722
11725
  }
11723
11726
  }
11724
11727
  /**
@@ -11788,10 +11791,10 @@ function insertWrapperWithAlignment(writer, align, table) {
11788
11791
  });
11789
11792
  }
11790
11793
  /**
11791
- * Enables the extended block`'alignment'` attribute for table.
11794
+ * Enables the `'alignment'` attribute for table.
11792
11795
  *
11793
11796
  * @param defaultValue The default alignment value.
11794
- */ function enableExtendedAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
11797
+ */ function enableAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
11795
11798
  schema.extend('table', {
11796
11799
  allowAttributes: [
11797
11800
  'tableAlignment'
@@ -11890,144 +11893,6 @@ function insertWrapperWithAlignment(writer, align, table) {
11890
11893
  });
11891
11894
  conversion.for('upcast').add(upcastTableAlignedDiv(defaultValue));
11892
11895
  }
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
- }
12031
11896
  /**
12032
11897
  * Returns a function that converts the table view representation:
12033
11898
  *
@@ -12218,6 +12083,9 @@ function insertWrapperWithAlignment(writer, align, table) {
12218
12083
  /**
12219
12084
  * The "Cancel" button view.
12220
12085
  */ cancelButtonView;
12086
+ /**
12087
+ * The Back button view displayed in the header.
12088
+ */ backButtonView;
12221
12089
  /**
12222
12090
  * A collection of views that can be focused in the form.
12223
12091
  */ _focusables;
@@ -12259,6 +12127,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12259
12127
  const { saveButtonView, cancelButtonView } = this._createActionButtons();
12260
12128
  this.saveButtonView = saveButtonView;
12261
12129
  this.cancelButtonView = cancelButtonView;
12130
+ this.backButtonView = this._createBackButton();
12262
12131
  this._focusables = new ViewCollection();
12263
12132
  this._focusCycler = new FocusCycler({
12264
12133
  focusables: this._focusables,
@@ -12272,29 +12141,22 @@ function insertWrapperWithAlignment(writer, align, table) {
12272
12141
  }
12273
12142
  });
12274
12143
  // Form header.
12275
- this.children.add(new FormHeaderView(locale, {
12144
+ const headerView = new FormHeaderView(locale, {
12276
12145
  label: this.t('Table properties')
12277
- }));
12146
+ });
12147
+ headerView.children.add(this.backButtonView, 0);
12148
+ this.children.add(headerView);
12278
12149
  // Border row.
12279
12150
  this.children.add(new FormRowView(locale, {
12280
12151
  labelView: borderRowLabel,
12281
12152
  children: [
12282
12153
  borderRowLabel,
12283
12154
  borderStyleDropdown,
12284
- borderColorInput,
12285
- borderWidthInput
12155
+ borderWidthInput,
12156
+ borderColorInput
12286
12157
  ],
12287
12158
  class: 'ck-table-form__border-row'
12288
12159
  }));
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
- }));
12298
12160
  this.children.add(new FormRowView(locale, {
12299
12161
  children: [
12300
12162
  // Dimensions row.
@@ -12308,22 +12170,31 @@ function insertWrapperWithAlignment(writer, align, table) {
12308
12170
  ],
12309
12171
  class: 'ck-table-form__dimensions-row'
12310
12172
  }),
12311
- // Alignment row.
12173
+ // Background row.
12312
12174
  new FormRowView(locale, {
12313
- labelView: alignmentLabel,
12175
+ labelView: backgroundRowLabel,
12314
12176
  children: [
12315
- alignmentLabel,
12316
- alignmentToolbar
12177
+ backgroundRowLabel,
12178
+ backgroundInput
12317
12179
  ],
12318
- class: 'ck-table-properties-form__alignment-row'
12180
+ class: 'ck-table-form__background-row'
12319
12181
  })
12320
12182
  ]
12321
12183
  }));
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
+ }));
12322
12193
  // Action row.
12323
12194
  this.children.add(new FormRowView(locale, {
12324
12195
  children: [
12325
- this.saveButtonView,
12326
- this.cancelButtonView
12196
+ this.cancelButtonView,
12197
+ this.saveButtonView
12327
12198
  ],
12328
12199
  class: 'ck-table-form__action-row'
12329
12200
  }));
@@ -12360,14 +12231,15 @@ function insertWrapperWithAlignment(writer, align, table) {
12360
12231
  });
12361
12232
  [
12362
12233
  this.borderStyleDropdown,
12363
- this.borderColorInput,
12364
12234
  this.borderWidthInput,
12365
- this.backgroundInput,
12235
+ this.borderColorInput,
12366
12236
  this.widthInput,
12367
12237
  this.heightInput,
12238
+ this.backgroundInput,
12368
12239
  this.alignmentToolbar,
12240
+ this.cancelButtonView,
12369
12241
  this.saveButtonView,
12370
- this.cancelButtonView
12242
+ this.backButtonView
12371
12243
  ].forEach((view)=>{
12372
12244
  // Register the view as focusable.
12373
12245
  this._focusables.add(view);
@@ -12402,7 +12274,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12402
12274
  width: defaultTableProperties.borderWidth,
12403
12275
  color: defaultTableProperties.borderColor
12404
12276
  };
12405
- const colorInputCreator = getLabeledColorInputCreator$1({
12277
+ const colorInputCreator = getLabeledColorInputCreator({
12406
12278
  colorConfig: this.options.borderColors,
12407
12279
  columns: 5,
12408
12280
  defaultColorValue: defaultBorder.color,
@@ -12415,7 +12287,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12415
12287
  const borderRowLabel = new LabelView(locale);
12416
12288
  borderRowLabel.text = t('Border');
12417
12289
  // -- Style ---------------------------------------------------
12418
- const styleLabels = getBorderStyleLabels$1(t);
12290
+ const styleLabels = getBorderStyleLabels(t);
12419
12291
  const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
12420
12292
  borderStyleDropdown.set({
12421
12293
  label: accessibleLabel,
@@ -12435,7 +12307,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12435
12307
  this.borderStyle = evt.source._borderStyleValue;
12436
12308
  });
12437
12309
  borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
12438
- addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
12310
+ addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
12439
12311
  role: 'menu',
12440
12312
  ariaLabel: accessibleLabel
12441
12313
  });
@@ -12446,7 +12318,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12446
12318
  class: 'ck-table-form__border-width'
12447
12319
  });
12448
12320
  borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
12449
- borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
12321
+ borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
12450
12322
  borderWidthInput.fieldView.on('input', ()=>{
12451
12323
  this.borderWidth = borderWidthInput.fieldView.element.value;
12452
12324
  });
@@ -12457,7 +12329,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12457
12329
  class: 'ck-table-form__border-color'
12458
12330
  });
12459
12331
  borderColorInput.fieldView.bind('value').to(this, 'borderColor');
12460
- borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
12332
+ borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
12461
12333
  borderColorInput.fieldView.on('input', ()=>{
12462
12334
  this.borderColor = borderColorInput.fieldView.value;
12463
12335
  });
@@ -12465,12 +12337,12 @@ function insertWrapperWithAlignment(writer, align, table) {
12465
12337
  this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
12466
12338
  // When removing the border (`border-style:none`), clear the remaining `border-*` properties.
12467
12339
  // See: https://github.com/ckeditor/ckeditor5/issues/6227.
12468
- if (!isBorderStyleSet$2(newValue)) {
12340
+ if (!isBorderStyleSet(newValue)) {
12469
12341
  this.borderColor = '';
12470
12342
  this.borderWidth = '';
12471
12343
  }
12472
12344
  // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
12473
- if (!isBorderStyleSet$2(oldValue)) {
12345
+ if (!isBorderStyleSet(oldValue)) {
12474
12346
  this.borderColor = defaultBorder.color;
12475
12347
  this.borderWidth = defaultBorder.width;
12476
12348
  }
@@ -12493,7 +12365,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12493
12365
  const backgroundRowLabel = new LabelView(locale);
12494
12366
  backgroundRowLabel.text = t('Background');
12495
12367
  // -- Background color input -----------------------------------
12496
- const backgroundInputCreator = getLabeledColorInputCreator$1({
12368
+ const backgroundInputCreator = getLabeledColorInputCreator({
12497
12369
  colorConfig: this.options.backgroundColors,
12498
12370
  columns: 5,
12499
12371
  defaultColorValue: this.options.defaultTableProperties.backgroundColor,
@@ -12575,7 +12447,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12575
12447
  const t = this.t;
12576
12448
  // -- Label ---------------------------------------------------
12577
12449
  const alignmentLabel = new LabelView(locale);
12578
- alignmentLabel.text = t('Alignment');
12450
+ alignmentLabel.text = t('Table Alignment');
12579
12451
  // -- Toolbar ---------------------------------------------------
12580
12452
  const alignmentToolbar = new ToolbarView(locale);
12581
12453
  alignmentToolbar.set({
@@ -12583,12 +12455,14 @@ function insertWrapperWithAlignment(writer, align, table) {
12583
12455
  isCompact: true,
12584
12456
  ariaLabel: t('Table alignment toolbar')
12585
12457
  });
12586
- fillToolbar$1({
12458
+ fillToolbar({
12587
12459
  view: this,
12588
12460
  icons: {
12589
12461
  left: IconObjectInlineLeft,
12590
12462
  center: IconObjectCenter,
12591
- right: IconObjectInlineRight
12463
+ right: IconObjectInlineRight,
12464
+ blockLeft: IconObjectLeft,
12465
+ blockRight: IconObjectRight
12592
12466
  },
12593
12467
  toolbar: alignmentToolbar,
12594
12468
  labels: this._alignmentLabels,
@@ -12619,8 +12493,7 @@ function insertWrapperWithAlignment(writer, align, table) {
12619
12493
  ];
12620
12494
  saveButtonView.set({
12621
12495
  label: t('Save'),
12622
- icon: IconCheck,
12623
- class: 'ck-button-save',
12496
+ class: 'ck-button-action',
12624
12497
  type: 'submit',
12625
12498
  withText: true
12626
12499
  });
@@ -12629,8 +12502,6 @@ function insertWrapperWithAlignment(writer, align, table) {
12629
12502
  });
12630
12503
  cancelButtonView.set({
12631
12504
  label: t('Cancel'),
12632
- icon: IconCancel,
12633
- class: 'ck-button-cancel',
12634
12505
  withText: true
12635
12506
  });
12636
12507
  cancelButtonView.delegate('execute').to(this, 'cancel');
@@ -12639,37 +12510,56 @@ function insertWrapperWithAlignment(writer, align, table) {
12639
12510
  cancelButtonView
12640
12511
  };
12641
12512
  }
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
+ }
12642
12527
  /**
12643
12528
  * Provides localized labels for {@link #alignmentToolbar} buttons.
12644
12529
  */ get _alignmentLabels() {
12645
12530
  const locale = this.locale;
12646
12531
  const t = this.t;
12647
- const left = t('Align table to the left');
12648
- const center = t('Center table');
12649
- const right = t('Align table to the right');
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');
12650
12537
  // Returns object with a proper order of labels.
12651
12538
  if (locale.uiLanguageDirection === 'rtl') {
12652
12539
  return {
12653
12540
  right,
12654
- center,
12655
- left
12656
- };
12657
- } else {
12658
- return {
12659
12541
  left,
12542
+ blockRight,
12660
12543
  center,
12661
- right
12544
+ blockLeft
12662
12545
  };
12663
12546
  }
12664
- }
12665
- }
12666
- function isBorderStyleSet$2(value) {
12547
+ return {
12548
+ blockLeft,
12549
+ center,
12550
+ blockRight,
12551
+ left,
12552
+ right
12553
+ };
12554
+ }
12555
+ }
12556
+ function isBorderStyleSet(value) {
12667
12557
  return value !== 'none';
12668
12558
  }
12669
12559
 
12670
- const ERROR_TEXT_TIMEOUT$2 = 500;
12560
+ const ERROR_TEXT_TIMEOUT = 500;
12671
12561
  // Map of view properties and related commands.
12672
- const propertyToCommandMap$2 = {
12562
+ const propertyToCommandMap = {
12673
12563
  borderStyle: 'tableBorderStyle',
12674
12564
  borderColor: 'tableBorderColor',
12675
12565
  borderWidth: 'tableBorderWidth',
@@ -12761,7 +12651,7 @@ const propertyToCommandMap$2 = {
12761
12651
  tooltip: true
12762
12652
  });
12763
12653
  this.listenTo(view, 'execute', ()=>this._showView());
12764
- const commands = Object.values(propertyToCommandMap$2).map((commandName)=>editor.commands.get(commandName));
12654
+ const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
12765
12655
  view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
12766
12656
  return view;
12767
12657
  }
@@ -12871,7 +12761,7 @@ const propertyToCommandMap$2 = {
12871
12761
  */ _fillViewFormFromCommandValues() {
12872
12762
  const commands = this.editor.commands;
12873
12763
  const borderStyleCommand = commands.get('tableBorderStyle');
12874
- Object.entries(propertyToCommandMap$2).map(([property, commandName])=>{
12764
+ Object.entries(propertyToCommandMap).map(([property, commandName])=>{
12875
12765
  const propertyKey = property;
12876
12766
  const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
12877
12767
  return [
@@ -12980,7 +12870,7 @@ const propertyToCommandMap$2 = {
12980
12870
  const { commandName, viewField, validator, errorText } = options;
12981
12871
  const setErrorTextDebounced = debounce(()=>{
12982
12872
  viewField.errorText = errorText;
12983
- }, ERROR_TEXT_TIMEOUT$2);
12873
+ }, ERROR_TEXT_TIMEOUT);
12984
12874
  return (evt, propertyName, newValue)=>{
12985
12875
  setErrorTextDebounced.cancel();
12986
12876
  // Do not execute the command on initial call (opening the table properties view).
@@ -13421,1966 +13311,5 @@ const propertyToCommandMap$2 = {
13421
13311
  }
13422
13312
  }
13423
13313
 
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 };
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 };
15386
13315
  //# sourceMappingURL=index.js.map