@ckeditor/ckeditor5-table 0.0.0-nightly-next-20251217.0 → 0.0.0-nightly-20251218.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 +2 -11
- package/dist/index-content.css +30 -30
- package/dist/index-editor.css +170 -104
- package/dist/index.css +237 -147
- package/dist/index.css.map +1 -1
- package/dist/index.js +2399 -307
- package/dist/index.js.map +1 -1
- package/lang/contexts.json +4 -0
- package/package.json +9 -9
- package/src/augmentation.d.ts +15 -0
- package/src/converters/downcast.js +12 -3
- package/src/index.d.ts +4 -0
- package/src/index.js +5 -0
- package/src/tablecellproperties/tablecellpropertiesediting.js +4 -2
- package/src/tablecellproperties/tablecellpropertiesui.js +10 -30
- package/src/tablecellproperties/tablecellpropertiesuiexperimental.d.ts +128 -0
- package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +408 -0
- package/src/tablecellproperties/ui/tablecellpropertiesview.d.ts +0 -35
- package/src/tablecellproperties/ui/tablecellpropertiesview.js +23 -137
- package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts +266 -0
- package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +744 -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/common.js +3 -2
- 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/tablecellproperties-experimental.css +4 -0
- package/theme/tableform-experimental.css +61 -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, priorities, 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';
|
|
@@ -1053,8 +1053,8 @@ const downcastTableAlignmentConfig = {
|
|
|
1053
1053
|
*
|
|
1054
1054
|
* @internal
|
|
1055
1055
|
*/ function isTableCellTypeEnabled(editor) {
|
|
1056
|
-
const { model } = editor;
|
|
1057
|
-
return model.schema.checkAttribute('tableCell', 'tableCellType');
|
|
1056
|
+
const { model, config } = editor;
|
|
1057
|
+
return model.schema.checkAttribute('tableCell', 'tableCellType') && config.get('experimentalFlags.tableCellTypeSupport') === true;
|
|
1058
1058
|
}
|
|
1059
1059
|
|
|
1060
1060
|
/**
|
|
@@ -2175,7 +2175,10 @@ const downcastTableAlignmentConfig = {
|
|
|
2175
2175
|
* Downcasts a plain table (also used in the clipboard pipeline).
|
|
2176
2176
|
*/ function convertPlainTable(editor) {
|
|
2177
2177
|
return (table, conversionApi)=>{
|
|
2178
|
-
|
|
2178
|
+
const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
|
|
2179
|
+
const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
|
|
2180
|
+
const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
|
|
2181
|
+
if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
|
|
2179
2182
|
return null;
|
|
2180
2183
|
}
|
|
2181
2184
|
return downcastPlainTable(table, conversionApi, editor);
|
|
@@ -2185,7 +2188,10 @@ const downcastTableAlignmentConfig = {
|
|
|
2185
2188
|
* Downcasts a plain table caption (also used in the clipboard pipeline).
|
|
2186
2189
|
*/ function convertPlainTableCaption(editor) {
|
|
2187
2190
|
return (modelElement, { writer, options })=>{
|
|
2188
|
-
|
|
2191
|
+
const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
|
|
2192
|
+
const isClipboardPipeline = options.isClipboardPipeline;
|
|
2193
|
+
const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
|
|
2194
|
+
if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
|
|
2189
2195
|
return null;
|
|
2190
2196
|
}
|
|
2191
2197
|
if (modelElement.parent.name === 'table') {
|
|
@@ -2273,7 +2279,10 @@ const downcastTableAlignmentConfig = {
|
|
|
2273
2279
|
return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{
|
|
2274
2280
|
const { item, attributeNewValue } = data;
|
|
2275
2281
|
const { mapper, writer } = conversionApi;
|
|
2276
|
-
|
|
2282
|
+
const hasPlainTableOutput = editor.plugins.has('PlainTableOutput');
|
|
2283
|
+
const isClipboardPipeline = conversionApi.options.isClipboardPipeline;
|
|
2284
|
+
const useExtendedAlignment = editor.config.get('experimentalFlags.useExtendedTableBlockAlignment');
|
|
2285
|
+
if (!hasPlainTableOutput && !(useExtendedAlignment && isClipboardPipeline)) {
|
|
2277
2286
|
return;
|
|
2278
2287
|
}
|
|
2279
2288
|
if (!conversionApi.consumable.consume(item, evt.name)) {
|
|
@@ -7898,7 +7907,7 @@ const isEmpty = (val)=>val === '';
|
|
|
7898
7907
|
*
|
|
7899
7908
|
* @internal
|
|
7900
7909
|
* @param t The "t" function provided by the editor that is used to localize strings.
|
|
7901
|
-
*/ function getBorderStyleLabels(t) {
|
|
7910
|
+
*/ function getBorderStyleLabels$1(t) {
|
|
7902
7911
|
return {
|
|
7903
7912
|
none: t('None'),
|
|
7904
7913
|
solid: t('Solid'),
|
|
@@ -7968,9 +7977,9 @@ const isEmpty = (val)=>val === '';
|
|
|
7968
7977
|
*
|
|
7969
7978
|
* @internal
|
|
7970
7979
|
* @param defaultStyle The default border.
|
|
7971
|
-
*/ function getBorderStyleDefinitions(view, defaultStyle) {
|
|
7980
|
+
*/ function getBorderStyleDefinitions$1(view, defaultStyle) {
|
|
7972
7981
|
const itemDefinitions = new Collection();
|
|
7973
|
-
const styleLabels = getBorderStyleLabels(view.t);
|
|
7982
|
+
const styleLabels = getBorderStyleLabels$1(view.t);
|
|
7974
7983
|
for(const style in styleLabels){
|
|
7975
7984
|
const definition = {
|
|
7976
7985
|
type: 'button',
|
|
@@ -8013,7 +8022,7 @@ const isEmpty = (val)=>val === '';
|
|
|
8013
8022
|
* @param options.propertyName The name of the observable property in the view.
|
|
8014
8023
|
* @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
|
|
8015
8024
|
* @param options.defaultValue Default value for the property.
|
|
8016
|
-
*/ function fillToolbar(options) {
|
|
8025
|
+
*/ function fillToolbar$1(options) {
|
|
8017
8026
|
const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
|
|
8018
8027
|
for(const name in labels){
|
|
8019
8028
|
const button = new ButtonView(view.locale);
|
|
@@ -8217,10 +8226,10 @@ const isEmpty = (val)=>val === '';
|
|
|
8217
8226
|
* @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
|
|
8218
8227
|
* the "Restore default" button. Instead of clearing the input field, the default color value will be set.
|
|
8219
8228
|
* @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
|
|
8220
|
-
*/ function getLabeledColorInputCreator(options) {
|
|
8229
|
+
*/ function getLabeledColorInputCreator$1(options) {
|
|
8221
8230
|
return (labeledFieldView, viewUid, statusUid)=>{
|
|
8222
8231
|
const colorInputView = new ColorInputView(labeledFieldView.locale, {
|
|
8223
|
-
colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
|
|
8232
|
+
colorDefinitions: colorConfigToColorGridDefinitions$1(options.colorConfig),
|
|
8224
8233
|
columns: options.columns,
|
|
8225
8234
|
defaultColorValue: options.defaultColorValue,
|
|
8226
8235
|
colorPickerConfig: options.colorPickerConfig
|
|
@@ -8247,7 +8256,7 @@ const isEmpty = (val)=>val === '';
|
|
|
8247
8256
|
const parsedValue = parseFloat(value);
|
|
8248
8257
|
return !Number.isNaN(parsedValue) && value === String(parsedValue);
|
|
8249
8258
|
}
|
|
8250
|
-
function colorConfigToColorGridDefinitions(colorConfig) {
|
|
8259
|
+
function colorConfigToColorGridDefinitions$1(colorConfig) {
|
|
8251
8260
|
return colorConfig.map((item)=>({
|
|
8252
8261
|
color: item.model,
|
|
8253
8262
|
label: item.label,
|
|
@@ -8285,9 +8294,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8285
8294
|
/**
|
|
8286
8295
|
* An input that allows specifying the table cell background color.
|
|
8287
8296
|
*/ backgroundInput;
|
|
8288
|
-
/**
|
|
8289
|
-
* A dropdown that allows selecting the type of the table cell (data or header).
|
|
8290
|
-
*/ cellTypeDropdown;
|
|
8291
8297
|
/**
|
|
8292
8298
|
* An input that allows specifying the table cell padding.
|
|
8293
8299
|
*/ paddingInput;
|
|
@@ -8309,9 +8315,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8309
8315
|
/**
|
|
8310
8316
|
* The "Cancel" button view.
|
|
8311
8317
|
*/ cancelButtonView;
|
|
8312
|
-
/**
|
|
8313
|
-
* The "Back" button view.
|
|
8314
|
-
*/ backButtonView;
|
|
8315
8318
|
/**
|
|
8316
8319
|
* A collection of views that can be focused in the form.
|
|
8317
8320
|
*/ _focusables;
|
|
@@ -8337,13 +8340,11 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8337
8340
|
width: '',
|
|
8338
8341
|
height: '',
|
|
8339
8342
|
horizontalAlignment: '',
|
|
8340
|
-
verticalAlignment: ''
|
|
8341
|
-
cellType: ''
|
|
8343
|
+
verticalAlignment: ''
|
|
8342
8344
|
});
|
|
8343
8345
|
this.options = options;
|
|
8344
8346
|
const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
|
|
8345
8347
|
const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
|
|
8346
|
-
const { cellTypeRowLabel, cellTypeDropdown } = this._createCellTypeField();
|
|
8347
8348
|
const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
|
|
8348
8349
|
const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
|
|
8349
8350
|
this.focusTracker = new FocusTracker();
|
|
@@ -8353,7 +8354,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8353
8354
|
this.borderWidthInput = borderWidthInput;
|
|
8354
8355
|
this.borderColorInput = borderColorInput;
|
|
8355
8356
|
this.backgroundInput = backgroundInput;
|
|
8356
|
-
this.cellTypeDropdown = cellTypeDropdown;
|
|
8357
8357
|
this.paddingInput = this._createPaddingField();
|
|
8358
8358
|
this.widthInput = widthInput;
|
|
8359
8359
|
this.heightInput = heightInput;
|
|
@@ -8365,7 +8365,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8365
8365
|
const { saveButtonView, cancelButtonView } = this._createActionButtons();
|
|
8366
8366
|
this.saveButtonView = saveButtonView;
|
|
8367
8367
|
this.cancelButtonView = cancelButtonView;
|
|
8368
|
-
this.backButtonView = this._createBackButton();
|
|
8369
8368
|
this._focusables = new ViewCollection();
|
|
8370
8369
|
this._focusCycler = new FocusCycler({
|
|
8371
8370
|
focusables: this._focusables,
|
|
@@ -8379,42 +8378,28 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8379
8378
|
}
|
|
8380
8379
|
});
|
|
8381
8380
|
// Form header.
|
|
8382
|
-
|
|
8381
|
+
this.children.add(new FormHeaderView(locale, {
|
|
8383
8382
|
label: this.t('Cell properties')
|
|
8384
|
-
});
|
|
8385
|
-
header.children.add(this.backButtonView, 0);
|
|
8386
|
-
this.children.add(header);
|
|
8383
|
+
}));
|
|
8387
8384
|
// Border row.
|
|
8388
8385
|
this.children.add(new FormRowView(locale, {
|
|
8389
8386
|
labelView: borderRowLabel,
|
|
8390
8387
|
children: [
|
|
8391
8388
|
borderRowLabel,
|
|
8392
8389
|
borderStyleDropdown,
|
|
8393
|
-
|
|
8394
|
-
|
|
8390
|
+
borderColorInput,
|
|
8391
|
+
borderWidthInput
|
|
8395
8392
|
],
|
|
8396
8393
|
class: 'ck-table-form__border-row'
|
|
8397
8394
|
}));
|
|
8398
|
-
// Background
|
|
8395
|
+
// Background.
|
|
8399
8396
|
this.children.add(new FormRowView(locale, {
|
|
8397
|
+
labelView: backgroundRowLabel,
|
|
8400
8398
|
children: [
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
cellTypeDropdown
|
|
8406
|
-
],
|
|
8407
|
-
class: 'ck-table-form__cell-type-row'
|
|
8408
|
-
}),
|
|
8409
|
-
new FormRowView(locale, {
|
|
8410
|
-
labelView: backgroundRowLabel,
|
|
8411
|
-
children: [
|
|
8412
|
-
backgroundRowLabel,
|
|
8413
|
-
backgroundInput
|
|
8414
|
-
],
|
|
8415
|
-
class: 'ck-table-form__background-row'
|
|
8416
|
-
})
|
|
8417
|
-
]
|
|
8399
|
+
backgroundRowLabel,
|
|
8400
|
+
backgroundInput
|
|
8401
|
+
],
|
|
8402
|
+
class: 'ck-table-form__background-row'
|
|
8418
8403
|
}));
|
|
8419
8404
|
// Dimensions row and padding.
|
|
8420
8405
|
this.children.add(new FormRowView(locale, {
|
|
@@ -8452,8 +8437,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8452
8437
|
// Action row.
|
|
8453
8438
|
this.children.add(new FormRowView(locale, {
|
|
8454
8439
|
children: [
|
|
8455
|
-
this.
|
|
8456
|
-
this.
|
|
8440
|
+
this.saveButtonView,
|
|
8441
|
+
this.cancelButtonView
|
|
8457
8442
|
],
|
|
8458
8443
|
class: 'ck-table-form__action-row'
|
|
8459
8444
|
}));
|
|
@@ -8492,16 +8477,14 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8492
8477
|
this.borderStyleDropdown,
|
|
8493
8478
|
this.borderColorInput,
|
|
8494
8479
|
this.borderWidthInput,
|
|
8495
|
-
this.cellTypeDropdown,
|
|
8496
8480
|
this.backgroundInput,
|
|
8497
8481
|
this.widthInput,
|
|
8498
8482
|
this.heightInput,
|
|
8499
8483
|
this.paddingInput,
|
|
8500
8484
|
this.horizontalAlignmentToolbar,
|
|
8501
8485
|
this.verticalAlignmentToolbar,
|
|
8502
|
-
this.cancelButtonView,
|
|
8503
8486
|
this.saveButtonView,
|
|
8504
|
-
this.
|
|
8487
|
+
this.cancelButtonView
|
|
8505
8488
|
].forEach((view)=>{
|
|
8506
8489
|
// Register the view as focusable.
|
|
8507
8490
|
this._focusables.add(view);
|
|
@@ -8536,7 +8519,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8536
8519
|
width: defaultTableCellProperties.borderWidth,
|
|
8537
8520
|
color: defaultTableCellProperties.borderColor
|
|
8538
8521
|
};
|
|
8539
|
-
const colorInputCreator = getLabeledColorInputCreator({
|
|
8522
|
+
const colorInputCreator = getLabeledColorInputCreator$1({
|
|
8540
8523
|
colorConfig: this.options.borderColors,
|
|
8541
8524
|
columns: 5,
|
|
8542
8525
|
defaultColorValue: defaultBorder.color,
|
|
@@ -8549,7 +8532,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8549
8532
|
const borderRowLabel = new LabelView(locale);
|
|
8550
8533
|
borderRowLabel.text = t('Border');
|
|
8551
8534
|
// -- Style ---------------------------------------------------
|
|
8552
|
-
const styleLabels = getBorderStyleLabels(t);
|
|
8535
|
+
const styleLabels = getBorderStyleLabels$1(t);
|
|
8553
8536
|
const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
8554
8537
|
borderStyleDropdown.set({
|
|
8555
8538
|
label: accessibleLabel,
|
|
@@ -8569,7 +8552,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8569
8552
|
this.borderStyle = evt.source._borderStyleValue;
|
|
8570
8553
|
});
|
|
8571
8554
|
borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
|
|
8572
|
-
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
|
|
8555
|
+
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
|
|
8573
8556
|
role: 'menu',
|
|
8574
8557
|
ariaLabel: accessibleLabel
|
|
8575
8558
|
});
|
|
@@ -8580,7 +8563,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8580
8563
|
class: 'ck-table-form__border-width'
|
|
8581
8564
|
});
|
|
8582
8565
|
borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
|
|
8583
|
-
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$
|
|
8566
|
+
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
|
|
8584
8567
|
borderWidthInput.fieldView.on('input', ()=>{
|
|
8585
8568
|
this.borderWidth = borderWidthInput.fieldView.element.value;
|
|
8586
8569
|
});
|
|
@@ -8591,7 +8574,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8591
8574
|
class: 'ck-table-form__border-color'
|
|
8592
8575
|
});
|
|
8593
8576
|
borderColorInput.fieldView.bind('value').to(this, 'borderColor');
|
|
8594
|
-
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$
|
|
8577
|
+
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$3);
|
|
8595
8578
|
borderColorInput.fieldView.on('input', ()=>{
|
|
8596
8579
|
this.borderColor = borderColorInput.fieldView.value;
|
|
8597
8580
|
});
|
|
@@ -8599,12 +8582,12 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8599
8582
|
this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
|
|
8600
8583
|
// When removing the border (`border-style:none`), clear the remaining `border-*` properties.
|
|
8601
8584
|
// See: https://github.com/ckeditor/ckeditor5/issues/6227.
|
|
8602
|
-
if (!isBorderStyleSet$
|
|
8585
|
+
if (!isBorderStyleSet$3(newValue)) {
|
|
8603
8586
|
this.borderColor = '';
|
|
8604
8587
|
this.borderWidth = '';
|
|
8605
8588
|
}
|
|
8606
8589
|
// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
|
|
8607
|
-
if (!isBorderStyleSet$
|
|
8590
|
+
if (!isBorderStyleSet$3(oldValue)) {
|
|
8608
8591
|
this.borderColor = defaultBorder.color;
|
|
8609
8592
|
this.borderWidth = defaultBorder.width;
|
|
8610
8593
|
}
|
|
@@ -8627,7 +8610,7 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8627
8610
|
const backgroundRowLabel = new LabelView(locale);
|
|
8628
8611
|
backgroundRowLabel.text = t('Background');
|
|
8629
8612
|
// -- Background color input -----------------------------------
|
|
8630
|
-
const colorInputCreator = getLabeledColorInputCreator({
|
|
8613
|
+
const colorInputCreator = getLabeledColorInputCreator$1({
|
|
8631
8614
|
colorConfig: this.options.backgroundColors,
|
|
8632
8615
|
columns: 5,
|
|
8633
8616
|
defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
|
|
@@ -8647,46 +8630,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8647
8630
|
backgroundInput
|
|
8648
8631
|
};
|
|
8649
8632
|
}
|
|
8650
|
-
/**
|
|
8651
|
-
* Create cell type field.
|
|
8652
|
-
*
|
|
8653
|
-
* * {@link #cellTypeDropdown}.
|
|
8654
|
-
*
|
|
8655
|
-
* @internal
|
|
8656
|
-
*/ _createCellTypeField() {
|
|
8657
|
-
const locale = this.locale;
|
|
8658
|
-
const t = this.t;
|
|
8659
|
-
const cellTypeRowLabel = new LabelView(locale);
|
|
8660
|
-
cellTypeRowLabel.text = t('Cell type');
|
|
8661
|
-
const cellTypeLabels = this._cellTypeLabels;
|
|
8662
|
-
const cellTypeDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
8663
|
-
cellTypeDropdown.set({
|
|
8664
|
-
label: t('Cell type'),
|
|
8665
|
-
class: 'ck-table-cell-properties-form__cell-type'
|
|
8666
|
-
});
|
|
8667
|
-
cellTypeDropdown.fieldView.buttonView.set({
|
|
8668
|
-
ariaLabel: t('Cell type'),
|
|
8669
|
-
ariaLabelledBy: undefined,
|
|
8670
|
-
isOn: false,
|
|
8671
|
-
withText: true,
|
|
8672
|
-
tooltip: t('Cell type')
|
|
8673
|
-
});
|
|
8674
|
-
cellTypeDropdown.fieldView.buttonView.bind('label').to(this, 'cellType', (value)=>{
|
|
8675
|
-
return cellTypeLabels[value || 'data'];
|
|
8676
|
-
});
|
|
8677
|
-
cellTypeDropdown.fieldView.on('execute', (evt)=>{
|
|
8678
|
-
this.cellType = evt.source._cellTypeValue;
|
|
8679
|
-
});
|
|
8680
|
-
cellTypeDropdown.bind('isEmpty').to(this, 'cellType', (value)=>!value);
|
|
8681
|
-
addListToDropdown(cellTypeDropdown.fieldView, this._getCellTypeDefinitions(), {
|
|
8682
|
-
role: 'menu',
|
|
8683
|
-
ariaLabel: t('Cell type')
|
|
8684
|
-
});
|
|
8685
|
-
return {
|
|
8686
|
-
cellTypeRowLabel,
|
|
8687
|
-
cellTypeDropdown
|
|
8688
|
-
};
|
|
8689
|
-
}
|
|
8690
8633
|
/**
|
|
8691
8634
|
* Creates the following form fields:
|
|
8692
8635
|
*
|
|
@@ -8783,10 +8726,9 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8783
8726
|
horizontalAlignmentToolbar.set({
|
|
8784
8727
|
isCompact: true,
|
|
8785
8728
|
role: 'radiogroup',
|
|
8786
|
-
ariaLabel: t('Horizontal text alignment toolbar')
|
|
8787
|
-
class: 'ck-table-cell-properties-form__horizontal-alignment-toolbar'
|
|
8729
|
+
ariaLabel: t('Horizontal text alignment toolbar')
|
|
8788
8730
|
});
|
|
8789
|
-
fillToolbar({
|
|
8731
|
+
fillToolbar$1({
|
|
8790
8732
|
view: this,
|
|
8791
8733
|
icons: ALIGNMENT_ICONS,
|
|
8792
8734
|
toolbar: horizontalAlignmentToolbar,
|
|
@@ -8810,10 +8752,9 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8810
8752
|
verticalAlignmentToolbar.set({
|
|
8811
8753
|
isCompact: true,
|
|
8812
8754
|
role: 'radiogroup',
|
|
8813
|
-
ariaLabel: t('Vertical text alignment toolbar')
|
|
8814
|
-
class: 'ck-table-cell-properties-form__vertical-alignment-toolbar'
|
|
8755
|
+
ariaLabel: t('Vertical text alignment toolbar')
|
|
8815
8756
|
});
|
|
8816
|
-
fillToolbar({
|
|
8757
|
+
fillToolbar$1({
|
|
8817
8758
|
view: this,
|
|
8818
8759
|
icons: ALIGNMENT_ICONS,
|
|
8819
8760
|
toolbar: verticalAlignmentToolbar,
|
|
@@ -8845,7 +8786,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8845
8786
|
];
|
|
8846
8787
|
saveButtonView.set({
|
|
8847
8788
|
label: t('Save'),
|
|
8848
|
-
|
|
8789
|
+
icon: IconCheck,
|
|
8790
|
+
class: 'ck-button-save',
|
|
8849
8791
|
type: 'submit',
|
|
8850
8792
|
withText: true
|
|
8851
8793
|
});
|
|
@@ -8854,6 +8796,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8854
8796
|
});
|
|
8855
8797
|
cancelButtonView.set({
|
|
8856
8798
|
label: t('Cancel'),
|
|
8799
|
+
icon: IconCancel,
|
|
8800
|
+
class: 'ck-button-cancel',
|
|
8857
8801
|
withText: true
|
|
8858
8802
|
});
|
|
8859
8803
|
cancelButtonView.delegate('execute').to(this, 'cancel');
|
|
@@ -8862,43 +8806,6 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8862
8806
|
cancelButtonView
|
|
8863
8807
|
};
|
|
8864
8808
|
}
|
|
8865
|
-
/**
|
|
8866
|
-
* Creates a back button view that cancels the form.
|
|
8867
|
-
*/ _createBackButton() {
|
|
8868
|
-
const t = this.locale.t;
|
|
8869
|
-
const backButton = new ButtonView(this.locale);
|
|
8870
|
-
backButton.set({
|
|
8871
|
-
class: 'ck-button-back',
|
|
8872
|
-
label: t('Back'),
|
|
8873
|
-
icon: IconPreviousArrow,
|
|
8874
|
-
tooltip: true
|
|
8875
|
-
});
|
|
8876
|
-
backButton.delegate('execute').to(this, 'cancel');
|
|
8877
|
-
return backButton;
|
|
8878
|
-
}
|
|
8879
|
-
/**
|
|
8880
|
-
* Creates the cell type dropdown definitions.
|
|
8881
|
-
*/ _getCellTypeDefinitions() {
|
|
8882
|
-
const itemDefinitions = new Collection();
|
|
8883
|
-
const cellTypeLabels = this._cellTypeLabels;
|
|
8884
|
-
for (const type of [
|
|
8885
|
-
'data',
|
|
8886
|
-
'header'
|
|
8887
|
-
]){
|
|
8888
|
-
const definition = {
|
|
8889
|
-
type: 'button',
|
|
8890
|
-
model: new UIModel({
|
|
8891
|
-
_cellTypeValue: type,
|
|
8892
|
-
label: cellTypeLabels[type],
|
|
8893
|
-
role: 'menuitemradio',
|
|
8894
|
-
withText: true
|
|
8895
|
-
})
|
|
8896
|
-
};
|
|
8897
|
-
definition.model.bind('isOn').to(this, 'cellType', (value)=>value === type);
|
|
8898
|
-
itemDefinitions.add(definition);
|
|
8899
|
-
}
|
|
8900
|
-
return itemDefinitions;
|
|
8901
|
-
}
|
|
8902
8809
|
/**
|
|
8903
8810
|
* Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
|
|
8904
8811
|
*/ get _horizontalAlignmentLabels() {
|
|
@@ -8935,17 +8842,8 @@ function colorConfigToColorGridDefinitions(colorConfig) {
|
|
|
8935
8842
|
bottom: t('Align cell text to the bottom')
|
|
8936
8843
|
};
|
|
8937
8844
|
}
|
|
8938
|
-
/**
|
|
8939
|
-
* Provides localized labels for {@link #cellTypeDropdown}.
|
|
8940
|
-
*/ get _cellTypeLabels() {
|
|
8941
|
-
const t = this.t;
|
|
8942
|
-
return {
|
|
8943
|
-
data: t('Data cell'),
|
|
8944
|
-
header: t('Header cell')
|
|
8945
|
-
};
|
|
8946
|
-
}
|
|
8947
8845
|
}
|
|
8948
|
-
function isBorderStyleSet$
|
|
8846
|
+
function isBorderStyleSet$3(value) {
|
|
8949
8847
|
return value !== 'none';
|
|
8950
8848
|
}
|
|
8951
8849
|
|
|
@@ -9044,9 +8942,9 @@ const BALLOON_POSITIONS = /* #__PURE__ */ (()=>[
|
|
|
9044
8942
|
return Rect.getBoundingRect(rects);
|
|
9045
8943
|
}
|
|
9046
8944
|
|
|
9047
|
-
const ERROR_TEXT_TIMEOUT$
|
|
8945
|
+
const ERROR_TEXT_TIMEOUT$3 = 500;
|
|
9048
8946
|
// Map of view properties and related commands.
|
|
9049
|
-
const propertyToCommandMap$
|
|
8947
|
+
const propertyToCommandMap$3 = {
|
|
9050
8948
|
borderStyle: 'tableCellBorderStyle',
|
|
9051
8949
|
borderColor: 'tableCellBorderColor',
|
|
9052
8950
|
borderWidth: 'tableCellBorderWidth',
|
|
@@ -9055,8 +8953,7 @@ const propertyToCommandMap$1 = {
|
|
|
9055
8953
|
padding: 'tableCellPadding',
|
|
9056
8954
|
backgroundColor: 'tableCellBackgroundColor',
|
|
9057
8955
|
horizontalAlignment: 'tableCellHorizontalAlignment',
|
|
9058
|
-
verticalAlignment: 'tableCellVerticalAlignment'
|
|
9059
|
-
cellType: 'tableCellType'
|
|
8956
|
+
verticalAlignment: 'tableCellVerticalAlignment'
|
|
9060
8957
|
};
|
|
9061
8958
|
/**
|
|
9062
8959
|
* The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
|
|
@@ -9143,7 +9040,7 @@ const propertyToCommandMap$1 = {
|
|
|
9143
9040
|
tooltip: true
|
|
9144
9041
|
});
|
|
9145
9042
|
this.listenTo(view, 'execute', ()=>this._showView());
|
|
9146
|
-
const commands = Object.values(propertyToCommandMap$
|
|
9043
|
+
const commands = Object.values(propertyToCommandMap$3).map((commandName)=>editor.commands.get(commandName));
|
|
9147
9044
|
view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
|
|
9148
9045
|
return view;
|
|
9149
9046
|
});
|
|
@@ -9249,11 +9146,6 @@ const propertyToCommandMap$1 = {
|
|
|
9249
9146
|
}));
|
|
9250
9147
|
view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
|
|
9251
9148
|
view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
|
|
9252
|
-
const cellTypeCommand = editor.commands.get('tableCellType');
|
|
9253
|
-
if (cellTypeCommand) {
|
|
9254
|
-
view.cellTypeDropdown.bind('isEnabled').to(cellTypeCommand, 'isEnabled');
|
|
9255
|
-
view.on('change:cellType', this._getPropertyChangeCallback('tableCellType'));
|
|
9256
|
-
}
|
|
9257
9149
|
return view;
|
|
9258
9150
|
}
|
|
9259
9151
|
/**
|
|
@@ -9266,24 +9158,12 @@ const propertyToCommandMap$1 = {
|
|
|
9266
9158
|
*/ _fillViewFormFromCommandValues() {
|
|
9267
9159
|
const commands = this.editor.commands;
|
|
9268
9160
|
const borderStyleCommand = commands.get('tableCellBorderStyle');
|
|
9269
|
-
Object.entries(propertyToCommandMap$
|
|
9270
|
-
const command = commands.get(commandName);
|
|
9271
|
-
if (!command) {
|
|
9272
|
-
return [];
|
|
9273
|
-
}
|
|
9161
|
+
Object.entries(propertyToCommandMap$3).map(([property, commandName])=>{
|
|
9274
9162
|
const propertyKey = property;
|
|
9275
|
-
|
|
9276
|
-
if (propertyKey === 'cellType') {
|
|
9277
|
-
defaultValue = '';
|
|
9278
|
-
} else {
|
|
9279
|
-
defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
|
|
9280
|
-
}
|
|
9281
|
-
const entry = [
|
|
9282
|
-
property,
|
|
9283
|
-
command.value || defaultValue
|
|
9284
|
-
];
|
|
9163
|
+
const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
|
|
9285
9164
|
return [
|
|
9286
|
-
|
|
9165
|
+
property,
|
|
9166
|
+
commands.get(commandName).value || defaultValue
|
|
9287
9167
|
];
|
|
9288
9168
|
}).forEach(([property, value])=>{
|
|
9289
9169
|
// Do not set the `border-color` and `border-width` fields if `border-style:none`.
|
|
@@ -9384,7 +9264,7 @@ const propertyToCommandMap$1 = {
|
|
|
9384
9264
|
const { commandName, viewField, validator, errorText } = options;
|
|
9385
9265
|
const setErrorTextDebounced = debounce(()=>{
|
|
9386
9266
|
viewField.errorText = errorText;
|
|
9387
|
-
}, ERROR_TEXT_TIMEOUT$
|
|
9267
|
+
}, ERROR_TEXT_TIMEOUT$3);
|
|
9388
9268
|
return (evt, propertyName, newValue)=>{
|
|
9389
9269
|
setErrorTextDebounced.cancel();
|
|
9390
9270
|
// Do not execute the command on initial call (opening the table properties view).
|
|
@@ -10170,8 +10050,10 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
|
|
|
10170
10050
|
editor.commands.add('tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand(editor, defaultTableCellProperties.horizontalAlignment));
|
|
10171
10051
|
enableVerticalAlignmentProperty(schema, conversion, defaultTableCellProperties.verticalAlignment);
|
|
10172
10052
|
editor.commands.add('tableCellVerticalAlignment', new TableCellVerticalAlignmentCommand(editor, defaultTableCellProperties.verticalAlignment));
|
|
10173
|
-
|
|
10174
|
-
|
|
10053
|
+
if (editor.config.get('experimentalFlags.tableCellTypeSupport')) {
|
|
10054
|
+
enableCellTypeProperty(editor);
|
|
10055
|
+
editor.commands.add('tableCellType', new TableCellTypeCommand(editor));
|
|
10056
|
+
}
|
|
10175
10057
|
}
|
|
10176
10058
|
}
|
|
10177
10059
|
/**
|
|
@@ -12356,7 +12238,7 @@ const TABLE_TYPES = [
|
|
|
12356
12238
|
const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
|
|
12357
12239
|
includeAlignmentProperty: true
|
|
12358
12240
|
});
|
|
12359
|
-
const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles')
|
|
12241
|
+
const useInlineStyles = editor.config.get('table.tableProperties.alignment.useInlineStyles') !== false;
|
|
12360
12242
|
editor.data.addStyleProcessorRules(addMarginStylesRules);
|
|
12361
12243
|
editor.data.addStyleProcessorRules(addBorderStylesRules);
|
|
12362
12244
|
enableBorderProperties(editor, {
|
|
@@ -12367,7 +12249,11 @@ const TABLE_TYPES = [
|
|
|
12367
12249
|
editor.commands.add('tableBorderColor', new TableBorderColorCommand(editor, defaultTableProperties.borderColor));
|
|
12368
12250
|
editor.commands.add('tableBorderStyle', new TableBorderStyleCommand(editor, defaultTableProperties.borderStyle));
|
|
12369
12251
|
editor.commands.add('tableBorderWidth', new TableBorderWidthCommand(editor, defaultTableProperties.borderWidth));
|
|
12370
|
-
|
|
12252
|
+
if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
|
|
12253
|
+
enableExtendedAlignmentProperty(schema, conversion, defaultTableProperties.alignment, useInlineStyles);
|
|
12254
|
+
} else {
|
|
12255
|
+
enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment);
|
|
12256
|
+
}
|
|
12371
12257
|
editor.commands.add('tableAlignment', new TableAlignmentCommand(editor, defaultTableProperties.alignment));
|
|
12372
12258
|
enableTableToFigureProperty(schema, conversion, {
|
|
12373
12259
|
modelAttribute: 'tableWidth',
|
|
@@ -12394,18 +12280,20 @@ const TABLE_TYPES = [
|
|
|
12394
12280
|
defaultValue: defaultTableProperties.backgroundColor
|
|
12395
12281
|
});
|
|
12396
12282
|
editor.commands.add('tableBackgroundColor', new TableBackgroundColorCommand(editor, defaultTableProperties.backgroundColor));
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12283
|
+
if (editor.config.get('experimentalFlags.useExtendedTableBlockAlignment')) {
|
|
12284
|
+
const viewDoc = editor.editing.view.document;
|
|
12285
|
+
// Adjust clipboard output to wrap tables in divs if needed (for alignment).
|
|
12286
|
+
this.listenTo(viewDoc, 'clipboardOutput', (evt, data)=>{
|
|
12287
|
+
editor.editing.view.change((writer)=>{
|
|
12288
|
+
for (const { item } of writer.createRangeIn(data.content)){
|
|
12289
|
+
wrapInDivIfNeeded(item, writer);
|
|
12290
|
+
}
|
|
12291
|
+
data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));
|
|
12292
|
+
});
|
|
12293
|
+
}, {
|
|
12294
|
+
priority: 'lowest'
|
|
12405
12295
|
});
|
|
12406
|
-
}
|
|
12407
|
-
priority: 'lowest'
|
|
12408
|
-
});
|
|
12296
|
+
}
|
|
12409
12297
|
}
|
|
12410
12298
|
}
|
|
12411
12299
|
/**
|
|
@@ -12475,10 +12363,10 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12475
12363
|
});
|
|
12476
12364
|
}
|
|
12477
12365
|
/**
|
|
12478
|
-
* Enables the `'alignment'` attribute for table.
|
|
12366
|
+
* Enables the extended block`'alignment'` attribute for table.
|
|
12479
12367
|
*
|
|
12480
12368
|
* @param defaultValue The default alignment value.
|
|
12481
|
-
*/ function
|
|
12369
|
+
*/ function enableExtendedAlignmentProperty(schema, conversion, defaultValue, useInlineStyles) {
|
|
12482
12370
|
schema.extend('table', {
|
|
12483
12371
|
allowAttributes: [
|
|
12484
12372
|
'tableAlignment'
|
|
@@ -12578,37 +12466,175 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12578
12466
|
conversion.for('upcast').add(upcastTableAlignedDiv(defaultValue));
|
|
12579
12467
|
}
|
|
12580
12468
|
/**
|
|
12581
|
-
*
|
|
12582
|
-
*
|
|
12583
|
-
* ```html
|
|
12584
|
-
* <div align="right"><table>...</table></div>
|
|
12585
|
-
* <!-- or -->
|
|
12586
|
-
* <div align="center"><table>...</table></div>
|
|
12587
|
-
* <!-- or -->
|
|
12588
|
-
* <div align="left"><table>...</table></div>
|
|
12589
|
-
* ```
|
|
12590
|
-
*
|
|
12591
|
-
* to the model representation:
|
|
12592
|
-
*
|
|
12593
|
-
* ```xml
|
|
12594
|
-
* <table tableAlignment="right|center|left"></table>
|
|
12595
|
-
* ```
|
|
12469
|
+
* Enables the `'alignment'` attribute for table.
|
|
12596
12470
|
*
|
|
12597
|
-
* @
|
|
12598
|
-
*/ function
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12471
|
+
* @param defaultValue The default alignment value.
|
|
12472
|
+
*/ function enableAlignmentProperty(schema, conversion, defaultValue) {
|
|
12473
|
+
const ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;
|
|
12474
|
+
const FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;
|
|
12475
|
+
schema.extend('table', {
|
|
12476
|
+
allowAttributes: [
|
|
12477
|
+
'tableAlignment'
|
|
12478
|
+
]
|
|
12479
|
+
});
|
|
12480
|
+
schema.setAttributeProperties('tableAlignment', {
|
|
12481
|
+
isFormatting: true
|
|
12482
|
+
});
|
|
12483
|
+
conversion.for('downcast').attributeToAttribute({
|
|
12484
|
+
model: {
|
|
12485
|
+
name: 'table',
|
|
12486
|
+
key: 'tableAlignment',
|
|
12487
|
+
values: [
|
|
12488
|
+
'left',
|
|
12489
|
+
'center',
|
|
12490
|
+
'right'
|
|
12491
|
+
]
|
|
12492
|
+
},
|
|
12493
|
+
view: {
|
|
12494
|
+
left: {
|
|
12495
|
+
key: 'style',
|
|
12496
|
+
value: {
|
|
12497
|
+
float: 'left'
|
|
12498
|
+
}
|
|
12499
|
+
},
|
|
12500
|
+
right: {
|
|
12501
|
+
key: 'style',
|
|
12502
|
+
value: {
|
|
12503
|
+
float: 'right'
|
|
12504
|
+
}
|
|
12505
|
+
},
|
|
12506
|
+
center: (alignment, conversionApi, data)=>{
|
|
12507
|
+
const value = data.item.getAttribute('tableType') !== 'layout' ? {
|
|
12508
|
+
// Model: `alignment:center` => CSS: `float:none`.
|
|
12509
|
+
float: 'none'
|
|
12510
|
+
} : {
|
|
12511
|
+
'margin-left': 'auto',
|
|
12512
|
+
'margin-right': 'auto'
|
|
12513
|
+
};
|
|
12514
|
+
return {
|
|
12515
|
+
key: 'style',
|
|
12516
|
+
value
|
|
12517
|
+
};
|
|
12607
12518
|
}
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12519
|
+
},
|
|
12520
|
+
converterPriority: 'high'
|
|
12521
|
+
});
|
|
12522
|
+
conversion.for('upcast')// Support for the `float:*;` CSS definition for the table alignment.
|
|
12523
|
+
.attributeToAttribute({
|
|
12524
|
+
view: {
|
|
12525
|
+
name: /^(table|figure)$/,
|
|
12526
|
+
styles: {
|
|
12527
|
+
float: FLOAT_VALUES_REG_EXP
|
|
12528
|
+
}
|
|
12529
|
+
},
|
|
12530
|
+
model: {
|
|
12531
|
+
key: 'tableAlignment',
|
|
12532
|
+
value: (viewElement, conversionApi, data)=>{
|
|
12533
|
+
// Ignore other figure elements.
|
|
12534
|
+
if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
|
|
12535
|
+
return;
|
|
12536
|
+
}
|
|
12537
|
+
const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
|
|
12538
|
+
let align = viewElement.getStyle('float');
|
|
12539
|
+
// CSS: `float:none` => Model: `alignment:center`.
|
|
12540
|
+
if (align === 'none') {
|
|
12541
|
+
align = 'center';
|
|
12542
|
+
}
|
|
12543
|
+
if (align !== localDefaultValue) {
|
|
12544
|
+
return align;
|
|
12545
|
+
}
|
|
12546
|
+
// Consume the style even if not applied to the element so it won't be processed by other converters.
|
|
12547
|
+
conversionApi.consumable.consume(viewElement, {
|
|
12548
|
+
styles: 'float'
|
|
12549
|
+
});
|
|
12550
|
+
}
|
|
12551
|
+
}
|
|
12552
|
+
})// Support for the `margin-left:auto; margin-right:auto;` CSS definition for the table alignment.
|
|
12553
|
+
.attributeToAttribute({
|
|
12554
|
+
view: {
|
|
12555
|
+
name: /^(table|figure)$/,
|
|
12556
|
+
styles: {
|
|
12557
|
+
'margin-left': 'auto',
|
|
12558
|
+
'margin-right': 'auto'
|
|
12559
|
+
}
|
|
12560
|
+
},
|
|
12561
|
+
model: {
|
|
12562
|
+
key: 'tableAlignment',
|
|
12563
|
+
value: (viewElement, conversionApi, data)=>{
|
|
12564
|
+
// Ignore other figure elements.
|
|
12565
|
+
if (viewElement.name == 'figure' && !viewElement.hasClass('table')) {
|
|
12566
|
+
return;
|
|
12567
|
+
}
|
|
12568
|
+
const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
|
|
12569
|
+
const align = 'center';
|
|
12570
|
+
if (align !== localDefaultValue) {
|
|
12571
|
+
return align;
|
|
12572
|
+
}
|
|
12573
|
+
// Consume the styles even if not applied to the element so it won't be processed by other converters.
|
|
12574
|
+
conversionApi.consumable.consume(viewElement, {
|
|
12575
|
+
styles: [
|
|
12576
|
+
'margin-left',
|
|
12577
|
+
'margin-right'
|
|
12578
|
+
]
|
|
12579
|
+
});
|
|
12580
|
+
}
|
|
12581
|
+
}
|
|
12582
|
+
})// Support for the `align` attribute as the backward compatibility while pasting from other sources.
|
|
12583
|
+
.attributeToAttribute({
|
|
12584
|
+
view: {
|
|
12585
|
+
name: 'table',
|
|
12586
|
+
attributes: {
|
|
12587
|
+
align: ALIGN_VALUES_REG_EXP
|
|
12588
|
+
}
|
|
12589
|
+
},
|
|
12590
|
+
model: {
|
|
12591
|
+
key: 'tableAlignment',
|
|
12592
|
+
value: (viewElement, conversionApi, data)=>{
|
|
12593
|
+
const localDefaultValue = getDefaultValueAdjusted(defaultValue, '', data);
|
|
12594
|
+
const align = viewElement.getAttribute('align');
|
|
12595
|
+
if (align !== localDefaultValue) {
|
|
12596
|
+
return align;
|
|
12597
|
+
}
|
|
12598
|
+
// Consume the attribute even if not applied to the element so it won't be processed by other converters.
|
|
12599
|
+
conversionApi.consumable.consume(viewElement, {
|
|
12600
|
+
attributes: 'align'
|
|
12601
|
+
});
|
|
12602
|
+
}
|
|
12603
|
+
}
|
|
12604
|
+
});
|
|
12605
|
+
}
|
|
12606
|
+
/**
|
|
12607
|
+
* Returns a function that converts the table view representation:
|
|
12608
|
+
*
|
|
12609
|
+
* ```html
|
|
12610
|
+
* <div align="right"><table>...</table></div>
|
|
12611
|
+
* <!-- or -->
|
|
12612
|
+
* <div align="center"><table>...</table></div>
|
|
12613
|
+
* <!-- or -->
|
|
12614
|
+
* <div align="left"><table>...</table></div>
|
|
12615
|
+
* ```
|
|
12616
|
+
*
|
|
12617
|
+
* to the model representation:
|
|
12618
|
+
*
|
|
12619
|
+
* ```xml
|
|
12620
|
+
* <table tableAlignment="right|center|left"></table>
|
|
12621
|
+
* ```
|
|
12622
|
+
*
|
|
12623
|
+
* @internal
|
|
12624
|
+
*/ function upcastTableAlignedDiv(defaultValue) {
|
|
12625
|
+
return (dispatcher)=>{
|
|
12626
|
+
dispatcher.on('element:div', (evt, data, conversionApi)=>{
|
|
12627
|
+
// Do not convert if this is not a "table wrapped in div with align attribute".
|
|
12628
|
+
if (!conversionApi.consumable.test(data.viewItem, {
|
|
12629
|
+
name: true,
|
|
12630
|
+
attributes: 'align'
|
|
12631
|
+
})) {
|
|
12632
|
+
return;
|
|
12633
|
+
}
|
|
12634
|
+
// Find a table element inside the div element.
|
|
12635
|
+
const viewTable = getViewTableFromWrapper(data.viewItem);
|
|
12636
|
+
// Do not convert if table element is absent or was already converted.
|
|
12637
|
+
if (!viewTable || !conversionApi.consumable.test(viewTable, {
|
|
12612
12638
|
name: true
|
|
12613
12639
|
})) {
|
|
12614
12640
|
return;
|
|
@@ -12767,9 +12793,6 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12767
12793
|
/**
|
|
12768
12794
|
* The "Cancel" button view.
|
|
12769
12795
|
*/ cancelButtonView;
|
|
12770
|
-
/**
|
|
12771
|
-
* The Back button view displayed in the header.
|
|
12772
|
-
*/ backButtonView;
|
|
12773
12796
|
/**
|
|
12774
12797
|
* A collection of views that can be focused in the form.
|
|
12775
12798
|
*/ _focusables;
|
|
@@ -12811,7 +12834,6 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12811
12834
|
const { saveButtonView, cancelButtonView } = this._createActionButtons();
|
|
12812
12835
|
this.saveButtonView = saveButtonView;
|
|
12813
12836
|
this.cancelButtonView = cancelButtonView;
|
|
12814
|
-
this.backButtonView = this._createBackButton();
|
|
12815
12837
|
this._focusables = new ViewCollection();
|
|
12816
12838
|
this._focusCycler = new FocusCycler({
|
|
12817
12839
|
focusables: this._focusables,
|
|
@@ -12825,22 +12847,29 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12825
12847
|
}
|
|
12826
12848
|
});
|
|
12827
12849
|
// Form header.
|
|
12828
|
-
|
|
12850
|
+
this.children.add(new FormHeaderView(locale, {
|
|
12829
12851
|
label: this.t('Table properties')
|
|
12830
|
-
});
|
|
12831
|
-
headerView.children.add(this.backButtonView, 0);
|
|
12832
|
-
this.children.add(headerView);
|
|
12852
|
+
}));
|
|
12833
12853
|
// Border row.
|
|
12834
12854
|
this.children.add(new FormRowView(locale, {
|
|
12835
12855
|
labelView: borderRowLabel,
|
|
12836
12856
|
children: [
|
|
12837
12857
|
borderRowLabel,
|
|
12838
12858
|
borderStyleDropdown,
|
|
12839
|
-
|
|
12840
|
-
|
|
12859
|
+
borderColorInput,
|
|
12860
|
+
borderWidthInput
|
|
12841
12861
|
],
|
|
12842
12862
|
class: 'ck-table-form__border-row'
|
|
12843
12863
|
}));
|
|
12864
|
+
// Background row.
|
|
12865
|
+
this.children.add(new FormRowView(locale, {
|
|
12866
|
+
labelView: backgroundRowLabel,
|
|
12867
|
+
children: [
|
|
12868
|
+
backgroundRowLabel,
|
|
12869
|
+
backgroundInput
|
|
12870
|
+
],
|
|
12871
|
+
class: 'ck-table-form__background-row'
|
|
12872
|
+
}));
|
|
12844
12873
|
this.children.add(new FormRowView(locale, {
|
|
12845
12874
|
children: [
|
|
12846
12875
|
// Dimensions row.
|
|
@@ -12854,31 +12883,22 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12854
12883
|
],
|
|
12855
12884
|
class: 'ck-table-form__dimensions-row'
|
|
12856
12885
|
}),
|
|
12857
|
-
//
|
|
12886
|
+
// Alignment row.
|
|
12858
12887
|
new FormRowView(locale, {
|
|
12859
|
-
labelView:
|
|
12888
|
+
labelView: alignmentLabel,
|
|
12860
12889
|
children: [
|
|
12861
|
-
|
|
12862
|
-
|
|
12890
|
+
alignmentLabel,
|
|
12891
|
+
alignmentToolbar
|
|
12863
12892
|
],
|
|
12864
|
-
class: 'ck-table-
|
|
12893
|
+
class: 'ck-table-properties-form__alignment-row'
|
|
12865
12894
|
})
|
|
12866
12895
|
]
|
|
12867
12896
|
}));
|
|
12868
|
-
// Alignment row.
|
|
12869
|
-
this.children.add(new FormRowView(locale, {
|
|
12870
|
-
labelView: alignmentLabel,
|
|
12871
|
-
children: [
|
|
12872
|
-
alignmentLabel,
|
|
12873
|
-
alignmentToolbar
|
|
12874
|
-
],
|
|
12875
|
-
class: 'ck-table-properties-form__alignment-row'
|
|
12876
|
-
}));
|
|
12877
12897
|
// Action row.
|
|
12878
12898
|
this.children.add(new FormRowView(locale, {
|
|
12879
12899
|
children: [
|
|
12880
|
-
this.
|
|
12881
|
-
this.
|
|
12900
|
+
this.saveButtonView,
|
|
12901
|
+
this.cancelButtonView
|
|
12882
12902
|
],
|
|
12883
12903
|
class: 'ck-table-form__action-row'
|
|
12884
12904
|
}));
|
|
@@ -12915,15 +12935,14 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12915
12935
|
});
|
|
12916
12936
|
[
|
|
12917
12937
|
this.borderStyleDropdown,
|
|
12918
|
-
this.borderWidthInput,
|
|
12919
12938
|
this.borderColorInput,
|
|
12939
|
+
this.borderWidthInput,
|
|
12940
|
+
this.backgroundInput,
|
|
12920
12941
|
this.widthInput,
|
|
12921
12942
|
this.heightInput,
|
|
12922
|
-
this.backgroundInput,
|
|
12923
12943
|
this.alignmentToolbar,
|
|
12924
|
-
this.cancelButtonView,
|
|
12925
12944
|
this.saveButtonView,
|
|
12926
|
-
this.
|
|
12945
|
+
this.cancelButtonView
|
|
12927
12946
|
].forEach((view)=>{
|
|
12928
12947
|
// Register the view as focusable.
|
|
12929
12948
|
this._focusables.add(view);
|
|
@@ -12958,7 +12977,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12958
12977
|
width: defaultTableProperties.borderWidth,
|
|
12959
12978
|
color: defaultTableProperties.borderColor
|
|
12960
12979
|
};
|
|
12961
|
-
const colorInputCreator = getLabeledColorInputCreator({
|
|
12980
|
+
const colorInputCreator = getLabeledColorInputCreator$1({
|
|
12962
12981
|
colorConfig: this.options.borderColors,
|
|
12963
12982
|
columns: 5,
|
|
12964
12983
|
defaultColorValue: defaultBorder.color,
|
|
@@ -12971,7 +12990,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12971
12990
|
const borderRowLabel = new LabelView(locale);
|
|
12972
12991
|
borderRowLabel.text = t('Border');
|
|
12973
12992
|
// -- Style ---------------------------------------------------
|
|
12974
|
-
const styleLabels = getBorderStyleLabels(t);
|
|
12993
|
+
const styleLabels = getBorderStyleLabels$1(t);
|
|
12975
12994
|
const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
12976
12995
|
borderStyleDropdown.set({
|
|
12977
12996
|
label: accessibleLabel,
|
|
@@ -12991,7 +13010,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
12991
13010
|
this.borderStyle = evt.source._borderStyleValue;
|
|
12992
13011
|
});
|
|
12993
13012
|
borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
|
|
12994
|
-
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
|
|
13013
|
+
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions$1(this, defaultBorder.style), {
|
|
12995
13014
|
role: 'menu',
|
|
12996
13015
|
ariaLabel: accessibleLabel
|
|
12997
13016
|
});
|
|
@@ -13002,7 +13021,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13002
13021
|
class: 'ck-table-form__border-width'
|
|
13003
13022
|
});
|
|
13004
13023
|
borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
|
|
13005
|
-
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
|
|
13024
|
+
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
|
|
13006
13025
|
borderWidthInput.fieldView.on('input', ()=>{
|
|
13007
13026
|
this.borderWidth = borderWidthInput.fieldView.element.value;
|
|
13008
13027
|
});
|
|
@@ -13013,7 +13032,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13013
13032
|
class: 'ck-table-form__border-color'
|
|
13014
13033
|
});
|
|
13015
13034
|
borderColorInput.fieldView.bind('value').to(this, 'borderColor');
|
|
13016
|
-
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
|
|
13035
|
+
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$2);
|
|
13017
13036
|
borderColorInput.fieldView.on('input', ()=>{
|
|
13018
13037
|
this.borderColor = borderColorInput.fieldView.value;
|
|
13019
13038
|
});
|
|
@@ -13021,12 +13040,12 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13021
13040
|
this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
|
|
13022
13041
|
// When removing the border (`border-style:none`), clear the remaining `border-*` properties.
|
|
13023
13042
|
// See: https://github.com/ckeditor/ckeditor5/issues/6227.
|
|
13024
|
-
if (!isBorderStyleSet(newValue)) {
|
|
13043
|
+
if (!isBorderStyleSet$2(newValue)) {
|
|
13025
13044
|
this.borderColor = '';
|
|
13026
13045
|
this.borderWidth = '';
|
|
13027
13046
|
}
|
|
13028
13047
|
// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
|
|
13029
|
-
if (!isBorderStyleSet(oldValue)) {
|
|
13048
|
+
if (!isBorderStyleSet$2(oldValue)) {
|
|
13030
13049
|
this.borderColor = defaultBorder.color;
|
|
13031
13050
|
this.borderWidth = defaultBorder.width;
|
|
13032
13051
|
}
|
|
@@ -13049,7 +13068,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13049
13068
|
const backgroundRowLabel = new LabelView(locale);
|
|
13050
13069
|
backgroundRowLabel.text = t('Background');
|
|
13051
13070
|
// -- Background color input -----------------------------------
|
|
13052
|
-
const backgroundInputCreator = getLabeledColorInputCreator({
|
|
13071
|
+
const backgroundInputCreator = getLabeledColorInputCreator$1({
|
|
13053
13072
|
colorConfig: this.options.backgroundColors,
|
|
13054
13073
|
columns: 5,
|
|
13055
13074
|
defaultColorValue: this.options.defaultTableProperties.backgroundColor,
|
|
@@ -13131,7 +13150,7 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13131
13150
|
const t = this.t;
|
|
13132
13151
|
// -- Label ---------------------------------------------------
|
|
13133
13152
|
const alignmentLabel = new LabelView(locale);
|
|
13134
|
-
alignmentLabel.text = t('
|
|
13153
|
+
alignmentLabel.text = t('Alignment');
|
|
13135
13154
|
// -- Toolbar ---------------------------------------------------
|
|
13136
13155
|
const alignmentToolbar = new ToolbarView(locale);
|
|
13137
13156
|
alignmentToolbar.set({
|
|
@@ -13139,14 +13158,12 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13139
13158
|
isCompact: true,
|
|
13140
13159
|
ariaLabel: t('Table alignment toolbar')
|
|
13141
13160
|
});
|
|
13142
|
-
fillToolbar({
|
|
13161
|
+
fillToolbar$1({
|
|
13143
13162
|
view: this,
|
|
13144
13163
|
icons: {
|
|
13145
13164
|
left: IconObjectInlineLeft,
|
|
13146
13165
|
center: IconObjectCenter,
|
|
13147
|
-
right: IconObjectInlineRight
|
|
13148
|
-
blockLeft: IconObjectLeft,
|
|
13149
|
-
blockRight: IconObjectRight
|
|
13166
|
+
right: IconObjectInlineRight
|
|
13150
13167
|
},
|
|
13151
13168
|
toolbar: alignmentToolbar,
|
|
13152
13169
|
labels: this._alignmentLabels,
|
|
@@ -13177,7 +13194,8 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13177
13194
|
];
|
|
13178
13195
|
saveButtonView.set({
|
|
13179
13196
|
label: t('Save'),
|
|
13180
|
-
|
|
13197
|
+
icon: IconCheck,
|
|
13198
|
+
class: 'ck-button-save',
|
|
13181
13199
|
type: 'submit',
|
|
13182
13200
|
withText: true
|
|
13183
13201
|
});
|
|
@@ -13186,6 +13204,8 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13186
13204
|
});
|
|
13187
13205
|
cancelButtonView.set({
|
|
13188
13206
|
label: t('Cancel'),
|
|
13207
|
+
icon: IconCancel,
|
|
13208
|
+
class: 'ck-button-cancel',
|
|
13189
13209
|
withText: true
|
|
13190
13210
|
});
|
|
13191
13211
|
cancelButtonView.delegate('execute').to(this, 'cancel');
|
|
@@ -13194,56 +13214,37 @@ function insertWrapperWithAlignment(writer, align, table) {
|
|
|
13194
13214
|
cancelButtonView
|
|
13195
13215
|
};
|
|
13196
13216
|
}
|
|
13197
|
-
/**
|
|
13198
|
-
* Creates a back button view that cancels the form.
|
|
13199
|
-
*/ _createBackButton() {
|
|
13200
|
-
const t = this.locale.t;
|
|
13201
|
-
const backButton = new ButtonView(this.locale);
|
|
13202
|
-
backButton.set({
|
|
13203
|
-
class: 'ck-button-back',
|
|
13204
|
-
label: t('Back'),
|
|
13205
|
-
icon: IconPreviousArrow,
|
|
13206
|
-
tooltip: true
|
|
13207
|
-
});
|
|
13208
|
-
backButton.delegate('execute').to(this, 'cancel');
|
|
13209
|
-
return backButton;
|
|
13210
|
-
}
|
|
13211
13217
|
/**
|
|
13212
13218
|
* Provides localized labels for {@link #alignmentToolbar} buttons.
|
|
13213
13219
|
*/ get _alignmentLabels() {
|
|
13214
13220
|
const locale = this.locale;
|
|
13215
13221
|
const t = this.t;
|
|
13216
|
-
const
|
|
13217
|
-
const
|
|
13218
|
-
const
|
|
13219
|
-
const center = t('Center table with no text wrapping');
|
|
13220
|
-
const right = t('Align table to the right with text wrapping');
|
|
13222
|
+
const left = t('Align table to the left');
|
|
13223
|
+
const center = t('Center table');
|
|
13224
|
+
const right = t('Align table to the right');
|
|
13221
13225
|
// Returns object with a proper order of labels.
|
|
13222
13226
|
if (locale.uiLanguageDirection === 'rtl') {
|
|
13223
13227
|
return {
|
|
13224
13228
|
right,
|
|
13229
|
+
center,
|
|
13230
|
+
left
|
|
13231
|
+
};
|
|
13232
|
+
} else {
|
|
13233
|
+
return {
|
|
13225
13234
|
left,
|
|
13226
|
-
blockRight,
|
|
13227
13235
|
center,
|
|
13228
|
-
|
|
13236
|
+
right
|
|
13229
13237
|
};
|
|
13230
13238
|
}
|
|
13231
|
-
return {
|
|
13232
|
-
blockLeft,
|
|
13233
|
-
center,
|
|
13234
|
-
blockRight,
|
|
13235
|
-
left,
|
|
13236
|
-
right
|
|
13237
|
-
};
|
|
13238
13239
|
}
|
|
13239
13240
|
}
|
|
13240
|
-
function isBorderStyleSet(value) {
|
|
13241
|
+
function isBorderStyleSet$2(value) {
|
|
13241
13242
|
return value !== 'none';
|
|
13242
13243
|
}
|
|
13243
13244
|
|
|
13244
|
-
const ERROR_TEXT_TIMEOUT = 500;
|
|
13245
|
+
const ERROR_TEXT_TIMEOUT$2 = 500;
|
|
13245
13246
|
// Map of view properties and related commands.
|
|
13246
|
-
const propertyToCommandMap = {
|
|
13247
|
+
const propertyToCommandMap$2 = {
|
|
13247
13248
|
borderStyle: 'tableBorderStyle',
|
|
13248
13249
|
borderColor: 'tableBorderColor',
|
|
13249
13250
|
borderWidth: 'tableBorderWidth',
|
|
@@ -13335,7 +13336,7 @@ const propertyToCommandMap = {
|
|
|
13335
13336
|
tooltip: true
|
|
13336
13337
|
});
|
|
13337
13338
|
this.listenTo(view, 'execute', ()=>this._showView());
|
|
13338
|
-
const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
|
|
13339
|
+
const commands = Object.values(propertyToCommandMap$2).map((commandName)=>editor.commands.get(commandName));
|
|
13339
13340
|
view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
|
|
13340
13341
|
return view;
|
|
13341
13342
|
}
|
|
@@ -13445,7 +13446,7 @@ const propertyToCommandMap = {
|
|
|
13445
13446
|
*/ _fillViewFormFromCommandValues() {
|
|
13446
13447
|
const commands = this.editor.commands;
|
|
13447
13448
|
const borderStyleCommand = commands.get('tableBorderStyle');
|
|
13448
|
-
Object.entries(propertyToCommandMap).map(([property, commandName])=>{
|
|
13449
|
+
Object.entries(propertyToCommandMap$2).map(([property, commandName])=>{
|
|
13449
13450
|
const propertyKey = property;
|
|
13450
13451
|
const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
|
|
13451
13452
|
return [
|
|
@@ -13554,7 +13555,7 @@ const propertyToCommandMap = {
|
|
|
13554
13555
|
const { commandName, viewField, validator, errorText } = options;
|
|
13555
13556
|
const setErrorTextDebounced = debounce(()=>{
|
|
13556
13557
|
viewField.errorText = errorText;
|
|
13557
|
-
}, ERROR_TEXT_TIMEOUT);
|
|
13558
|
+
}, ERROR_TEXT_TIMEOUT$2);
|
|
13558
13559
|
return (evt, propertyName, newValue)=>{
|
|
13559
13560
|
setErrorTextDebounced.cancel();
|
|
13560
13561
|
// Do not execute the command on initial call (opening the table properties view).
|
|
@@ -13995,5 +13996,2096 @@ const propertyToCommandMap = {
|
|
|
13995
13996
|
}
|
|
13996
13997
|
}
|
|
13997
13998
|
|
|
13998
|
-
|
|
13999
|
+
/**
|
|
14000
|
+
* Returns an object containing pairs of CSS border style values and their localized UI
|
|
14001
|
+
* labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}
|
|
14002
|
+
* and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.
|
|
14003
|
+
*
|
|
14004
|
+
* @internal
|
|
14005
|
+
* @param t The "t" function provided by the editor that is used to localize strings.
|
|
14006
|
+
*/ function getBorderStyleLabels(t) {
|
|
14007
|
+
return {
|
|
14008
|
+
none: t('None'),
|
|
14009
|
+
solid: t('Solid'),
|
|
14010
|
+
dotted: t('Dotted'),
|
|
14011
|
+
dashed: t('Dashed'),
|
|
14012
|
+
double: t('Double'),
|
|
14013
|
+
groove: t('Groove'),
|
|
14014
|
+
ridge: t('Ridge'),
|
|
14015
|
+
inset: t('Inset'),
|
|
14016
|
+
outset: t('Outset')
|
|
14017
|
+
};
|
|
14018
|
+
}
|
|
14019
|
+
/**
|
|
14020
|
+
* Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.
|
|
14021
|
+
*
|
|
14022
|
+
* @internal
|
|
14023
|
+
* @param defaultStyle The default border.
|
|
14024
|
+
*/ function getBorderStyleDefinitions(view, defaultStyle) {
|
|
14025
|
+
const itemDefinitions = new Collection();
|
|
14026
|
+
const styleLabels = getBorderStyleLabels(view.t);
|
|
14027
|
+
for(const style in styleLabels){
|
|
14028
|
+
const definition = {
|
|
14029
|
+
type: 'button',
|
|
14030
|
+
model: new UIModel({
|
|
14031
|
+
_borderStyleValue: style,
|
|
14032
|
+
label: styleLabels[style],
|
|
14033
|
+
role: 'menuitemradio',
|
|
14034
|
+
withText: true
|
|
14035
|
+
})
|
|
14036
|
+
};
|
|
14037
|
+
if (style === 'none') {
|
|
14038
|
+
definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
|
|
14039
|
+
if (defaultStyle === 'none') {
|
|
14040
|
+
return !value;
|
|
14041
|
+
}
|
|
14042
|
+
return value === style;
|
|
14043
|
+
});
|
|
14044
|
+
} else {
|
|
14045
|
+
definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{
|
|
14046
|
+
return value === style;
|
|
14047
|
+
});
|
|
14048
|
+
}
|
|
14049
|
+
itemDefinitions.add(definition);
|
|
14050
|
+
}
|
|
14051
|
+
return itemDefinitions;
|
|
14052
|
+
}
|
|
14053
|
+
/**
|
|
14054
|
+
* A helper that fills a toolbar with buttons that:
|
|
14055
|
+
*
|
|
14056
|
+
* * have some labels,
|
|
14057
|
+
* * have some icons,
|
|
14058
|
+
* * set a certain UI view property value upon execution.
|
|
14059
|
+
*
|
|
14060
|
+
* @internal
|
|
14061
|
+
* @param options Configuration options
|
|
14062
|
+
* @param options.view The view that has the observable property.
|
|
14063
|
+
* @param options.icons Object with button icons.
|
|
14064
|
+
* @param options.toolbar The toolbar to fill with buttons.
|
|
14065
|
+
* @param options.labels Object with button labels.
|
|
14066
|
+
* @param options.propertyName The name of the observable property in the view.
|
|
14067
|
+
* @param options.nameToValue A function that maps a button name to a value. By default names are the same as values.
|
|
14068
|
+
* @param options.defaultValue Default value for the property.
|
|
14069
|
+
*/ function fillToolbar(options) {
|
|
14070
|
+
const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;
|
|
14071
|
+
for(const name in labels){
|
|
14072
|
+
const button = new ButtonView(view.locale);
|
|
14073
|
+
button.set({
|
|
14074
|
+
role: 'radio',
|
|
14075
|
+
isToggleable: true,
|
|
14076
|
+
label: labels[name],
|
|
14077
|
+
icon: icons[name],
|
|
14078
|
+
tooltip: labels[name]
|
|
14079
|
+
});
|
|
14080
|
+
// If specified the `nameToValue()` callback, map the value based on the option's name.
|
|
14081
|
+
const buttonValue = nameToValue ? nameToValue(name) : name;
|
|
14082
|
+
button.bind('isOn').to(view, propertyName, (value)=>{
|
|
14083
|
+
// `value` comes from `view[ propertyName ]`.
|
|
14084
|
+
let valueToCompare = value;
|
|
14085
|
+
// If it's empty, and the `defaultValue` is specified, use it instead.
|
|
14086
|
+
if (value === '' && defaultValue) {
|
|
14087
|
+
valueToCompare = defaultValue;
|
|
14088
|
+
}
|
|
14089
|
+
return buttonValue === valueToCompare;
|
|
14090
|
+
});
|
|
14091
|
+
button.on('execute', ()=>{
|
|
14092
|
+
// Allow toggling alignment if there is no default value specified (especially for layout tables).
|
|
14093
|
+
if (!defaultValue && buttonValue && view[propertyName] === buttonValue) {
|
|
14094
|
+
view[propertyName] = undefined;
|
|
14095
|
+
} else {
|
|
14096
|
+
view[propertyName] = buttonValue;
|
|
14097
|
+
}
|
|
14098
|
+
});
|
|
14099
|
+
toolbar.items.add(button);
|
|
14100
|
+
}
|
|
14101
|
+
}
|
|
14102
|
+
/**
|
|
14103
|
+
* Returns a creator for a color input with a label.
|
|
14104
|
+
*
|
|
14105
|
+
* For given options, it returns a function that creates an instance of a
|
|
14106
|
+
* {@link module:table/ui/colorinputview~ColorInputView color input} logically related to
|
|
14107
|
+
* a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.
|
|
14108
|
+
*
|
|
14109
|
+
* The helper does the following:
|
|
14110
|
+
*
|
|
14111
|
+
* * It sets the color input `id` and `ariaDescribedById` attributes.
|
|
14112
|
+
* * It binds the color input `isReadOnly` to the labeled view.
|
|
14113
|
+
* * It binds the color input `hasError` to the labeled view.
|
|
14114
|
+
* * It enables a logic that cleans up the error when the user starts typing in the color input.
|
|
14115
|
+
*
|
|
14116
|
+
* Usage:
|
|
14117
|
+
*
|
|
14118
|
+
* ```ts
|
|
14119
|
+
* const colorInputCreator = getLabeledColorInputCreator( {
|
|
14120
|
+
* colorConfig: [ ... ],
|
|
14121
|
+
* columns: 3,
|
|
14122
|
+
* } );
|
|
14123
|
+
*
|
|
14124
|
+
* const labeledInputView = new LabeledFieldView( locale, colorInputCreator );
|
|
14125
|
+
* console.log( labeledInputView.view ); // A color input instance.
|
|
14126
|
+
* ```
|
|
14127
|
+
*
|
|
14128
|
+
* @internal
|
|
14129
|
+
* @param options Color input options.
|
|
14130
|
+
* @param options.colorConfig The configuration of the color palette displayed in the input's dropdown.
|
|
14131
|
+
* @param options.columns The configuration of the number of columns the color palette consists of in the input's dropdown.
|
|
14132
|
+
* @param options.defaultColorValue If specified, the color input view will replace the "Remove color" button with
|
|
14133
|
+
* the "Restore default" button. Instead of clearing the input field, the default color value will be set.
|
|
14134
|
+
* @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.
|
|
14135
|
+
*/ function getLabeledColorInputCreator(options) {
|
|
14136
|
+
return (labeledFieldView, viewUid, statusUid)=>{
|
|
14137
|
+
const colorInputView = new ColorInputView(labeledFieldView.locale, {
|
|
14138
|
+
colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),
|
|
14139
|
+
columns: options.columns,
|
|
14140
|
+
defaultColorValue: options.defaultColorValue,
|
|
14141
|
+
colorPickerConfig: options.colorPickerConfig
|
|
14142
|
+
});
|
|
14143
|
+
colorInputView.inputView.set({
|
|
14144
|
+
id: viewUid,
|
|
14145
|
+
ariaDescribedById: statusUid
|
|
14146
|
+
});
|
|
14147
|
+
colorInputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);
|
|
14148
|
+
colorInputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);
|
|
14149
|
+
colorInputView.on('input', ()=>{
|
|
14150
|
+
// UX: Make the error text disappear and disable the error indicator as the user
|
|
14151
|
+
// starts fixing the errors.
|
|
14152
|
+
labeledFieldView.errorText = null;
|
|
14153
|
+
});
|
|
14154
|
+
labeledFieldView.bind('isEmpty', 'isFocused').to(colorInputView);
|
|
14155
|
+
return colorInputView;
|
|
14156
|
+
};
|
|
14157
|
+
}
|
|
14158
|
+
function colorConfigToColorGridDefinitions(colorConfig) {
|
|
14159
|
+
return colorConfig.map((item)=>({
|
|
14160
|
+
color: item.model,
|
|
14161
|
+
label: item.label,
|
|
14162
|
+
options: {
|
|
14163
|
+
hasBorder: item.hasBorder
|
|
14164
|
+
}
|
|
14165
|
+
}));
|
|
14166
|
+
}
|
|
14167
|
+
|
|
14168
|
+
/**
|
|
14169
|
+
* The class representing a table properties form, allowing users to customize
|
|
14170
|
+
* certain style aspects of a table, for instance, border, background color, alignment, etc..
|
|
14171
|
+
*/ class TablePropertiesViewExperimental extends View {
|
|
14172
|
+
/**
|
|
14173
|
+
* Options passed to the view. See {@link #constructor} to learn more.
|
|
14174
|
+
*/ options;
|
|
14175
|
+
/**
|
|
14176
|
+
* Tracks information about the DOM focus in the form.
|
|
14177
|
+
*/ focusTracker;
|
|
14178
|
+
/**
|
|
14179
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
|
14180
|
+
*/ keystrokes;
|
|
14181
|
+
/**
|
|
14182
|
+
* A collection of child views in the form.
|
|
14183
|
+
*/ children;
|
|
14184
|
+
/**
|
|
14185
|
+
* A dropdown that allows selecting the style of the table border.
|
|
14186
|
+
*/ borderStyleDropdown;
|
|
14187
|
+
/**
|
|
14188
|
+
* An input that allows specifying the width of the table border.
|
|
14189
|
+
*/ borderWidthInput;
|
|
14190
|
+
/**
|
|
14191
|
+
* An input that allows specifying the color of the table border.
|
|
14192
|
+
*/ borderColorInput;
|
|
14193
|
+
/**
|
|
14194
|
+
* An input that allows specifying the table background color.
|
|
14195
|
+
*/ backgroundInput;
|
|
14196
|
+
/**
|
|
14197
|
+
* An input that allows specifying the table width.
|
|
14198
|
+
*/ widthInput;
|
|
14199
|
+
/**
|
|
14200
|
+
* An input that allows specifying the table height.
|
|
14201
|
+
*/ heightInput;
|
|
14202
|
+
/**
|
|
14203
|
+
* A toolbar with buttons that allow changing the alignment of an entire table.
|
|
14204
|
+
*/ alignmentToolbar;
|
|
14205
|
+
/**
|
|
14206
|
+
* The "Save" button view.
|
|
14207
|
+
*/ saveButtonView;
|
|
14208
|
+
/**
|
|
14209
|
+
* The "Cancel" button view.
|
|
14210
|
+
*/ cancelButtonView;
|
|
14211
|
+
/**
|
|
14212
|
+
* The Back button view displayed in the header.
|
|
14213
|
+
*/ backButtonView;
|
|
14214
|
+
/**
|
|
14215
|
+
* A collection of views that can be focused in the form.
|
|
14216
|
+
*/ _focusables;
|
|
14217
|
+
/**
|
|
14218
|
+
* Helps cycling over {@link #_focusables} in the form.
|
|
14219
|
+
*/ _focusCycler;
|
|
14220
|
+
/**
|
|
14221
|
+
* @param locale The {@link module:core/editor/editor~Editor#locale} instance.
|
|
14222
|
+
* @param options Additional configuration of the view.
|
|
14223
|
+
*/ constructor(locale, options){
|
|
14224
|
+
super(locale);
|
|
14225
|
+
this.set({
|
|
14226
|
+
borderStyle: '',
|
|
14227
|
+
borderWidth: '',
|
|
14228
|
+
borderColor: '',
|
|
14229
|
+
backgroundColor: '',
|
|
14230
|
+
width: '',
|
|
14231
|
+
height: '',
|
|
14232
|
+
alignment: ''
|
|
14233
|
+
});
|
|
14234
|
+
this.options = options;
|
|
14235
|
+
const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
|
|
14236
|
+
const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
|
|
14237
|
+
const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
|
|
14238
|
+
const { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();
|
|
14239
|
+
this.focusTracker = new FocusTracker();
|
|
14240
|
+
this.keystrokes = new KeystrokeHandler();
|
|
14241
|
+
this.children = this.createCollection();
|
|
14242
|
+
this.borderStyleDropdown = borderStyleDropdown;
|
|
14243
|
+
this.borderWidthInput = borderWidthInput;
|
|
14244
|
+
this.borderColorInput = borderColorInput;
|
|
14245
|
+
this.backgroundInput = backgroundInput;
|
|
14246
|
+
this.widthInput = widthInput;
|
|
14247
|
+
this.heightInput = heightInput;
|
|
14248
|
+
this.alignmentToolbar = alignmentToolbar;
|
|
14249
|
+
// Defer creating to make sure other fields are present and the Save button can
|
|
14250
|
+
// bind its #isEnabled to their error messages so there's no way to save unless all
|
|
14251
|
+
// fields are valid.
|
|
14252
|
+
const { saveButtonView, cancelButtonView } = this._createActionButtons();
|
|
14253
|
+
this.saveButtonView = saveButtonView;
|
|
14254
|
+
this.cancelButtonView = cancelButtonView;
|
|
14255
|
+
this.backButtonView = this._createBackButton();
|
|
14256
|
+
this._focusables = new ViewCollection();
|
|
14257
|
+
this._focusCycler = new FocusCycler({
|
|
14258
|
+
focusables: this._focusables,
|
|
14259
|
+
focusTracker: this.focusTracker,
|
|
14260
|
+
keystrokeHandler: this.keystrokes,
|
|
14261
|
+
actions: {
|
|
14262
|
+
// Navigate form fields backwards using the Shift + Tab keystroke.
|
|
14263
|
+
focusPrevious: 'shift + tab',
|
|
14264
|
+
// Navigate form fields forwards using the Tab key.
|
|
14265
|
+
focusNext: 'tab'
|
|
14266
|
+
}
|
|
14267
|
+
});
|
|
14268
|
+
// Form header.
|
|
14269
|
+
const headerView = new FormHeaderView(locale, {
|
|
14270
|
+
label: this.t('Table properties')
|
|
14271
|
+
});
|
|
14272
|
+
headerView.children.add(this.backButtonView, 0);
|
|
14273
|
+
this.children.add(headerView);
|
|
14274
|
+
// Border row.
|
|
14275
|
+
this.children.add(new FormRowView(locale, {
|
|
14276
|
+
labelView: borderRowLabel,
|
|
14277
|
+
children: [
|
|
14278
|
+
borderRowLabel,
|
|
14279
|
+
borderStyleDropdown,
|
|
14280
|
+
borderWidthInput,
|
|
14281
|
+
borderColorInput
|
|
14282
|
+
],
|
|
14283
|
+
class: 'ck-table-form__border-row'
|
|
14284
|
+
}));
|
|
14285
|
+
this.children.add(new FormRowView(locale, {
|
|
14286
|
+
children: [
|
|
14287
|
+
// Dimensions row.
|
|
14288
|
+
new FormRowView(locale, {
|
|
14289
|
+
labelView: dimensionsLabel,
|
|
14290
|
+
children: [
|
|
14291
|
+
dimensionsLabel,
|
|
14292
|
+
widthInput,
|
|
14293
|
+
operatorLabel,
|
|
14294
|
+
heightInput
|
|
14295
|
+
],
|
|
14296
|
+
class: 'ck-table-form__dimensions-row'
|
|
14297
|
+
}),
|
|
14298
|
+
// Background row.
|
|
14299
|
+
new FormRowView(locale, {
|
|
14300
|
+
labelView: backgroundRowLabel,
|
|
14301
|
+
children: [
|
|
14302
|
+
backgroundRowLabel,
|
|
14303
|
+
backgroundInput
|
|
14304
|
+
],
|
|
14305
|
+
class: 'ck-table-form__background-row'
|
|
14306
|
+
})
|
|
14307
|
+
]
|
|
14308
|
+
}));
|
|
14309
|
+
// Alignment row.
|
|
14310
|
+
this.children.add(new FormRowView(locale, {
|
|
14311
|
+
labelView: alignmentLabel,
|
|
14312
|
+
children: [
|
|
14313
|
+
alignmentLabel,
|
|
14314
|
+
alignmentToolbar
|
|
14315
|
+
],
|
|
14316
|
+
class: 'ck-table-properties-form__alignment-row'
|
|
14317
|
+
}));
|
|
14318
|
+
// Action row.
|
|
14319
|
+
this.children.add(new FormRowView(locale, {
|
|
14320
|
+
children: [
|
|
14321
|
+
this.cancelButtonView,
|
|
14322
|
+
this.saveButtonView
|
|
14323
|
+
],
|
|
14324
|
+
class: 'ck-table-form__action-row'
|
|
14325
|
+
}));
|
|
14326
|
+
this.setTemplate({
|
|
14327
|
+
tag: 'form',
|
|
14328
|
+
attributes: {
|
|
14329
|
+
class: [
|
|
14330
|
+
'ck',
|
|
14331
|
+
'ck-form',
|
|
14332
|
+
'ck-table-form',
|
|
14333
|
+
'ck-table-properties-form',
|
|
14334
|
+
'ck-table-properties-form_experimental'
|
|
14335
|
+
],
|
|
14336
|
+
// https://github.com/ckeditor/ckeditor5-link/issues/90
|
|
14337
|
+
tabindex: '-1'
|
|
14338
|
+
},
|
|
14339
|
+
children: this.children
|
|
14340
|
+
});
|
|
14341
|
+
}
|
|
14342
|
+
/**
|
|
14343
|
+
* @inheritDoc
|
|
14344
|
+
*/ render() {
|
|
14345
|
+
super.render();
|
|
14346
|
+
// Enable the "submit" event for this view. It can be triggered by the #saveButtonView
|
|
14347
|
+
// which is of the "submit" DOM "type".
|
|
14348
|
+
submitHandler({
|
|
14349
|
+
view: this
|
|
14350
|
+
});
|
|
14351
|
+
// Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
|
|
14352
|
+
[
|
|
14353
|
+
this.borderColorInput,
|
|
14354
|
+
this.backgroundInput
|
|
14355
|
+
].forEach((view)=>{
|
|
14356
|
+
this._focusCycler.chain(view.fieldView.focusCycler);
|
|
14357
|
+
});
|
|
14358
|
+
[
|
|
14359
|
+
this.borderStyleDropdown,
|
|
14360
|
+
this.borderWidthInput,
|
|
14361
|
+
this.borderColorInput,
|
|
14362
|
+
this.widthInput,
|
|
14363
|
+
this.heightInput,
|
|
14364
|
+
this.backgroundInput,
|
|
14365
|
+
this.alignmentToolbar,
|
|
14366
|
+
this.cancelButtonView,
|
|
14367
|
+
this.saveButtonView,
|
|
14368
|
+
this.backButtonView
|
|
14369
|
+
].forEach((view)=>{
|
|
14370
|
+
// Register the view as focusable.
|
|
14371
|
+
this._focusables.add(view);
|
|
14372
|
+
// Register the view in the focus tracker.
|
|
14373
|
+
this.focusTracker.add(view.element);
|
|
14374
|
+
});
|
|
14375
|
+
// Mainly for closing using "Esc" and navigation using "Tab".
|
|
14376
|
+
this.keystrokes.listenTo(this.element);
|
|
14377
|
+
}
|
|
14378
|
+
/**
|
|
14379
|
+
* @inheritDoc
|
|
14380
|
+
*/ destroy() {
|
|
14381
|
+
super.destroy();
|
|
14382
|
+
this.focusTracker.destroy();
|
|
14383
|
+
this.keystrokes.destroy();
|
|
14384
|
+
}
|
|
14385
|
+
/**
|
|
14386
|
+
* Focuses the fist focusable field in the form.
|
|
14387
|
+
*/ focus() {
|
|
14388
|
+
this._focusCycler.focusFirst();
|
|
14389
|
+
}
|
|
14390
|
+
/**
|
|
14391
|
+
* Creates the following form fields:
|
|
14392
|
+
*
|
|
14393
|
+
* * {@link #borderStyleDropdown},
|
|
14394
|
+
* * {@link #borderWidthInput},
|
|
14395
|
+
* * {@link #borderColorInput}.
|
|
14396
|
+
*/ _createBorderFields() {
|
|
14397
|
+
const defaultTableProperties = this.options.defaultTableProperties;
|
|
14398
|
+
const defaultBorder = {
|
|
14399
|
+
style: defaultTableProperties.borderStyle,
|
|
14400
|
+
width: defaultTableProperties.borderWidth,
|
|
14401
|
+
color: defaultTableProperties.borderColor
|
|
14402
|
+
};
|
|
14403
|
+
const colorInputCreator = getLabeledColorInputCreator({
|
|
14404
|
+
colorConfig: this.options.borderColors,
|
|
14405
|
+
columns: 5,
|
|
14406
|
+
defaultColorValue: defaultBorder.color,
|
|
14407
|
+
colorPickerConfig: this.options.colorPickerConfig
|
|
14408
|
+
});
|
|
14409
|
+
const locale = this.locale;
|
|
14410
|
+
const t = this.t;
|
|
14411
|
+
const accessibleLabel = t('Style');
|
|
14412
|
+
// -- Group label ---------------------------------------------
|
|
14413
|
+
const borderRowLabel = new LabelView(locale);
|
|
14414
|
+
borderRowLabel.text = t('Border');
|
|
14415
|
+
// -- Style ---------------------------------------------------
|
|
14416
|
+
const styleLabels = getBorderStyleLabels(t);
|
|
14417
|
+
const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
14418
|
+
borderStyleDropdown.set({
|
|
14419
|
+
label: accessibleLabel,
|
|
14420
|
+
class: 'ck-table-form__border-style'
|
|
14421
|
+
});
|
|
14422
|
+
borderStyleDropdown.fieldView.buttonView.set({
|
|
14423
|
+
ariaLabel: accessibleLabel,
|
|
14424
|
+
ariaLabelledBy: undefined,
|
|
14425
|
+
isOn: false,
|
|
14426
|
+
withText: true,
|
|
14427
|
+
tooltip: accessibleLabel
|
|
14428
|
+
});
|
|
14429
|
+
borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
|
|
14430
|
+
return styleLabels[value ? value : 'none'];
|
|
14431
|
+
});
|
|
14432
|
+
borderStyleDropdown.fieldView.on('execute', (evt)=>{
|
|
14433
|
+
this.borderStyle = evt.source._borderStyleValue;
|
|
14434
|
+
});
|
|
14435
|
+
borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
|
|
14436
|
+
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
|
|
14437
|
+
role: 'menu',
|
|
14438
|
+
ariaLabel: accessibleLabel
|
|
14439
|
+
});
|
|
14440
|
+
// -- Width ---------------------------------------------------
|
|
14441
|
+
const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
14442
|
+
borderWidthInput.set({
|
|
14443
|
+
label: t('Width'),
|
|
14444
|
+
class: 'ck-table-form__border-width'
|
|
14445
|
+
});
|
|
14446
|
+
borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
|
|
14447
|
+
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
|
|
14448
|
+
borderWidthInput.fieldView.on('input', ()=>{
|
|
14449
|
+
this.borderWidth = borderWidthInput.fieldView.element.value;
|
|
14450
|
+
});
|
|
14451
|
+
// -- Color ---------------------------------------------------
|
|
14452
|
+
const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
|
|
14453
|
+
borderColorInput.set({
|
|
14454
|
+
label: t('Color'),
|
|
14455
|
+
class: 'ck-table-form__border-color'
|
|
14456
|
+
});
|
|
14457
|
+
borderColorInput.fieldView.bind('value').to(this, 'borderColor');
|
|
14458
|
+
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);
|
|
14459
|
+
borderColorInput.fieldView.on('input', ()=>{
|
|
14460
|
+
this.borderColor = borderColorInput.fieldView.value;
|
|
14461
|
+
});
|
|
14462
|
+
// Reset the border color and width fields depending on the `border-style` value.
|
|
14463
|
+
this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
|
|
14464
|
+
// When removing the border (`border-style:none`), clear the remaining `border-*` properties.
|
|
14465
|
+
// See: https://github.com/ckeditor/ckeditor5/issues/6227.
|
|
14466
|
+
if (!isBorderStyleSet$1(newValue)) {
|
|
14467
|
+
this.borderColor = '';
|
|
14468
|
+
this.borderWidth = '';
|
|
14469
|
+
}
|
|
14470
|
+
// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
|
|
14471
|
+
if (!isBorderStyleSet$1(oldValue)) {
|
|
14472
|
+
this.borderColor = defaultBorder.color;
|
|
14473
|
+
this.borderWidth = defaultBorder.width;
|
|
14474
|
+
}
|
|
14475
|
+
});
|
|
14476
|
+
return {
|
|
14477
|
+
borderRowLabel,
|
|
14478
|
+
borderStyleDropdown,
|
|
14479
|
+
borderColorInput,
|
|
14480
|
+
borderWidthInput
|
|
14481
|
+
};
|
|
14482
|
+
}
|
|
14483
|
+
/**
|
|
14484
|
+
* Creates the following form fields:
|
|
14485
|
+
*
|
|
14486
|
+
* * {@link #backgroundInput}.
|
|
14487
|
+
*/ _createBackgroundFields() {
|
|
14488
|
+
const locale = this.locale;
|
|
14489
|
+
const t = this.t;
|
|
14490
|
+
// -- Group label ---------------------------------------------
|
|
14491
|
+
const backgroundRowLabel = new LabelView(locale);
|
|
14492
|
+
backgroundRowLabel.text = t('Background');
|
|
14493
|
+
// -- Background color input -----------------------------------
|
|
14494
|
+
const backgroundInputCreator = getLabeledColorInputCreator({
|
|
14495
|
+
colorConfig: this.options.backgroundColors,
|
|
14496
|
+
columns: 5,
|
|
14497
|
+
defaultColorValue: this.options.defaultTableProperties.backgroundColor,
|
|
14498
|
+
colorPickerConfig: this.options.colorPickerConfig
|
|
14499
|
+
});
|
|
14500
|
+
const backgroundInput = new LabeledFieldView(locale, backgroundInputCreator);
|
|
14501
|
+
backgroundInput.set({
|
|
14502
|
+
label: t('Color'),
|
|
14503
|
+
class: 'ck-table-properties-form__background'
|
|
14504
|
+
});
|
|
14505
|
+
backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
|
|
14506
|
+
backgroundInput.fieldView.on('input', ()=>{
|
|
14507
|
+
this.backgroundColor = backgroundInput.fieldView.value;
|
|
14508
|
+
});
|
|
14509
|
+
return {
|
|
14510
|
+
backgroundRowLabel,
|
|
14511
|
+
backgroundInput
|
|
14512
|
+
};
|
|
14513
|
+
}
|
|
14514
|
+
/**
|
|
14515
|
+
* Creates the following form fields:
|
|
14516
|
+
*
|
|
14517
|
+
* * {@link #widthInput},
|
|
14518
|
+
* * {@link #heightInput}.
|
|
14519
|
+
*/ _createDimensionFields() {
|
|
14520
|
+
const locale = this.locale;
|
|
14521
|
+
const t = this.t;
|
|
14522
|
+
// -- Label ---------------------------------------------------
|
|
14523
|
+
const dimensionsLabel = new LabelView(locale);
|
|
14524
|
+
dimensionsLabel.text = t('Dimensions');
|
|
14525
|
+
// -- Width ---------------------------------------------------
|
|
14526
|
+
const widthInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
14527
|
+
widthInput.set({
|
|
14528
|
+
label: t('Width'),
|
|
14529
|
+
class: 'ck-table-form__dimensions-row__width'
|
|
14530
|
+
});
|
|
14531
|
+
widthInput.fieldView.bind('value').to(this, 'width');
|
|
14532
|
+
widthInput.fieldView.on('input', ()=>{
|
|
14533
|
+
this.width = widthInput.fieldView.element.value;
|
|
14534
|
+
});
|
|
14535
|
+
// -- Operator ---------------------------------------------------
|
|
14536
|
+
const operatorLabel = new View(locale);
|
|
14537
|
+
operatorLabel.setTemplate({
|
|
14538
|
+
tag: 'span',
|
|
14539
|
+
attributes: {
|
|
14540
|
+
class: [
|
|
14541
|
+
'ck-table-form__dimension-operator'
|
|
14542
|
+
]
|
|
14543
|
+
},
|
|
14544
|
+
children: [
|
|
14545
|
+
{
|
|
14546
|
+
text: '×'
|
|
14547
|
+
}
|
|
14548
|
+
]
|
|
14549
|
+
});
|
|
14550
|
+
// -- Height ---------------------------------------------------
|
|
14551
|
+
const heightInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
14552
|
+
heightInput.set({
|
|
14553
|
+
label: t('Height'),
|
|
14554
|
+
class: 'ck-table-form__dimensions-row__height'
|
|
14555
|
+
});
|
|
14556
|
+
heightInput.fieldView.bind('value').to(this, 'height');
|
|
14557
|
+
heightInput.fieldView.on('input', ()=>{
|
|
14558
|
+
this.height = heightInput.fieldView.element.value;
|
|
14559
|
+
});
|
|
14560
|
+
return {
|
|
14561
|
+
dimensionsLabel,
|
|
14562
|
+
widthInput,
|
|
14563
|
+
operatorLabel,
|
|
14564
|
+
heightInput
|
|
14565
|
+
};
|
|
14566
|
+
}
|
|
14567
|
+
/**
|
|
14568
|
+
* Creates the following form fields:
|
|
14569
|
+
*
|
|
14570
|
+
* * {@link #alignmentToolbar}.
|
|
14571
|
+
*/ _createAlignmentFields() {
|
|
14572
|
+
const locale = this.locale;
|
|
14573
|
+
const t = this.t;
|
|
14574
|
+
// -- Label ---------------------------------------------------
|
|
14575
|
+
const alignmentLabel = new LabelView(locale);
|
|
14576
|
+
alignmentLabel.text = t('Table Alignment');
|
|
14577
|
+
// -- Toolbar ---------------------------------------------------
|
|
14578
|
+
const alignmentToolbar = new ToolbarView(locale);
|
|
14579
|
+
alignmentToolbar.set({
|
|
14580
|
+
role: 'radiogroup',
|
|
14581
|
+
isCompact: true,
|
|
14582
|
+
ariaLabel: t('Table alignment toolbar')
|
|
14583
|
+
});
|
|
14584
|
+
fillToolbar({
|
|
14585
|
+
view: this,
|
|
14586
|
+
icons: {
|
|
14587
|
+
left: IconObjectInlineLeft,
|
|
14588
|
+
center: IconObjectCenter,
|
|
14589
|
+
right: IconObjectInlineRight,
|
|
14590
|
+
blockLeft: IconObjectLeft,
|
|
14591
|
+
blockRight: IconObjectRight
|
|
14592
|
+
},
|
|
14593
|
+
toolbar: alignmentToolbar,
|
|
14594
|
+
labels: this._alignmentLabels,
|
|
14595
|
+
propertyName: 'alignment',
|
|
14596
|
+
defaultValue: this.options.defaultTableProperties.alignment
|
|
14597
|
+
});
|
|
14598
|
+
return {
|
|
14599
|
+
alignmentLabel,
|
|
14600
|
+
alignmentToolbar
|
|
14601
|
+
};
|
|
14602
|
+
}
|
|
14603
|
+
/**
|
|
14604
|
+
* Creates the following form controls:
|
|
14605
|
+
*
|
|
14606
|
+
* * {@link #saveButtonView},
|
|
14607
|
+
* * {@link #cancelButtonView}.
|
|
14608
|
+
*/ _createActionButtons() {
|
|
14609
|
+
const locale = this.locale;
|
|
14610
|
+
const t = this.t;
|
|
14611
|
+
const saveButtonView = new ButtonView(locale);
|
|
14612
|
+
const cancelButtonView = new ButtonView(locale);
|
|
14613
|
+
const fieldsThatShouldValidateToSave = [
|
|
14614
|
+
this.borderWidthInput,
|
|
14615
|
+
this.borderColorInput,
|
|
14616
|
+
this.backgroundInput,
|
|
14617
|
+
this.widthInput,
|
|
14618
|
+
this.heightInput
|
|
14619
|
+
];
|
|
14620
|
+
saveButtonView.set({
|
|
14621
|
+
label: t('Save'),
|
|
14622
|
+
class: 'ck-button-action',
|
|
14623
|
+
type: 'submit',
|
|
14624
|
+
withText: true
|
|
14625
|
+
});
|
|
14626
|
+
saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
|
|
14627
|
+
return errorTexts.every((errorText)=>!errorText);
|
|
14628
|
+
});
|
|
14629
|
+
cancelButtonView.set({
|
|
14630
|
+
label: t('Cancel'),
|
|
14631
|
+
withText: true
|
|
14632
|
+
});
|
|
14633
|
+
cancelButtonView.delegate('execute').to(this, 'cancel');
|
|
14634
|
+
return {
|
|
14635
|
+
saveButtonView,
|
|
14636
|
+
cancelButtonView
|
|
14637
|
+
};
|
|
14638
|
+
}
|
|
14639
|
+
/**
|
|
14640
|
+
* Creates a back button view that cancels the form.
|
|
14641
|
+
*/ _createBackButton() {
|
|
14642
|
+
const t = this.locale.t;
|
|
14643
|
+
const backButton = new ButtonView(this.locale);
|
|
14644
|
+
backButton.set({
|
|
14645
|
+
class: 'ck-button-back',
|
|
14646
|
+
label: t('Back'),
|
|
14647
|
+
icon: IconPreviousArrow,
|
|
14648
|
+
tooltip: true
|
|
14649
|
+
});
|
|
14650
|
+
backButton.delegate('execute').to(this, 'cancel');
|
|
14651
|
+
return backButton;
|
|
14652
|
+
}
|
|
14653
|
+
/**
|
|
14654
|
+
* Provides localized labels for {@link #alignmentToolbar} buttons.
|
|
14655
|
+
*/ get _alignmentLabels() {
|
|
14656
|
+
const locale = this.locale;
|
|
14657
|
+
const t = this.t;
|
|
14658
|
+
const blockLeft = t('Align table to the left with no text wrapping');
|
|
14659
|
+
const blockRight = t('Align table to the right with no text wrapping');
|
|
14660
|
+
const left = t('Align table to the left with text wrapping');
|
|
14661
|
+
const center = t('Center table with no text wrapping');
|
|
14662
|
+
const right = t('Align table to the right with text wrapping');
|
|
14663
|
+
// Returns object with a proper order of labels.
|
|
14664
|
+
if (locale.uiLanguageDirection === 'rtl') {
|
|
14665
|
+
return {
|
|
14666
|
+
right,
|
|
14667
|
+
left,
|
|
14668
|
+
blockRight,
|
|
14669
|
+
center,
|
|
14670
|
+
blockLeft
|
|
14671
|
+
};
|
|
14672
|
+
}
|
|
14673
|
+
return {
|
|
14674
|
+
blockLeft,
|
|
14675
|
+
center,
|
|
14676
|
+
blockRight,
|
|
14677
|
+
left,
|
|
14678
|
+
right
|
|
14679
|
+
};
|
|
14680
|
+
}
|
|
14681
|
+
}
|
|
14682
|
+
function isBorderStyleSet$1(value) {
|
|
14683
|
+
return value !== 'none';
|
|
14684
|
+
}
|
|
14685
|
+
|
|
14686
|
+
const ERROR_TEXT_TIMEOUT$1 = 500;
|
|
14687
|
+
// Map of view properties and related commands.
|
|
14688
|
+
const propertyToCommandMap$1 = {
|
|
14689
|
+
borderStyle: 'tableBorderStyle',
|
|
14690
|
+
borderColor: 'tableBorderColor',
|
|
14691
|
+
borderWidth: 'tableBorderWidth',
|
|
14692
|
+
backgroundColor: 'tableBackgroundColor',
|
|
14693
|
+
width: 'tableWidth',
|
|
14694
|
+
height: 'tableHeight',
|
|
14695
|
+
alignment: 'tableAlignment'
|
|
14696
|
+
};
|
|
14697
|
+
/**
|
|
14698
|
+
* The table properties UI plugin. It introduces the `'tableProperties'` button
|
|
14699
|
+
* that opens a form allowing to specify visual styling of an entire table.
|
|
14700
|
+
*
|
|
14701
|
+
* It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
|
|
14702
|
+
*/ class TablePropertiesUIExperimental extends Plugin {
|
|
14703
|
+
/**
|
|
14704
|
+
* The default table properties.
|
|
14705
|
+
*/ _defaultContentTableProperties;
|
|
14706
|
+
/**
|
|
14707
|
+
* The default layout table properties.
|
|
14708
|
+
*/ _defaultLayoutTableProperties;
|
|
14709
|
+
/**
|
|
14710
|
+
* The contextual balloon plugin instance.
|
|
14711
|
+
*/ _balloon;
|
|
14712
|
+
/**
|
|
14713
|
+
* The properties form view displayed inside the balloon.
|
|
14714
|
+
*/ view = null;
|
|
14715
|
+
/**
|
|
14716
|
+
* The properties form view displayed inside the balloon (content table).
|
|
14717
|
+
*/ _viewWithContentTableDefaults = null;
|
|
14718
|
+
/**
|
|
14719
|
+
* The properties form view displayed inside the balloon (layout table).
|
|
14720
|
+
*/ _viewWithLayoutTableDefaults = null;
|
|
14721
|
+
/**
|
|
14722
|
+
* The batch used to undo all changes made by the form (which are live, as the user types)
|
|
14723
|
+
* when "Cancel" was pressed. Each time the view is shown, a new batch is created.
|
|
14724
|
+
*/ _undoStepBatch;
|
|
14725
|
+
/**
|
|
14726
|
+
* Flag used to indicate whether view is ready to execute update commands
|
|
14727
|
+
* (it finished loading initial data).
|
|
14728
|
+
*/ _isReady;
|
|
14729
|
+
/**
|
|
14730
|
+
* @inheritDoc
|
|
14731
|
+
*/ static get requires() {
|
|
14732
|
+
return [
|
|
14733
|
+
ContextualBalloon
|
|
14734
|
+
];
|
|
14735
|
+
}
|
|
14736
|
+
/**
|
|
14737
|
+
* @inheritDoc
|
|
14738
|
+
*/ static get pluginName() {
|
|
14739
|
+
return 'TablePropertiesUIExperimental';
|
|
14740
|
+
}
|
|
14741
|
+
/**
|
|
14742
|
+
* @inheritDoc
|
|
14743
|
+
*/ static get isOfficialPlugin() {
|
|
14744
|
+
return true;
|
|
14745
|
+
}
|
|
14746
|
+
/**
|
|
14747
|
+
* @inheritDoc
|
|
14748
|
+
*/ constructor(editor){
|
|
14749
|
+
super(editor);
|
|
14750
|
+
editor.config.define('table.tableProperties', {
|
|
14751
|
+
borderColors: defaultColors,
|
|
14752
|
+
backgroundColors: defaultColors
|
|
14753
|
+
});
|
|
14754
|
+
}
|
|
14755
|
+
/**
|
|
14756
|
+
* @inheritDoc
|
|
14757
|
+
*/ init() {
|
|
14758
|
+
const editor = this.editor;
|
|
14759
|
+
this._defaultContentTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {
|
|
14760
|
+
includeAlignmentProperty: true
|
|
14761
|
+
});
|
|
14762
|
+
this._defaultLayoutTableProperties = getNormalizedDefaultProperties();
|
|
14763
|
+
this._balloon = editor.plugins.get(ContextualBalloon);
|
|
14764
|
+
editor.ui.componentFactory.add('tableProperties', ()=>this._createTablePropertiesButton());
|
|
14765
|
+
}
|
|
14766
|
+
/**
|
|
14767
|
+
* Creates the table properties button.
|
|
14768
|
+
*
|
|
14769
|
+
* @internal
|
|
14770
|
+
*/ _createTablePropertiesButton() {
|
|
14771
|
+
const editor = this.editor;
|
|
14772
|
+
const t = editor.t;
|
|
14773
|
+
const view = new ButtonView(editor.locale);
|
|
14774
|
+
view.set({
|
|
14775
|
+
label: t('Table properties'),
|
|
14776
|
+
icon: IconTableProperties,
|
|
14777
|
+
tooltip: true
|
|
14778
|
+
});
|
|
14779
|
+
this.listenTo(view, 'execute', ()=>this._showView());
|
|
14780
|
+
const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));
|
|
14781
|
+
view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
|
|
14782
|
+
return view;
|
|
14783
|
+
}
|
|
14784
|
+
/**
|
|
14785
|
+
* @inheritDoc
|
|
14786
|
+
*/ destroy() {
|
|
14787
|
+
super.destroy();
|
|
14788
|
+
// Destroy created UI components as they are not automatically destroyed.
|
|
14789
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1341.
|
|
14790
|
+
if (this.view) {
|
|
14791
|
+
this.view.destroy();
|
|
14792
|
+
}
|
|
14793
|
+
}
|
|
14794
|
+
/**
|
|
14795
|
+
* Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.
|
|
14796
|
+
*
|
|
14797
|
+
* @returns The table properties form view instance.
|
|
14798
|
+
*/ _createPropertiesView(defaultTableProperties) {
|
|
14799
|
+
const editor = this.editor;
|
|
14800
|
+
const config = editor.config.get('table.tableProperties');
|
|
14801
|
+
const borderColorsConfig = normalizeColorOptions(config.borderColors);
|
|
14802
|
+
const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
|
|
14803
|
+
const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
|
|
14804
|
+
const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
|
|
14805
|
+
const hasColorPicker = config.colorPicker !== false;
|
|
14806
|
+
const view = new TablePropertiesViewExperimental(editor.locale, {
|
|
14807
|
+
borderColors: localizedBorderColors,
|
|
14808
|
+
backgroundColors: localizedBackgroundColors,
|
|
14809
|
+
defaultTableProperties,
|
|
14810
|
+
colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
|
|
14811
|
+
});
|
|
14812
|
+
const t = editor.t;
|
|
14813
|
+
// Render the view so its #element is available for the clickOutsideHandler.
|
|
14814
|
+
view.render();
|
|
14815
|
+
this.listenTo(view, 'submit', ()=>{
|
|
14816
|
+
this._hideView();
|
|
14817
|
+
});
|
|
14818
|
+
this.listenTo(view, 'cancel', ()=>{
|
|
14819
|
+
// https://github.com/ckeditor/ckeditor5/issues/6180
|
|
14820
|
+
if (this._undoStepBatch.operations.length) {
|
|
14821
|
+
editor.execute('undo', this._undoStepBatch);
|
|
14822
|
+
}
|
|
14823
|
+
this._hideView();
|
|
14824
|
+
});
|
|
14825
|
+
// Close the balloon on Esc key press.
|
|
14826
|
+
view.keystrokes.set('Esc', (data, cancel)=>{
|
|
14827
|
+
this._hideView();
|
|
14828
|
+
cancel();
|
|
14829
|
+
});
|
|
14830
|
+
// Close on click outside of balloon panel element.
|
|
14831
|
+
clickOutsideHandler({
|
|
14832
|
+
emitter: view,
|
|
14833
|
+
activator: ()=>this._isViewInBalloon,
|
|
14834
|
+
contextElements: [
|
|
14835
|
+
this._balloon.view.element
|
|
14836
|
+
],
|
|
14837
|
+
callback: ()=>this._hideView()
|
|
14838
|
+
});
|
|
14839
|
+
const colorErrorText = getLocalizedColorErrorText(t);
|
|
14840
|
+
const lengthErrorText = getLocalizedLengthErrorText(t);
|
|
14841
|
+
// Create the "UI -> editor data" binding.
|
|
14842
|
+
// These listeners update the editor data (via table commands) when any observable
|
|
14843
|
+
// property of the view has changed. They also validate the value and display errors in the UI
|
|
14844
|
+
// when necessary. This makes the view live, which means the changes are
|
|
14845
|
+
// visible in the editing as soon as the user types or changes fields' values.
|
|
14846
|
+
view.on('change:borderStyle', this._getPropertyChangeCallback('tableBorderStyle'));
|
|
14847
|
+
view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
|
|
14848
|
+
viewField: view.borderColorInput,
|
|
14849
|
+
commandName: 'tableBorderColor',
|
|
14850
|
+
errorText: colorErrorText,
|
|
14851
|
+
validator: colorFieldValidator
|
|
14852
|
+
}));
|
|
14853
|
+
view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
|
|
14854
|
+
viewField: view.borderWidthInput,
|
|
14855
|
+
commandName: 'tableBorderWidth',
|
|
14856
|
+
errorText: lengthErrorText,
|
|
14857
|
+
validator: lineWidthFieldValidator
|
|
14858
|
+
}));
|
|
14859
|
+
view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
|
|
14860
|
+
viewField: view.backgroundInput,
|
|
14861
|
+
commandName: 'tableBackgroundColor',
|
|
14862
|
+
errorText: colorErrorText,
|
|
14863
|
+
validator: colorFieldValidator
|
|
14864
|
+
}));
|
|
14865
|
+
view.on('change:width', this._getValidatedPropertyChangeCallback({
|
|
14866
|
+
viewField: view.widthInput,
|
|
14867
|
+
commandName: 'tableWidth',
|
|
14868
|
+
errorText: lengthErrorText,
|
|
14869
|
+
validator: lengthFieldValidator
|
|
14870
|
+
}));
|
|
14871
|
+
view.on('change:height', this._getValidatedPropertyChangeCallback({
|
|
14872
|
+
viewField: view.heightInput,
|
|
14873
|
+
commandName: 'tableHeight',
|
|
14874
|
+
errorText: lengthErrorText,
|
|
14875
|
+
validator: lengthFieldValidator
|
|
14876
|
+
}));
|
|
14877
|
+
view.on('change:alignment', this._getPropertyChangeCallback('tableAlignment'));
|
|
14878
|
+
return view;
|
|
14879
|
+
}
|
|
14880
|
+
/**
|
|
14881
|
+
* In this method the "editor data -> UI" binding is happening.
|
|
14882
|
+
*
|
|
14883
|
+
* When executed, this method obtains selected table property values from various table commands
|
|
14884
|
+
* and passes them to the {@link #view}.
|
|
14885
|
+
*
|
|
14886
|
+
* This way, the UI stays up–to–date with the editor data.
|
|
14887
|
+
*/ _fillViewFormFromCommandValues() {
|
|
14888
|
+
const commands = this.editor.commands;
|
|
14889
|
+
const borderStyleCommand = commands.get('tableBorderStyle');
|
|
14890
|
+
Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{
|
|
14891
|
+
const propertyKey = property;
|
|
14892
|
+
const defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableProperties[propertyKey] || '' : this._defaultLayoutTableProperties[propertyKey] || '';
|
|
14893
|
+
return [
|
|
14894
|
+
propertyKey,
|
|
14895
|
+
commands.get(commandName).value || defaultValue
|
|
14896
|
+
];
|
|
14897
|
+
}).forEach(([property, value])=>{
|
|
14898
|
+
// Do not set the `border-color` and `border-width` fields if `border-style:none`.
|
|
14899
|
+
if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
|
|
14900
|
+
return;
|
|
14901
|
+
}
|
|
14902
|
+
this.view.set(property, value);
|
|
14903
|
+
});
|
|
14904
|
+
this._isReady = true;
|
|
14905
|
+
}
|
|
14906
|
+
/**
|
|
14907
|
+
* Shows the {@link #view} in the {@link #_balloon}.
|
|
14908
|
+
*
|
|
14909
|
+
* **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains
|
|
14910
|
+
* all changes made to the document when the view is visible, allowing a single undo step
|
|
14911
|
+
* for all of them.
|
|
14912
|
+
*/ _showView() {
|
|
14913
|
+
const editor = this.editor;
|
|
14914
|
+
const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
|
|
14915
|
+
const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
|
|
14916
|
+
const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
|
|
14917
|
+
if (useDefaults && !this._viewWithContentTableDefaults) {
|
|
14918
|
+
this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableProperties);
|
|
14919
|
+
} else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
|
|
14920
|
+
this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableProperties);
|
|
14921
|
+
}
|
|
14922
|
+
this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
|
|
14923
|
+
this.listenTo(editor.ui, 'update', ()=>{
|
|
14924
|
+
this._updateView();
|
|
14925
|
+
});
|
|
14926
|
+
// Update the view with the model values.
|
|
14927
|
+
this._fillViewFormFromCommandValues();
|
|
14928
|
+
this._balloon.add({
|
|
14929
|
+
view: this.view,
|
|
14930
|
+
position: getBalloonTablePositionData(editor)
|
|
14931
|
+
});
|
|
14932
|
+
// Create a new batch. Clicking "Cancel" will undo this batch.
|
|
14933
|
+
this._undoStepBatch = editor.model.createBatch();
|
|
14934
|
+
// Basic a11y.
|
|
14935
|
+
this.view.focus();
|
|
14936
|
+
}
|
|
14937
|
+
/**
|
|
14938
|
+
* Removes the {@link #view} from the {@link #_balloon}.
|
|
14939
|
+
*/ _hideView() {
|
|
14940
|
+
const editor = this.editor;
|
|
14941
|
+
this.stopListening(editor.ui, 'update');
|
|
14942
|
+
this._isReady = false;
|
|
14943
|
+
// Blur any input element before removing it from DOM to prevent issues in some browsers.
|
|
14944
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1501.
|
|
14945
|
+
this.view.saveButtonView.focus();
|
|
14946
|
+
this._balloon.remove(this.view);
|
|
14947
|
+
// Make sure the focus is not lost in the process by putting it directly
|
|
14948
|
+
// into the editing view.
|
|
14949
|
+
this.editor.editing.view.focus();
|
|
14950
|
+
}
|
|
14951
|
+
/**
|
|
14952
|
+
* Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.
|
|
14953
|
+
*/ _updateView() {
|
|
14954
|
+
const editor = this.editor;
|
|
14955
|
+
const viewDocument = editor.editing.view.document;
|
|
14956
|
+
if (!getSelectionAffectedTableWidget(viewDocument.selection)) {
|
|
14957
|
+
this._hideView();
|
|
14958
|
+
} else if (this._isViewVisible) {
|
|
14959
|
+
repositionContextualBalloon(editor, 'table');
|
|
14960
|
+
}
|
|
14961
|
+
}
|
|
14962
|
+
/**
|
|
14963
|
+
* Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.
|
|
14964
|
+
*/ get _isViewVisible() {
|
|
14965
|
+
return !!this.view && this._balloon.visibleView === this.view;
|
|
14966
|
+
}
|
|
14967
|
+
/**
|
|
14968
|
+
* Returns `true` when the {@link #view} is in the {@link #_balloon}.
|
|
14969
|
+
*/ get _isViewInBalloon() {
|
|
14970
|
+
return !!this.view && this._balloon.hasView(this.view);
|
|
14971
|
+
}
|
|
14972
|
+
/**
|
|
14973
|
+
* Creates a callback that when executed upon {@link #view view's} property change
|
|
14974
|
+
* executes a related editor command with the new property value.
|
|
14975
|
+
*
|
|
14976
|
+
* If new value will be set to the default value, the command will not be executed.
|
|
14977
|
+
*
|
|
14978
|
+
* @param commandName The command that will be executed.
|
|
14979
|
+
*/ _getPropertyChangeCallback(commandName) {
|
|
14980
|
+
return (evt, propertyName, newValue)=>{
|
|
14981
|
+
// Do not execute the command on initial call (opening the table properties view).
|
|
14982
|
+
if (!this._isReady) {
|
|
14983
|
+
return;
|
|
14984
|
+
}
|
|
14985
|
+
this.editor.execute(commandName, {
|
|
14986
|
+
value: newValue,
|
|
14987
|
+
batch: this._undoStepBatch
|
|
14988
|
+
});
|
|
14989
|
+
};
|
|
14990
|
+
}
|
|
14991
|
+
/**
|
|
14992
|
+
* Creates a callback that when executed upon {@link #view view's} property change:
|
|
14993
|
+
* * executes a related editor command with the new property value if the value is valid,
|
|
14994
|
+
* * or sets the error text next to the invalid field, if the value did not pass the validation.
|
|
14995
|
+
*/ _getValidatedPropertyChangeCallback(options) {
|
|
14996
|
+
const { commandName, viewField, validator, errorText } = options;
|
|
14997
|
+
const setErrorTextDebounced = debounce(()=>{
|
|
14998
|
+
viewField.errorText = errorText;
|
|
14999
|
+
}, ERROR_TEXT_TIMEOUT$1);
|
|
15000
|
+
return (evt, propertyName, newValue)=>{
|
|
15001
|
+
setErrorTextDebounced.cancel();
|
|
15002
|
+
// Do not execute the command on initial call (opening the table properties view).
|
|
15003
|
+
if (!this._isReady) {
|
|
15004
|
+
return;
|
|
15005
|
+
}
|
|
15006
|
+
if (validator(newValue)) {
|
|
15007
|
+
this.editor.execute(commandName, {
|
|
15008
|
+
value: newValue,
|
|
15009
|
+
batch: this._undoStepBatch
|
|
15010
|
+
});
|
|
15011
|
+
viewField.errorText = null;
|
|
15012
|
+
} else {
|
|
15013
|
+
setErrorTextDebounced();
|
|
15014
|
+
}
|
|
15015
|
+
};
|
|
15016
|
+
}
|
|
15017
|
+
}
|
|
15018
|
+
|
|
15019
|
+
/**
|
|
15020
|
+
* The class representing a table cell properties form, allowing users to customize
|
|
15021
|
+
* certain style aspects of a table cell, for instance, border, padding, text alignment, etc..
|
|
15022
|
+
*/ class TableCellPropertiesViewExperimental extends View {
|
|
15023
|
+
/**
|
|
15024
|
+
* Options passed to the view. See {@link #constructor} to learn more.
|
|
15025
|
+
*/ options;
|
|
15026
|
+
/**
|
|
15027
|
+
* Tracks information about the DOM focus in the form.
|
|
15028
|
+
*/ focusTracker;
|
|
15029
|
+
/**
|
|
15030
|
+
* An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
|
|
15031
|
+
*/ keystrokes;
|
|
15032
|
+
/**
|
|
15033
|
+
* A collection of child views in the form.
|
|
15034
|
+
*/ children;
|
|
15035
|
+
/**
|
|
15036
|
+
* A dropdown that allows selecting the style of the table cell border.
|
|
15037
|
+
*/ borderStyleDropdown;
|
|
15038
|
+
/**
|
|
15039
|
+
* An input that allows specifying the width of the table cell border.
|
|
15040
|
+
*/ borderWidthInput;
|
|
15041
|
+
/**
|
|
15042
|
+
* An input that allows specifying the color of the table cell border.
|
|
15043
|
+
*/ borderColorInput;
|
|
15044
|
+
/**
|
|
15045
|
+
* An input that allows specifying the table cell background color.
|
|
15046
|
+
*/ backgroundInput;
|
|
15047
|
+
/**
|
|
15048
|
+
* A dropdown that allows selecting the type of the table cell (data or header).
|
|
15049
|
+
*/ cellTypeDropdown;
|
|
15050
|
+
/**
|
|
15051
|
+
* An input that allows specifying the table cell padding.
|
|
15052
|
+
*/ paddingInput;
|
|
15053
|
+
/**
|
|
15054
|
+
* An input that allows specifying the table cell width.
|
|
15055
|
+
*/ widthInput;
|
|
15056
|
+
/**
|
|
15057
|
+
* An input that allows specifying the table cell height.
|
|
15058
|
+
*/ heightInput;
|
|
15059
|
+
/**
|
|
15060
|
+
* A toolbar with buttons that allow changing the horizontal text alignment in a table cell.
|
|
15061
|
+
*/ horizontalAlignmentToolbar;
|
|
15062
|
+
/**
|
|
15063
|
+
* A toolbar with buttons that allow changing the vertical text alignment in a table cell.
|
|
15064
|
+
*/ verticalAlignmentToolbar;
|
|
15065
|
+
/**
|
|
15066
|
+
* The "Save" button view.
|
|
15067
|
+
*/ saveButtonView;
|
|
15068
|
+
/**
|
|
15069
|
+
* The "Cancel" button view.
|
|
15070
|
+
*/ cancelButtonView;
|
|
15071
|
+
/**
|
|
15072
|
+
* The "Back" button view.
|
|
15073
|
+
*/ backButtonView;
|
|
15074
|
+
/**
|
|
15075
|
+
* A collection of views that can be focused in the form.
|
|
15076
|
+
*/ _focusables;
|
|
15077
|
+
/**
|
|
15078
|
+
* Helps cycling over {@link #_focusables} in the form.
|
|
15079
|
+
*/ _focusCycler;
|
|
15080
|
+
/**
|
|
15081
|
+
* @param locale The {@link module:core/editor/editor~Editor#locale} instance.
|
|
15082
|
+
* @param options Additional configuration of the view.
|
|
15083
|
+
* @param options.borderColors A configuration of the border color palette used by the
|
|
15084
|
+
* {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.
|
|
15085
|
+
* @param options.backgroundColors A configuration of the background color palette used by the
|
|
15086
|
+
* {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.
|
|
15087
|
+
* @param options.defaultTableCellProperties The default table cell properties.
|
|
15088
|
+
* @param options.isTableCellTypeSupported A flag indicating whether the table cell type is supported.
|
|
15089
|
+
*/ constructor(locale, options){
|
|
15090
|
+
super(locale);
|
|
15091
|
+
this.set({
|
|
15092
|
+
borderStyle: '',
|
|
15093
|
+
borderWidth: '',
|
|
15094
|
+
borderColor: '',
|
|
15095
|
+
padding: '',
|
|
15096
|
+
backgroundColor: '',
|
|
15097
|
+
width: '',
|
|
15098
|
+
height: '',
|
|
15099
|
+
horizontalAlignment: '',
|
|
15100
|
+
verticalAlignment: '',
|
|
15101
|
+
cellType: ''
|
|
15102
|
+
});
|
|
15103
|
+
this.options = options;
|
|
15104
|
+
const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
|
|
15105
|
+
const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
|
|
15106
|
+
const { cellTypeRowLabel, cellTypeDropdown } = this._createCellTypeField();
|
|
15107
|
+
const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
|
|
15108
|
+
const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
|
|
15109
|
+
this.focusTracker = new FocusTracker();
|
|
15110
|
+
this.keystrokes = new KeystrokeHandler();
|
|
15111
|
+
this.children = this.createCollection();
|
|
15112
|
+
this.borderStyleDropdown = borderStyleDropdown;
|
|
15113
|
+
this.borderWidthInput = borderWidthInput;
|
|
15114
|
+
this.borderColorInput = borderColorInput;
|
|
15115
|
+
this.backgroundInput = backgroundInput;
|
|
15116
|
+
this.cellTypeDropdown = cellTypeDropdown;
|
|
15117
|
+
this.paddingInput = this._createPaddingField();
|
|
15118
|
+
this.widthInput = widthInput;
|
|
15119
|
+
this.heightInput = heightInput;
|
|
15120
|
+
this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;
|
|
15121
|
+
this.verticalAlignmentToolbar = verticalAlignmentToolbar;
|
|
15122
|
+
// Defer creating to make sure other fields are present and the Save button can
|
|
15123
|
+
// bind its #isEnabled to their error messages so there's no way to save unless all
|
|
15124
|
+
// fields are valid.
|
|
15125
|
+
const { saveButtonView, cancelButtonView } = this._createActionButtons();
|
|
15126
|
+
this.saveButtonView = saveButtonView;
|
|
15127
|
+
this.cancelButtonView = cancelButtonView;
|
|
15128
|
+
this.backButtonView = this._createBackButton();
|
|
15129
|
+
this._focusables = new ViewCollection();
|
|
15130
|
+
this._focusCycler = new FocusCycler({
|
|
15131
|
+
focusables: this._focusables,
|
|
15132
|
+
focusTracker: this.focusTracker,
|
|
15133
|
+
keystrokeHandler: this.keystrokes,
|
|
15134
|
+
actions: {
|
|
15135
|
+
// Navigate form fields backwards using the Shift + Tab keystroke.
|
|
15136
|
+
focusPrevious: 'shift + tab',
|
|
15137
|
+
// Navigate form fields forwards using the Tab key.
|
|
15138
|
+
focusNext: 'tab'
|
|
15139
|
+
}
|
|
15140
|
+
});
|
|
15141
|
+
// Form header.
|
|
15142
|
+
const header = new FormHeaderView(locale, {
|
|
15143
|
+
label: this.t('Cell properties')
|
|
15144
|
+
});
|
|
15145
|
+
header.children.add(this.backButtonView, 0);
|
|
15146
|
+
this.children.add(header);
|
|
15147
|
+
// Border row.
|
|
15148
|
+
this.children.add(new FormRowView(locale, {
|
|
15149
|
+
labelView: borderRowLabel,
|
|
15150
|
+
children: this.options.isTableCellTypeSupported ? [
|
|
15151
|
+
borderRowLabel,
|
|
15152
|
+
borderStyleDropdown,
|
|
15153
|
+
borderWidthInput,
|
|
15154
|
+
borderColorInput
|
|
15155
|
+
] : [
|
|
15156
|
+
borderRowLabel,
|
|
15157
|
+
borderStyleDropdown,
|
|
15158
|
+
borderColorInput,
|
|
15159
|
+
borderWidthInput
|
|
15160
|
+
],
|
|
15161
|
+
class: `ck-table-form__border-row${this.options.isTableCellTypeSupported ? ' ck-table-form__border-row_experimental' : ''}`
|
|
15162
|
+
}));
|
|
15163
|
+
// Background and cell type.
|
|
15164
|
+
this.children.add(new FormRowView(locale, {
|
|
15165
|
+
children: this.options.isTableCellTypeSupported ? [
|
|
15166
|
+
new FormRowView(locale, {
|
|
15167
|
+
labelView: cellTypeRowLabel,
|
|
15168
|
+
children: [
|
|
15169
|
+
cellTypeRowLabel,
|
|
15170
|
+
cellTypeDropdown
|
|
15171
|
+
],
|
|
15172
|
+
class: 'ck-table-form__cell-type-row'
|
|
15173
|
+
}),
|
|
15174
|
+
new FormRowView(locale, {
|
|
15175
|
+
labelView: backgroundRowLabel,
|
|
15176
|
+
children: [
|
|
15177
|
+
backgroundRowLabel,
|
|
15178
|
+
backgroundInput
|
|
15179
|
+
],
|
|
15180
|
+
class: 'ck-table-form__background-row'
|
|
15181
|
+
})
|
|
15182
|
+
] : [
|
|
15183
|
+
new FormRowView(locale, {
|
|
15184
|
+
labelView: backgroundRowLabel,
|
|
15185
|
+
children: [
|
|
15186
|
+
backgroundRowLabel,
|
|
15187
|
+
backgroundInput
|
|
15188
|
+
],
|
|
15189
|
+
class: 'ck-table-form__background-row'
|
|
15190
|
+
})
|
|
15191
|
+
]
|
|
15192
|
+
}));
|
|
15193
|
+
// Dimensions row and padding.
|
|
15194
|
+
this.children.add(new FormRowView(locale, {
|
|
15195
|
+
children: [
|
|
15196
|
+
// Dimensions row.
|
|
15197
|
+
new FormRowView(locale, {
|
|
15198
|
+
labelView: dimensionsLabel,
|
|
15199
|
+
children: [
|
|
15200
|
+
dimensionsLabel,
|
|
15201
|
+
widthInput,
|
|
15202
|
+
operatorLabel,
|
|
15203
|
+
heightInput
|
|
15204
|
+
],
|
|
15205
|
+
class: 'ck-table-form__dimensions-row'
|
|
15206
|
+
}),
|
|
15207
|
+
// Padding row.
|
|
15208
|
+
new FormRowView(locale, {
|
|
15209
|
+
children: [
|
|
15210
|
+
this.paddingInput
|
|
15211
|
+
],
|
|
15212
|
+
class: 'ck-table-cell-properties-form__padding-row'
|
|
15213
|
+
})
|
|
15214
|
+
]
|
|
15215
|
+
}));
|
|
15216
|
+
// Text alignment row.
|
|
15217
|
+
this.children.add(new FormRowView(locale, {
|
|
15218
|
+
labelView: alignmentLabel,
|
|
15219
|
+
children: [
|
|
15220
|
+
alignmentLabel,
|
|
15221
|
+
horizontalAlignmentToolbar,
|
|
15222
|
+
verticalAlignmentToolbar
|
|
15223
|
+
],
|
|
15224
|
+
class: 'ck-table-cell-properties-form__alignment-row'
|
|
15225
|
+
}));
|
|
15226
|
+
// Action row.
|
|
15227
|
+
this.children.add(new FormRowView(locale, {
|
|
15228
|
+
children: [
|
|
15229
|
+
this.cancelButtonView,
|
|
15230
|
+
this.saveButtonView
|
|
15231
|
+
],
|
|
15232
|
+
class: 'ck-table-form__action-row'
|
|
15233
|
+
}));
|
|
15234
|
+
this.setTemplate({
|
|
15235
|
+
tag: 'form',
|
|
15236
|
+
attributes: {
|
|
15237
|
+
class: [
|
|
15238
|
+
'ck',
|
|
15239
|
+
'ck-form',
|
|
15240
|
+
'ck-table-form',
|
|
15241
|
+
'ck-table-cell-properties-form',
|
|
15242
|
+
'ck-table-cell-properties-form_experimental',
|
|
15243
|
+
this.options.isTableCellTypeSupported ? 'ck-table-cell-properties-form_experimental-no-cell-type' : ''
|
|
15244
|
+
],
|
|
15245
|
+
// https://github.com/ckeditor/ckeditor5-link/issues/90
|
|
15246
|
+
tabindex: '-1'
|
|
15247
|
+
},
|
|
15248
|
+
children: this.children
|
|
15249
|
+
});
|
|
15250
|
+
}
|
|
15251
|
+
/**
|
|
15252
|
+
* @inheritDoc
|
|
15253
|
+
*/ render() {
|
|
15254
|
+
super.render();
|
|
15255
|
+
// Enable the "submit" event for this view. It can be triggered by the #saveButtonView
|
|
15256
|
+
// which is of the "submit" DOM "type".
|
|
15257
|
+
submitHandler({
|
|
15258
|
+
view: this
|
|
15259
|
+
});
|
|
15260
|
+
// Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.
|
|
15261
|
+
[
|
|
15262
|
+
this.borderColorInput,
|
|
15263
|
+
this.backgroundInput
|
|
15264
|
+
].forEach((view)=>{
|
|
15265
|
+
this._focusCycler.chain(view.fieldView.focusCycler);
|
|
15266
|
+
});
|
|
15267
|
+
[
|
|
15268
|
+
this.borderStyleDropdown,
|
|
15269
|
+
this.borderColorInput,
|
|
15270
|
+
this.borderWidthInput,
|
|
15271
|
+
this.cellTypeDropdown,
|
|
15272
|
+
this.backgroundInput,
|
|
15273
|
+
this.widthInput,
|
|
15274
|
+
this.heightInput,
|
|
15275
|
+
this.paddingInput,
|
|
15276
|
+
this.horizontalAlignmentToolbar,
|
|
15277
|
+
this.verticalAlignmentToolbar,
|
|
15278
|
+
this.cancelButtonView,
|
|
15279
|
+
this.saveButtonView,
|
|
15280
|
+
this.backButtonView
|
|
15281
|
+
].forEach((view)=>{
|
|
15282
|
+
// Register the view as focusable.
|
|
15283
|
+
this._focusables.add(view);
|
|
15284
|
+
// Register the view in the focus tracker.
|
|
15285
|
+
this.focusTracker.add(view.element);
|
|
15286
|
+
});
|
|
15287
|
+
// Mainly for closing using "Esc" and navigation using "Tab".
|
|
15288
|
+
this.keystrokes.listenTo(this.element);
|
|
15289
|
+
}
|
|
15290
|
+
/**
|
|
15291
|
+
* @inheritDoc
|
|
15292
|
+
*/ destroy() {
|
|
15293
|
+
super.destroy();
|
|
15294
|
+
this.focusTracker.destroy();
|
|
15295
|
+
this.keystrokes.destroy();
|
|
15296
|
+
}
|
|
15297
|
+
/**
|
|
15298
|
+
* Focuses the fist focusable field in the form.
|
|
15299
|
+
*/ focus() {
|
|
15300
|
+
this._focusCycler.focusFirst();
|
|
15301
|
+
}
|
|
15302
|
+
/**
|
|
15303
|
+
* Creates the following form fields:
|
|
15304
|
+
*
|
|
15305
|
+
* * {@link #borderStyleDropdown},
|
|
15306
|
+
* * {@link #borderWidthInput},
|
|
15307
|
+
* * {@link #borderColorInput}.
|
|
15308
|
+
*/ _createBorderFields() {
|
|
15309
|
+
const defaultTableCellProperties = this.options.defaultTableCellProperties;
|
|
15310
|
+
const defaultBorder = {
|
|
15311
|
+
style: defaultTableCellProperties.borderStyle,
|
|
15312
|
+
width: defaultTableCellProperties.borderWidth,
|
|
15313
|
+
color: defaultTableCellProperties.borderColor
|
|
15314
|
+
};
|
|
15315
|
+
const colorInputCreator = getLabeledColorInputCreator({
|
|
15316
|
+
colorConfig: this.options.borderColors,
|
|
15317
|
+
columns: 5,
|
|
15318
|
+
defaultColorValue: defaultBorder.color,
|
|
15319
|
+
colorPickerConfig: this.options.colorPickerConfig
|
|
15320
|
+
});
|
|
15321
|
+
const locale = this.locale;
|
|
15322
|
+
const t = this.t;
|
|
15323
|
+
const accessibleLabel = t('Style');
|
|
15324
|
+
// -- Group label ---------------------------------------------
|
|
15325
|
+
const borderRowLabel = new LabelView(locale);
|
|
15326
|
+
borderRowLabel.text = t('Border');
|
|
15327
|
+
// -- Style ---------------------------------------------------
|
|
15328
|
+
const styleLabels = getBorderStyleLabels(t);
|
|
15329
|
+
const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
15330
|
+
borderStyleDropdown.set({
|
|
15331
|
+
label: accessibleLabel,
|
|
15332
|
+
class: 'ck-table-form__border-style'
|
|
15333
|
+
});
|
|
15334
|
+
borderStyleDropdown.fieldView.buttonView.set({
|
|
15335
|
+
ariaLabel: accessibleLabel,
|
|
15336
|
+
ariaLabelledBy: undefined,
|
|
15337
|
+
isOn: false,
|
|
15338
|
+
withText: true,
|
|
15339
|
+
tooltip: accessibleLabel
|
|
15340
|
+
});
|
|
15341
|
+
borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{
|
|
15342
|
+
return styleLabels[value ? value : 'none'];
|
|
15343
|
+
});
|
|
15344
|
+
borderStyleDropdown.fieldView.on('execute', (evt)=>{
|
|
15345
|
+
this.borderStyle = evt.source._borderStyleValue;
|
|
15346
|
+
});
|
|
15347
|
+
borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);
|
|
15348
|
+
addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {
|
|
15349
|
+
role: 'menu',
|
|
15350
|
+
ariaLabel: accessibleLabel
|
|
15351
|
+
});
|
|
15352
|
+
// -- Width ---------------------------------------------------
|
|
15353
|
+
const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
15354
|
+
borderWidthInput.set({
|
|
15355
|
+
label: t('Width'),
|
|
15356
|
+
class: 'ck-table-form__border-width'
|
|
15357
|
+
});
|
|
15358
|
+
borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');
|
|
15359
|
+
borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
|
|
15360
|
+
borderWidthInput.fieldView.on('input', ()=>{
|
|
15361
|
+
this.borderWidth = borderWidthInput.fieldView.element.value;
|
|
15362
|
+
});
|
|
15363
|
+
// -- Color ---------------------------------------------------
|
|
15364
|
+
const borderColorInput = new LabeledFieldView(locale, colorInputCreator);
|
|
15365
|
+
borderColorInput.set({
|
|
15366
|
+
label: t('Color'),
|
|
15367
|
+
class: 'ck-table-form__border-color'
|
|
15368
|
+
});
|
|
15369
|
+
borderColorInput.fieldView.bind('value').to(this, 'borderColor');
|
|
15370
|
+
borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);
|
|
15371
|
+
borderColorInput.fieldView.on('input', ()=>{
|
|
15372
|
+
this.borderColor = borderColorInput.fieldView.value;
|
|
15373
|
+
});
|
|
15374
|
+
// Reset the border color and width fields depending on the `border-style` value.
|
|
15375
|
+
this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{
|
|
15376
|
+
// When removing the border (`border-style:none`), clear the remaining `border-*` properties.
|
|
15377
|
+
// See: https://github.com/ckeditor/ckeditor5/issues/6227.
|
|
15378
|
+
if (!isBorderStyleSet(newValue)) {
|
|
15379
|
+
this.borderColor = '';
|
|
15380
|
+
this.borderWidth = '';
|
|
15381
|
+
}
|
|
15382
|
+
// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.
|
|
15383
|
+
if (!isBorderStyleSet(oldValue)) {
|
|
15384
|
+
this.borderColor = defaultBorder.color;
|
|
15385
|
+
this.borderWidth = defaultBorder.width;
|
|
15386
|
+
}
|
|
15387
|
+
});
|
|
15388
|
+
return {
|
|
15389
|
+
borderRowLabel,
|
|
15390
|
+
borderStyleDropdown,
|
|
15391
|
+
borderColorInput,
|
|
15392
|
+
borderWidthInput
|
|
15393
|
+
};
|
|
15394
|
+
}
|
|
15395
|
+
/**
|
|
15396
|
+
* Creates the following form fields:
|
|
15397
|
+
*
|
|
15398
|
+
* * {@link #backgroundInput}.
|
|
15399
|
+
*/ _createBackgroundFields() {
|
|
15400
|
+
const locale = this.locale;
|
|
15401
|
+
const t = this.t;
|
|
15402
|
+
// -- Group label ---------------------------------------------
|
|
15403
|
+
const backgroundRowLabel = new LabelView(locale);
|
|
15404
|
+
backgroundRowLabel.text = t('Background');
|
|
15405
|
+
// -- Background color input -----------------------------------
|
|
15406
|
+
const colorInputCreator = getLabeledColorInputCreator({
|
|
15407
|
+
colorConfig: this.options.backgroundColors,
|
|
15408
|
+
columns: 5,
|
|
15409
|
+
defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,
|
|
15410
|
+
colorPickerConfig: this.options.colorPickerConfig
|
|
15411
|
+
});
|
|
15412
|
+
const backgroundInput = new LabeledFieldView(locale, colorInputCreator);
|
|
15413
|
+
backgroundInput.set({
|
|
15414
|
+
label: t('Color'),
|
|
15415
|
+
class: 'ck-table-cell-properties-form__background'
|
|
15416
|
+
});
|
|
15417
|
+
backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');
|
|
15418
|
+
backgroundInput.fieldView.on('input', ()=>{
|
|
15419
|
+
this.backgroundColor = backgroundInput.fieldView.value;
|
|
15420
|
+
});
|
|
15421
|
+
return {
|
|
15422
|
+
backgroundRowLabel,
|
|
15423
|
+
backgroundInput
|
|
15424
|
+
};
|
|
15425
|
+
}
|
|
15426
|
+
/**
|
|
15427
|
+
* Create cell type field.
|
|
15428
|
+
*
|
|
15429
|
+
* * {@link #cellTypeDropdown}.
|
|
15430
|
+
*
|
|
15431
|
+
* @internal
|
|
15432
|
+
*/ _createCellTypeField() {
|
|
15433
|
+
const locale = this.locale;
|
|
15434
|
+
const t = this.t;
|
|
15435
|
+
const cellTypeRowLabel = new LabelView(locale);
|
|
15436
|
+
cellTypeRowLabel.text = t('Cell type');
|
|
15437
|
+
const cellTypeLabels = this._cellTypeLabels;
|
|
15438
|
+
const cellTypeDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
15439
|
+
cellTypeDropdown.set({
|
|
15440
|
+
label: t('Cell type'),
|
|
15441
|
+
class: 'ck-table-cell-properties-form__cell-type'
|
|
15442
|
+
});
|
|
15443
|
+
cellTypeDropdown.fieldView.buttonView.set({
|
|
15444
|
+
ariaLabel: t('Cell type'),
|
|
15445
|
+
ariaLabelledBy: undefined,
|
|
15446
|
+
isOn: false,
|
|
15447
|
+
withText: true,
|
|
15448
|
+
tooltip: t('Cell type')
|
|
15449
|
+
});
|
|
15450
|
+
cellTypeDropdown.fieldView.buttonView.bind('label').to(this, 'cellType', (value)=>{
|
|
15451
|
+
return cellTypeLabels[value || 'data'];
|
|
15452
|
+
});
|
|
15453
|
+
cellTypeDropdown.fieldView.on('execute', (evt)=>{
|
|
15454
|
+
this.cellType = evt.source._cellTypeValue;
|
|
15455
|
+
});
|
|
15456
|
+
cellTypeDropdown.bind('isEmpty').to(this, 'cellType', (value)=>!value);
|
|
15457
|
+
addListToDropdown(cellTypeDropdown.fieldView, this._getCellTypeDefinitions(), {
|
|
15458
|
+
role: 'menu',
|
|
15459
|
+
ariaLabel: t('Cell type')
|
|
15460
|
+
});
|
|
15461
|
+
return {
|
|
15462
|
+
cellTypeRowLabel,
|
|
15463
|
+
cellTypeDropdown
|
|
15464
|
+
};
|
|
15465
|
+
}
|
|
15466
|
+
/**
|
|
15467
|
+
* Creates the following form fields:
|
|
15468
|
+
*
|
|
15469
|
+
* * {@link #widthInput}.
|
|
15470
|
+
* * {@link #heightInput}.
|
|
15471
|
+
*/ _createDimensionFields() {
|
|
15472
|
+
const locale = this.locale;
|
|
15473
|
+
const t = this.t;
|
|
15474
|
+
// -- Label ---------------------------------------------------
|
|
15475
|
+
const dimensionsLabel = new LabelView(locale);
|
|
15476
|
+
dimensionsLabel.text = t('Dimensions');
|
|
15477
|
+
// -- Width ---------------------------------------------------
|
|
15478
|
+
const widthInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
15479
|
+
widthInput.set({
|
|
15480
|
+
label: t('Width'),
|
|
15481
|
+
class: 'ck-table-form__dimensions-row__width'
|
|
15482
|
+
});
|
|
15483
|
+
widthInput.fieldView.bind('value').to(this, 'width');
|
|
15484
|
+
widthInput.fieldView.on('input', ()=>{
|
|
15485
|
+
this.width = widthInput.fieldView.element.value;
|
|
15486
|
+
});
|
|
15487
|
+
// -- Operator ---------------------------------------------------
|
|
15488
|
+
const operatorLabel = new View(locale);
|
|
15489
|
+
operatorLabel.setTemplate({
|
|
15490
|
+
tag: 'span',
|
|
15491
|
+
attributes: {
|
|
15492
|
+
class: [
|
|
15493
|
+
'ck-table-form__dimension-operator'
|
|
15494
|
+
]
|
|
15495
|
+
},
|
|
15496
|
+
children: [
|
|
15497
|
+
{
|
|
15498
|
+
text: '×'
|
|
15499
|
+
}
|
|
15500
|
+
]
|
|
15501
|
+
});
|
|
15502
|
+
// -- Height ---------------------------------------------------
|
|
15503
|
+
const heightInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
15504
|
+
heightInput.set({
|
|
15505
|
+
label: t('Height'),
|
|
15506
|
+
class: 'ck-table-form__dimensions-row__height'
|
|
15507
|
+
});
|
|
15508
|
+
heightInput.fieldView.bind('value').to(this, 'height');
|
|
15509
|
+
heightInput.fieldView.on('input', ()=>{
|
|
15510
|
+
this.height = heightInput.fieldView.element.value;
|
|
15511
|
+
});
|
|
15512
|
+
return {
|
|
15513
|
+
dimensionsLabel,
|
|
15514
|
+
widthInput,
|
|
15515
|
+
operatorLabel,
|
|
15516
|
+
heightInput
|
|
15517
|
+
};
|
|
15518
|
+
}
|
|
15519
|
+
/**
|
|
15520
|
+
* Creates the following form fields:
|
|
15521
|
+
*
|
|
15522
|
+
* * {@link #paddingInput}.
|
|
15523
|
+
*/ _createPaddingField() {
|
|
15524
|
+
const locale = this.locale;
|
|
15525
|
+
const t = this.t;
|
|
15526
|
+
const paddingInput = new LabeledFieldView(locale, createLabeledInputText);
|
|
15527
|
+
paddingInput.set({
|
|
15528
|
+
label: t('Padding'),
|
|
15529
|
+
class: 'ck-table-cell-properties-form__padding'
|
|
15530
|
+
});
|
|
15531
|
+
paddingInput.fieldView.bind('value').to(this, 'padding');
|
|
15532
|
+
paddingInput.fieldView.on('input', ()=>{
|
|
15533
|
+
this.padding = paddingInput.fieldView.element.value;
|
|
15534
|
+
});
|
|
15535
|
+
return paddingInput;
|
|
15536
|
+
}
|
|
15537
|
+
/**
|
|
15538
|
+
* Creates the following form fields:
|
|
15539
|
+
*
|
|
15540
|
+
* * {@link #horizontalAlignmentToolbar},
|
|
15541
|
+
* * {@link #verticalAlignmentToolbar}.
|
|
15542
|
+
*/ _createAlignmentFields() {
|
|
15543
|
+
const locale = this.locale;
|
|
15544
|
+
const t = this.t;
|
|
15545
|
+
const alignmentLabel = new LabelView(locale);
|
|
15546
|
+
const ALIGNMENT_ICONS = {
|
|
15547
|
+
left: IconAlignLeft,
|
|
15548
|
+
center: IconAlignCenter,
|
|
15549
|
+
right: IconAlignRight,
|
|
15550
|
+
justify: IconAlignJustify,
|
|
15551
|
+
top: IconAlignTop,
|
|
15552
|
+
middle: IconAlignMiddle,
|
|
15553
|
+
bottom: IconAlignBottom
|
|
15554
|
+
};
|
|
15555
|
+
alignmentLabel.text = t('Table cell text alignment');
|
|
15556
|
+
// -- Horizontal ---------------------------------------------------
|
|
15557
|
+
const horizontalAlignmentToolbar = new ToolbarView(locale);
|
|
15558
|
+
const isContentRTL = locale.contentLanguageDirection === 'rtl';
|
|
15559
|
+
horizontalAlignmentToolbar.set({
|
|
15560
|
+
isCompact: true,
|
|
15561
|
+
role: 'radiogroup',
|
|
15562
|
+
ariaLabel: t('Horizontal text alignment toolbar'),
|
|
15563
|
+
class: 'ck-table-cell-properties-form__horizontal-alignment-toolbar'
|
|
15564
|
+
});
|
|
15565
|
+
fillToolbar({
|
|
15566
|
+
view: this,
|
|
15567
|
+
icons: ALIGNMENT_ICONS,
|
|
15568
|
+
toolbar: horizontalAlignmentToolbar,
|
|
15569
|
+
labels: this._horizontalAlignmentLabels,
|
|
15570
|
+
propertyName: 'horizontalAlignment',
|
|
15571
|
+
nameToValue: (name)=>{
|
|
15572
|
+
// For the RTL content, we want to swap the buttons "align to the left" and "align to the right".
|
|
15573
|
+
if (isContentRTL) {
|
|
15574
|
+
if (name === 'left') {
|
|
15575
|
+
return 'right';
|
|
15576
|
+
} else if (name === 'right') {
|
|
15577
|
+
return 'left';
|
|
15578
|
+
}
|
|
15579
|
+
}
|
|
15580
|
+
return name;
|
|
15581
|
+
},
|
|
15582
|
+
defaultValue: this.options.defaultTableCellProperties.horizontalAlignment
|
|
15583
|
+
});
|
|
15584
|
+
// -- Vertical -----------------------------------------------------
|
|
15585
|
+
const verticalAlignmentToolbar = new ToolbarView(locale);
|
|
15586
|
+
verticalAlignmentToolbar.set({
|
|
15587
|
+
isCompact: true,
|
|
15588
|
+
role: 'radiogroup',
|
|
15589
|
+
ariaLabel: t('Vertical text alignment toolbar'),
|
|
15590
|
+
class: 'ck-table-cell-properties-form__vertical-alignment-toolbar'
|
|
15591
|
+
});
|
|
15592
|
+
fillToolbar({
|
|
15593
|
+
view: this,
|
|
15594
|
+
icons: ALIGNMENT_ICONS,
|
|
15595
|
+
toolbar: verticalAlignmentToolbar,
|
|
15596
|
+
labels: this._verticalAlignmentLabels,
|
|
15597
|
+
propertyName: 'verticalAlignment',
|
|
15598
|
+
defaultValue: this.options.defaultTableCellProperties.verticalAlignment
|
|
15599
|
+
});
|
|
15600
|
+
return {
|
|
15601
|
+
horizontalAlignmentToolbar,
|
|
15602
|
+
verticalAlignmentToolbar,
|
|
15603
|
+
alignmentLabel
|
|
15604
|
+
};
|
|
15605
|
+
}
|
|
15606
|
+
/**
|
|
15607
|
+
* Creates the following form controls:
|
|
15608
|
+
*
|
|
15609
|
+
* * {@link #saveButtonView},
|
|
15610
|
+
* * {@link #cancelButtonView}.
|
|
15611
|
+
*/ _createActionButtons() {
|
|
15612
|
+
const locale = this.locale;
|
|
15613
|
+
const t = this.t;
|
|
15614
|
+
const saveButtonView = new ButtonView(locale);
|
|
15615
|
+
const cancelButtonView = new ButtonView(locale);
|
|
15616
|
+
const fieldsThatShouldValidateToSave = [
|
|
15617
|
+
this.borderWidthInput,
|
|
15618
|
+
this.borderColorInput,
|
|
15619
|
+
this.backgroundInput,
|
|
15620
|
+
this.paddingInput
|
|
15621
|
+
];
|
|
15622
|
+
saveButtonView.set({
|
|
15623
|
+
label: t('Save'),
|
|
15624
|
+
class: 'ck-button-action',
|
|
15625
|
+
type: 'submit',
|
|
15626
|
+
withText: true
|
|
15627
|
+
});
|
|
15628
|
+
saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{
|
|
15629
|
+
return errorTexts.every((errorText)=>!errorText);
|
|
15630
|
+
});
|
|
15631
|
+
cancelButtonView.set({
|
|
15632
|
+
label: t('Cancel'),
|
|
15633
|
+
withText: true
|
|
15634
|
+
});
|
|
15635
|
+
cancelButtonView.delegate('execute').to(this, 'cancel');
|
|
15636
|
+
return {
|
|
15637
|
+
saveButtonView,
|
|
15638
|
+
cancelButtonView
|
|
15639
|
+
};
|
|
15640
|
+
}
|
|
15641
|
+
/**
|
|
15642
|
+
* Creates a back button view that cancels the form.
|
|
15643
|
+
*/ _createBackButton() {
|
|
15644
|
+
const t = this.locale.t;
|
|
15645
|
+
const backButton = new ButtonView(this.locale);
|
|
15646
|
+
backButton.set({
|
|
15647
|
+
class: 'ck-button-back',
|
|
15648
|
+
label: t('Back'),
|
|
15649
|
+
icon: IconPreviousArrow,
|
|
15650
|
+
tooltip: true
|
|
15651
|
+
});
|
|
15652
|
+
backButton.delegate('execute').to(this, 'cancel');
|
|
15653
|
+
return backButton;
|
|
15654
|
+
}
|
|
15655
|
+
/**
|
|
15656
|
+
* Creates the cell type dropdown definitions.
|
|
15657
|
+
*/ _getCellTypeDefinitions() {
|
|
15658
|
+
const itemDefinitions = new Collection();
|
|
15659
|
+
const cellTypeLabels = this._cellTypeLabels;
|
|
15660
|
+
for (const type of [
|
|
15661
|
+
'data',
|
|
15662
|
+
'header'
|
|
15663
|
+
]){
|
|
15664
|
+
const definition = {
|
|
15665
|
+
type: 'button',
|
|
15666
|
+
model: new UIModel({
|
|
15667
|
+
_cellTypeValue: type,
|
|
15668
|
+
label: cellTypeLabels[type],
|
|
15669
|
+
role: 'menuitemradio',
|
|
15670
|
+
withText: true
|
|
15671
|
+
})
|
|
15672
|
+
};
|
|
15673
|
+
definition.model.bind('isOn').to(this, 'cellType', (value)=>value === type);
|
|
15674
|
+
itemDefinitions.add(definition);
|
|
15675
|
+
}
|
|
15676
|
+
return itemDefinitions;
|
|
15677
|
+
}
|
|
15678
|
+
/**
|
|
15679
|
+
* Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
|
|
15680
|
+
*/ get _horizontalAlignmentLabels() {
|
|
15681
|
+
const locale = this.locale;
|
|
15682
|
+
const t = this.t;
|
|
15683
|
+
const left = t('Align cell text to the left');
|
|
15684
|
+
const center = t('Align cell text to the center');
|
|
15685
|
+
const right = t('Align cell text to the right');
|
|
15686
|
+
const justify = t('Justify cell text');
|
|
15687
|
+
// Returns object with a proper order of labels.
|
|
15688
|
+
if (locale.uiLanguageDirection === 'rtl') {
|
|
15689
|
+
return {
|
|
15690
|
+
right,
|
|
15691
|
+
center,
|
|
15692
|
+
left,
|
|
15693
|
+
justify
|
|
15694
|
+
};
|
|
15695
|
+
} else {
|
|
15696
|
+
return {
|
|
15697
|
+
left,
|
|
15698
|
+
center,
|
|
15699
|
+
right,
|
|
15700
|
+
justify
|
|
15701
|
+
};
|
|
15702
|
+
}
|
|
15703
|
+
}
|
|
15704
|
+
/**
|
|
15705
|
+
* Provides localized labels for {@link #verticalAlignmentToolbar} buttons.
|
|
15706
|
+
*/ get _verticalAlignmentLabels() {
|
|
15707
|
+
const t = this.t;
|
|
15708
|
+
return {
|
|
15709
|
+
top: t('Align cell text to the top'),
|
|
15710
|
+
middle: t('Align cell text to the middle'),
|
|
15711
|
+
bottom: t('Align cell text to the bottom')
|
|
15712
|
+
};
|
|
15713
|
+
}
|
|
15714
|
+
/**
|
|
15715
|
+
* Provides localized labels for {@link #cellTypeDropdown}.
|
|
15716
|
+
*/ get _cellTypeLabels() {
|
|
15717
|
+
const t = this.t;
|
|
15718
|
+
return {
|
|
15719
|
+
data: t('Data cell'),
|
|
15720
|
+
header: t('Header cell')
|
|
15721
|
+
};
|
|
15722
|
+
}
|
|
15723
|
+
}
|
|
15724
|
+
function isBorderStyleSet(value) {
|
|
15725
|
+
return value !== 'none';
|
|
15726
|
+
}
|
|
15727
|
+
|
|
15728
|
+
const ERROR_TEXT_TIMEOUT = 500;
|
|
15729
|
+
// Map of view properties and related commands.
|
|
15730
|
+
const propertyToCommandMap = {
|
|
15731
|
+
borderStyle: 'tableCellBorderStyle',
|
|
15732
|
+
borderColor: 'tableCellBorderColor',
|
|
15733
|
+
borderWidth: 'tableCellBorderWidth',
|
|
15734
|
+
height: 'tableCellHeight',
|
|
15735
|
+
width: 'tableCellWidth',
|
|
15736
|
+
padding: 'tableCellPadding',
|
|
15737
|
+
backgroundColor: 'tableCellBackgroundColor',
|
|
15738
|
+
horizontalAlignment: 'tableCellHorizontalAlignment',
|
|
15739
|
+
verticalAlignment: 'tableCellVerticalAlignment',
|
|
15740
|
+
cellType: 'tableCellType'
|
|
15741
|
+
};
|
|
15742
|
+
/**
|
|
15743
|
+
* The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
|
|
15744
|
+
* that opens a form allowing to specify the visual styling of a table cell.
|
|
15745
|
+
*
|
|
15746
|
+
* It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.
|
|
15747
|
+
*/ class TableCellPropertiesUIExperimental extends Plugin {
|
|
15748
|
+
/**
|
|
15749
|
+
* The default table cell properties.
|
|
15750
|
+
*/ _defaultContentTableCellProperties;
|
|
15751
|
+
/**
|
|
15752
|
+
* The default layout table cell properties.
|
|
15753
|
+
*/ _defaultLayoutTableCellProperties;
|
|
15754
|
+
/**
|
|
15755
|
+
* The contextual balloon plugin instance.
|
|
15756
|
+
*/ _balloon;
|
|
15757
|
+
/**
|
|
15758
|
+
* The cell properties form view displayed inside the balloon.
|
|
15759
|
+
*/ view;
|
|
15760
|
+
/**
|
|
15761
|
+
* The cell properties form view displayed inside the balloon (content table).
|
|
15762
|
+
*/ _viewWithContentTableDefaults;
|
|
15763
|
+
/**
|
|
15764
|
+
* The cell properties form view displayed inside the balloon (layout table).
|
|
15765
|
+
*/ _viewWithLayoutTableDefaults;
|
|
15766
|
+
/**
|
|
15767
|
+
* The batch used to undo all changes made by the form (which are live, as the user types)
|
|
15768
|
+
* when "Cancel" was pressed. Each time the view is shown, a new batch is created.
|
|
15769
|
+
*/ _undoStepBatch;
|
|
15770
|
+
/**
|
|
15771
|
+
* Flag used to indicate whether view is ready to execute update commands
|
|
15772
|
+
* (it finished loading initial data).
|
|
15773
|
+
*/ _isReady;
|
|
15774
|
+
/**
|
|
15775
|
+
* @inheritDoc
|
|
15776
|
+
*/ static get requires() {
|
|
15777
|
+
return [
|
|
15778
|
+
ContextualBalloon
|
|
15779
|
+
];
|
|
15780
|
+
}
|
|
15781
|
+
/**
|
|
15782
|
+
* @inheritDoc
|
|
15783
|
+
*/ static get pluginName() {
|
|
15784
|
+
return 'TableCellPropertiesUIExperimental';
|
|
15785
|
+
}
|
|
15786
|
+
/**
|
|
15787
|
+
* @inheritDoc
|
|
15788
|
+
*/ static get isOfficialPlugin() {
|
|
15789
|
+
return true;
|
|
15790
|
+
}
|
|
15791
|
+
/**
|
|
15792
|
+
* @inheritDoc
|
|
15793
|
+
*/ constructor(editor){
|
|
15794
|
+
super(editor);
|
|
15795
|
+
editor.config.define('table.tableCellProperties', {
|
|
15796
|
+
borderColors: defaultColors,
|
|
15797
|
+
backgroundColors: defaultColors
|
|
15798
|
+
});
|
|
15799
|
+
}
|
|
15800
|
+
/**
|
|
15801
|
+
* @inheritDoc
|
|
15802
|
+
*/ init() {
|
|
15803
|
+
const editor = this.editor;
|
|
15804
|
+
const t = editor.t;
|
|
15805
|
+
this._defaultContentTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {
|
|
15806
|
+
includeVerticalAlignmentProperty: true,
|
|
15807
|
+
includeHorizontalAlignmentProperty: true,
|
|
15808
|
+
includePaddingProperty: true,
|
|
15809
|
+
isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
|
|
15810
|
+
});
|
|
15811
|
+
this._defaultLayoutTableCellProperties = getNormalizedDefaultProperties(undefined, {
|
|
15812
|
+
includeVerticalAlignmentProperty: true,
|
|
15813
|
+
includeHorizontalAlignmentProperty: true,
|
|
15814
|
+
isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'
|
|
15815
|
+
});
|
|
15816
|
+
this._balloon = editor.plugins.get(ContextualBalloon);
|
|
15817
|
+
this.view = null;
|
|
15818
|
+
this._isReady = false;
|
|
15819
|
+
editor.ui.componentFactory.add('tableCellProperties', (locale)=>{
|
|
15820
|
+
const view = new ButtonView(locale);
|
|
15821
|
+
view.set({
|
|
15822
|
+
label: t('Cell properties'),
|
|
15823
|
+
icon: IconTableCellProperties,
|
|
15824
|
+
tooltip: true
|
|
15825
|
+
});
|
|
15826
|
+
this.listenTo(view, 'execute', ()=>this._showView());
|
|
15827
|
+
const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName)).filter((val)=>!!val);
|
|
15828
|
+
view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
|
|
15829
|
+
return view;
|
|
15830
|
+
});
|
|
15831
|
+
}
|
|
15832
|
+
/**
|
|
15833
|
+
* @inheritDoc
|
|
15834
|
+
*/ destroy() {
|
|
15835
|
+
super.destroy();
|
|
15836
|
+
// Destroy created UI components as they are not automatically destroyed.
|
|
15837
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1341.
|
|
15838
|
+
if (this.view) {
|
|
15839
|
+
this.view.destroy();
|
|
15840
|
+
}
|
|
15841
|
+
}
|
|
15842
|
+
/**
|
|
15843
|
+
* Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.
|
|
15844
|
+
*
|
|
15845
|
+
* @returns The cell properties form view instance.
|
|
15846
|
+
*/ _createPropertiesView(defaultTableCellProperties) {
|
|
15847
|
+
const editor = this.editor;
|
|
15848
|
+
const config = editor.config.get('table.tableCellProperties');
|
|
15849
|
+
const borderColorsConfig = normalizeColorOptions(config.borderColors);
|
|
15850
|
+
const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);
|
|
15851
|
+
const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
|
|
15852
|
+
const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
|
|
15853
|
+
const hasColorPicker = config.colorPicker !== false;
|
|
15854
|
+
const isTableCellTypeSupported = !!editor.config.get('experimentalFlags.tableCellTypeSupport');
|
|
15855
|
+
const view = new TableCellPropertiesViewExperimental(editor.locale, {
|
|
15856
|
+
borderColors: localizedBorderColors,
|
|
15857
|
+
backgroundColors: localizedBackgroundColors,
|
|
15858
|
+
defaultTableCellProperties,
|
|
15859
|
+
colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false,
|
|
15860
|
+
isTableCellTypeSupported
|
|
15861
|
+
});
|
|
15862
|
+
const t = editor.t;
|
|
15863
|
+
// Render the view so its #element is available for the clickOutsideHandler.
|
|
15864
|
+
view.render();
|
|
15865
|
+
this.listenTo(view, 'submit', ()=>{
|
|
15866
|
+
this._hideView();
|
|
15867
|
+
});
|
|
15868
|
+
this.listenTo(view, 'cancel', ()=>{
|
|
15869
|
+
// https://github.com/ckeditor/ckeditor5/issues/6180
|
|
15870
|
+
if (this._undoStepBatch.operations.length) {
|
|
15871
|
+
editor.execute('undo', this._undoStepBatch);
|
|
15872
|
+
}
|
|
15873
|
+
this._hideView();
|
|
15874
|
+
});
|
|
15875
|
+
// Close the balloon on Esc key press.
|
|
15876
|
+
view.keystrokes.set('Esc', (data, cancel)=>{
|
|
15877
|
+
this._hideView();
|
|
15878
|
+
cancel();
|
|
15879
|
+
});
|
|
15880
|
+
// Close on click outside of balloon panel element.
|
|
15881
|
+
clickOutsideHandler({
|
|
15882
|
+
emitter: view,
|
|
15883
|
+
activator: ()=>this._isViewInBalloon,
|
|
15884
|
+
contextElements: [
|
|
15885
|
+
this._balloon.view.element
|
|
15886
|
+
],
|
|
15887
|
+
callback: ()=>this._hideView()
|
|
15888
|
+
});
|
|
15889
|
+
const colorErrorText = getLocalizedColorErrorText(t);
|
|
15890
|
+
const lengthErrorText = getLocalizedLengthErrorText(t);
|
|
15891
|
+
// Create the "UI -> editor data" binding.
|
|
15892
|
+
// These listeners update the editor data (via table commands) when any observable
|
|
15893
|
+
// property of the view has changed. They also validate the value and display errors in the UI
|
|
15894
|
+
// when necessary. This makes the view live, which means the changes are
|
|
15895
|
+
// visible in the editing as soon as the user types or changes fields' values.
|
|
15896
|
+
view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));
|
|
15897
|
+
view.on('change:borderColor', this._getValidatedPropertyChangeCallback({
|
|
15898
|
+
viewField: view.borderColorInput,
|
|
15899
|
+
commandName: 'tableCellBorderColor',
|
|
15900
|
+
errorText: colorErrorText,
|
|
15901
|
+
validator: colorFieldValidator
|
|
15902
|
+
}));
|
|
15903
|
+
view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({
|
|
15904
|
+
viewField: view.borderWidthInput,
|
|
15905
|
+
commandName: 'tableCellBorderWidth',
|
|
15906
|
+
errorText: lengthErrorText,
|
|
15907
|
+
validator: lineWidthFieldValidator
|
|
15908
|
+
}));
|
|
15909
|
+
view.on('change:padding', this._getValidatedPropertyChangeCallback({
|
|
15910
|
+
viewField: view.paddingInput,
|
|
15911
|
+
commandName: 'tableCellPadding',
|
|
15912
|
+
errorText: lengthErrorText,
|
|
15913
|
+
validator: lengthFieldValidator
|
|
15914
|
+
}));
|
|
15915
|
+
view.on('change:width', this._getValidatedPropertyChangeCallback({
|
|
15916
|
+
viewField: view.widthInput,
|
|
15917
|
+
commandName: 'tableCellWidth',
|
|
15918
|
+
errorText: lengthErrorText,
|
|
15919
|
+
validator: lengthFieldValidator
|
|
15920
|
+
}));
|
|
15921
|
+
view.on('change:height', this._getValidatedPropertyChangeCallback({
|
|
15922
|
+
viewField: view.heightInput,
|
|
15923
|
+
commandName: 'tableCellHeight',
|
|
15924
|
+
errorText: lengthErrorText,
|
|
15925
|
+
validator: lengthFieldValidator
|
|
15926
|
+
}));
|
|
15927
|
+
view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({
|
|
15928
|
+
viewField: view.backgroundInput,
|
|
15929
|
+
commandName: 'tableCellBackgroundColor',
|
|
15930
|
+
errorText: colorErrorText,
|
|
15931
|
+
validator: colorFieldValidator
|
|
15932
|
+
}));
|
|
15933
|
+
view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
|
|
15934
|
+
view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
|
|
15935
|
+
const cellTypeCommand = editor.commands.get('tableCellType');
|
|
15936
|
+
if (cellTypeCommand) {
|
|
15937
|
+
view.cellTypeDropdown.bind('isEnabled').to(cellTypeCommand, 'isEnabled');
|
|
15938
|
+
view.on('change:cellType', this._getPropertyChangeCallback('tableCellType'));
|
|
15939
|
+
}
|
|
15940
|
+
return view;
|
|
15941
|
+
}
|
|
15942
|
+
/**
|
|
15943
|
+
* In this method the "editor data -> UI" binding is happening.
|
|
15944
|
+
*
|
|
15945
|
+
* When executed, this method obtains selected cell property values from various table commands
|
|
15946
|
+
* and passes them to the {@link #view}.
|
|
15947
|
+
*
|
|
15948
|
+
* This way, the UI stays up–to–date with the editor data.
|
|
15949
|
+
*/ _fillViewFormFromCommandValues() {
|
|
15950
|
+
const commands = this.editor.commands;
|
|
15951
|
+
const borderStyleCommand = commands.get('tableCellBorderStyle');
|
|
15952
|
+
Object.entries(propertyToCommandMap).flatMap(([property, commandName])=>{
|
|
15953
|
+
const command = commands.get(commandName);
|
|
15954
|
+
if (!command) {
|
|
15955
|
+
return [];
|
|
15956
|
+
}
|
|
15957
|
+
const propertyKey = property;
|
|
15958
|
+
let defaultValue;
|
|
15959
|
+
if (propertyKey === 'cellType') {
|
|
15960
|
+
defaultValue = '';
|
|
15961
|
+
} else {
|
|
15962
|
+
defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
|
|
15963
|
+
}
|
|
15964
|
+
const entry = [
|
|
15965
|
+
property,
|
|
15966
|
+
command.value || defaultValue
|
|
15967
|
+
];
|
|
15968
|
+
return [
|
|
15969
|
+
entry
|
|
15970
|
+
];
|
|
15971
|
+
}).forEach(([property, value])=>{
|
|
15972
|
+
// Do not set the `border-color` and `border-width` fields if `border-style:none`.
|
|
15973
|
+
if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {
|
|
15974
|
+
return;
|
|
15975
|
+
}
|
|
15976
|
+
this.view.set(property, value);
|
|
15977
|
+
});
|
|
15978
|
+
this._isReady = true;
|
|
15979
|
+
}
|
|
15980
|
+
/**
|
|
15981
|
+
* Shows the {@link #view} in the {@link #_balloon}.
|
|
15982
|
+
*
|
|
15983
|
+
* **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains
|
|
15984
|
+
* all changes made to the document when the view is visible, allowing a single undo step
|
|
15985
|
+
* for all of them.
|
|
15986
|
+
*/ _showView() {
|
|
15987
|
+
const editor = this.editor;
|
|
15988
|
+
const viewTable = getSelectionAffectedTableWidget(editor.editing.view.document.selection);
|
|
15989
|
+
const modelTable = viewTable && editor.editing.mapper.toModelElement(viewTable);
|
|
15990
|
+
const useDefaults = !modelTable || modelTable.getAttribute('tableType') !== 'layout';
|
|
15991
|
+
if (useDefaults && !this._viewWithContentTableDefaults) {
|
|
15992
|
+
this._viewWithContentTableDefaults = this._createPropertiesView(this._defaultContentTableCellProperties);
|
|
15993
|
+
} else if (!useDefaults && !this._viewWithLayoutTableDefaults) {
|
|
15994
|
+
this._viewWithLayoutTableDefaults = this._createPropertiesView(this._defaultLayoutTableCellProperties);
|
|
15995
|
+
}
|
|
15996
|
+
this.view = useDefaults ? this._viewWithContentTableDefaults : this._viewWithLayoutTableDefaults;
|
|
15997
|
+
this.listenTo(editor.ui, 'update', ()=>{
|
|
15998
|
+
this._updateView();
|
|
15999
|
+
});
|
|
16000
|
+
// Update the view with the model values.
|
|
16001
|
+
this._fillViewFormFromCommandValues();
|
|
16002
|
+
this._balloon.add({
|
|
16003
|
+
view: this.view,
|
|
16004
|
+
position: getBalloonCellPositionData(editor)
|
|
16005
|
+
});
|
|
16006
|
+
// Create a new batch. Clicking "Cancel" will undo this batch.
|
|
16007
|
+
this._undoStepBatch = editor.model.createBatch();
|
|
16008
|
+
// Basic a11y.
|
|
16009
|
+
this.view.focus();
|
|
16010
|
+
}
|
|
16011
|
+
/**
|
|
16012
|
+
* Removes the {@link #view} from the {@link #_balloon}.
|
|
16013
|
+
*/ _hideView() {
|
|
16014
|
+
const editor = this.editor;
|
|
16015
|
+
this.stopListening(editor.ui, 'update');
|
|
16016
|
+
this._isReady = false;
|
|
16017
|
+
// Blur any input element before removing it from DOM to prevent issues in some browsers.
|
|
16018
|
+
// See https://github.com/ckeditor/ckeditor5/issues/1501.
|
|
16019
|
+
this.view.saveButtonView.focus();
|
|
16020
|
+
this._balloon.remove(this.view);
|
|
16021
|
+
// Make sure the focus is not lost in the process by putting it directly
|
|
16022
|
+
// into the editing view.
|
|
16023
|
+
this.editor.editing.view.focus();
|
|
16024
|
+
}
|
|
16025
|
+
/**
|
|
16026
|
+
* Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.
|
|
16027
|
+
*/ _updateView() {
|
|
16028
|
+
const editor = this.editor;
|
|
16029
|
+
const viewDocument = editor.editing.view.document;
|
|
16030
|
+
if (!getTableWidgetAncestor(viewDocument.selection)) {
|
|
16031
|
+
this._hideView();
|
|
16032
|
+
} else if (this._isViewVisible) {
|
|
16033
|
+
repositionContextualBalloon(editor, 'cell');
|
|
16034
|
+
}
|
|
16035
|
+
}
|
|
16036
|
+
/**
|
|
16037
|
+
* Returns `true` when the {@link #view} is visible in the {@link #_balloon}.
|
|
16038
|
+
*/ get _isViewVisible() {
|
|
16039
|
+
return !!this.view && this._balloon.visibleView === this.view;
|
|
16040
|
+
}
|
|
16041
|
+
/**
|
|
16042
|
+
* Returns `true` when the {@link #view} is in the {@link #_balloon}.
|
|
16043
|
+
*/ get _isViewInBalloon() {
|
|
16044
|
+
return !!this.view && this._balloon.hasView(this.view);
|
|
16045
|
+
}
|
|
16046
|
+
/**
|
|
16047
|
+
* Creates a callback that when executed upon the {@link #view view's} property change
|
|
16048
|
+
* executes a related editor command with the new property value.
|
|
16049
|
+
*
|
|
16050
|
+
* @param commandName The default value of the command.
|
|
16051
|
+
*/ _getPropertyChangeCallback(commandName) {
|
|
16052
|
+
return (evt, propertyName, newValue)=>{
|
|
16053
|
+
if (!this._isReady) {
|
|
16054
|
+
return;
|
|
16055
|
+
}
|
|
16056
|
+
this.editor.execute(commandName, {
|
|
16057
|
+
value: newValue,
|
|
16058
|
+
batch: this._undoStepBatch
|
|
16059
|
+
});
|
|
16060
|
+
};
|
|
16061
|
+
}
|
|
16062
|
+
/**
|
|
16063
|
+
* Creates a callback that when executed upon the {@link #view view's} property change:
|
|
16064
|
+
* * Executes a related editor command with the new property value if the value is valid,
|
|
16065
|
+
* * Or sets the error text next to the invalid field, if the value did not pass the validation.
|
|
16066
|
+
*/ _getValidatedPropertyChangeCallback(options) {
|
|
16067
|
+
const { commandName, viewField, validator, errorText } = options;
|
|
16068
|
+
const setErrorTextDebounced = debounce(()=>{
|
|
16069
|
+
viewField.errorText = errorText;
|
|
16070
|
+
}, ERROR_TEXT_TIMEOUT);
|
|
16071
|
+
return (evt, propertyName, newValue)=>{
|
|
16072
|
+
setErrorTextDebounced.cancel();
|
|
16073
|
+
// Do not execute the command on initial call (opening the table properties view).
|
|
16074
|
+
if (!this._isReady) {
|
|
16075
|
+
return;
|
|
16076
|
+
}
|
|
16077
|
+
if (validator(newValue)) {
|
|
16078
|
+
this.editor.execute(commandName, {
|
|
16079
|
+
value: newValue,
|
|
16080
|
+
batch: this._undoStepBatch
|
|
16081
|
+
});
|
|
16082
|
+
viewField.errorText = null;
|
|
16083
|
+
} else {
|
|
16084
|
+
setErrorTextDebounced();
|
|
16085
|
+
}
|
|
16086
|
+
};
|
|
16087
|
+
}
|
|
16088
|
+
}
|
|
16089
|
+
|
|
16090
|
+
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, TableCellTypeCommand, 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 };
|
|
13999
16091
|
//# sourceMappingURL=index.js.map
|