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