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