@ckeditor/ckeditor5-table 48.3.1 → 48.4.0-alpha.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/ckeditor5-metadata.json +12 -1
- package/dist/augmentation.d.ts +4 -1
- package/dist/commands/inserttablecommand.d.ts +5 -0
- package/dist/commands/inserttablelayoutcommand.d.ts +5 -0
- package/dist/commands/splitcellcommand.d.ts +2 -1
- package/dist/index-content.css +81 -82
- package/dist/index-content.css.map +1 -0
- package/dist/index-editor.css +537 -450
- package/dist/index-editor.css.map +1 -0
- package/dist/index.css +214 -125
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +908 -60
- package/dist/index.js.map +1 -1
- package/dist/table.d.ts +0 -1
- package/dist/tablecaption.d.ts +0 -1
- package/dist/tablecellproperties/tablecellpropertiesui.d.ts +7 -0
- package/dist/tablecellproperties/ui/tablecellpropertiesview.d.ts +0 -3
- package/dist/tablecolumnresize/commands/tablecolumnwidthcommand.d.ts +56 -0
- package/dist/tablecolumnresize/constants.d.ts +15 -0
- package/dist/tablecolumnresize/tablecolumnresizeediting.d.ts +81 -2
- package/dist/tablecolumnresize/utils.d.ts +30 -0
- package/dist/tablecolumnresize.d.ts +0 -1
- package/dist/tableconfig.d.ts +38 -0
- package/dist/tableediting.d.ts +0 -1
- package/dist/tablelayout/tablelayoutediting.d.ts +0 -1
- package/dist/tableproperties/ui/tablepropertiesview.d.ts +0 -3
- package/dist/tablescroll/tablescrollediting.d.ts +82 -0
- package/dist/tablescroll/watchers.d.ts +23 -0
- package/dist/tablescroll.d.ts +23 -0
- package/dist/tableselection.d.ts +0 -1
- package/dist/ui/colorinputview.d.ts +0 -1
- package/dist/ui/inserttableview.d.ts +0 -1
- package/dist/utils/common.d.ts +6 -0
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -6,10 +6,11 @@ import { Command, Plugin } from "@ckeditor/ckeditor5-core";
|
|
|
6
6
|
import { Widget, WidgetToolbarRepository, isWidget, toWidget, toWidgetEditable } from "@ckeditor/ckeditor5-widget";
|
|
7
7
|
import { CKEditorError, Collection, DomEmitterMixin, FocusTracker, KeystrokeHandler, Rect, first, getLocalizedArrowKeyCodeDirection, global, priorities, toUnit, uid } from "@ckeditor/ckeditor5-utils";
|
|
8
8
|
import { debounce, isEqual, isObject, throttle } from "es-toolkit/compat";
|
|
9
|
+
import { DomEventObserver, Matcher, ModelDocumentSelection, ModelElement, addBackgroundStylesRules, addBorderStylesRules, addMarginStylesRules, addPaddingStylesRules, enableViewPlaceholder, isColorStyleValue, isLengthStyleValue, isPercentageStyleValue } from "@ckeditor/ckeditor5-engine";
|
|
10
|
+
import { _getCopyOnEnterAttributes } from "@ckeditor/ckeditor5-enter";
|
|
9
11
|
import { IconAlignBottom, IconAlignCenter, IconAlignJustify, IconAlignLeft, IconAlignMiddle, IconAlignRight, IconAlignTop, IconCaption, IconObjectCenter, IconObjectInlineLeft, IconObjectInlineRight, IconObjectLeft, IconObjectRight, IconPreviousArrow, IconTable, IconTableCellProperties, IconTableColumn, IconTableLayout, IconTableMergeCell, IconTableProperties, IconTableRow } from "@ckeditor/ckeditor5-icons";
|
|
10
12
|
import { BalloonPanelView, ButtonView, ColorSelectorView, ContextualBalloon, DropdownButtonView, FocusCycler, FormHeaderView, FormRowView, InputTextView, LabelView, LabeledFieldView, MenuBarMenuView, SplitButtonView, SwitchButtonView, ToolbarView, UIModel, View, ViewCollection, addKeyboardHandlingForGrid, addListToDropdown, clickOutsideHandler, createDropdown, createLabeledDropdown, createLabeledInputText, getLocalizedColorOptions, normalizeColorOptions, submitHandler } from "@ckeditor/ckeditor5-ui";
|
|
11
13
|
import { ClipboardMarkersUtils, ClipboardPipeline } from "@ckeditor/ckeditor5-clipboard";
|
|
12
|
-
import { DomEventObserver, Matcher, ModelElement, addBackgroundStylesRules, addBorderStylesRules, addMarginStylesRules, addPaddingStylesRules, enableViewPlaceholder, isColorStyleValue, isLengthStyleValue, isPercentageStyleValue } from "@ckeditor/ckeditor5-engine";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -970,6 +971,20 @@ function isEntireCellsLineHeader({ table, row, column }) {
|
|
|
970
971
|
function isTableCellTypeEnabled(editor) {
|
|
971
972
|
return editor.model.schema.checkAttribute("tableCell", "tableCellType");
|
|
972
973
|
}
|
|
974
|
+
/**
|
|
975
|
+
* Yields every empty block (typically a `paragraph`) found inside the given table's cells.
|
|
976
|
+
*
|
|
977
|
+
* @internal
|
|
978
|
+
*/
|
|
979
|
+
function* getEmptyTableCellBlocks(table) {
|
|
980
|
+
for (const row of table.getChildren()) {
|
|
981
|
+
if (!row.is("element", "tableRow")) continue;
|
|
982
|
+
for (const cell of row.getChildren()) {
|
|
983
|
+
if (!cell.is("element", "tableCell")) continue;
|
|
984
|
+
for (const block of cell.getChildren()) if (block.is("element") && block.isEmpty) yield block;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
973
988
|
|
|
974
989
|
/**
|
|
975
990
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -1809,6 +1824,16 @@ function getElementWidthInPixels(domElement) {
|
|
|
1809
1824
|
else return parseFloat(styles.width);
|
|
1810
1825
|
}
|
|
1811
1826
|
/**
|
|
1827
|
+
* Returns the inner pixel width of a given editing root, or `null` if the root has no
|
|
1828
|
+
* DOM element attached yet (e.g. it hasn't been rendered for the first time).
|
|
1829
|
+
*
|
|
1830
|
+
* @internal
|
|
1831
|
+
*/
|
|
1832
|
+
function getEditableWidth(editor, rootName) {
|
|
1833
|
+
const domRoot = editor.editing.view.getDomRoot(rootName);
|
|
1834
|
+
return domRoot ? getElementWidthInPixels(domRoot) : null;
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1812
1837
|
* Returns the column indexes on the left and right edges of a cell. They differ if the cell spans
|
|
1813
1838
|
* across multiple columns.
|
|
1814
1839
|
*
|
|
@@ -1881,6 +1906,9 @@ function sumArray(array) {
|
|
|
1881
1906
|
* @returns An array of column widths guaranteed to sum up to 100%.
|
|
1882
1907
|
*/
|
|
1883
1908
|
function normalizeColumnWidths(columnWidths) {
|
|
1909
|
+
const hasPixels = columnWidths.some((width) => typeof width === "string" && width.endsWith("px"));
|
|
1910
|
+
const hasPercentages = columnWidths.some((width) => typeof width === "string" && width.endsWith("%"));
|
|
1911
|
+
if (hasPixels && !hasPercentages) return columnWidths.map((width) => width === "auto" || width === void 0 ? "auto" : `${toPrecision(width)}px`);
|
|
1884
1912
|
let normalizedWidths = calculateMissingColumnWidths(columnWidths.map((width) => {
|
|
1885
1913
|
if (width === "auto" || width === void 0) return "auto";
|
|
1886
1914
|
return parseFloat(width.replace("%", ""));
|
|
@@ -1979,6 +2007,26 @@ function getTableColumnsWidths(element) {
|
|
|
1979
2007
|
return getTableColumnElements(element).map((column) => column.getAttribute("columnWidth"));
|
|
1980
2008
|
}
|
|
1981
2009
|
/**
|
|
2010
|
+
* Tells whether a table is in the pixel width mode, that is, its `tableWidth` attribute is expressed in pixels.
|
|
2011
|
+
* The `tableWidth` unit is the single source of truth for the whole table's width mode.
|
|
2012
|
+
*
|
|
2013
|
+
* @internal
|
|
2014
|
+
* @param table A 'table' model element.
|
|
2015
|
+
*/
|
|
2016
|
+
function isTableWidthInPixels(table) {
|
|
2017
|
+
const tableWidth = table.getAttribute("tableWidth");
|
|
2018
|
+
return typeof tableWidth === "string" && tableWidth.trim().endsWith("px");
|
|
2019
|
+
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Tells whether the given column widths are expressed in pixels.
|
|
2022
|
+
*
|
|
2023
|
+
* @internal
|
|
2024
|
+
* @param columnWidths An array of column widths.
|
|
2025
|
+
*/
|
|
2026
|
+
function isColumnWidthsInPixels(columnWidths) {
|
|
2027
|
+
return columnWidths.some((width) => typeof width === "string" && width.endsWith("px"));
|
|
2028
|
+
}
|
|
2029
|
+
/**
|
|
1982
2030
|
* Translates the `colSpan` model attribute into additional column widths and returns the resulting array.
|
|
1983
2031
|
*
|
|
1984
2032
|
* @internal
|
|
@@ -1999,6 +2047,19 @@ function translateColSpanAttribute(element, writer) {
|
|
|
1999
2047
|
return acc;
|
|
2000
2048
|
}, []);
|
|
2001
2049
|
}
|
|
2050
|
+
/**
|
|
2051
|
+
* Removes the `tableCellWidth` attribute from every cell of the given table. Once a column is resized (with the resize
|
|
2052
|
+
* handler or the column-width command), a per-cell width is obsolete - the column width governs the layout - so it is
|
|
2053
|
+
* dropped to keep the model clean.
|
|
2054
|
+
*
|
|
2055
|
+
* @internal
|
|
2056
|
+
*/
|
|
2057
|
+
function removeCellWidthsFromTable(writer, table) {
|
|
2058
|
+
for (const row of table.getChildren()) {
|
|
2059
|
+
if (!row.is("element", "tableRow")) continue;
|
|
2060
|
+
for (const cell of row.getChildren()) writer.removeAttribute("tableCellWidth", cell);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2002
2063
|
|
|
2003
2064
|
/**
|
|
2004
2065
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -2388,10 +2449,12 @@ var TableUtils = class extends Plugin {
|
|
|
2388
2449
|
else if (column === removedColumnIndex) writer.remove(cell);
|
|
2389
2450
|
if (tableColumns[removedColumnIndex]) {
|
|
2390
2451
|
const adjacentColumn = removedColumnIndex === 0 ? tableColumns[1] : tableColumns[removedColumnIndex - 1];
|
|
2391
|
-
const
|
|
2452
|
+
const removedColumnWidthAttribute = tableColumns[removedColumnIndex].getAttribute("columnWidth");
|
|
2453
|
+
const removedColumnWidth = parseFloat(removedColumnWidthAttribute);
|
|
2392
2454
|
const adjacentColumnWidth = parseFloat(adjacentColumn.getAttribute("columnWidth"));
|
|
2393
2455
|
writer.remove(tableColumns[removedColumnIndex]);
|
|
2394
|
-
|
|
2456
|
+
const unit = removedColumnWidthAttribute.trim().endsWith("px") ? "px" : "%";
|
|
2457
|
+
writer.setAttribute("columnWidth", `${removedColumnWidth + adjacentColumnWidth}${unit}`, adjacentColumn);
|
|
2395
2458
|
}
|
|
2396
2459
|
}
|
|
2397
2460
|
if (!removeEmptyRows(table, this)) removeEmptyColumns(table, this);
|
|
@@ -3503,11 +3566,16 @@ var InsertTableCommand = class extends Command {
|
|
|
3503
3566
|
* @param options.footerRows The number of footer rows. If not provided it will default to
|
|
3504
3567
|
* {@link module:table/tableconfig~TableConfig#defaultFooters `config.table.defaultFooters`} table config.
|
|
3505
3568
|
* This option is ignored when {@link module:table/tableconfig~TableConfig#enableFooters `config.table.enableFooters`} is `false`.
|
|
3569
|
+
* @param options.inheritTextFormattingAttributes Whether every empty cell should inherit the `copyOnEnter` text
|
|
3570
|
+
* formatting attributes (e.g. bold, font color) that were uniformly active in the content right before
|
|
3571
|
+
* the table, so that whichever cell the user starts typing in first continues that formatting. Defaults
|
|
3572
|
+
* to `true`.
|
|
3506
3573
|
* @fires execute
|
|
3507
3574
|
*/
|
|
3508
3575
|
execute(options = {}) {
|
|
3509
3576
|
const editor = this.editor;
|
|
3510
3577
|
const model = editor.model;
|
|
3578
|
+
const selection = model.document.selection;
|
|
3511
3579
|
const tableUtils = editor.plugins.get("TableUtils");
|
|
3512
3580
|
const areTableFootersEnabled = !!editor.config.get("table.enableFooters");
|
|
3513
3581
|
const defaultRows = editor.config.get("table.defaultHeadings.rows");
|
|
@@ -3518,6 +3586,7 @@ var InsertTableCommand = class extends Command {
|
|
|
3518
3586
|
if (areTableFootersEnabled && options.footerRows === void 0 && defaultFooterRows) options.footerRows = defaultFooterRows;
|
|
3519
3587
|
if (!areTableFootersEnabled && "footerRows" in options) delete options.footerRows;
|
|
3520
3588
|
model.change((writer) => {
|
|
3589
|
+
const selectionAttributesToCopy = Array.from(_getCopyOnEnterAttributes(model.schema, selection.getAttributes()));
|
|
3521
3590
|
const table = tableUtils.createTable(writer, options);
|
|
3522
3591
|
model.insertObject(table, null, null, { findOptimalPosition: "auto" });
|
|
3523
3592
|
writer.setSelection(writer.createPositionAt(table.getNodeByPath([
|
|
@@ -3525,6 +3594,7 @@ var InsertTableCommand = class extends Command {
|
|
|
3525
3594
|
0,
|
|
3526
3595
|
0
|
|
3527
3596
|
]), 0));
|
|
3597
|
+
if (options.inheritTextFormattingAttributes !== false && selectionAttributesToCopy.length) for (const cellBlock of getEmptyTableCellBlocks(table)) for (const [key, value] of selectionAttributesToCopy) writer.setAttribute(ModelDocumentSelection._getStoreAttributeKey(key), value, cellBlock);
|
|
3528
3598
|
});
|
|
3529
3599
|
}
|
|
3530
3600
|
};
|
|
@@ -3695,7 +3765,8 @@ var InsertColumnCommand = class extends Command {
|
|
|
3695
3765
|
* The command is registered by {@link module:table/tableediting~TableEditing} as the `'splitTableCellVertically'`
|
|
3696
3766
|
* and `'splitTableCellHorizontally'` editor commands.
|
|
3697
3767
|
*
|
|
3698
|
-
* You can split any cell vertically or horizontally by executing this command.
|
|
3768
|
+
* You can split any cell vertically or horizontally by executing this command. When multiple cells are selected, each of them
|
|
3769
|
+
* is split, and the whole operation is a single undo step. For example, to split the selected table cells vertically:
|
|
3699
3770
|
*
|
|
3700
3771
|
* ```ts
|
|
3701
3772
|
* editor.execute( 'splitTableCellVertically' );
|
|
@@ -3721,16 +3792,19 @@ var SplitCellCommand = class extends Command {
|
|
|
3721
3792
|
*/
|
|
3722
3793
|
refresh() {
|
|
3723
3794
|
const selectedCells = this.editor.plugins.get("TableUtils").getSelectionAffectedTableCells(this.editor.model.document.selection);
|
|
3724
|
-
this.isEnabled = selectedCells.length
|
|
3795
|
+
this.isEnabled = selectedCells.length > 0;
|
|
3725
3796
|
}
|
|
3726
3797
|
/**
|
|
3727
3798
|
* @inheritDoc
|
|
3728
3799
|
*/
|
|
3729
3800
|
execute() {
|
|
3730
3801
|
const tableUtils = this.editor.plugins.get("TableUtils");
|
|
3731
|
-
const
|
|
3732
|
-
|
|
3733
|
-
|
|
3802
|
+
const tableCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);
|
|
3803
|
+
const isHorizontal = this.direction === "horizontally";
|
|
3804
|
+
this.editor.model.change(() => {
|
|
3805
|
+
for (const tableCell of tableCells) if (isHorizontal) tableUtils.splitCellHorizontally(tableCell, 2);
|
|
3806
|
+
else tableUtils.splitCellVertically(tableCell, 2);
|
|
3807
|
+
});
|
|
3734
3808
|
}
|
|
3735
3809
|
};
|
|
3736
3810
|
|
|
@@ -8552,7 +8626,8 @@ var TableCellPropertiesUI = class extends Plugin {
|
|
|
8552
8626
|
const commands = this.editor.commands;
|
|
8553
8627
|
const borderStyleCommand = commands.get("tableCellBorderStyle");
|
|
8554
8628
|
Object.entries(propertyToCommandMap$1).flatMap(([property, commandName]) => {
|
|
8555
|
-
const
|
|
8629
|
+
const effectiveCommandName = property === "width" ? this._getWidthCommandName() : commandName;
|
|
8630
|
+
const command = commands.get(effectiveCommandName);
|
|
8556
8631
|
if (!command) return [];
|
|
8557
8632
|
const propertyKey = property;
|
|
8558
8633
|
let defaultValue;
|
|
@@ -8652,7 +8727,8 @@ var TableCellPropertiesUI = class extends Plugin {
|
|
|
8652
8727
|
setErrorTextDebounced.cancel();
|
|
8653
8728
|
if (!this._isReady) return;
|
|
8654
8729
|
if (validator(newValue)) {
|
|
8655
|
-
this.
|
|
8730
|
+
const executedCommandName = commandName === "tableCellWidth" ? this._getWidthCommandName() : commandName;
|
|
8731
|
+
this.editor.execute(executedCommandName, {
|
|
8656
8732
|
value: newValue,
|
|
8657
8733
|
batch: this._undoStepBatch
|
|
8658
8734
|
});
|
|
@@ -8660,6 +8736,16 @@ var TableCellPropertiesUI = class extends Plugin {
|
|
|
8660
8736
|
} else setErrorTextDebounced();
|
|
8661
8737
|
};
|
|
8662
8738
|
}
|
|
8739
|
+
/**
|
|
8740
|
+
* Returns the command that drives the width field. When the table is resized and the selection maps onto a single
|
|
8741
|
+
* column, the width field is bound to (and executes) the `'tableColumnWidth'` command, so the width applies to the
|
|
8742
|
+
* column instead of being set as a per-cell width that the column group would shadow. Otherwise it falls back to
|
|
8743
|
+
* the `'tableCellWidth'` command.
|
|
8744
|
+
*/
|
|
8745
|
+
_getWidthCommandName() {
|
|
8746
|
+
const columnWidthCommand = this.editor.commands.get("tableColumnWidth");
|
|
8747
|
+
return columnWidthCommand && columnWidthCommand.isEnabled ? "tableColumnWidth" : "tableCellWidth";
|
|
8748
|
+
}
|
|
8663
8749
|
};
|
|
8664
8750
|
|
|
8665
8751
|
/**
|
|
@@ -9560,11 +9646,14 @@ function enableLegacyHorizontalAlignmentAttribute(conversion) {
|
|
|
9560
9646
|
if (!modelElement?.is("element")) return;
|
|
9561
9647
|
const alignValue = data.viewItem.getAttribute("align");
|
|
9562
9648
|
if (!conversionApi.consumable.consume(data.viewItem, { attributes: ["align"] })) return;
|
|
9563
|
-
for (const child of modelElement.getChildren())
|
|
9649
|
+
for (const child of modelElement.getChildren())
|
|
9650
|
+
/* v8 ignore else -- A table cell only contains block elements, so its children are always elements. */
|
|
9651
|
+
if (child.is("element")) applyAlignmentToChild(child, alignValue, conversionApi);
|
|
9564
9652
|
}, { priority: "low" });
|
|
9565
9653
|
});
|
|
9566
9654
|
function applyAlignmentToChild(child, alignValue, { schema, writer }) {
|
|
9567
9655
|
const definition = schema.getDefinition(child);
|
|
9656
|
+
/* v8 ignore else -- A converted child element is always registered in the schema, so it always has a definition. */
|
|
9568
9657
|
if (definition) for (const attrName of definition.allowAttributes) {
|
|
9569
9658
|
if (child.hasAttribute(attrName)) continue;
|
|
9570
9659
|
const { blockAlignment } = schema.getAttributeProperties(attrName);
|
|
@@ -9704,12 +9793,14 @@ function enableCellTypeProperty(editor) {
|
|
|
9704
9793
|
const cell = change.range.start.nodeAfter;
|
|
9705
9794
|
if (cell?.is("element", "tableCell") && cell.root.rootName !== "$graveyard") {
|
|
9706
9795
|
const table = cell.findAncestor("table");
|
|
9796
|
+
/* v8 ignore else -- A table cell always lives inside a table, so it always has a table ancestor here. */
|
|
9707
9797
|
if (table) tablesToCheck.add(table);
|
|
9708
9798
|
}
|
|
9709
9799
|
}
|
|
9710
9800
|
if (change.type === "insert" && change.position.nodeAfter) {
|
|
9711
9801
|
for (const { item } of model.createRangeOn(change.position.nodeAfter)) if (item.is("element", "tableCell") && item.getAttribute("tableCellType") && item.root.rootName !== "$graveyard") {
|
|
9712
9802
|
const table = item.findAncestor("table");
|
|
9803
|
+
/* v8 ignore else -- An inserted table cell always lives inside a table, so it always has a table ancestor here. */
|
|
9713
9804
|
if (table) tablesToCheck.add(table);
|
|
9714
9805
|
}
|
|
9715
9806
|
}
|
|
@@ -9880,7 +9971,8 @@ var TableLayoutUI = class extends Plugin {
|
|
|
9880
9971
|
if (!editor.plugins.has("TablePropertiesUI")) return;
|
|
9881
9972
|
const tablePropertiesUI = plugins.get("TablePropertiesUI");
|
|
9882
9973
|
ui.componentFactory.add("tableProperties", (locale) => {
|
|
9883
|
-
|
|
9974
|
+
const splitButtonView = new SplitButtonView(locale, tablePropertiesUI._createTablePropertiesButton());
|
|
9975
|
+
return createTableTypeDropdown(editor, splitButtonView);
|
|
9884
9976
|
});
|
|
9885
9977
|
}
|
|
9886
9978
|
};
|
|
@@ -9980,13 +10072,19 @@ var InsertTableLayoutCommand = class extends Command {
|
|
|
9980
10072
|
*
|
|
9981
10073
|
* @param options.rows The number of rows to create in the inserted table. Default value is 2.
|
|
9982
10074
|
* @param options.columns The number of columns to create in the inserted table. Default value is 2.
|
|
10075
|
+
* @param options.inheritTextFormattingAttributes Whether every empty cell should inherit the `copyOnEnter` text
|
|
10076
|
+
* formatting attributes (e.g. bold, font color) that were uniformly active in the content right before
|
|
10077
|
+
* the table, so that whichever cell the user starts typing in first continues that formatting. Defaults
|
|
10078
|
+
* to `true`.
|
|
9983
10079
|
* @fires execute
|
|
9984
10080
|
*/
|
|
9985
10081
|
execute(options = {}) {
|
|
9986
10082
|
const editor = this.editor;
|
|
9987
10083
|
const model = editor.model;
|
|
10084
|
+
const selection = model.document.selection;
|
|
9988
10085
|
const tableUtils = editor.plugins.get("TableUtils");
|
|
9989
10086
|
model.change((writer) => {
|
|
10087
|
+
const selectionAttributesToCopy = Array.from(_getCopyOnEnterAttributes(model.schema, selection.getAttributes()));
|
|
9990
10088
|
const normalizedOptions = {
|
|
9991
10089
|
rows: options.rows || 2,
|
|
9992
10090
|
columns: options.columns || 2
|
|
@@ -10006,6 +10104,7 @@ var InsertTableLayoutCommand = class extends Command {
|
|
|
10006
10104
|
0,
|
|
10007
10105
|
0
|
|
10008
10106
|
]), 0));
|
|
10107
|
+
if (options.inheritTextFormattingAttributes !== false && selectionAttributesToCopy.length) for (const cellBlock of getEmptyTableCellBlocks(table)) for (const [key, value] of selectionAttributesToCopy) writer.setAttribute(ModelDocumentSelection._getStoreAttributeKey(key), value, cellBlock);
|
|
10009
10108
|
});
|
|
10010
10109
|
}
|
|
10011
10110
|
};
|
|
@@ -10047,6 +10146,7 @@ var TableWidthsCommand = class extends Command {
|
|
|
10047
10146
|
if (!columnWidths && !tableColumnGroup) return;
|
|
10048
10147
|
if (!columnWidths) return writer.remove(tableColumnGroup);
|
|
10049
10148
|
const widths = normalizeColumnWidths(columnWidths);
|
|
10149
|
+
removeCellWidthsFromTable(writer, table);
|
|
10050
10150
|
if (!tableColumnGroup) {
|
|
10051
10151
|
const colGroupElement = writer.createElement("tableColumnGroup");
|
|
10052
10152
|
widths.forEach((columnWidth) => writer.appendElement("tableColumn", { columnWidth }, colGroupElement));
|
|
@@ -10056,6 +10156,76 @@ var TableWidthsCommand = class extends Command {
|
|
|
10056
10156
|
}
|
|
10057
10157
|
};
|
|
10058
10158
|
|
|
10159
|
+
/**
|
|
10160
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
10161
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
10162
|
+
*/
|
|
10163
|
+
/**
|
|
10164
|
+
* @module table/tablecolumnresize/commands/tablecolumnwidthcommand
|
|
10165
|
+
*/
|
|
10166
|
+
/**
|
|
10167
|
+
* The table column width command.
|
|
10168
|
+
*
|
|
10169
|
+
* The command is registered by the {@link module:table/tablecolumnresize/tablecolumnresizeediting~TableColumnResizeEditing}
|
|
10170
|
+
* as the `'tableColumnWidth'` editor command.
|
|
10171
|
+
*
|
|
10172
|
+
* It sets the width of every column covered by the selected cells (keeping the whole table's width mode consistent),
|
|
10173
|
+
* so the change actually takes effect in a resized table - where a per-cell width would be shadowed by the column
|
|
10174
|
+
* group. The command is enabled whenever the selection maps onto the columns of a resized, regular table.
|
|
10175
|
+
*
|
|
10176
|
+
* ```ts
|
|
10177
|
+
* editor.execute( 'tableColumnWidth', {
|
|
10178
|
+
* value: '150px'
|
|
10179
|
+
* } );
|
|
10180
|
+
* ```
|
|
10181
|
+
*
|
|
10182
|
+
* **Note**: This command adds a default `'px'` unit to numeric values. Executing:
|
|
10183
|
+
*
|
|
10184
|
+
* ```ts
|
|
10185
|
+
* editor.execute( 'tableColumnWidth', {
|
|
10186
|
+
* value: '150'
|
|
10187
|
+
* } );
|
|
10188
|
+
* ```
|
|
10189
|
+
*
|
|
10190
|
+
* will set the column width to `'150px'`.
|
|
10191
|
+
*/
|
|
10192
|
+
var TableColumnWidthCommand = class extends Command {
|
|
10193
|
+
/**
|
|
10194
|
+
* @inheritDoc
|
|
10195
|
+
*/
|
|
10196
|
+
refresh() {
|
|
10197
|
+
const editor = this.editor;
|
|
10198
|
+
const tableUtils = editor.plugins.get("TableUtils");
|
|
10199
|
+
const tableColumnResize = editor.plugins.get("TableColumnResizeEditing");
|
|
10200
|
+
const tableCells = tableUtils.getSelectionAffectedTableCells(editor.model.document.selection);
|
|
10201
|
+
const columns = tableColumnResize.getColumnIndexesForCells(tableCells);
|
|
10202
|
+
if (!columns) {
|
|
10203
|
+
this.isEnabled = false;
|
|
10204
|
+
this.value = null;
|
|
10205
|
+
return;
|
|
10206
|
+
}
|
|
10207
|
+
this.isEnabled = true;
|
|
10208
|
+
this.value = tableColumnResize.getTableColumnElements(columns.table)[columns.columnIndexes[0]].getAttribute("columnWidth");
|
|
10209
|
+
}
|
|
10210
|
+
/**
|
|
10211
|
+
* @inheritDoc
|
|
10212
|
+
*/
|
|
10213
|
+
execute(options = {}) {
|
|
10214
|
+
const editor = this.editor;
|
|
10215
|
+
const model = editor.model;
|
|
10216
|
+
const tableUtils = editor.plugins.get("TableUtils");
|
|
10217
|
+
const tableColumnResize = editor.plugins.get("TableColumnResizeEditing");
|
|
10218
|
+
const value = addDefaultUnitToNumericValue(options.value, "px");
|
|
10219
|
+
const tableCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);
|
|
10220
|
+
const columns = tableColumnResize.getColumnIndexesForCells(tableCells);
|
|
10221
|
+
if (!value || !columns || Number.isNaN(parseFloat(value))) return;
|
|
10222
|
+
model.enqueueChange(options.batch, (writer) => {
|
|
10223
|
+
tableColumnResize.applyColumnWidths(writer, columns.table, columns.columnIndexes, value);
|
|
10224
|
+
removeCellWidthsFromTable(writer, columns.table);
|
|
10225
|
+
});
|
|
10226
|
+
}
|
|
10227
|
+
};
|
|
10228
|
+
|
|
10059
10229
|
/**
|
|
10060
10230
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
10061
10231
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -10118,10 +10288,6 @@ const toPx = /* #__PURE__ */ toUnit("px");
|
|
|
10118
10288
|
* The table column resize editing plugin.
|
|
10119
10289
|
*/
|
|
10120
10290
|
var TableColumnResizeEditing = class extends Plugin {
|
|
10121
|
-
/**
|
|
10122
|
-
* A flag indicating if the column resizing is in progress.
|
|
10123
|
-
*/
|
|
10124
|
-
_isResizingActive;
|
|
10125
10291
|
/**
|
|
10126
10292
|
* A temporary storage for the required data needed to correctly calculate the widths of the resized columns. This storage is
|
|
10127
10293
|
* initialized when column resizing begins, and is purged upon completion.
|
|
@@ -10175,7 +10341,7 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10175
10341
|
*/
|
|
10176
10342
|
constructor(editor) {
|
|
10177
10343
|
super(editor);
|
|
10178
|
-
this._isResizingActive
|
|
10344
|
+
this.set("_isResizingActive", false);
|
|
10179
10345
|
this.set("_isResizingAllowed", true);
|
|
10180
10346
|
this._resizingData = null;
|
|
10181
10347
|
this._domEmitter = new (DomEmitterMixin())();
|
|
@@ -10186,6 +10352,10 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10186
10352
|
for (const root of editor.editing.view.document.roots) writer[classAction]("ck-column-resize_disabled", editor.editing.view.document.getRoot(root.rootName));
|
|
10187
10353
|
});
|
|
10188
10354
|
});
|
|
10355
|
+
this.on("change:_isResizingActive", (evt, name, value) => {
|
|
10356
|
+
const classAction = value ? "add" : "remove";
|
|
10357
|
+
global.document.body.classList[classAction]("ck-table-column-resize__resizing-cursor");
|
|
10358
|
+
});
|
|
10189
10359
|
}
|
|
10190
10360
|
/**
|
|
10191
10361
|
* @inheritDoc
|
|
@@ -10196,6 +10366,8 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10196
10366
|
this._registerConverters();
|
|
10197
10367
|
this._registerResizingListeners();
|
|
10198
10368
|
this._registerResizerInserter();
|
|
10369
|
+
this.decorate("_setResizingTableWidth");
|
|
10370
|
+
this.decorate("_getResizingTableWidth");
|
|
10199
10371
|
const editor = this.editor;
|
|
10200
10372
|
const columnResizePlugin = editor.plugins.get("TableColumnResize");
|
|
10201
10373
|
editor.plugins.get("TableEditing").registerAdditionalSlot({
|
|
@@ -10205,16 +10377,43 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10205
10377
|
const tableWidthsCommand = new TableWidthsCommand(editor);
|
|
10206
10378
|
editor.commands.add("resizeTableWidth", tableWidthsCommand);
|
|
10207
10379
|
editor.commands.add("resizeColumnWidths", tableWidthsCommand);
|
|
10380
|
+
editor.commands.add("tableColumnWidth", new TableColumnWidthCommand(editor));
|
|
10208
10381
|
this.bind("_isResizingAllowed").to(editor, "isReadOnly", columnResizePlugin, "isEnabled", tableWidthsCommand, "isEnabled", (isEditorReadOnly, isPluginEnabled, isTableWidthsCommandCommandEnabled) => !isEditorReadOnly && isPluginEnabled && isTableWidthsCommandCommandEnabled);
|
|
10209
10382
|
}
|
|
10210
10383
|
/**
|
|
10211
10384
|
* @inheritDoc
|
|
10212
10385
|
*/
|
|
10386
|
+
afterInit() {
|
|
10387
|
+
const editor = this.editor;
|
|
10388
|
+
const tableWidthCommand = editor.commands.get("tableWidth");
|
|
10389
|
+
if (tableWidthCommand) {
|
|
10390
|
+
this.listenTo(tableWidthCommand, "execute", (evt, args) => {
|
|
10391
|
+
const options = args[0] || (args[0] = {});
|
|
10392
|
+
if (!options.batch) options.batch = editor.model.createBatch();
|
|
10393
|
+
}, { priority: "high" });
|
|
10394
|
+
this.listenTo(tableWidthCommand, "execute", (evt, args) => {
|
|
10395
|
+
const options = args[0];
|
|
10396
|
+
const table = getSelectionAffectedTable(editor.model.document.selection);
|
|
10397
|
+
editor.model.enqueueChange(options.batch, (writer) => this._reconcileColumnUnits(writer, table));
|
|
10398
|
+
}, { priority: "low" });
|
|
10399
|
+
}
|
|
10400
|
+
}
|
|
10401
|
+
/**
|
|
10402
|
+
* @inheritDoc
|
|
10403
|
+
*/
|
|
10213
10404
|
destroy() {
|
|
10214
10405
|
this._domEmitter.stopListening();
|
|
10406
|
+
this._isResizingActive = false;
|
|
10215
10407
|
super.destroy();
|
|
10216
10408
|
}
|
|
10217
10409
|
/**
|
|
10410
|
+
* The table for which a column resize is currently in progress, or `null` if no resize is active.
|
|
10411
|
+
* Only one table can be resized at a time.
|
|
10412
|
+
*/
|
|
10413
|
+
get resizingTable() {
|
|
10414
|
+
return this._resizingData ? this._resizingData.elements.modelTable : null;
|
|
10415
|
+
}
|
|
10416
|
+
/**
|
|
10218
10417
|
* Returns a 'tableColumnGroup' element from the 'table'.
|
|
10219
10418
|
*
|
|
10220
10419
|
* @param element A 'table' or 'tableColumnGroup' element.
|
|
@@ -10242,6 +10441,144 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10242
10441
|
return getTableColumnsWidths(element);
|
|
10243
10442
|
}
|
|
10244
10443
|
/**
|
|
10444
|
+
* Returns the table and the sorted, unique indexes of the columns covered by the given cells (a `colspan` cell
|
|
10445
|
+
* covers several columns). Returns `null` when the selection cannot be mapped onto columns - a non-resized table
|
|
10446
|
+
* or an irregular column structure.
|
|
10447
|
+
*
|
|
10448
|
+
* @param cells An array of 'tableCell' model elements.
|
|
10449
|
+
*/
|
|
10450
|
+
getColumnIndexesForCells(cells) {
|
|
10451
|
+
const table = cells.length ? cells[0].findAncestor("table") : null;
|
|
10452
|
+
if (!table) return null;
|
|
10453
|
+
const columns = getTableColumnElements(table);
|
|
10454
|
+
if (!columns.length || columns.length !== this._tableUtilsPlugin.getColumns(table) || columns.some((column) => column.hasAttribute("colSpan"))) return null;
|
|
10455
|
+
const columnIndexes = /* @__PURE__ */ new Set();
|
|
10456
|
+
for (const cell of cells) {
|
|
10457
|
+
const { leftEdge, rightEdge } = getColumnEdgesIndexes(cell, this._tableUtilsPlugin);
|
|
10458
|
+
for (let index = leftEdge; index <= rightEdge; index++) columnIndexes.add(index);
|
|
10459
|
+
}
|
|
10460
|
+
return {
|
|
10461
|
+
table,
|
|
10462
|
+
columnIndexes: Array.from(columnIndexes).sort((indexA, indexB) => indexA - indexB)
|
|
10463
|
+
};
|
|
10464
|
+
}
|
|
10465
|
+
/**
|
|
10466
|
+
* Applies the given width to every column in `columnIndexes`, keeping the whole table's width mode consistent
|
|
10467
|
+
* (see {@link module:table/tablecolumnresize/utils~isTableWidthInPixels}).
|
|
10468
|
+
*
|
|
10469
|
+
* @param writer A model writer instance.
|
|
10470
|
+
* @param table A 'table' model element.
|
|
10471
|
+
* @param columnIndexes Indexes of the columns the width is applied to.
|
|
10472
|
+
* @param value The width to apply. May be expressed in pixels or as a percentage.
|
|
10473
|
+
*/
|
|
10474
|
+
applyColumnWidths(writer, table, columnIndexes, value) {
|
|
10475
|
+
if (isTableWidthInPixels(table)) applyPixelColumnWidths(writer, table, columnIndexes, value);
|
|
10476
|
+
else this._applyPercentageColumnWidths(writer, table, columnIndexes, value);
|
|
10477
|
+
}
|
|
10478
|
+
/**
|
|
10479
|
+
* Converts the column widths of a resized table to the unit of the table's own width (`px` or `%`), so a table
|
|
10480
|
+
* width change (in the table properties) also switches the columns' unit. It is a no-op when the table is not
|
|
10481
|
+
* resized or the columns already use that unit.
|
|
10482
|
+
*/
|
|
10483
|
+
_reconcileColumnUnits(writer, table) {
|
|
10484
|
+
const tableColumnGroup = getColumnGroupElement(table);
|
|
10485
|
+
if (!tableColumnGroup) return;
|
|
10486
|
+
const columnWidths = getTableColumnsWidths(tableColumnGroup);
|
|
10487
|
+
const tableIsPixels = isTableWidthInPixels(table);
|
|
10488
|
+
if (tableIsPixels === isColumnWidthsInPixels(columnWidths)) return;
|
|
10489
|
+
let reconciledWidths;
|
|
10490
|
+
if (tableIsPixels) {
|
|
10491
|
+
const tableWidthInPixels = parseFloat(table.getAttribute("tableWidth"));
|
|
10492
|
+
reconciledWidths = columnWidths.map((width) => `${toPrecision(parseFloat(width) / 100 * tableWidthInPixels)}px`);
|
|
10493
|
+
} else {
|
|
10494
|
+
const totalWidth = sumArray(columnWidths.map((width) => parseFloat(width)));
|
|
10495
|
+
reconciledWidths = columnWidths.map((width) => `${toPrecision(parseFloat(width) / totalWidth * 100)}%`);
|
|
10496
|
+
}
|
|
10497
|
+
updateColumnElements(getTableColumnElements(tableColumnGroup), tableColumnGroup, reconciledWidths, writer);
|
|
10498
|
+
}
|
|
10499
|
+
/**
|
|
10500
|
+
* Applies a column width in the percentage mode: the target column gets the (clamped) percentage and the remaining
|
|
10501
|
+
* columns are redistributed proportionally so that all the widths keep summing up to 100%.
|
|
10502
|
+
*/
|
|
10503
|
+
_applyPercentageColumnWidths(writer, table, columnIndexes, value) {
|
|
10504
|
+
const columns = getTableColumnElements(table);
|
|
10505
|
+
const widths = getTableColumnsWidths(table).map((width) => parseFloat(width));
|
|
10506
|
+
if (columnIndexes.includes(columns.length - 1)) {
|
|
10507
|
+
this._growTableToColumnWidths(writer, table, columns, widths, columnIndexes, value);
|
|
10508
|
+
return;
|
|
10509
|
+
}
|
|
10510
|
+
const targetPercentage = value.trim().endsWith("%") ? parseFloat(value) : parseFloat(value) / getTableWidthInPixels(table, this.editor) * 100;
|
|
10511
|
+
const nextWidths = widths.slice();
|
|
10512
|
+
for (const band of getContiguousBands(columnIndexes)) {
|
|
10513
|
+
const neighbor = band.end + 1;
|
|
10514
|
+
const bandCount = band.indexes.length;
|
|
10515
|
+
const available = band.indexes.reduce((sum, index) => sum + widths[index], widths[neighbor]);
|
|
10516
|
+
if (available < 5 * (bandCount + 1)) {
|
|
10517
|
+
const equalWidth = available / (bandCount + 1);
|
|
10518
|
+
for (const index of band.indexes) nextWidths[index] = equalWidth;
|
|
10519
|
+
nextWidths[neighbor] = equalWidth;
|
|
10520
|
+
continue;
|
|
10521
|
+
}
|
|
10522
|
+
const target = clamp(targetPercentage, 5, (available - 5) / bandCount);
|
|
10523
|
+
for (const index of band.indexes) nextWidths[index] = target;
|
|
10524
|
+
nextWidths[neighbor] = available - target * bandCount;
|
|
10525
|
+
}
|
|
10526
|
+
columns.forEach((columnElement, index) => {
|
|
10527
|
+
writer.setAttribute("columnWidth", `${toPrecision(nextWidths[index])}%`, columnElement);
|
|
10528
|
+
});
|
|
10529
|
+
}
|
|
10530
|
+
/**
|
|
10531
|
+
* Applies a width to the target columns in the percentage mode when the selection reaches the last column. As
|
|
10532
|
+
* there is no next column to balance against, the table itself grows or shrinks (like dragging the last column's
|
|
10533
|
+
* right edge): every other column keeps its absolute width, so expressed against the resized table their
|
|
10534
|
+
* percentages scale, and the table's own width scales by the inverse.
|
|
10535
|
+
*/
|
|
10536
|
+
_growTableToColumnWidths(writer, table, columns, widths, columnIndexes, value) {
|
|
10537
|
+
const targetColumns = new Set(columnIndexes);
|
|
10538
|
+
const targetCount = columnIndexes.length;
|
|
10539
|
+
const otherColumnsShare = 100 - columnIndexes.reduce((sum, index) => sum + widths[index], 0);
|
|
10540
|
+
if (otherColumnsShare <= 0) {
|
|
10541
|
+
const equalWidth = 100 / columns.length;
|
|
10542
|
+
columns.forEach((columnElement) => {
|
|
10543
|
+
writer.setAttribute("columnWidth", `${toPrecision(equalWidth)}%`, columnElement);
|
|
10544
|
+
});
|
|
10545
|
+
return;
|
|
10546
|
+
}
|
|
10547
|
+
let targetPercentage;
|
|
10548
|
+
if (value.trim().endsWith("%")) targetPercentage = parseFloat(value);
|
|
10549
|
+
else {
|
|
10550
|
+
const pixelWidth = parseFloat(value);
|
|
10551
|
+
targetPercentage = pixelWidth / (otherColumnsShare / 100 * getTableWidthInPixels(table, this.editor) + targetCount * pixelWidth) * 100;
|
|
10552
|
+
}
|
|
10553
|
+
const target = clamp(targetPercentage, 5, Math.max(5, (100 - 5 * (columns.length - targetCount)) / targetCount));
|
|
10554
|
+
const scale = (100 - target * targetCount) / otherColumnsShare;
|
|
10555
|
+
columns.forEach((columnElement, index) => {
|
|
10556
|
+
const next = targetColumns.has(index) ? target : widths[index] * scale;
|
|
10557
|
+
writer.setAttribute("columnWidth", `${toPrecision(next)}%`, columnElement);
|
|
10558
|
+
});
|
|
10559
|
+
const tableWidth = parseFloat(table.getAttribute("tableWidth"));
|
|
10560
|
+
if (!Number.isNaN(tableWidth)) writer.setAttribute("tableWidth", `${toPrecision(tableWidth / scale)}%`, table);
|
|
10561
|
+
}
|
|
10562
|
+
/**
|
|
10563
|
+
* Applies `width` to whichever element currently represents the table's actual width - by default the
|
|
10564
|
+
* widget's `<figure>`. Passing `null` clears it instead of setting anything.
|
|
10565
|
+
*
|
|
10566
|
+
* @internal
|
|
10567
|
+
*/
|
|
10568
|
+
_setResizingTableWidth(writer, viewFigure, width) {
|
|
10569
|
+
if (width === null) writer.removeStyle("width", viewFigure);
|
|
10570
|
+
else writer.setStyle("width", width, viewFigure);
|
|
10571
|
+
}
|
|
10572
|
+
/**
|
|
10573
|
+
* Returns the table's current actual width, read from whichever element holds it - by default the
|
|
10574
|
+
* widget's `<figure>`.
|
|
10575
|
+
*
|
|
10576
|
+
* @internal
|
|
10577
|
+
*/
|
|
10578
|
+
_getResizingTableWidth(viewFigure) {
|
|
10579
|
+
return viewFigure.getStyle("width");
|
|
10580
|
+
}
|
|
10581
|
+
/**
|
|
10245
10582
|
* Registers new attributes for a table model element.
|
|
10246
10583
|
*/
|
|
10247
10584
|
_extendSchema() {
|
|
@@ -10273,8 +10610,11 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10273
10610
|
const tableColumnGroup = this.getColumnGroupElement(table);
|
|
10274
10611
|
const columns = this.getTableColumnElements(tableColumnGroup);
|
|
10275
10612
|
const columnWidths = this.getTableColumnsWidths(tableColumnGroup);
|
|
10276
|
-
|
|
10613
|
+
const isPixelMode = isColumnWidthsInPixels(columnWidths);
|
|
10614
|
+
let normalizedWidths = isPixelMode ? normalizePixelColumnWidths(columnWidths, table) : normalizeColumnWidths(columnWidths);
|
|
10277
10615
|
normalizedWidths = adjustColumnWidths(normalizedWidths, table, this);
|
|
10616
|
+
if (isPixelMode && normalizedWidths.length !== columnWidths.length) writer.setAttribute("tableWidth", `${toPrecision(sumArray(normalizedWidths))}px`, table);
|
|
10617
|
+
else normalizedWidths = scalePixelColumnsToTableWidth(normalizedWidths, table);
|
|
10278
10618
|
if (isEqual(columnWidths, normalizedWidths)) continue;
|
|
10279
10619
|
updateColumnElements(columns, tableColumnGroup, normalizedWidths, writer);
|
|
10280
10620
|
changed = true;
|
|
@@ -10290,7 +10630,8 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10290
10630
|
function adjustColumnWidths(columnWidths, table, plugin) {
|
|
10291
10631
|
const newTableColumnsCount = plugin._tableUtilsPlugin.getColumns(table);
|
|
10292
10632
|
if (newTableColumnsCount - columnWidths.length === 0) return columnWidths;
|
|
10293
|
-
const
|
|
10633
|
+
const isPixelMode = isColumnWidthsInPixels(columnWidths);
|
|
10634
|
+
const widths = columnWidths.map((width) => parseFloat(width));
|
|
10294
10635
|
const cellSet = getAffectedCells(plugin.editor.model.document.differ, table);
|
|
10295
10636
|
for (const cell of cellSet) {
|
|
10296
10637
|
const currentColumnsDelta = newTableColumnsCount - widths.length;
|
|
@@ -10298,14 +10639,14 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10298
10639
|
const hasMoreColumns = currentColumnsDelta > 0;
|
|
10299
10640
|
const currentColumnIndex = plugin._tableUtilsPlugin.getCellLocation(cell).column;
|
|
10300
10641
|
if (hasMoreColumns) {
|
|
10301
|
-
const columnWidthsToInsert = createFilledArray(currentColumnsDelta, getColumnMinWidthAsPercentage(table, plugin.editor));
|
|
10642
|
+
const columnWidthsToInsert = createFilledArray(currentColumnsDelta, isPixelMode ? 40 : getColumnMinWidthAsPercentage(table, plugin.editor));
|
|
10302
10643
|
widths.splice(currentColumnIndex, 0, ...columnWidthsToInsert);
|
|
10303
10644
|
} else {
|
|
10304
10645
|
const removedColumnWidths = widths.splice(currentColumnIndex, Math.abs(currentColumnsDelta));
|
|
10305
10646
|
widths[currentColumnIndex] += sumArray(removedColumnWidths);
|
|
10306
10647
|
}
|
|
10307
10648
|
}
|
|
10308
|
-
return widths.map((width) => width
|
|
10649
|
+
return widths.map((width) => `${width}${isPixelMode ? "px" : "%"}`);
|
|
10309
10650
|
}
|
|
10310
10651
|
/**
|
|
10311
10652
|
* Returns a set of cells that have been changed in a given table.
|
|
@@ -10369,7 +10710,7 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10369
10710
|
key: "columnWidth",
|
|
10370
10711
|
value: (viewElement) => {
|
|
10371
10712
|
const viewColWidth = viewElement.getStyle("width");
|
|
10372
|
-
if (!viewColWidth || !viewColWidth.endsWith("%") && !viewColWidth.endsWith("pt")) return "auto";
|
|
10713
|
+
if (!viewColWidth || !viewColWidth.endsWith("%") && !viewColWidth.endsWith("pt") && !(viewColWidth.endsWith("px") && isViewTableWidthInPixels(viewElement))) return "auto";
|
|
10373
10714
|
return viewColWidth;
|
|
10374
10715
|
}
|
|
10375
10716
|
}
|
|
@@ -10490,13 +10831,18 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10490
10831
|
const { target } = domEventData;
|
|
10491
10832
|
const modelTable = this.editor.editing.mapper.toModelElement(target.findAncestor("figure"));
|
|
10492
10833
|
const viewTable = target.findAncestor("table");
|
|
10834
|
+
const viewFigure = target.findAncestor("figure");
|
|
10835
|
+
const isPixelMode = isTableWidthInPixels(modelTable);
|
|
10493
10836
|
const columnWidthsInPx = _calculateDomColumnWidths(modelTable, this._tableUtilsPlugin, this.editor);
|
|
10494
10837
|
if (!Array.from(viewTable.getChildren()).find((viewCol) => viewCol.is("element", "colgroup"))) this.editor.editing.view.change((viewWriter) => {
|
|
10495
|
-
_insertColgroupElement(viewWriter, columnWidthsInPx, viewTable);
|
|
10838
|
+
_insertColgroupElement(viewWriter, columnWidthsInPx, viewTable, isPixelMode);
|
|
10496
10839
|
});
|
|
10497
10840
|
this._isResizingActive = true;
|
|
10498
10841
|
this._resizingData = this._getResizingData(domEventData, columnWidthsInPx);
|
|
10499
|
-
this.editor.editing.view.change((writer) =>
|
|
10842
|
+
this.editor.editing.view.change((writer) => {
|
|
10843
|
+
const initialWidth = _applyResizingAttributesToTable(writer, viewTable, this._resizingData);
|
|
10844
|
+
this._setResizingTableWidth(writer, viewFigure, initialWidth);
|
|
10845
|
+
});
|
|
10500
10846
|
/**
|
|
10501
10847
|
* Calculates the DOM columns' widths. It is done by taking the width of the widest cell
|
|
10502
10848
|
* from each table column (we rely on the {@link module:table/tablewalker~TableWalker}
|
|
@@ -10524,28 +10870,29 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10524
10870
|
* @param columnWidthsInPx Column widths.
|
|
10525
10871
|
* @param viewTable A table view element.
|
|
10526
10872
|
*/
|
|
10527
|
-
function _insertColgroupElement(viewWriter, columnWidthsInPx, viewTable) {
|
|
10873
|
+
function _insertColgroupElement(viewWriter, columnWidthsInPx, viewTable, isPixelMode) {
|
|
10528
10874
|
const colgroup = viewWriter.createContainerElement("colgroup");
|
|
10529
10875
|
for (let i = 0; i < columnWidthsInPx.length; i++) {
|
|
10530
10876
|
const viewColElement = viewWriter.createEmptyElement("col");
|
|
10531
|
-
const
|
|
10532
|
-
viewWriter.setStyle("width",
|
|
10877
|
+
const columnWidth = isPixelMode ? `${toPrecision(columnWidthsInPx[i])}px` : `${toPrecision(columnWidthsInPx[i] / sumArray(columnWidthsInPx) * 100)}%`;
|
|
10878
|
+
viewWriter.setStyle("width", columnWidth, viewColElement);
|
|
10533
10879
|
viewWriter.insert(viewWriter.createPositionAt(colgroup, "end"), viewColElement);
|
|
10534
10880
|
}
|
|
10535
10881
|
viewWriter.insert(viewWriter.createPositionAt(viewTable, 0), colgroup);
|
|
10536
10882
|
}
|
|
10537
10883
|
/**
|
|
10538
|
-
* Applies the
|
|
10884
|
+
* Applies the classes to the view table as the resizing begun, and computes the initial live width.
|
|
10539
10885
|
*
|
|
10540
10886
|
* @param viewWriter A writer instance.
|
|
10541
10887
|
* @param viewTable A table containing the clicked resizer.
|
|
10542
10888
|
* @param resizingData Data related to the resizing.
|
|
10889
|
+
* @returns The table's current width as a `%` string, e.g. for seeding {@link #_setResizingTableWidth}.
|
|
10543
10890
|
*/
|
|
10544
10891
|
function _applyResizingAttributesToTable(viewWriter, viewTable, resizingData) {
|
|
10545
|
-
const figureInitialPcWidth = resizingData.widths.viewFigureWidth / resizingData.widths.viewFigureParentWidth;
|
|
10546
10892
|
viewWriter.addClass("ck-table-resized", viewTable);
|
|
10547
10893
|
viewWriter.addClass("ck-table-column-resizer__active", resizingData.elements.viewResizer);
|
|
10548
|
-
|
|
10894
|
+
const figureWidth = Math.max(resizingData.widths.tableWidth, resizingData.widths.viewFigureWidth);
|
|
10895
|
+
return resizingData.flags.isPixelMode ? `${toPrecision(figureWidth)}px` : `${toPrecision(figureWidth / resizingData.widths.viewFigureParentWidth * 100)}%`;
|
|
10549
10896
|
}
|
|
10550
10897
|
}
|
|
10551
10898
|
/**
|
|
@@ -10570,22 +10917,40 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10570
10917
|
this._onMouseUpHandler();
|
|
10571
10918
|
return;
|
|
10572
10919
|
}
|
|
10573
|
-
const {
|
|
10920
|
+
const { plugins } = this.editor;
|
|
10921
|
+
const { columnPosition, flags: { isRightEdge, isTableCentered, isLtrContent, isPixelMode, isTableWidthWithinContainerAtDragStart, isTableScrollAllowed }, elements: { modelTable, viewFigure, viewLeftColumn, viewRightColumn, viewResizer }, widths: { viewFigureParentWidth, tableWidth, leftColumnWidth, rightColumnWidth } } = this._resizingData;
|
|
10574
10922
|
const dxLowerBound = -leftColumnWidth + 40;
|
|
10575
|
-
const
|
|
10576
|
-
const
|
|
10577
|
-
|
|
10923
|
+
const isTableScrollActive = !!(plugins.has("TableScrollEditing") ? plugins.get("TableScrollEditing") : null) && isTableScrollAllowed;
|
|
10924
|
+
const containerWidth = getEditableWidth(this.editor, modelTable.root.rootName);
|
|
10925
|
+
let dxUpperBound;
|
|
10926
|
+
if (isRightEdge) dxUpperBound = isTableScrollActive ? Infinity : viewFigureParentWidth - tableWidth;
|
|
10927
|
+
else dxUpperBound = rightColumnWidth - 40;
|
|
10928
|
+
const rawDx = mouseEventData.clientX - columnPosition;
|
|
10929
|
+
const ltrSign = isLtrContent ? 1 : -1;
|
|
10930
|
+
const isCenteredRightEdge = isRightEdge && isTableCentered;
|
|
10931
|
+
let dx;
|
|
10932
|
+
if (isTableScrollActive && isCenteredRightEdge) {
|
|
10933
|
+
const mouseDelta = rawDx * ltrSign;
|
|
10934
|
+
let newTableWidth;
|
|
10935
|
+
if (isTableWidthWithinContainerAtDragStart) {
|
|
10936
|
+
const crossoverPoint = (containerWidth - tableWidth) / 2;
|
|
10937
|
+
newTableWidth = mouseDelta <= crossoverPoint ? tableWidth + 2 * mouseDelta : containerWidth + (mouseDelta - crossoverPoint);
|
|
10938
|
+
} else {
|
|
10939
|
+
const crossoverPoint = containerWidth - tableWidth;
|
|
10940
|
+
newTableWidth = mouseDelta >= crossoverPoint ? tableWidth + mouseDelta : containerWidth + 2 * (mouseDelta - crossoverPoint);
|
|
10941
|
+
}
|
|
10942
|
+
dx = newTableWidth - tableWidth;
|
|
10943
|
+
} else dx = rawDx * (ltrSign * (isCenteredRightEdge ? 2 : 1));
|
|
10944
|
+
dx = clamp(dx, Math.min(dxLowerBound, 0), Math.max(dxUpperBound, 0));
|
|
10945
|
+
if (isTableScrollActive && isRightEdge) dx = clamp(applyContainerWidthResistance(tableWidth + dx, containerWidth) - tableWidth, Math.min(dxLowerBound, 0), Math.max(dxUpperBound, 0));
|
|
10578
10946
|
if (dx === 0) return;
|
|
10579
10947
|
this.editor.editing.view.change((writer) => {
|
|
10580
|
-
const
|
|
10581
|
-
writer.setStyle("width",
|
|
10948
|
+
const toWidthValue = (widthInPx, basisInPx) => isPixelMode ? `${toPrecision(widthInPx)}px` : `${toPrecision(widthInPx * 100 / basisInPx)}%`;
|
|
10949
|
+
writer.setStyle("width", toWidthValue(leftColumnWidth + dx, tableWidth), viewLeftColumn);
|
|
10582
10950
|
if (isRightEdge) {
|
|
10583
|
-
const
|
|
10584
|
-
|
|
10585
|
-
} else
|
|
10586
|
-
const rightColumnWidthAsPercentage = toPrecision((rightColumnWidth - dx) * 100 / tableWidth);
|
|
10587
|
-
writer.setStyle("width", `${rightColumnWidthAsPercentage}%`, viewRightColumn);
|
|
10588
|
-
}
|
|
10951
|
+
const tableFigureWidth = isPixelMode ? `${toPrecision(tableWidth + dx)}px` : `${toPrecision((tableWidth + dx) * 100 / viewFigureParentWidth)}%`;
|
|
10952
|
+
this._setResizingTableWidth(writer, viewFigure, tableFigureWidth);
|
|
10953
|
+
} else writer.setStyle("width", toWidthValue(rightColumnWidth - dx, tableWidth), viewRightColumn);
|
|
10589
10954
|
});
|
|
10590
10955
|
this._recalculateResizerElement(viewResizer);
|
|
10591
10956
|
}
|
|
@@ -10598,7 +10963,8 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10598
10963
|
_onMouseUpHandler() {
|
|
10599
10964
|
this._initialMouseEventData = null;
|
|
10600
10965
|
if (!this._isResizingActive) return;
|
|
10601
|
-
const { viewResizer, modelTable, viewFigure, viewColgroup } = this._resizingData.elements;
|
|
10966
|
+
const { viewResizer, modelTable, viewFigure, viewTable, viewColgroup } = this._resizingData.elements;
|
|
10967
|
+
const { isPixelMode } = this._resizingData.flags;
|
|
10602
10968
|
const editor = this.editor;
|
|
10603
10969
|
const editingView = editor.editing.view;
|
|
10604
10970
|
const tableColumnGroup = this.getColumnGroupElement(modelTable);
|
|
@@ -10607,19 +10973,22 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10607
10973
|
const columnWidthsAttributeNew = viewColumns.map((column) => column.getStyle("width"));
|
|
10608
10974
|
const isColumnWidthsAttributeChanged = !isEqual(columnWidthsAttributeOld, columnWidthsAttributeNew);
|
|
10609
10975
|
const tableWidthAttributeOld = modelTable.getAttribute("tableWidth");
|
|
10610
|
-
const tableWidthAttributeNew =
|
|
10976
|
+
const tableWidthAttributeNew = this._getResizingTableWidth(viewFigure);
|
|
10611
10977
|
const isTableWidthAttributeChanged = tableWidthAttributeOld !== tableWidthAttributeNew;
|
|
10612
|
-
if (isColumnWidthsAttributeChanged || isTableWidthAttributeChanged) if (this._isResizingAllowed)
|
|
10613
|
-
|
|
10614
|
-
|
|
10615
|
-
columnWidths: columnWidthsAttributeNew
|
|
10616
|
-
|
|
10617
|
-
|
|
10978
|
+
if (isColumnWidthsAttributeChanged || isTableWidthAttributeChanged) if (this._isResizingAllowed) {
|
|
10979
|
+
const tableWidthInPixels = toPrecision(tableWidthAttributeNew);
|
|
10980
|
+
const tableWidthInPixelsBeforeResize = toPrecision(tableWidthAttributeOld);
|
|
10981
|
+
const columnWidths = isPixelMode ? columnWidthsAttributeNew.map((width) => typeof width === "string" && !width.endsWith("px") ? `${toPrecision(parseFloat(width) / 100 * tableWidthInPixelsBeforeResize)}px` : width) : columnWidthsAttributeNew;
|
|
10982
|
+
editor.execute("resizeTableWidth", {
|
|
10983
|
+
table: modelTable,
|
|
10984
|
+
tableWidth: isPixelMode ? `${toPrecision(tableWidthInPixels)}px` : `${toPrecision(tableWidthAttributeNew)}%`,
|
|
10985
|
+
columnWidths
|
|
10986
|
+
});
|
|
10987
|
+
} else editingView.change((writer) => {
|
|
10618
10988
|
if (columnWidthsAttributeOld) for (const viewCol of viewColumns) writer.setStyle("width", columnWidthsAttributeOld.shift(), viewCol);
|
|
10619
10989
|
else writer.remove(viewColgroup);
|
|
10620
|
-
if (isTableWidthAttributeChanged)
|
|
10621
|
-
|
|
10622
|
-
if (!columnWidthsAttributeOld && !tableWidthAttributeOld) writer.removeClass("ck-table-resized", [...viewFigure.getChildren()].find((element) => element.name === "table"));
|
|
10990
|
+
if (isTableWidthAttributeChanged) this._setResizingTableWidth(writer, viewFigure, tableWidthAttributeOld || null);
|
|
10991
|
+
if (!columnWidthsAttributeOld && !tableWidthAttributeOld) writer.removeClass("ck-table-resized", viewTable);
|
|
10623
10992
|
});
|
|
10624
10993
|
editingView.change((writer) => {
|
|
10625
10994
|
writer.removeClass("ck-table-column-resizer__active", viewResizer);
|
|
@@ -10652,6 +11021,7 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10652
11021
|
const isRightEdge = leftColumnIndex === lastColumnIndex;
|
|
10653
11022
|
const isLtrContent = editor.locale.contentLanguageDirection !== "rtl";
|
|
10654
11023
|
const isTableCentered = tableAlignment === "center";
|
|
11024
|
+
const isPixelMode = isTableWidthInPixels(modelTable);
|
|
10655
11025
|
const viewTable = viewLeftCell.findAncestor("table");
|
|
10656
11026
|
const viewFigure = viewTable.findAncestor("figure");
|
|
10657
11027
|
const viewColgroup = [...viewTable.getChildren()].find((viewCol) => viewCol.is("element", "colgroup"));
|
|
@@ -10662,24 +11032,30 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10662
11032
|
const tableWidth = getTableWidthInPixels(modelTable, editor);
|
|
10663
11033
|
const leftColumnWidth = columnWidths[leftColumnIndex];
|
|
10664
11034
|
const rightColumnWidth = isRightEdge ? void 0 : columnWidths[leftColumnIndex + 1];
|
|
11035
|
+
const isTableWidthWithinContainerAtDragStart = tableWidth <= getEditableWidth(editor, modelTable.root.rootName);
|
|
11036
|
+
const tableScrollPlugin = editor.plugins.has("TableScrollEditing") ? editor.plugins.get("TableScrollEditing") : null;
|
|
10665
11037
|
return {
|
|
10666
11038
|
columnPosition,
|
|
10667
11039
|
flags: {
|
|
10668
11040
|
isRightEdge,
|
|
10669
11041
|
isTableCentered,
|
|
10670
|
-
isLtrContent
|
|
11042
|
+
isLtrContent,
|
|
11043
|
+
isPixelMode,
|
|
11044
|
+
isTableWidthWithinContainerAtDragStart,
|
|
11045
|
+
isTableScrollAllowed: !!tableScrollPlugin && tableScrollPlugin._isTableScrollable(modelTable)
|
|
10671
11046
|
},
|
|
10672
11047
|
elements: {
|
|
10673
11048
|
viewResizer,
|
|
10674
11049
|
modelTable,
|
|
10675
11050
|
viewFigure,
|
|
11051
|
+
viewTable,
|
|
10676
11052
|
viewColgroup,
|
|
10677
11053
|
viewLeftColumn,
|
|
10678
11054
|
viewRightColumn
|
|
10679
11055
|
},
|
|
10680
11056
|
widths: {
|
|
10681
|
-
viewFigureParentWidth,
|
|
10682
11057
|
viewFigureWidth,
|
|
11058
|
+
viewFigureParentWidth,
|
|
10683
11059
|
tableWidth,
|
|
10684
11060
|
leftColumnWidth,
|
|
10685
11061
|
rightColumnWidth
|
|
@@ -10700,6 +11076,104 @@ var TableColumnResizeEditing = class extends Plugin {
|
|
|
10700
11076
|
});
|
|
10701
11077
|
}
|
|
10702
11078
|
};
|
|
11079
|
+
/**
|
|
11080
|
+
* Tells whether the table wrapping the given view `<col>` element is sized in pixels. The width is read from the
|
|
11081
|
+
* column's own table (or its wrapping `<figure>`), never from an ancestor further up, so a width-less table nested
|
|
11082
|
+
* inside a wider one is not mistaken for a pixel table.
|
|
11083
|
+
*/
|
|
11084
|
+
function isViewTableWidthInPixels(viewColElement) {
|
|
11085
|
+
const viewTable = viewColElement.findAncestor((element) => element.is("element", "table"));
|
|
11086
|
+
const viewParent = viewTable.parent;
|
|
11087
|
+
const width = (viewParent.is("element", "figure") ? viewParent : viewTable).getStyle("width");
|
|
11088
|
+
return typeof width === "string" && width.trim().endsWith("px");
|
|
11089
|
+
}
|
|
11090
|
+
/**
|
|
11091
|
+
* In the pixel mode keeps the sum of the column widths equal to the table width. If they differ (for example after a
|
|
11092
|
+
* manual table width change), the columns are scaled proportionally so that they sum up to the table width. In the
|
|
11093
|
+
* percentage mode (or when the columns already sum to the table width) it is a no-op.
|
|
11094
|
+
*/
|
|
11095
|
+
function scalePixelColumnsToTableWidth(columnWidths, table) {
|
|
11096
|
+
if (!isTableWidthInPixels(table) || !isColumnWidthsInPixels(columnWidths)) return columnWidths;
|
|
11097
|
+
const tableWidthInPixels = parseFloat(table.getAttribute("tableWidth"));
|
|
11098
|
+
const totalWidth = sumArray(columnWidths);
|
|
11099
|
+
if (!totalWidth || Math.abs(totalWidth - tableWidthInPixels) < .5) return columnWidths;
|
|
11100
|
+
const factor = tableWidthInPixels / totalWidth;
|
|
11101
|
+
return columnWidths.map((width) => `${toPrecision(parseFloat(width) * factor)}px`);
|
|
11102
|
+
}
|
|
11103
|
+
/**
|
|
11104
|
+
* Normalizes a pixel-mode column group to concrete pixel widths. It mirrors {@link ~normalizeColumnWidths} (the
|
|
11105
|
+
* percentage path): percentages are resolved against the table width, and missing (`auto`/`undefined`) columns are
|
|
11106
|
+
* filled from the width left over in the table - so the column group never keeps `auto` widths or mixes units, and
|
|
11107
|
+
* downstream arithmetic never sees a non-pixel value.
|
|
11108
|
+
*/
|
|
11109
|
+
function normalizePixelColumnWidths(columnWidths, table) {
|
|
11110
|
+
const tableWidthInPixels = parseFloat(table.getAttribute("tableWidth"));
|
|
11111
|
+
const pixelWidths = columnWidths.map((width) => {
|
|
11112
|
+
if (width === "auto" || width === void 0) return null;
|
|
11113
|
+
return width.endsWith("%") ? parseFloat(width) / 100 * tableWidthInPixels : parseFloat(width);
|
|
11114
|
+
});
|
|
11115
|
+
const missingColumns = pixelWidths.filter((width) => width === null).length;
|
|
11116
|
+
if (missingColumns) {
|
|
11117
|
+
const knownWidth = pixelWidths.reduce((sum, width) => width === null ? sum : sum + width, 0);
|
|
11118
|
+
const widthForMissingColumn = Math.max((tableWidthInPixels - knownWidth) / missingColumns, 40);
|
|
11119
|
+
return pixelWidths.map((width) => `${toPrecision(width === null ? widthForMissingColumn : width)}px`);
|
|
11120
|
+
}
|
|
11121
|
+
return pixelWidths.map((width) => `${toPrecision(width)}px`);
|
|
11122
|
+
}
|
|
11123
|
+
/**
|
|
11124
|
+
* Applies a column width in the pixel mode: the target column gets the absolute width and the table's own width
|
|
11125
|
+
* grows or shrinks to the sum of all column widths.
|
|
11126
|
+
*/
|
|
11127
|
+
function applyPixelColumnWidths(writer, table, columnIndexes, value) {
|
|
11128
|
+
const columns = getTableColumnElements(table);
|
|
11129
|
+
const tableWidthInPixels = parseFloat(table.getAttribute("tableWidth"));
|
|
11130
|
+
const toPixels = (width) => width.trim().endsWith("%") ? parseFloat(width) / 100 * tableWidthInPixels : parseFloat(width);
|
|
11131
|
+
const targetPixels = Math.max(toPixels(value), 40);
|
|
11132
|
+
const widths = getTableColumnsWidths(table).map(toPixels);
|
|
11133
|
+
for (const index of columnIndexes) widths[index] = targetPixels;
|
|
11134
|
+
const roundedWidths = widths.map((width) => toPrecision(width));
|
|
11135
|
+
columns.forEach((columnElement, index) => {
|
|
11136
|
+
writer.setAttribute("columnWidth", `${roundedWidths[index]}px`, columnElement);
|
|
11137
|
+
});
|
|
11138
|
+
writer.setAttribute("tableWidth", `${toPrecision(sumArray(roundedWidths))}px`, table);
|
|
11139
|
+
}
|
|
11140
|
+
/**
|
|
11141
|
+
* Splits a sorted list of column indexes into maximal contiguous bands, for example `[ 0, 1, 3 ]` into `[ 0, 1 ]`
|
|
11142
|
+
* and `[ 3 ]`.
|
|
11143
|
+
*/
|
|
11144
|
+
function getContiguousBands(columnIndexes) {
|
|
11145
|
+
const bands = [];
|
|
11146
|
+
for (const index of columnIndexes) {
|
|
11147
|
+
const lastBand = bands[bands.length - 1];
|
|
11148
|
+
if (lastBand && index === lastBand.end + 1) {
|
|
11149
|
+
lastBand.indexes.push(index);
|
|
11150
|
+
lastBand.end = index;
|
|
11151
|
+
} else bands.push({
|
|
11152
|
+
indexes: [index],
|
|
11153
|
+
end: index
|
|
11154
|
+
});
|
|
11155
|
+
}
|
|
11156
|
+
return bands;
|
|
11157
|
+
}
|
|
11158
|
+
/**
|
|
11159
|
+
* Given the table width a drag would naturally produce, returns the width that should actually be applied
|
|
11160
|
+
* once snapping and growth resistance around the container's width are taken into account:
|
|
11161
|
+
*
|
|
11162
|
+
* * if the natural width lands close to the container's width (on either side), it's pulled to exactly
|
|
11163
|
+
* match it,
|
|
11164
|
+
* * if the natural width is past the container's width, it stays pinned at the container's width until the
|
|
11165
|
+
* drag has gone far enough beyond it (the "resistance" zone) - past that point it keeps growing 1:1,
|
|
11166
|
+
* continuing smoothly from where the resistance was overcome instead of jumping,
|
|
11167
|
+
* * shrinking below the container's width is never resisted, only snapped when close.
|
|
11168
|
+
*
|
|
11169
|
+
* @internal
|
|
11170
|
+
*/
|
|
11171
|
+
function applyContainerWidthResistance(naturalTableWidth, containerWidth) {
|
|
11172
|
+
const distance = naturalTableWidth - containerWidth;
|
|
11173
|
+
if (distance < 0) return -distance <= 5 ? containerWidth : naturalTableWidth;
|
|
11174
|
+
const resistanceZone = 5 + 10;
|
|
11175
|
+
return distance <= resistanceZone ? containerWidth : containerWidth + (distance - resistanceZone);
|
|
11176
|
+
}
|
|
10703
11177
|
|
|
10704
11178
|
/**
|
|
10705
11179
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -10920,7 +11394,9 @@ var TableLayoutEditing = class extends Plugin {
|
|
|
10920
11394
|
}
|
|
10921
11395
|
}
|
|
10922
11396
|
if (entry.type == "attribute" && entry.attributeKey == "tableType") {
|
|
10923
|
-
for (const item of entry.range.getItems())
|
|
11397
|
+
for (const item of entry.range.getItems())
|
|
11398
|
+
/* v8 ignore else -- `tableType` is only ever set on a single `table`, so the range holds no other items. */
|
|
11399
|
+
if (item.is("element", "table")) {
|
|
10924
11400
|
editor.model.schema.removeDisallowedAttributes([item], writer);
|
|
10925
11401
|
const tableChildren = item.getChildren();
|
|
10926
11402
|
for (const child of tableChildren) if (!editor.model.schema.checkChild(item, child)) {
|
|
@@ -11736,8 +12212,13 @@ function upcastTableAlignedDiv(defaultValue) {
|
|
|
11736
12212
|
name: true,
|
|
11737
12213
|
attributes: "align"
|
|
11738
12214
|
})) return;
|
|
11739
|
-
const
|
|
11740
|
-
|
|
12215
|
+
const significantChildren = Array.from(data.viewItem.getChildren()).filter((child) => {
|
|
12216
|
+
if (child.is("$text") || child.is("$textProxy")) return child.data.trim() !== "";
|
|
12217
|
+
return true;
|
|
12218
|
+
});
|
|
12219
|
+
if (significantChildren.length !== 1 || !significantChildren[0].is("element", "table")) return;
|
|
12220
|
+
const [viewTable] = significantChildren;
|
|
12221
|
+
if (!conversionApi.consumable.test(viewTable, { name: true })) return;
|
|
11741
12222
|
conversionApi.consumable.consume(data.viewItem, {
|
|
11742
12223
|
name: true,
|
|
11743
12224
|
attributes: "align"
|
|
@@ -11757,7 +12238,6 @@ function upcastTableAlignedDiv(defaultValue) {
|
|
|
11757
12238
|
}
|
|
11758
12239
|
const align = convertToTableAlignment(data.viewItem.getAttribute("align"), viewTable.getAttribute("align"), getDefaultValueAdjusted(defaultValue, "", data));
|
|
11759
12240
|
if (align) conversionApi.writer.setAttribute("tableAlignment", align, modelTable);
|
|
11760
|
-
conversionApi.convertChildren(data.viewItem, conversionApi.writer.createPositionAt(modelTable, "end"));
|
|
11761
12241
|
conversionApi.updateConversionResult(modelTable, data);
|
|
11762
12242
|
});
|
|
11763
12243
|
};
|
|
@@ -13076,10 +13556,378 @@ var TableCaption = class extends Plugin {
|
|
|
13076
13556
|
}
|
|
13077
13557
|
};
|
|
13078
13558
|
|
|
13559
|
+
/**
|
|
13560
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
13561
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
13562
|
+
*/
|
|
13563
|
+
/**
|
|
13564
|
+
* @module table/tablescroll/watchers
|
|
13565
|
+
*/
|
|
13566
|
+
/**
|
|
13567
|
+
* Creates a live collection of all `table` model elements present in the document and keeps it
|
|
13568
|
+
* up to date as tables are inserted, moved, or removed.
|
|
13569
|
+
*
|
|
13570
|
+
* @internal
|
|
13571
|
+
*/
|
|
13572
|
+
function watchTableModelElements(model) {
|
|
13573
|
+
const tables = new Collection();
|
|
13574
|
+
model.document.on("change", () => {
|
|
13575
|
+
const documentChanges = model.document.differ.getChanges();
|
|
13576
|
+
const insertedTables = /* @__PURE__ */ new Set();
|
|
13577
|
+
const movedTables = /* @__PURE__ */ new Set();
|
|
13578
|
+
for (const change of documentChanges) if (change.type === "insert" && change.name !== "$text" && change.position.nodeAfter) {
|
|
13579
|
+
const range = model.createRangeOn(change.position.nodeAfter);
|
|
13580
|
+
for (const item of range.getItems()) {
|
|
13581
|
+
if (!item.is("element", "table")) continue;
|
|
13582
|
+
if (tables.has(item)) movedTables.add(item);
|
|
13583
|
+
else insertedTables.add(item);
|
|
13584
|
+
}
|
|
13585
|
+
}
|
|
13586
|
+
for (const table of Array.from(tables)) {
|
|
13587
|
+
if (table.root.rootName !== "$graveyard") continue;
|
|
13588
|
+
insertedTables.delete(table);
|
|
13589
|
+
movedTables.delete(table);
|
|
13590
|
+
if (tables.has(table)) tables.remove(table);
|
|
13591
|
+
}
|
|
13592
|
+
for (const table of movedTables)
|
|
13593
|
+
/* v8 ignore else -- @preserve */
|
|
13594
|
+
if (tables.has(table)) tables.remove(table);
|
|
13595
|
+
if (insertedTables.size || movedTables.size) tables.addMany([...insertedTables, ...movedTables]);
|
|
13596
|
+
});
|
|
13597
|
+
return tables;
|
|
13598
|
+
}
|
|
13599
|
+
/**
|
|
13600
|
+
* Observes the DOM width of every editing root and calls `onResize` whenever any of them changes width.
|
|
13601
|
+
* Height-only changes are ignored, since only a root's width can make a table overflow it.
|
|
13602
|
+
*
|
|
13603
|
+
* @internal
|
|
13604
|
+
*/
|
|
13605
|
+
function watchRootsWidthResize(view, onResize) {
|
|
13606
|
+
const { roots } = view.document;
|
|
13607
|
+
const observedRoots = /* @__PURE__ */ new Map();
|
|
13608
|
+
const lastKnownWidths = /* @__PURE__ */ new Map();
|
|
13609
|
+
const attachRoot = (rootName) => {
|
|
13610
|
+
if (observedRoots.has(rootName)) return;
|
|
13611
|
+
const domRoot = view.getDomRoot(rootName);
|
|
13612
|
+
if (!domRoot) return;
|
|
13613
|
+
const observer = new ResizeObserver((entries) => {
|
|
13614
|
+
for (const entry of entries) {
|
|
13615
|
+
const width = entry.contentRect.width;
|
|
13616
|
+
if (lastKnownWidths.get(rootName) === width) continue;
|
|
13617
|
+
lastKnownWidths.set(rootName, width);
|
|
13618
|
+
onResize();
|
|
13619
|
+
}
|
|
13620
|
+
});
|
|
13621
|
+
observer.observe(domRoot);
|
|
13622
|
+
observedRoots.set(rootName, observer);
|
|
13623
|
+
};
|
|
13624
|
+
const detachRoot = (rootName) => {
|
|
13625
|
+
const observer = observedRoots.get(rootName);
|
|
13626
|
+
if (observer) {
|
|
13627
|
+
observer.disconnect();
|
|
13628
|
+
observedRoots.delete(rootName);
|
|
13629
|
+
lastKnownWidths.delete(rootName);
|
|
13630
|
+
}
|
|
13631
|
+
};
|
|
13632
|
+
const onRootAdd = (evt, viewRoot) => attachRoot(viewRoot.rootName);
|
|
13633
|
+
const onRootRemove = (evt, viewRoot) => detachRoot(viewRoot.rootName);
|
|
13634
|
+
const attachAllRoots = () => {
|
|
13635
|
+
for (const root of roots) attachRoot(root.rootName);
|
|
13636
|
+
};
|
|
13637
|
+
attachAllRoots();
|
|
13638
|
+
roots.on("add", onRootAdd);
|
|
13639
|
+
roots.on("remove", onRootRemove);
|
|
13640
|
+
view.on("render", attachAllRoots);
|
|
13641
|
+
return () => {
|
|
13642
|
+
roots.off("add", onRootAdd);
|
|
13643
|
+
roots.off("remove", onRootRemove);
|
|
13644
|
+
view.off("render", attachAllRoots);
|
|
13645
|
+
for (const observer of observedRoots.values()) observer.disconnect();
|
|
13646
|
+
observedRoots.clear();
|
|
13647
|
+
lastKnownWidths.clear();
|
|
13648
|
+
};
|
|
13649
|
+
}
|
|
13650
|
+
|
|
13651
|
+
/**
|
|
13652
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
13653
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
13654
|
+
*/
|
|
13655
|
+
/**
|
|
13656
|
+
* @module table/tablescroll/tablescrollediting
|
|
13657
|
+
*/
|
|
13658
|
+
/**
|
|
13659
|
+
* The table scrolling editing plugin.
|
|
13660
|
+
*/
|
|
13661
|
+
var TableScrollEditing = class extends Plugin {
|
|
13662
|
+
/**
|
|
13663
|
+
* Used to listen to native DOM events.
|
|
13664
|
+
*/
|
|
13665
|
+
_domEmitter = new (DomEmitterMixin())();
|
|
13666
|
+
/**
|
|
13667
|
+
* @inheritDoc
|
|
13668
|
+
*/
|
|
13669
|
+
static get pluginName() {
|
|
13670
|
+
return "TableScrollEditing";
|
|
13671
|
+
}
|
|
13672
|
+
/**
|
|
13673
|
+
* @inheritDoc
|
|
13674
|
+
*/
|
|
13675
|
+
static get isOfficialPlugin() {
|
|
13676
|
+
return true;
|
|
13677
|
+
}
|
|
13678
|
+
/**
|
|
13679
|
+
* @inheritDoc
|
|
13680
|
+
*/
|
|
13681
|
+
static get requires() {
|
|
13682
|
+
return [TableEditing];
|
|
13683
|
+
}
|
|
13684
|
+
/**
|
|
13685
|
+
* @inheritDoc
|
|
13686
|
+
*/
|
|
13687
|
+
constructor(editor) {
|
|
13688
|
+
super(editor);
|
|
13689
|
+
editor.config.define("table.tableScroll.tableTypes", ["content"]);
|
|
13690
|
+
}
|
|
13691
|
+
/**
|
|
13692
|
+
* @inheritDoc
|
|
13693
|
+
*/
|
|
13694
|
+
init() {
|
|
13695
|
+
const { editor } = this;
|
|
13696
|
+
const tables = watchTableModelElements(editor.model);
|
|
13697
|
+
this._watchNewTables(tables);
|
|
13698
|
+
this._watchRootEditables(tables);
|
|
13699
|
+
this._registerConversion();
|
|
13700
|
+
this._watchColumnResize();
|
|
13701
|
+
this._watchFiguresScroll();
|
|
13702
|
+
}
|
|
13703
|
+
/**
|
|
13704
|
+
* @inheritDoc
|
|
13705
|
+
*/
|
|
13706
|
+
destroy() {
|
|
13707
|
+
this._domEmitter.stopListening();
|
|
13708
|
+
super.destroy();
|
|
13709
|
+
}
|
|
13710
|
+
/**
|
|
13711
|
+
* Whether a given table may overflow its container and become horizontally scrollable, and whether
|
|
13712
|
+
* column/table resizing is allowed to grow it past the container's width.
|
|
13713
|
+
*
|
|
13714
|
+
* @internal
|
|
13715
|
+
*/
|
|
13716
|
+
_isTableScrollable(table) {
|
|
13717
|
+
if (table.parent !== table.root) return false;
|
|
13718
|
+
const tableType = table.getAttribute("tableType") || "content";
|
|
13719
|
+
return this.editor.config.get("table.tableScroll.tableTypes").includes(tableType);
|
|
13720
|
+
}
|
|
13721
|
+
/**
|
|
13722
|
+
* Determines whether a table overflows its container and applies the corresponding view state:
|
|
13723
|
+
* the `ck-table-overflowing` class on the figure, and the actual (possibly container-exceeding)
|
|
13724
|
+
* width on the inner `<table>` and a sibling `<figcaption>`, if present.
|
|
13725
|
+
*
|
|
13726
|
+
* @internal
|
|
13727
|
+
*/
|
|
13728
|
+
_updateTableScrollOverflowState(table, tableWidthOverride) {
|
|
13729
|
+
const { editor } = this;
|
|
13730
|
+
const containerWidth = getEditableWidth(editor, table.root.rootName);
|
|
13731
|
+
if (containerWidth === null) return;
|
|
13732
|
+
const viewFigure = editor.editing.mapper.toViewElement(table);
|
|
13733
|
+
if (!viewFigure) return;
|
|
13734
|
+
const viewTable = findChildElement(viewFigure, "table");
|
|
13735
|
+
if (!viewTable) return;
|
|
13736
|
+
const viewFigcaption = findChildElement(viewFigure, "figcaption");
|
|
13737
|
+
let tableWidth = null;
|
|
13738
|
+
let hasTableWidthSource = false;
|
|
13739
|
+
if (tableWidthOverride !== void 0) {
|
|
13740
|
+
tableWidth = tableWidthOverride;
|
|
13741
|
+
hasTableWidthSource = true;
|
|
13742
|
+
} else if (table.hasAttribute("tableWidth")) {
|
|
13743
|
+
tableWidth = table.getAttribute("tableWidth");
|
|
13744
|
+
hasTableWidthSource = true;
|
|
13745
|
+
}
|
|
13746
|
+
if (!hasTableWidthSource) return;
|
|
13747
|
+
const isOverflowing = !!tableWidth && this._isTableScrollable(table) && isTableWidthOverflowing(tableWidth, containerWidth);
|
|
13748
|
+
if (isOverflowing) this._scheduleScrollOffsetSync(viewFigure);
|
|
13749
|
+
editor.editing.view.change((writer) => {
|
|
13750
|
+
if (isOverflowing) {
|
|
13751
|
+
writer.removeStyle("width", viewFigure);
|
|
13752
|
+
writer.addClass("ck-table-overflowing", viewFigure);
|
|
13753
|
+
writer.setStyle("width", tableWidth, viewTable);
|
|
13754
|
+
if (viewFigcaption) writer.setStyle("width", tableWidth, viewFigcaption);
|
|
13755
|
+
} else {
|
|
13756
|
+
if (tableWidth) writer.setStyle("width", tableWidth, viewFigure);
|
|
13757
|
+
else writer.removeStyle("width", viewFigure);
|
|
13758
|
+
if (viewFigcaption) writer.removeStyle("width", viewFigcaption);
|
|
13759
|
+
writer.removeClass("ck-table-overflowing", viewFigure);
|
|
13760
|
+
writer.removeStyle("width", viewTable);
|
|
13761
|
+
writer.removeStyle("--ck-table-scroll-offset", viewFigure);
|
|
13762
|
+
}
|
|
13763
|
+
});
|
|
13764
|
+
}
|
|
13765
|
+
/**
|
|
13766
|
+
* Schedules a re-read of the widget figure's actual `scrollLeft` into `--ck-table-scroll-offset`, once
|
|
13767
|
+
* the render reflecting the change that triggered it has actually happened - see the call site for why
|
|
13768
|
+
* this can't just read (and force a reflow for) `scrollLeft` immediately instead.
|
|
13769
|
+
*/
|
|
13770
|
+
_scheduleScrollOffsetSync(viewFigure) {
|
|
13771
|
+
const { view } = this.editor.editing;
|
|
13772
|
+
view.once("render", () => {
|
|
13773
|
+
const domFigure = view.domConverter.mapViewToDom(viewFigure);
|
|
13774
|
+
/* v8 ignore else -- @preserve */
|
|
13775
|
+
if (domFigure) view.change((writer) => {
|
|
13776
|
+
writer.setStyle("--ck-table-scroll-offset", `${domFigure.scrollLeft}px`, viewFigure);
|
|
13777
|
+
});
|
|
13778
|
+
});
|
|
13779
|
+
}
|
|
13780
|
+
/**
|
|
13781
|
+
* Registers editing-only downcast listeners that keep overflow state in sync.
|
|
13782
|
+
*/
|
|
13783
|
+
_registerConversion() {
|
|
13784
|
+
const { editor } = this;
|
|
13785
|
+
editor.conversion.for("editingDowncast").add((dispatcher) => {
|
|
13786
|
+
dispatcher.on("attribute:tableWidth:table", (evt, data) => {
|
|
13787
|
+
this._updateTableScrollOverflowState(data.item, data.attributeNewValue);
|
|
13788
|
+
}, { priority: "low" });
|
|
13789
|
+
dispatcher.on("attribute:tableType:table", (evt, data) => {
|
|
13790
|
+
this._updateTableScrollOverflowState(data.item);
|
|
13791
|
+
}, { priority: "low" });
|
|
13792
|
+
dispatcher.on("insert:caption", (evt, data) => {
|
|
13793
|
+
const modelTable = data.item.parent;
|
|
13794
|
+
if (modelTable?.is("element", "table")) this._updateTableScrollOverflowState(modelTable);
|
|
13795
|
+
}, { priority: "lowest" });
|
|
13796
|
+
dispatcher.on("insert:table", (evt, data) => {
|
|
13797
|
+
this._updateTableScrollOverflowState(data.item);
|
|
13798
|
+
}, { priority: "lowest" });
|
|
13799
|
+
});
|
|
13800
|
+
}
|
|
13801
|
+
/**
|
|
13802
|
+
* Keeps every overflowing table's `--ck-table-scroll-offset` custom property in sync with its
|
|
13803
|
+
* `scrollLeft`, using a single delegated listener instead of one native listener per table.
|
|
13804
|
+
*/
|
|
13805
|
+
_watchFiguresScroll() {
|
|
13806
|
+
const { editor } = this;
|
|
13807
|
+
const { view } = editor.editing;
|
|
13808
|
+
const onScroll = (evt, domEvent) => {
|
|
13809
|
+
const domFigure = domEvent.target;
|
|
13810
|
+
if (!domFigure.classList?.contains("ck-table-overflowing")) return;
|
|
13811
|
+
const viewFigure = view.domConverter.mapDomToView(domFigure);
|
|
13812
|
+
if (!viewFigure) return;
|
|
13813
|
+
view.change((writer) => {
|
|
13814
|
+
writer.setStyle("--ck-table-scroll-offset", `${domFigure.scrollLeft}px`, viewFigure);
|
|
13815
|
+
});
|
|
13816
|
+
};
|
|
13817
|
+
this._domEmitter.listenTo(global.document, "scroll", onScroll, { useCapture: true });
|
|
13818
|
+
}
|
|
13819
|
+
/**
|
|
13820
|
+
* Listen for column resize events and updates proper view element size.
|
|
13821
|
+
*/
|
|
13822
|
+
_watchColumnResize() {
|
|
13823
|
+
const { editor } = this;
|
|
13824
|
+
const { plugins } = editor;
|
|
13825
|
+
if (!plugins.has("TableColumnResizeEditing")) return;
|
|
13826
|
+
const columnResizeEditing = plugins.get("TableColumnResizeEditing");
|
|
13827
|
+
this.listenTo(columnResizeEditing, "_setResizingTableWidth", (evt, [, viewFigure, width]) => {
|
|
13828
|
+
evt.stop();
|
|
13829
|
+
const modelTable = editor.editing.mapper.toModelElement(viewFigure);
|
|
13830
|
+
this._updateTableScrollOverflowState(modelTable, width);
|
|
13831
|
+
}, { priority: "high" });
|
|
13832
|
+
this.listenTo(columnResizeEditing, "_getResizingTableWidth", (evt, [viewFigure]) => {
|
|
13833
|
+
evt.stop();
|
|
13834
|
+
evt.return = getWidthHoldingElement(viewFigure).getStyle("width");
|
|
13835
|
+
}, { priority: "high" });
|
|
13836
|
+
}
|
|
13837
|
+
/**
|
|
13838
|
+
* Re-evaluates the overflow state of every table whenever the window or an editing root is resized.
|
|
13839
|
+
*/
|
|
13840
|
+
_watchRootEditables(tables) {
|
|
13841
|
+
const { editor } = this;
|
|
13842
|
+
const recalculateAll = () => {
|
|
13843
|
+
const resizingTable = getCurrentlyResizingTable(editor);
|
|
13844
|
+
for (const table of tables) {
|
|
13845
|
+
if (table === resizingTable) continue;
|
|
13846
|
+
this._updateTableScrollOverflowState(table);
|
|
13847
|
+
}
|
|
13848
|
+
};
|
|
13849
|
+
const throttledRecalculateAll = throttle(recalculateAll, 100);
|
|
13850
|
+
const stopWatchingRootsResize = watchRootsWidthResize(editor.editing.view, throttledRecalculateAll);
|
|
13851
|
+
editor.ui.view.listenTo(global.window, "resize", throttledRecalculateAll);
|
|
13852
|
+
editor.once("ready", recalculateAll);
|
|
13853
|
+
this.listenTo(editor, "destroy", () => {
|
|
13854
|
+
throttledRecalculateAll.cancel();
|
|
13855
|
+
stopWatchingRootsResize();
|
|
13856
|
+
});
|
|
13857
|
+
}
|
|
13858
|
+
/**
|
|
13859
|
+
* Evaluates the overflow state of every newly inserted table.
|
|
13860
|
+
*/
|
|
13861
|
+
_watchNewTables(tables) {
|
|
13862
|
+
this.listenTo(tables, "change", (evt, data) => {
|
|
13863
|
+
for (const table of data.added) this._updateTableScrollOverflowState(table);
|
|
13864
|
+
});
|
|
13865
|
+
}
|
|
13866
|
+
};
|
|
13867
|
+
/**
|
|
13868
|
+
* Returns the table for which a column resize is currently in progress, if the
|
|
13869
|
+
* `TableColumnResizeEditing` plugin is loaded and such a resize is active.
|
|
13870
|
+
*/
|
|
13871
|
+
function getCurrentlyResizingTable(editor) {
|
|
13872
|
+
const { plugins } = editor;
|
|
13873
|
+
if (!plugins.has("TableColumnResizeEditing")) return null;
|
|
13874
|
+
return plugins.get("TableColumnResizeEditing").resizingTable;
|
|
13875
|
+
}
|
|
13876
|
+
/**
|
|
13877
|
+
* Checks if given table width overflows container width.
|
|
13878
|
+
*/
|
|
13879
|
+
function isTableWidthOverflowing(tableWidth, containerWidth) {
|
|
13880
|
+
if (tableWidth.endsWith("%")) return parseFloat(tableWidth) > 100;
|
|
13881
|
+
if (tableWidth.endsWith("px")) return parseFloat(tableWidth) > containerWidth;
|
|
13882
|
+
return false;
|
|
13883
|
+
}
|
|
13884
|
+
/**
|
|
13885
|
+
* Returns whichever element - the widget's `<figure>` or its inner `<table>` - currently holds the
|
|
13886
|
+
* table's actual (possibly container-exceeding) width: the `<table>` while overflowing, the `<figure>`
|
|
13887
|
+
* otherwise.
|
|
13888
|
+
*/
|
|
13889
|
+
function getWidthHoldingElement(viewFigure) {
|
|
13890
|
+
return viewFigure.hasClass("ck-table-overflowing") ? findChildElement(viewFigure, "table") : viewFigure;
|
|
13891
|
+
}
|
|
13892
|
+
/**
|
|
13893
|
+
* Finds a direct child element of `parent` by its name.
|
|
13894
|
+
*/
|
|
13895
|
+
function findChildElement(parent, elementName) {
|
|
13896
|
+
return Array.from(parent.getChildren()).find((child) => child.is("element", elementName));
|
|
13897
|
+
}
|
|
13898
|
+
|
|
13899
|
+
/**
|
|
13900
|
+
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
13901
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
13902
|
+
*/
|
|
13903
|
+
/**
|
|
13904
|
+
* @module table/tablescroll
|
|
13905
|
+
*/
|
|
13906
|
+
var TableScroll = class extends Plugin {
|
|
13907
|
+
/**
|
|
13908
|
+
* @inheritDoc
|
|
13909
|
+
*/
|
|
13910
|
+
static get pluginName() {
|
|
13911
|
+
return "TableScroll";
|
|
13912
|
+
}
|
|
13913
|
+
/**
|
|
13914
|
+
* @inheritDoc
|
|
13915
|
+
*/
|
|
13916
|
+
static get isOfficialPlugin() {
|
|
13917
|
+
return true;
|
|
13918
|
+
}
|
|
13919
|
+
/**
|
|
13920
|
+
* @inheritDoc
|
|
13921
|
+
*/
|
|
13922
|
+
static get requires() {
|
|
13923
|
+
return [TableScrollEditing];
|
|
13924
|
+
}
|
|
13925
|
+
};
|
|
13926
|
+
|
|
13079
13927
|
/**
|
|
13080
13928
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
13081
13929
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
13082
13930
|
*/
|
|
13083
13931
|
|
|
13084
|
-
export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetFooterRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesView, TableCellPropertyCommand, TableCellTypeCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesView, TablePropertyCommand, TableSelection, TableSlot, 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 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableStructureRefreshHandler as _tableStructureRefreshHandler, 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, isTableHeaderCellType };
|
|
13932
|
+
export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetFooterRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesView, TableCellPropertyCommand, TableCellTypeCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableColumnWidthCommand, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesView, TablePropertyCommand, TableScroll, TableScrollEditing, TableSelection, TableSlot, 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 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableStructureRefreshHandler as _tableStructureRefreshHandler, 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, isTableHeaderCellType };
|
|
13085
13933
|
//# sourceMappingURL=index.js.map
|