@ckeditor/ckeditor5-table 0.0.0-nightly-20251215.0 → 0.0.0-nightly-20251216.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/table.js +1 -1
- package/dist/index-editor.css +76 -85
- package/dist/index.css +102 -111
- package/dist/index.css.map +1 -1
- package/dist/index.js +830 -125
- package/dist/index.js.map +1 -1
- package/lang/contexts.json +3 -0
- package/package.json +9 -9
- package/src/augmentation.d.ts +10 -1
- package/src/commands/setheadercolumncommand.js +2 -2
- package/src/commands/setheaderrowcommand.js +1 -2
- package/src/converters/downcast.d.ts +3 -1
- package/src/converters/downcast.js +18 -6
- package/src/converters/upcasttable.js +12 -5
- package/src/index.d.ts +2 -1
- package/src/index.js +2 -1
- package/src/tablecellproperties/commands/tablecellpropertycommand.d.ts +19 -1
- package/src/tablecellproperties/commands/tablecellpropertycommand.js +8 -0
- package/src/tablecellproperties/commands/tablecelltypecommand.d.ts +53 -0
- package/src/tablecellproperties/commands/tablecelltypecommand.js +167 -0
- package/src/tablecellproperties/tablecellpropertiesediting.d.ts +0 -3
- package/src/tablecellproperties/tablecellpropertiesediting.js +113 -0
- package/src/tablecellproperties/tablecellpropertiesuiexperimental.js +33 -11
- package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.d.ts +32 -3
- package/src/tablecellproperties/ui/tablecellpropertiesviewexperimental.js +129 -18
- package/src/tableediting.js +13 -3
- package/src/tableutils.d.ts +38 -0
- package/src/tableutils.js +219 -13
- package/src/utils/common.d.ts +23 -0
- package/src/utils/common.js +42 -0
- package/theme/tablecellproperties-experimental.css +4 -0
- package/theme/tableform-experimental.css +0 -12
- package/theme/tableform.css +5 -6
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
6
|
import { toWidgetEditable, toWidget, Widget, isWidget, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';
|
|
7
|
-
import { first, global, CKEditorError, KeystrokeHandler, FocusTracker, Collection, getLocalizedArrowKeyCodeDirection, Rect, DomEmitterMixin, toUnit } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
7
|
+
import { first, global, CKEditorError, KeystrokeHandler, FocusTracker, Collection, getLocalizedArrowKeyCodeDirection, Rect, priorities, DomEmitterMixin, toUnit } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
8
8
|
import { isObject, debounce, isEqual, throttle } from 'es-toolkit/compat';
|
|
9
9
|
import { IconTable, IconTableColumn, IconTableRow, IconTableMergeCell, IconCheck, IconCancel, IconAlignBottom, IconAlignMiddle, IconAlignTop, IconAlignJustify, IconAlignRight, IconAlignCenter, IconAlignLeft, IconTableCellProperties, IconTableLayout, IconTableProperties, IconObjectInlineRight, IconObjectCenter, IconObjectInlineLeft, IconCaption, IconPreviousArrow, IconObjectRight, IconObjectLeft } from '@ckeditor/ckeditor5-icons/dist/index.js';
|
|
10
10
|
import { View, addKeyboardHandlingForGrid, ButtonView, createDropdown, MenuBarMenuView, SwitchButtonView, SplitButtonView, addListToDropdown, UIModel, ViewCollection, FocusCycler, InputTextView, ColorSelectorView, FormHeaderView, FormRowView, submitHandler, LabelView, LabeledFieldView, createLabeledDropdown, createLabeledInputText, ToolbarView, BalloonPanelView, ContextualBalloon, normalizeColorOptions, getLocalizedColorOptions, clickOutsideHandler, DropdownButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
|
|
@@ -503,82 +503,6 @@ const downcastTableAlignmentConfig = {
|
|
|
503
503
|
}
|
|
504
504
|
};
|
|
505
505
|
|
|
506
|
-
/**
|
|
507
|
-
* A common method to update the numeric value. If a value is the default one, it will be unset.
|
|
508
|
-
*
|
|
509
|
-
* @internal
|
|
510
|
-
* @param key An attribute key.
|
|
511
|
-
* @param value The new attribute value.
|
|
512
|
-
* @param item A model item on which the attribute will be set.
|
|
513
|
-
* @param defaultValue The default attribute value. If a value is lower or equal, it will be unset.
|
|
514
|
-
*/ function updateNumericAttribute(key, value, item, writer, defaultValue = 1) {
|
|
515
|
-
if (value !== undefined && value !== null && defaultValue !== undefined && defaultValue !== null && value > defaultValue) {
|
|
516
|
-
writer.setAttribute(key, value, item);
|
|
517
|
-
} else {
|
|
518
|
-
writer.removeAttribute(key, item);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* A common method to create an empty table cell. It creates a proper model structure as a table cell must have at least one block inside.
|
|
523
|
-
*
|
|
524
|
-
* @internal
|
|
525
|
-
* @param writer The model writer.
|
|
526
|
-
* @param insertPosition The position at which the table cell should be inserted.
|
|
527
|
-
* @param attributes The element attributes.
|
|
528
|
-
* @returns Created table cell.
|
|
529
|
-
*/ function createEmptyTableCell(writer, insertPosition, attributes = {}) {
|
|
530
|
-
const tableCell = writer.createElement('tableCell', attributes);
|
|
531
|
-
writer.insertElement('paragraph', tableCell);
|
|
532
|
-
writer.insert(tableCell, insertPosition);
|
|
533
|
-
return tableCell;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Checks if a table cell belongs to the heading column section.
|
|
537
|
-
*
|
|
538
|
-
* @internal
|
|
539
|
-
*/ function isHeadingColumnCell(tableUtils, tableCell) {
|
|
540
|
-
const table = tableCell.parent.parent;
|
|
541
|
-
const headingColumns = parseInt(table.getAttribute('headingColumns') || '0');
|
|
542
|
-
const { column } = tableUtils.getCellLocation(tableCell);
|
|
543
|
-
return !!headingColumns && column < headingColumns;
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Enables conversion for an attribute for simple view-model mappings.
|
|
547
|
-
*
|
|
548
|
-
* @internal
|
|
549
|
-
* @param options.defaultValue The default value for the specified `modelAttribute`.
|
|
550
|
-
*/ function enableProperty$1(schema, conversion, options) {
|
|
551
|
-
const { modelAttribute } = options;
|
|
552
|
-
schema.extend('tableCell', {
|
|
553
|
-
allowAttributes: [
|
|
554
|
-
modelAttribute
|
|
555
|
-
]
|
|
556
|
-
});
|
|
557
|
-
schema.setAttributeProperties(modelAttribute, {
|
|
558
|
-
isFormatting: true
|
|
559
|
-
});
|
|
560
|
-
upcastStyleToAttribute(conversion, {
|
|
561
|
-
viewElement: /^(td|th)$/,
|
|
562
|
-
...options
|
|
563
|
-
});
|
|
564
|
-
downcastAttributeToStyle(conversion, {
|
|
565
|
-
modelElement: 'tableCell',
|
|
566
|
-
...options
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.
|
|
571
|
-
*
|
|
572
|
-
* @internal
|
|
573
|
-
*/ function getSelectionAffectedTable(selection) {
|
|
574
|
-
const selectedElement = selection.getSelectedElement();
|
|
575
|
-
// Is the command triggered from the `tableToolbar`?
|
|
576
|
-
if (selectedElement && selectedElement.is('element', 'table')) {
|
|
577
|
-
return selectedElement;
|
|
578
|
-
}
|
|
579
|
-
return selection.getFirstPosition().findAncestor('table');
|
|
580
|
-
}
|
|
581
|
-
|
|
582
506
|
/**
|
|
583
507
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
584
508
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
@@ -1017,6 +941,122 @@ const downcastTableAlignmentConfig = {
|
|
|
1017
941
|
// @if CK_DEBUG // } );
|
|
1018
942
|
// @if CK_DEBUG // }
|
|
1019
943
|
|
|
944
|
+
/**
|
|
945
|
+
* A common method to update the numeric value. If a value is the default one, it will be unset.
|
|
946
|
+
*
|
|
947
|
+
* @internal
|
|
948
|
+
* @param key An attribute key.
|
|
949
|
+
* @param value The new attribute value.
|
|
950
|
+
* @param item A model item on which the attribute will be set.
|
|
951
|
+
* @param defaultValue The default attribute value. If a value is lower or equal, it will be unset.
|
|
952
|
+
*/ function updateNumericAttribute(key, value, item, writer, defaultValue = 1) {
|
|
953
|
+
if (value !== undefined && value !== null && defaultValue !== undefined && defaultValue !== null && value > defaultValue) {
|
|
954
|
+
writer.setAttribute(key, value, item);
|
|
955
|
+
} else {
|
|
956
|
+
writer.removeAttribute(key, item);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* A common method to create an empty table cell. It creates a proper model structure as a table cell must have at least one block inside.
|
|
961
|
+
*
|
|
962
|
+
* @internal
|
|
963
|
+
* @param writer The model writer.
|
|
964
|
+
* @param insertPosition The position at which the table cell should be inserted.
|
|
965
|
+
* @param attributes The element attributes.
|
|
966
|
+
* @returns Created table cell.
|
|
967
|
+
*/ function createEmptyTableCell(writer, insertPosition, attributes = {}) {
|
|
968
|
+
const tableCell = writer.createElement('tableCell', attributes);
|
|
969
|
+
writer.insertElement('paragraph', tableCell);
|
|
970
|
+
writer.insert(tableCell, insertPosition);
|
|
971
|
+
return tableCell;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Checks if a table cell belongs to the heading column section.
|
|
975
|
+
*
|
|
976
|
+
* @internal
|
|
977
|
+
*/ function isHeadingColumnCell(tableUtils, tableCell) {
|
|
978
|
+
const table = tableCell.parent.parent;
|
|
979
|
+
const headingColumns = parseInt(table.getAttribute('headingColumns') || '0');
|
|
980
|
+
const { column } = tableUtils.getCellLocation(tableCell);
|
|
981
|
+
return !!headingColumns && column < headingColumns;
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Enables conversion for an attribute for simple view-model mappings.
|
|
985
|
+
*
|
|
986
|
+
* @internal
|
|
987
|
+
* @param options.defaultValue The default value for the specified `modelAttribute`.
|
|
988
|
+
*/ function enableProperty$1(schema, conversion, options) {
|
|
989
|
+
const { modelAttribute } = options;
|
|
990
|
+
schema.extend('tableCell', {
|
|
991
|
+
allowAttributes: [
|
|
992
|
+
modelAttribute
|
|
993
|
+
]
|
|
994
|
+
});
|
|
995
|
+
schema.setAttributeProperties(modelAttribute, {
|
|
996
|
+
isFormatting: true
|
|
997
|
+
});
|
|
998
|
+
upcastStyleToAttribute(conversion, {
|
|
999
|
+
viewElement: /^(td|th)$/,
|
|
1000
|
+
...options
|
|
1001
|
+
});
|
|
1002
|
+
downcastAttributeToStyle(conversion, {
|
|
1003
|
+
modelElement: 'tableCell',
|
|
1004
|
+
...options
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.
|
|
1009
|
+
*
|
|
1010
|
+
* @internal
|
|
1011
|
+
*/ function getSelectionAffectedTable(selection) {
|
|
1012
|
+
const selectedElement = selection.getSelectedElement();
|
|
1013
|
+
// Is the command triggered from the `tableToolbar`?
|
|
1014
|
+
if (selectedElement && selectedElement.is('element', 'table')) {
|
|
1015
|
+
return selectedElement;
|
|
1016
|
+
}
|
|
1017
|
+
return selection.getFirstPosition().findAncestor('table');
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Groups table cells by their parent table.
|
|
1021
|
+
*
|
|
1022
|
+
* @internal
|
|
1023
|
+
*/ function groupCellsByTable(tableCells) {
|
|
1024
|
+
const tableMap = new Map();
|
|
1025
|
+
for (const tableCell of tableCells){
|
|
1026
|
+
const table = tableCell.findAncestor('table');
|
|
1027
|
+
if (!tableMap.has(table)) {
|
|
1028
|
+
tableMap.set(table, []);
|
|
1029
|
+
}
|
|
1030
|
+
tableMap.get(table).push(tableCell);
|
|
1031
|
+
}
|
|
1032
|
+
return tableMap;
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Checks if all cells in a given row or column are header cells.
|
|
1036
|
+
*
|
|
1037
|
+
* @internal
|
|
1038
|
+
*/ function isEntireCellsLineHeader({ table, row, column }) {
|
|
1039
|
+
const tableWalker = new TableWalker(table, {
|
|
1040
|
+
row,
|
|
1041
|
+
column
|
|
1042
|
+
});
|
|
1043
|
+
for (const { cell } of tableWalker){
|
|
1044
|
+
const cellType = cell.getAttribute('tableCellType');
|
|
1045
|
+
if (cellType !== 'header') {
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return true;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Checks whether the `tableCellType` attribute is enabled in the editor schema and the experimental flag is set.
|
|
1053
|
+
*
|
|
1054
|
+
* @internal
|
|
1055
|
+
*/ function isTableCellTypeEnabled(editor) {
|
|
1056
|
+
const { model, config } = editor;
|
|
1057
|
+
return model.schema.checkAttribute('tableCell', 'tableCellType') && config.get('experimentalFlags.tableCellTypeSupport') === true;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1020
1060
|
/**
|
|
1021
1061
|
* Returns a cropped table according to given dimensions.
|
|
1022
1062
|
|
|
@@ -1642,9 +1682,12 @@ const downcastTableAlignmentConfig = {
|
|
|
1642
1682
|
* headingRows - The number of rows that go as table headers.
|
|
1643
1683
|
* headingColumns - The maximum number of row headings.
|
|
1644
1684
|
* rows - Sorted `<tr>` elements as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.
|
|
1685
|
+
*
|
|
1686
|
+
* @param viewTable The view table element.
|
|
1687
|
+
* @returns The table metadata.
|
|
1645
1688
|
*/ function scanTable(viewTable) {
|
|
1646
|
-
let headingRows = 0;
|
|
1647
1689
|
let headingColumns = undefined;
|
|
1690
|
+
let shouldAccumulateHeadingRows = true;
|
|
1648
1691
|
// The `<tbody>` and `<thead>` sections in the DOM do not have to be in order `<thead>` -> `<tbody>` and there might be more than one
|
|
1649
1692
|
// of them.
|
|
1650
1693
|
// As the model does not have these sections, rows from different sections must be sorted.
|
|
@@ -1670,6 +1713,7 @@ const downcastTableAlignmentConfig = {
|
|
|
1670
1713
|
}
|
|
1671
1714
|
// Save the first `<thead>` in the table as table header - all other ones will be converted to table body rows.
|
|
1672
1715
|
if (tableChild.name === 'thead' && !firstTheadElement) {
|
|
1716
|
+
shouldAccumulateHeadingRows = true;
|
|
1673
1717
|
firstTheadElement = tableChild;
|
|
1674
1718
|
}
|
|
1675
1719
|
// There might be some extra empty text nodes between the `<tr>`s.
|
|
@@ -1684,11 +1728,13 @@ const downcastTableAlignmentConfig = {
|
|
|
1684
1728
|
// This case is problematic because it's not clear if this row should be a heading row or not, as it may be result
|
|
1685
1729
|
// of the cell span from the previous row.
|
|
1686
1730
|
// Issue: https://github.com/ckeditor/ckeditor5/issues/17556
|
|
1687
|
-
(maxPrevColumns === null || trColumns.length === maxPrevColumns) && trColumns.every((e)=>e.is('element', 'th'))
|
|
1688
|
-
|
|
1731
|
+
(maxPrevColumns === null || trColumns.length === maxPrevColumns) && trColumns.every((e)=>e.is('element', 'th')) && // If there is at least one "normal" table row between heading rows, then stop accumulating heading rows.
|
|
1732
|
+
shouldAccumulateHeadingRows) {
|
|
1689
1733
|
headRows.push(tr);
|
|
1734
|
+
shouldAccumulateHeadingRows = true;
|
|
1690
1735
|
} else {
|
|
1691
1736
|
bodyRows.push(tr);
|
|
1737
|
+
shouldAccumulateHeadingRows = false;
|
|
1692
1738
|
}
|
|
1693
1739
|
// We use the maximum number of columns to avoid false positives when detecting
|
|
1694
1740
|
// multiple rows with single column within `rowspan`. Without it the last row of `rowspan=3`
|
|
@@ -1708,12 +1754,12 @@ const downcastTableAlignmentConfig = {
|
|
|
1708
1754
|
index += 1;
|
|
1709
1755
|
}
|
|
1710
1756
|
// Update headingColumns.
|
|
1711
|
-
if (
|
|
1757
|
+
if (headingColumns === undefined || index < headingColumns) {
|
|
1712
1758
|
headingColumns = index;
|
|
1713
1759
|
}
|
|
1714
1760
|
}
|
|
1715
1761
|
return {
|
|
1716
|
-
headingRows,
|
|
1762
|
+
headingRows: headRows.length,
|
|
1717
1763
|
headingColumns: headingColumns || 0,
|
|
1718
1764
|
rows: [
|
|
1719
1765
|
...headRows,
|
|
@@ -2017,9 +2063,17 @@ const downcastTableAlignmentConfig = {
|
|
|
2017
2063
|
*
|
|
2018
2064
|
* @internal
|
|
2019
2065
|
* @param options.asWidget If set to `true`, the downcast conversion will produce a widget.
|
|
2066
|
+
* @param options.cellTypeEnabled If returns `true`, the downcast conversion will use the `tableCellType` attribute to determine cell type.
|
|
2020
2067
|
* @returns Element creator.
|
|
2021
|
-
*/ function downcastCell(options
|
|
2068
|
+
*/ function downcastCell(options) {
|
|
2022
2069
|
return (tableCell, { writer })=>{
|
|
2070
|
+
// If the table cell type feature is enabled, then we can simply check the cell type attribute.
|
|
2071
|
+
if (options.cellTypeEnabled?.()) {
|
|
2072
|
+
const cellElementName = tableCell.getAttribute('tableCellType') === 'header' ? 'th' : 'td';
|
|
2073
|
+
return createCellElement(writer, cellElementName);
|
|
2074
|
+
}
|
|
2075
|
+
// If the table cell type feature is not enabled, we should iterate through the table structure
|
|
2076
|
+
// to determine whether the cell is in the heading section.
|
|
2023
2077
|
const tableRow = tableCell.parent;
|
|
2024
2078
|
const table = tableRow.parent;
|
|
2025
2079
|
const rowIndex = table.getChildIndex(tableRow);
|
|
@@ -2033,15 +2087,17 @@ const downcastTableAlignmentConfig = {
|
|
|
2033
2087
|
for (const tableSlot of tableWalker){
|
|
2034
2088
|
if (tableSlot.cell == tableCell) {
|
|
2035
2089
|
const isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;
|
|
2036
|
-
|
|
2037
|
-
result = options.asWidget ? toWidgetEditable(writer.createEditableElement(cellElementName), writer, {
|
|
2038
|
-
withAriaRole: false
|
|
2039
|
-
}) : writer.createContainerElement(cellElementName);
|
|
2090
|
+
result = createCellElement(writer, isHeading ? 'th' : 'td');
|
|
2040
2091
|
break;
|
|
2041
2092
|
}
|
|
2042
2093
|
}
|
|
2043
2094
|
return result;
|
|
2044
2095
|
};
|
|
2096
|
+
function createCellElement(writer, name) {
|
|
2097
|
+
return options.asWidget ? toWidgetEditable(writer.createEditableElement(name), writer, {
|
|
2098
|
+
withAriaRole: false
|
|
2099
|
+
}) : writer.createContainerElement(name);
|
|
2100
|
+
}
|
|
2045
2101
|
}
|
|
2046
2102
|
/**
|
|
2047
2103
|
* Overrides paragraph inside table cell conversion.
|
|
@@ -2885,7 +2941,7 @@ const downcastTableAlignmentConfig = {
|
|
|
2885
2941
|
splitHorizontally(cell, headingRowsToSet, writer);
|
|
2886
2942
|
}
|
|
2887
2943
|
}
|
|
2888
|
-
|
|
2944
|
+
tableUtils.setHeadingRowsCount(writer, table, headingRowsToSet);
|
|
2889
2945
|
});
|
|
2890
2946
|
}
|
|
2891
2947
|
/**
|
|
@@ -2955,7 +3011,7 @@ const downcastTableAlignmentConfig = {
|
|
|
2955
3011
|
splitVertically(cell, column, headingColumnsToSet, writer);
|
|
2956
3012
|
}
|
|
2957
3013
|
}
|
|
2958
|
-
|
|
3014
|
+
tableUtils.setHeadingColumnsCount(writer, table, headingColumnsToSet);
|
|
2959
3015
|
});
|
|
2960
3016
|
}
|
|
2961
3017
|
}
|
|
@@ -3413,10 +3469,10 @@ const downcastTableAlignmentConfig = {
|
|
|
3413
3469
|
const columns = options.columns || 2;
|
|
3414
3470
|
createEmptyRows(writer, table, 0, rows, columns);
|
|
3415
3471
|
if (options.headingRows) {
|
|
3416
|
-
|
|
3472
|
+
this.setHeadingRowsCount(writer, table, Math.min(options.headingRows, rows));
|
|
3417
3473
|
}
|
|
3418
3474
|
if (options.headingColumns) {
|
|
3419
|
-
|
|
3475
|
+
this.setHeadingColumnsCount(writer, table, Math.min(options.headingColumns, columns));
|
|
3420
3476
|
}
|
|
3421
3477
|
return table;
|
|
3422
3478
|
}
|
|
@@ -3453,6 +3509,7 @@ const downcastTableAlignmentConfig = {
|
|
|
3453
3509
|
const rowsToInsert = options.rows || 1;
|
|
3454
3510
|
const isCopyStructure = options.copyStructureFromAbove !== undefined;
|
|
3455
3511
|
const copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;
|
|
3512
|
+
const cellTypeEnabled = isTableCellTypeEnabled(this.editor);
|
|
3456
3513
|
const rows = this.getRows(table);
|
|
3457
3514
|
const columns = this.getColumns(table);
|
|
3458
3515
|
if (insertAt > rows) {
|
|
@@ -3465,14 +3522,29 @@ const downcastTableAlignmentConfig = {
|
|
|
3465
3522
|
});
|
|
3466
3523
|
}
|
|
3467
3524
|
model.change((writer)=>{
|
|
3468
|
-
|
|
3525
|
+
let headingRows = table.getAttribute('headingRows') || 0;
|
|
3526
|
+
const headingColumns = table.getAttribute('headingColumns') || 0;
|
|
3469
3527
|
// Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.
|
|
3470
3528
|
if (headingRows > insertAt) {
|
|
3471
|
-
|
|
3529
|
+
headingRows += rowsToInsert;
|
|
3530
|
+
this.setHeadingRowsCount(writer, table, headingRows, {
|
|
3531
|
+
shallow: true
|
|
3532
|
+
});
|
|
3472
3533
|
}
|
|
3473
3534
|
// Inserting at the end or at the beginning of a table doesn't require to calculate anything special.
|
|
3474
3535
|
if (!isCopyStructure && (insertAt === 0 || insertAt === rows)) {
|
|
3475
|
-
createEmptyRows(writer, table, insertAt, rowsToInsert, columns);
|
|
3536
|
+
const rows = createEmptyRows(writer, table, insertAt, rowsToInsert, columns);
|
|
3537
|
+
if (cellTypeEnabled) {
|
|
3538
|
+
for(let rowOffset = 0; rowOffset < rows.length; rowOffset++){
|
|
3539
|
+
const row = rows[rowOffset];
|
|
3540
|
+
for(let columnIndex = 0; columnIndex < columns; columnIndex++){
|
|
3541
|
+
const cell = row[columnIndex];
|
|
3542
|
+
if (insertAt + rowOffset < headingRows || columnIndex < headingColumns) {
|
|
3543
|
+
writer.setAttribute('tableCellType', 'header', cell);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3476
3548
|
return;
|
|
3477
3549
|
}
|
|
3478
3550
|
// Iterate over all the rows above the inserted rows in order to check for the row-spanned cells.
|
|
@@ -3504,9 +3576,13 @@ const downcastTableAlignmentConfig = {
|
|
|
3504
3576
|
const insertPosition = writer.createPositionAt(tableRow, 'end');
|
|
3505
3577
|
// Insert the empty cell only if this slot is not row-spanned from any other cell.
|
|
3506
3578
|
if (colspan > 0) {
|
|
3507
|
-
createEmptyTableCell(writer, insertPosition, colspan > 1 ? {
|
|
3579
|
+
const insertedCells = createEmptyTableCell(writer, insertPosition, colspan > 1 ? {
|
|
3508
3580
|
colspan
|
|
3509
3581
|
} : undefined);
|
|
3582
|
+
// If we insert row in heading section, set proper cell type.
|
|
3583
|
+
if (cellTypeEnabled && (insertAt + rowIndex < headingRows || cellIndex < headingColumns)) {
|
|
3584
|
+
writer.setAttribute('tableCellType', 'header', insertedCells);
|
|
3585
|
+
}
|
|
3510
3586
|
}
|
|
3511
3587
|
// Skip the col-spanned slots, there won't be any cells.
|
|
3512
3588
|
cellIndex += Math.abs(colspan) - 1;
|
|
@@ -3544,21 +3620,36 @@ const downcastTableAlignmentConfig = {
|
|
|
3544
3620
|
const model = this.editor.model;
|
|
3545
3621
|
const insertAt = options.at || 0;
|
|
3546
3622
|
const columnsToInsert = options.columns || 1;
|
|
3623
|
+
const cellTypeEnabled = isTableCellTypeEnabled(this.editor);
|
|
3547
3624
|
model.change((writer)=>{
|
|
3548
|
-
const
|
|
3625
|
+
const headingRows = table.getAttribute('headingRows') || 0;
|
|
3626
|
+
let headingColumns = table.getAttribute('headingColumns');
|
|
3549
3627
|
// Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.
|
|
3550
3628
|
if (insertAt < headingColumns) {
|
|
3551
|
-
|
|
3629
|
+
headingColumns += columnsToInsert;
|
|
3630
|
+
this.setHeadingColumnsCount(writer, table, headingColumns, {
|
|
3631
|
+
shallow: true
|
|
3632
|
+
});
|
|
3552
3633
|
}
|
|
3553
3634
|
const tableColumns = this.getColumns(table);
|
|
3554
3635
|
// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.
|
|
3555
3636
|
if (insertAt === 0 || tableColumns === insertAt) {
|
|
3637
|
+
let rowIndex = 0;
|
|
3556
3638
|
for (const tableRow of table.getChildren()){
|
|
3557
3639
|
// Ignore non-row elements inside the table (e.g. caption).
|
|
3558
3640
|
if (!tableRow.is('element', 'tableRow')) {
|
|
3559
3641
|
continue;
|
|
3560
3642
|
}
|
|
3561
|
-
createCells(columnsToInsert, writer, writer.createPositionAt(tableRow, insertAt ? 'end' : 0));
|
|
3643
|
+
const insertedCells = createCells(columnsToInsert, writer, writer.createPositionAt(tableRow, insertAt ? 'end' : 0));
|
|
3644
|
+
if (cellTypeEnabled) {
|
|
3645
|
+
// If we insert column in heading section, set proper cell type.
|
|
3646
|
+
for(let columnOffset = 0; columnOffset < insertedCells.length; columnOffset++){
|
|
3647
|
+
if (insertAt + columnOffset < headingColumns || rowIndex < headingRows) {
|
|
3648
|
+
writer.setAttribute('tableCellType', 'header', insertedCells[columnOffset]);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
rowIndex++;
|
|
3562
3653
|
}
|
|
3563
3654
|
return;
|
|
3564
3655
|
}
|
|
@@ -3584,7 +3675,15 @@ const downcastTableAlignmentConfig = {
|
|
|
3584
3675
|
} else {
|
|
3585
3676
|
// It's either cell at this column index or spanned cell by a row-spanned cell from row above.
|
|
3586
3677
|
// In table above it's cell "e" and a spanned position from row below (empty cell between cells "g" and "h")
|
|
3587
|
-
createCells(columnsToInsert, writer, tableSlot.getPositionBefore());
|
|
3678
|
+
const insertedCells = createCells(columnsToInsert, writer, tableSlot.getPositionBefore());
|
|
3679
|
+
// If we insert column in heading section, set proper cell type.
|
|
3680
|
+
if (cellTypeEnabled) {
|
|
3681
|
+
for(let columnOffset = 0; columnOffset < insertedCells.length; columnOffset++){
|
|
3682
|
+
if (insertAt + columnOffset < headingColumns || row < headingRows) {
|
|
3683
|
+
writer.setAttribute('tableCellType', 'header', insertedCells[columnOffset]);
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3588
3687
|
}
|
|
3589
3688
|
}
|
|
3590
3689
|
});
|
|
@@ -3664,6 +3763,20 @@ const downcastTableAlignmentConfig = {
|
|
|
3664
3763
|
// because of cleaning empty rows and we only removed one of them.
|
|
3665
3764
|
removeEmptyRows(table, this);
|
|
3666
3765
|
}
|
|
3766
|
+
// 3. If next rows are entirely header, adjust heading rows count.
|
|
3767
|
+
if (isTableCellTypeEnabled(this.editor)) {
|
|
3768
|
+
let headingRows = table.getAttribute('headingRows') || 0;
|
|
3769
|
+
const totalRows = this.getRows(table);
|
|
3770
|
+
while(headingRows < totalRows && isEntireCellsLineHeader({
|
|
3771
|
+
table,
|
|
3772
|
+
row: headingRows
|
|
3773
|
+
})){
|
|
3774
|
+
headingRows++;
|
|
3775
|
+
}
|
|
3776
|
+
this.setHeadingRowsCount(writer, table, headingRows, {
|
|
3777
|
+
shallow: true
|
|
3778
|
+
});
|
|
3779
|
+
}
|
|
3667
3780
|
});
|
|
3668
3781
|
}
|
|
3669
3782
|
/**
|
|
@@ -3736,6 +3849,20 @@ const downcastTableAlignmentConfig = {
|
|
|
3736
3849
|
// because of cleaning empty columns and we only removed one of them.
|
|
3737
3850
|
removeEmptyColumns(table, this);
|
|
3738
3851
|
}
|
|
3852
|
+
// If next columns are entirely header, adjust heading columns count.
|
|
3853
|
+
if (isTableCellTypeEnabled(this.editor)) {
|
|
3854
|
+
let headingColumns = table.getAttribute('headingColumns') || 0;
|
|
3855
|
+
const totalColumns = this.getColumns(table);
|
|
3856
|
+
while(headingColumns < totalColumns && isEntireCellsLineHeader({
|
|
3857
|
+
table,
|
|
3858
|
+
column: headingColumns
|
|
3859
|
+
})){
|
|
3860
|
+
headingColumns++;
|
|
3861
|
+
}
|
|
3862
|
+
this.setHeadingColumnsCount(writer, table, headingColumns, {
|
|
3863
|
+
shallow: true
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
3739
3866
|
});
|
|
3740
3867
|
}
|
|
3741
3868
|
/**
|
|
@@ -4050,6 +4177,148 @@ const downcastTableAlignmentConfig = {
|
|
|
4050
4177
|
}
|
|
4051
4178
|
return cells;
|
|
4052
4179
|
}
|
|
4180
|
+
/**
|
|
4181
|
+
* Sets the number of heading rows for the given `table`.
|
|
4182
|
+
*
|
|
4183
|
+
* @param writer The model writer.
|
|
4184
|
+
* @param table The table model element.
|
|
4185
|
+
* @param headingRows The number of heading rows to set.
|
|
4186
|
+
* @param options Additional options.
|
|
4187
|
+
* @param options.shallow If set to `true` it will only update the `headingRows` attribute
|
|
4188
|
+
* without updating the cell types in the table. Default is `false`.
|
|
4189
|
+
* @param options.resetFormerHeadingCells If set to `true`, it will check if the rows that are no longer in the heading section
|
|
4190
|
+
* should be updated to body cells. Default is `true`.
|
|
4191
|
+
* @param options.autoExpand If set to `true`, it will check if the following rows look like a header and expand the heading section.
|
|
4192
|
+
* Default is `true`.
|
|
4193
|
+
*/ setHeadingRowsCount(writer, table, headingRows, options = {}) {
|
|
4194
|
+
const { shallow, resetFormerHeadingCells = true, autoExpand = true } = options;
|
|
4195
|
+
const oldHeadingRows = table.getAttribute('headingRows') || 0;
|
|
4196
|
+
if (headingRows === oldHeadingRows) {
|
|
4197
|
+
return;
|
|
4198
|
+
}
|
|
4199
|
+
updateNumericAttribute('headingRows', headingRows, table, writer, 0);
|
|
4200
|
+
if (shallow || !isTableCellTypeEnabled(this.editor)) {
|
|
4201
|
+
return;
|
|
4202
|
+
}
|
|
4203
|
+
// Set header type to all cells in new heading rows.
|
|
4204
|
+
for (const { cell, row, column } of new TableWalker(table, {
|
|
4205
|
+
endRow: headingRows - 1
|
|
4206
|
+
})){
|
|
4207
|
+
updateTableCellType({
|
|
4208
|
+
table,
|
|
4209
|
+
writer,
|
|
4210
|
+
cell,
|
|
4211
|
+
row,
|
|
4212
|
+
column
|
|
4213
|
+
});
|
|
4214
|
+
}
|
|
4215
|
+
// If heading rows were reduced, set body type to all cells in rows that are no longer in heading section.
|
|
4216
|
+
if (resetFormerHeadingCells && headingRows < oldHeadingRows) {
|
|
4217
|
+
for(let row = headingRows; row < oldHeadingRows; row++){
|
|
4218
|
+
// Handle edge case when some cells were already changed to body type manually,
|
|
4219
|
+
// before changing heading rows count.
|
|
4220
|
+
if (!isEntireCellsLineHeader({
|
|
4221
|
+
table,
|
|
4222
|
+
row
|
|
4223
|
+
})) {
|
|
4224
|
+
break;
|
|
4225
|
+
}
|
|
4226
|
+
for (const { cell, row: cellRow, column } of new TableWalker(table, {
|
|
4227
|
+
row
|
|
4228
|
+
})){
|
|
4229
|
+
updateTableCellType({
|
|
4230
|
+
table,
|
|
4231
|
+
writer,
|
|
4232
|
+
cell,
|
|
4233
|
+
row: cellRow,
|
|
4234
|
+
column
|
|
4235
|
+
});
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
// If following rows looks like header, expand heading rows to cover them.
|
|
4240
|
+
if (autoExpand && headingRows > oldHeadingRows) {
|
|
4241
|
+
const totalRows = this.getRows(table);
|
|
4242
|
+
while(headingRows < totalRows && isEntireCellsLineHeader({
|
|
4243
|
+
table,
|
|
4244
|
+
row: headingRows
|
|
4245
|
+
})){
|
|
4246
|
+
headingRows++;
|
|
4247
|
+
}
|
|
4248
|
+
updateNumericAttribute('headingRows', headingRows, table, writer, 0);
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
/**
|
|
4252
|
+
* Sets the number of heading columns for the given `table`.
|
|
4253
|
+
*
|
|
4254
|
+
* @param writer The model writer to use.
|
|
4255
|
+
* @param table The table model element.
|
|
4256
|
+
* @param headingColumns The number of heading columns to set.
|
|
4257
|
+
* @param options Additional options.
|
|
4258
|
+
* @param options.shallow If set to `true` it will only update the `headingColumns` attribute
|
|
4259
|
+
* without updating the cell types in the table. Default is `false`.
|
|
4260
|
+
* @param options.resetFormerHeadingCells If set to `true`, it will check if the columns that are no longer in the heading section
|
|
4261
|
+
* should be updated to body cells. Default is `true`.
|
|
4262
|
+
* @param options.autoExpand If set to `true`, it will check if the following columns look like a header and expand the heading section.
|
|
4263
|
+
* Default is `true`.
|
|
4264
|
+
*/ setHeadingColumnsCount(writer, table, headingColumns, options = {}) {
|
|
4265
|
+
const { shallow, resetFormerHeadingCells = true, autoExpand = true } = options;
|
|
4266
|
+
const oldHeadingColumns = table.getAttribute('headingColumns') || 0;
|
|
4267
|
+
if (headingColumns === oldHeadingColumns) {
|
|
4268
|
+
return;
|
|
4269
|
+
}
|
|
4270
|
+
updateNumericAttribute('headingColumns', headingColumns, table, writer, 0);
|
|
4271
|
+
if (shallow || !isTableCellTypeEnabled(this.editor)) {
|
|
4272
|
+
return;
|
|
4273
|
+
}
|
|
4274
|
+
// Set header type to all cells in new heading columns.
|
|
4275
|
+
for (const { cell, row, column } of new TableWalker(table, {
|
|
4276
|
+
endColumn: headingColumns - 1
|
|
4277
|
+
})){
|
|
4278
|
+
updateTableCellType({
|
|
4279
|
+
table,
|
|
4280
|
+
writer,
|
|
4281
|
+
cell,
|
|
4282
|
+
row,
|
|
4283
|
+
column
|
|
4284
|
+
});
|
|
4285
|
+
}
|
|
4286
|
+
// If heading columns were reduced, set body type to all cells in columns that are no longer in heading section.
|
|
4287
|
+
if (resetFormerHeadingCells && headingColumns < oldHeadingColumns) {
|
|
4288
|
+
for(let column = headingColumns; column < oldHeadingColumns; column++){
|
|
4289
|
+
// Handle edge case when some cells were already changed to body type manually,
|
|
4290
|
+
// before changing heading columns count.
|
|
4291
|
+
if (!isEntireCellsLineHeader({
|
|
4292
|
+
table,
|
|
4293
|
+
column
|
|
4294
|
+
})) {
|
|
4295
|
+
break;
|
|
4296
|
+
}
|
|
4297
|
+
for (const { cell, row, column: cellColumn } of new TableWalker(table, {
|
|
4298
|
+
column
|
|
4299
|
+
})){
|
|
4300
|
+
updateTableCellType({
|
|
4301
|
+
table,
|
|
4302
|
+
writer,
|
|
4303
|
+
cell,
|
|
4304
|
+
row,
|
|
4305
|
+
column: cellColumn
|
|
4306
|
+
});
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
}
|
|
4310
|
+
// If following columns looks like header, expand heading columns to cover them.
|
|
4311
|
+
if (autoExpand && headingColumns > oldHeadingColumns) {
|
|
4312
|
+
const totalColumns = this.getColumns(table);
|
|
4313
|
+
while(headingColumns < totalColumns && isEntireCellsLineHeader({
|
|
4314
|
+
table,
|
|
4315
|
+
column: headingColumns
|
|
4316
|
+
})){
|
|
4317
|
+
headingColumns++;
|
|
4318
|
+
}
|
|
4319
|
+
updateNumericAttribute('headingColumns', headingColumns, table, writer, 0);
|
|
4320
|
+
}
|
|
4321
|
+
}
|
|
4053
4322
|
/**
|
|
4054
4323
|
* Returns all model table cells that the provided model selection's ranges
|
|
4055
4324
|
* {@link module:engine/model/range~ModelRange#start} inside.
|
|
@@ -4228,20 +4497,27 @@ const downcastTableAlignmentConfig = {
|
|
|
4228
4497
|
* @param rows The number of rows to create.
|
|
4229
4498
|
* @param tableCellToInsert The number of cells to insert in each row.
|
|
4230
4499
|
*/ function createEmptyRows(writer, table, insertAt, rows, tableCellToInsert, attributes = {}) {
|
|
4500
|
+
const insertedRows = [];
|
|
4231
4501
|
for(let i = 0; i < rows; i++){
|
|
4232
4502
|
const tableRow = writer.createElement('tableRow');
|
|
4233
4503
|
writer.insert(tableRow, table, insertAt);
|
|
4234
|
-
createCells(tableCellToInsert, writer, writer.createPositionAt(tableRow, 'end'), attributes);
|
|
4504
|
+
insertedRows.push(createCells(tableCellToInsert, writer, writer.createPositionAt(tableRow, 'end'), attributes));
|
|
4235
4505
|
}
|
|
4506
|
+
return insertedRows;
|
|
4236
4507
|
}
|
|
4237
4508
|
/**
|
|
4238
4509
|
* Creates cells at a given position.
|
|
4239
4510
|
*
|
|
4240
4511
|
* @param cells The number of cells to create
|
|
4241
4512
|
*/ function createCells(cells, writer, insertPosition, attributes = {}) {
|
|
4513
|
+
const createdCells = [];
|
|
4514
|
+
let currentPosition = insertPosition;
|
|
4242
4515
|
for(let i = 0; i < cells; i++){
|
|
4243
|
-
createEmptyTableCell(writer,
|
|
4516
|
+
const cell = createEmptyTableCell(writer, currentPosition, attributes);
|
|
4517
|
+
createdCells.push(cell);
|
|
4518
|
+
currentPosition = writer.createPositionAfter(cell);
|
|
4244
4519
|
}
|
|
4520
|
+
return createdCells;
|
|
4245
4521
|
}
|
|
4246
4522
|
/**
|
|
4247
4523
|
* Evenly distributes the span of a cell to a number of provided cells.
|
|
@@ -4390,6 +4666,18 @@ function compareRangeOrder(rangeA, rangeB) {
|
|
|
4390
4666
|
const firstColumn = Math.min(...columnIndexes);
|
|
4391
4667
|
return (lastRow - firstRow + 1) * (lastColumn - firstColumn + 1);
|
|
4392
4668
|
}
|
|
4669
|
+
/**
|
|
4670
|
+
* Updates the `tableCellType` attribute of a table cell based on its position in the table
|
|
4671
|
+
* and the table's `headingRows` and `headingColumns` attributes.
|
|
4672
|
+
*/ function updateTableCellType({ writer, table, row, column, cell }) {
|
|
4673
|
+
const headingRows = table.getAttribute('headingRows') || 0;
|
|
4674
|
+
const headingColumns = table.getAttribute('headingColumns') || 0;
|
|
4675
|
+
if (row >= headingRows && column >= headingColumns) {
|
|
4676
|
+
writer.removeAttribute('tableCellType', cell);
|
|
4677
|
+
} else {
|
|
4678
|
+
writer.setAttribute('tableCellType', 'header', cell);
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4393
4681
|
|
|
4394
4682
|
/**
|
|
4395
4683
|
* The merge cells command.
|
|
@@ -5232,12 +5520,15 @@ function getMaxOffset(tableCell, start, currentMaxOffset, which) {
|
|
|
5232
5520
|
conversion.for('editingDowncast').elementToElement({
|
|
5233
5521
|
model: 'tableCell',
|
|
5234
5522
|
view: downcastCell({
|
|
5235
|
-
asWidget: true
|
|
5523
|
+
asWidget: true,
|
|
5524
|
+
cellTypeEnabled: ()=>isTableCellTypeEnabled(this.editor)
|
|
5236
5525
|
})
|
|
5237
5526
|
});
|
|
5238
5527
|
conversion.for('dataDowncast').elementToElement({
|
|
5239
5528
|
model: 'tableCell',
|
|
5240
|
-
view: downcastCell(
|
|
5529
|
+
view: downcastCell({
|
|
5530
|
+
cellTypeEnabled: ()=>isTableCellTypeEnabled(this.editor)
|
|
5531
|
+
})
|
|
5241
5532
|
});
|
|
5242
5533
|
// Duplicates code - needed to properly refresh paragraph inside a table cell.
|
|
5243
5534
|
conversion.for('editingDowncast').elementToElement({
|
|
@@ -5322,7 +5613,11 @@ function getMaxOffset(tableCell, start, currentMaxOffset, which) {
|
|
|
5322
5613
|
injectTableLayoutPostFixer(model);
|
|
5323
5614
|
injectTableCellParagraphPostFixer(model);
|
|
5324
5615
|
this.listenTo(model.document, 'change:data', ()=>{
|
|
5325
|
-
|
|
5616
|
+
// It's no longer needed to refresh table headings on every data change if table cell type feature is enabled.
|
|
5617
|
+
// It's because headings rows / columns are updated based on cell types which triggers their own refresh handler.
|
|
5618
|
+
if (!isTableCellTypeEnabled(editor)) {
|
|
5619
|
+
tableHeadingsRefreshHandler(model, editor.editing);
|
|
5620
|
+
}
|
|
5326
5621
|
tableCellRefreshHandler(model, editor.editing);
|
|
5327
5622
|
});
|
|
5328
5623
|
}
|
|
@@ -9020,6 +9315,9 @@ const propertyToCommandMap$3 = {
|
|
|
9020
9315
|
this._defaultContentTableValue = defaultValue;
|
|
9021
9316
|
// Hardcoded defaults for layout table.
|
|
9022
9317
|
switch(attributeName){
|
|
9318
|
+
case 'tableCellType':
|
|
9319
|
+
this._defaultLayoutTableValue = 'data';
|
|
9320
|
+
break;
|
|
9023
9321
|
case 'tableCellBorderStyle':
|
|
9024
9322
|
this._defaultLayoutTableValue = 'none';
|
|
9025
9323
|
break;
|
|
@@ -9065,6 +9363,11 @@ const propertyToCommandMap$3 = {
|
|
|
9065
9363
|
} else {
|
|
9066
9364
|
tableCells.forEach((tableCell)=>writer.removeAttribute(this.attributeName, tableCell));
|
|
9067
9365
|
}
|
|
9366
|
+
this.fire('afterExecute', {
|
|
9367
|
+
writer,
|
|
9368
|
+
tableCells,
|
|
9369
|
+
valueToSet
|
|
9370
|
+
});
|
|
9068
9371
|
});
|
|
9069
9372
|
}
|
|
9070
9373
|
/**
|
|
@@ -9484,6 +9787,168 @@ const propertyToCommandMap$3 = {
|
|
|
9484
9787
|
}
|
|
9485
9788
|
}
|
|
9486
9789
|
|
|
9790
|
+
/**
|
|
9791
|
+
* The table cell type command.
|
|
9792
|
+
*
|
|
9793
|
+
* The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as
|
|
9794
|
+
* the `'tableCellType'` editor command.
|
|
9795
|
+
*
|
|
9796
|
+
* To change the type of selected cells, execute the command:
|
|
9797
|
+
*
|
|
9798
|
+
* ```ts
|
|
9799
|
+
* editor.execute( 'tableCellType', {
|
|
9800
|
+
* value: 'header'
|
|
9801
|
+
* } );
|
|
9802
|
+
* ```
|
|
9803
|
+
*
|
|
9804
|
+
* The `value` can be either `'header'` or `'data'`.
|
|
9805
|
+
* It'll return `undefined` if multiple types are selected.
|
|
9806
|
+
*/ class TableCellTypeCommand extends TableCellPropertyCommand {
|
|
9807
|
+
/**
|
|
9808
|
+
* Creates a new `TableCellTypeCommand` instance.
|
|
9809
|
+
*
|
|
9810
|
+
* @param editor An editor in which this command will be used.
|
|
9811
|
+
*/ constructor(editor){
|
|
9812
|
+
super(editor, 'tableCellType', 'data');
|
|
9813
|
+
this.on('afterExecute', (_, data)=>{
|
|
9814
|
+
const { writer, tableCells } = data;
|
|
9815
|
+
const tableUtils = this.editor.plugins.get(TableUtils);
|
|
9816
|
+
const tablesMap = groupCellsByTable(tableCells);
|
|
9817
|
+
updateTablesHeadingAttributes(tableUtils, writer, tablesMap.keys());
|
|
9818
|
+
});
|
|
9819
|
+
}
|
|
9820
|
+
/**
|
|
9821
|
+
* @inheritDoc
|
|
9822
|
+
*/ refresh() {
|
|
9823
|
+
super.refresh();
|
|
9824
|
+
const table = getSelectionAffectedTable(this.editor.model.document.selection);
|
|
9825
|
+
if (this.isEnabled && table && table.getAttribute('tableType') === 'layout') {
|
|
9826
|
+
this.isEnabled = false;
|
|
9827
|
+
}
|
|
9828
|
+
}
|
|
9829
|
+
/**
|
|
9830
|
+
* Returns the attribute value for a table cell.
|
|
9831
|
+
*/ _getAttribute(tableCell) {
|
|
9832
|
+
return tableCell?.getAttribute(this.attributeName) || 'data';
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
/**
|
|
9836
|
+
* Updates the `headingRows` and `headingColumns` attributes of the given tables
|
|
9837
|
+
* based on the `tableCellType` of their cells.
|
|
9838
|
+
*/ function updateTablesHeadingAttributes(tableUtils, writer, tables) {
|
|
9839
|
+
let changed = false;
|
|
9840
|
+
for (const table of tables){
|
|
9841
|
+
let headingRows = table.getAttribute('headingRows') || 0;
|
|
9842
|
+
let headingColumns = table.getAttribute('headingColumns') || 0;
|
|
9843
|
+
// Prioritize the dimension that is already larger to prevent the other dimension from
|
|
9844
|
+
// aggressively consuming "orphaned" header cells. In other words, if table has three
|
|
9845
|
+
// heading columns (which fills entire table), we should not count all rows as heading rows.
|
|
9846
|
+
// User might later add column to the right which should not be heading.
|
|
9847
|
+
//
|
|
9848
|
+
// The other example, in a 2x2 table where all cells are headers (e.g. due to concurrent edits),
|
|
9849
|
+
// if headingColumns=0 and headingRows=0 (but all cells are headers):
|
|
9850
|
+
// - Processing rows first would expand headingRows to 2 (covering all cells), leaving headingColumns at 0.
|
|
9851
|
+
// - Processing columns first expands headingColumns to 2, leaving headingRows at 0.
|
|
9852
|
+
//
|
|
9853
|
+
// It should be good enough to resolve conflicts in most cases.
|
|
9854
|
+
const processColumnsFirst = headingColumns > headingRows;
|
|
9855
|
+
if (processColumnsFirst) {
|
|
9856
|
+
const newHeadingColumns = getAdjustedHeadingSectionSize(tableUtils, table, 'column', headingColumns, headingRows);
|
|
9857
|
+
if (newHeadingColumns !== headingColumns) {
|
|
9858
|
+
tableUtils.setHeadingColumnsCount(writer, table, newHeadingColumns, {
|
|
9859
|
+
shallow: true
|
|
9860
|
+
});
|
|
9861
|
+
headingColumns = newHeadingColumns;
|
|
9862
|
+
changed = true;
|
|
9863
|
+
}
|
|
9864
|
+
}
|
|
9865
|
+
const newHeadingRows = getAdjustedHeadingSectionSize(tableUtils, table, 'row', headingRows, headingColumns);
|
|
9866
|
+
if (newHeadingRows !== headingRows) {
|
|
9867
|
+
tableUtils.setHeadingRowsCount(writer, table, newHeadingRows, {
|
|
9868
|
+
shallow: true
|
|
9869
|
+
});
|
|
9870
|
+
headingRows = newHeadingRows;
|
|
9871
|
+
changed = true;
|
|
9872
|
+
}
|
|
9873
|
+
if (!processColumnsFirst) {
|
|
9874
|
+
const newHeadingColumns = getAdjustedHeadingSectionSize(tableUtils, table, 'column', headingColumns, headingRows);
|
|
9875
|
+
if (newHeadingColumns !== headingColumns) {
|
|
9876
|
+
tableUtils.setHeadingColumnsCount(writer, table, newHeadingColumns, {
|
|
9877
|
+
shallow: true
|
|
9878
|
+
});
|
|
9879
|
+
changed = true;
|
|
9880
|
+
}
|
|
9881
|
+
}
|
|
9882
|
+
}
|
|
9883
|
+
return changed;
|
|
9884
|
+
}
|
|
9885
|
+
/**
|
|
9886
|
+
* Calculates the adjusted size of a heading section (rows or columns).
|
|
9887
|
+
*
|
|
9888
|
+
* The algorithm iterates through rows (or columns) to determine if they should be part of the heading section.
|
|
9889
|
+
* A row/column is included if:
|
|
9890
|
+
* 1. All its cells are of type 'header'.
|
|
9891
|
+
* 2. AND it contains at least one header cell that is NOT already covered by the perpendicular heading section.
|
|
9892
|
+
*
|
|
9893
|
+
* This check prevents the algorithm from aggressively expanding the heading section when cells are already
|
|
9894
|
+
* headers due to the other dimension.
|
|
9895
|
+
*
|
|
9896
|
+
* Consider a 2x2 table where all cells are headers:
|
|
9897
|
+
*
|
|
9898
|
+
* ```
|
|
9899
|
+
* C0 C1
|
|
9900
|
+
* +---+---+
|
|
9901
|
+
* R0| H | H |
|
|
9902
|
+
* +---+---+
|
|
9903
|
+
* R1| H | H |
|
|
9904
|
+
* +---+---+
|
|
9905
|
+
* ```
|
|
9906
|
+
*
|
|
9907
|
+
* If `headingColumns=2`, both C0 and C1 are heading columns.
|
|
9908
|
+
* If we want `headingRows=1` (only R0), the algorithm must NOT include R1, even though R1 consists of header cells.
|
|
9909
|
+
* R1's cells are headers because of C0 and C1.
|
|
9910
|
+
*
|
|
9911
|
+
* Without this check, the algorithm would see that R1 is all headers and force `headingRows` to 2.
|
|
9912
|
+
* This would prevent the user from reducing `headingRows` from 2 to 1 without converting R1 cells to 'data'
|
|
9913
|
+
* (which would incorrectly break C0 and C1).
|
|
9914
|
+
*/ function getAdjustedHeadingSectionSize(tableUtils, table, mode, currentSize, perpendicularHeadingSize) {
|
|
9915
|
+
const totalRowsOrColumns = mode === 'row' ? tableUtils.getRows(table) : tableUtils.getColumns(table);
|
|
9916
|
+
let size = currentSize;
|
|
9917
|
+
// Iterate through each row/column to check if all cells are headers.
|
|
9918
|
+
for(let currentIndex = 0; currentIndex < totalRowsOrColumns; currentIndex++){
|
|
9919
|
+
const walker = new TableWalker(table, {
|
|
9920
|
+
[mode]: currentIndex
|
|
9921
|
+
});
|
|
9922
|
+
let allCellsAreHeaders = true;
|
|
9923
|
+
let hasHeaderOutsidePerpendicularSection = false;
|
|
9924
|
+
// Check each cell in the current row/column.
|
|
9925
|
+
for (const { cell, row, column } of walker){
|
|
9926
|
+
// If we find a non-header cell, this row/column can't be part of the heading section.
|
|
9927
|
+
if (cell.getAttribute('tableCellType') !== 'header') {
|
|
9928
|
+
allCellsAreHeaders = false;
|
|
9929
|
+
break;
|
|
9930
|
+
}
|
|
9931
|
+
// Check if this header cell extends beyond the perpendicular heading section.
|
|
9932
|
+
// E.g., when checking rows, see if the cell extends beyond headingColumns.
|
|
9933
|
+
const perpendicularIndex = mode === 'row' ? column : row;
|
|
9934
|
+
if (perpendicularIndex >= perpendicularHeadingSize) {
|
|
9935
|
+
hasHeaderOutsidePerpendicularSection = true;
|
|
9936
|
+
}
|
|
9937
|
+
}
|
|
9938
|
+
// If not all cells are headers, we can't extend the heading section any further.
|
|
9939
|
+
if (!allCellsAreHeaders) {
|
|
9940
|
+
// The section cannot extend beyond the last valid header row/column.
|
|
9941
|
+
return Math.min(size, currentIndex);
|
|
9942
|
+
}
|
|
9943
|
+
// If there's a header extending beyond the perpendicular section,
|
|
9944
|
+
// we must include this row/column in the heading section.
|
|
9945
|
+
if (hasHeaderOutsidePerpendicularSection) {
|
|
9946
|
+
size = Math.max(size, currentIndex + 1);
|
|
9947
|
+
}
|
|
9948
|
+
}
|
|
9949
|
+
return Math.min(size, totalRowsOrColumns);
|
|
9950
|
+
}
|
|
9951
|
+
|
|
9487
9952
|
const VALIGN_VALUES_REG_EXP = /^(top|middle|bottom)$/;
|
|
9488
9953
|
const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
|
|
9489
9954
|
/**
|
|
@@ -9585,6 +10050,10 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
|
|
|
9585
10050
|
editor.commands.add('tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand(editor, defaultTableCellProperties.horizontalAlignment));
|
|
9586
10051
|
enableVerticalAlignmentProperty(schema, conversion, defaultTableCellProperties.verticalAlignment);
|
|
9587
10052
|
editor.commands.add('tableCellVerticalAlignment', new TableCellVerticalAlignmentCommand(editor, defaultTableCellProperties.verticalAlignment));
|
|
10053
|
+
if (editor.config.get('experimentalFlags.tableCellTypeSupport')) {
|
|
10054
|
+
enableCellTypeProperty(editor);
|
|
10055
|
+
editor.commands.add('tableCellType', new TableCellTypeCommand(editor));
|
|
10056
|
+
}
|
|
9588
10057
|
}
|
|
9589
10058
|
}
|
|
9590
10059
|
/**
|
|
@@ -9771,6 +10240,112 @@ const ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;
|
|
|
9771
10240
|
}
|
|
9772
10241
|
});
|
|
9773
10242
|
}
|
|
10243
|
+
/**
|
|
10244
|
+
* Enables the `tableCellType` attribute for table cells.
|
|
10245
|
+
*/ function enableCellTypeProperty(editor) {
|
|
10246
|
+
const { model, conversion, editing } = editor;
|
|
10247
|
+
const { schema } = model;
|
|
10248
|
+
const tableUtils = editor.plugins.get(TableUtils);
|
|
10249
|
+
schema.extend('tableCell', {
|
|
10250
|
+
allowAttributes: [
|
|
10251
|
+
'tableCellType'
|
|
10252
|
+
]
|
|
10253
|
+
});
|
|
10254
|
+
schema.setAttributeProperties('tableCellType', {
|
|
10255
|
+
isFormatting: true
|
|
10256
|
+
});
|
|
10257
|
+
// Upcast conversion for td/th elements.
|
|
10258
|
+
conversion.for('upcast').add((dispatcher)=>{
|
|
10259
|
+
dispatcher.on('element:th', (evt, data, conversionApi)=>{
|
|
10260
|
+
const { writer } = conversionApi;
|
|
10261
|
+
const { modelRange } = data;
|
|
10262
|
+
const modelElement = modelRange?.start.nodeAfter;
|
|
10263
|
+
if (modelElement?.is('element', 'tableCell')) {
|
|
10264
|
+
writer.setAttribute('tableCellType', 'header', modelElement);
|
|
10265
|
+
}
|
|
10266
|
+
});
|
|
10267
|
+
// Table type is examined after all other cell converters, on low priority, so
|
|
10268
|
+
// we double check if there is any `th` left in the table. If so, the table is converted to a content table.
|
|
10269
|
+
dispatcher.on('element:table', (evt, data, conversionApi)=>{
|
|
10270
|
+
const { writer } = conversionApi;
|
|
10271
|
+
const { modelRange } = data;
|
|
10272
|
+
const modelElement = modelRange?.start.nodeAfter;
|
|
10273
|
+
if (modelElement?.is('element', 'table') && modelElement.getAttribute('tableType') === 'layout') {
|
|
10274
|
+
for (const { cell } of new TableWalker(modelElement)){
|
|
10275
|
+
if (cell.getAttribute('tableCellType') === 'header') {
|
|
10276
|
+
writer.setAttribute('tableType', 'content', modelElement);
|
|
10277
|
+
break;
|
|
10278
|
+
}
|
|
10279
|
+
}
|
|
10280
|
+
}
|
|
10281
|
+
}, {
|
|
10282
|
+
priority: priorities.low - 1
|
|
10283
|
+
});
|
|
10284
|
+
});
|
|
10285
|
+
// Registers a post-fixer that ensures the `headingRows` and `headingColumns` attributes
|
|
10286
|
+
// are consistent with the `tableCellType` attribute of the cells. `tableCellType` has priority
|
|
10287
|
+
// over `headingRows` and `headingColumns` and we use it to adjust the heading sections of the table.
|
|
10288
|
+
model.document.registerPostFixer((writer)=>{
|
|
10289
|
+
// 1. Collect all tables that need to be checked.
|
|
10290
|
+
const changes = model.document.differ.getChanges();
|
|
10291
|
+
const tablesToCheck = new Set();
|
|
10292
|
+
for (const change of changes){
|
|
10293
|
+
// Check if headingRows or headingColumns changed.
|
|
10294
|
+
if (change.type === 'attribute' && (change.attributeKey === 'headingRows' || change.attributeKey === 'headingColumns')) {
|
|
10295
|
+
const table = change.range.start.nodeAfter;
|
|
10296
|
+
if (table?.is('element', 'table') && table.root.rootName !== '$graveyard') {
|
|
10297
|
+
tablesToCheck.add(table);
|
|
10298
|
+
}
|
|
10299
|
+
}
|
|
10300
|
+
// Check if tableCellType changed.
|
|
10301
|
+
if (change.type === 'attribute' && change.attributeKey === 'tableCellType') {
|
|
10302
|
+
const cell = change.range.start.nodeAfter;
|
|
10303
|
+
if (cell?.is('element', 'tableCell') && cell.root.rootName !== '$graveyard') {
|
|
10304
|
+
const table = cell.findAncestor('table');
|
|
10305
|
+
if (table) {
|
|
10306
|
+
tablesToCheck.add(table);
|
|
10307
|
+
}
|
|
10308
|
+
}
|
|
10309
|
+
}
|
|
10310
|
+
// Check if new headers were inserted.
|
|
10311
|
+
if (change.type === 'insert' && change.position.nodeAfter) {
|
|
10312
|
+
for (const { item } of model.createRangeOn(change.position.nodeAfter)){
|
|
10313
|
+
if (item.is('element', 'tableCell') && item.getAttribute('tableCellType') && item.root.rootName !== '$graveyard') {
|
|
10314
|
+
const table = item.findAncestor('table');
|
|
10315
|
+
if (table) {
|
|
10316
|
+
tablesToCheck.add(table);
|
|
10317
|
+
}
|
|
10318
|
+
}
|
|
10319
|
+
}
|
|
10320
|
+
}
|
|
10321
|
+
}
|
|
10322
|
+
// 2. Update the attributes of the collected tables.
|
|
10323
|
+
return updateTablesHeadingAttributes(tableUtils, writer, tablesToCheck);
|
|
10324
|
+
});
|
|
10325
|
+
// Refresh the table cells in the editing view when their `tableCellType` attribute changes.
|
|
10326
|
+
model.document.on('change:data', ()=>{
|
|
10327
|
+
const { differ } = model.document;
|
|
10328
|
+
const cellsToReconvert = new Set();
|
|
10329
|
+
for (const change of differ.getChanges()){
|
|
10330
|
+
// If the `tableCellType` attribute changed, the entire cell needs to be re-rendered.
|
|
10331
|
+
if (change.type === 'attribute' && change.attributeKey === 'tableCellType') {
|
|
10332
|
+
const tableCell = change.range.start.nodeAfter;
|
|
10333
|
+
if (tableCell.is('element', 'tableCell')) {
|
|
10334
|
+
cellsToReconvert.add(tableCell);
|
|
10335
|
+
}
|
|
10336
|
+
}
|
|
10337
|
+
}
|
|
10338
|
+
// Reconvert table cells that had their `tableCellType` attribute changed.
|
|
10339
|
+
for (const tableCell of cellsToReconvert){
|
|
10340
|
+
const viewElement = editing.mapper.toViewElement(tableCell);
|
|
10341
|
+
const cellType = tableCell.getAttribute('tableCellType');
|
|
10342
|
+
const expectedElementName = cellType === 'header' ? 'th' : 'td';
|
|
10343
|
+
if (viewElement?.name !== expectedElementName) {
|
|
10344
|
+
editing.reconvertItem(tableCell);
|
|
10345
|
+
}
|
|
10346
|
+
}
|
|
10347
|
+
});
|
|
10348
|
+
}
|
|
9774
10349
|
|
|
9775
10350
|
/**
|
|
9776
10351
|
* The table cell properties feature. Enables support for setting properties of table cells (size, border, background, etc.).
|
|
@@ -14469,6 +15044,9 @@ const propertyToCommandMap$1 = {
|
|
|
14469
15044
|
/**
|
|
14470
15045
|
* An input that allows specifying the table cell background color.
|
|
14471
15046
|
*/ backgroundInput;
|
|
15047
|
+
/**
|
|
15048
|
+
* A dropdown that allows selecting the type of the table cell (data or header).
|
|
15049
|
+
*/ cellTypeDropdown;
|
|
14472
15050
|
/**
|
|
14473
15051
|
* An input that allows specifying the table cell padding.
|
|
14474
15052
|
*/ paddingInput;
|
|
@@ -14507,6 +15085,7 @@ const propertyToCommandMap$1 = {
|
|
|
14507
15085
|
* @param options.backgroundColors A configuration of the background color palette used by the
|
|
14508
15086
|
* {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.
|
|
14509
15087
|
* @param options.defaultTableCellProperties The default table cell properties.
|
|
15088
|
+
* @param options.isTableCellTypeSupported A flag indicating whether the table cell type is supported.
|
|
14510
15089
|
*/ constructor(locale, options){
|
|
14511
15090
|
super(locale);
|
|
14512
15091
|
this.set({
|
|
@@ -14518,11 +15097,13 @@ const propertyToCommandMap$1 = {
|
|
|
14518
15097
|
width: '',
|
|
14519
15098
|
height: '',
|
|
14520
15099
|
horizontalAlignment: '',
|
|
14521
|
-
verticalAlignment: ''
|
|
15100
|
+
verticalAlignment: '',
|
|
15101
|
+
cellType: ''
|
|
14522
15102
|
});
|
|
14523
15103
|
this.options = options;
|
|
14524
15104
|
const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();
|
|
14525
15105
|
const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();
|
|
15106
|
+
const { cellTypeRowLabel, cellTypeDropdown } = this._createCellTypeField();
|
|
14526
15107
|
const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();
|
|
14527
15108
|
const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();
|
|
14528
15109
|
this.focusTracker = new FocusTracker();
|
|
@@ -14532,6 +15113,7 @@ const propertyToCommandMap$1 = {
|
|
|
14532
15113
|
this.borderWidthInput = borderWidthInput;
|
|
14533
15114
|
this.borderColorInput = borderColorInput;
|
|
14534
15115
|
this.backgroundInput = backgroundInput;
|
|
15116
|
+
this.cellTypeDropdown = cellTypeDropdown;
|
|
14535
15117
|
this.paddingInput = this._createPaddingField();
|
|
14536
15118
|
this.widthInput = widthInput;
|
|
14537
15119
|
this.heightInput = heightInput;
|
|
@@ -14565,22 +15147,48 @@ const propertyToCommandMap$1 = {
|
|
|
14565
15147
|
// Border row.
|
|
14566
15148
|
this.children.add(new FormRowView(locale, {
|
|
14567
15149
|
labelView: borderRowLabel,
|
|
14568
|
-
children: [
|
|
15150
|
+
children: this.options.isTableCellTypeSupported ? [
|
|
15151
|
+
borderRowLabel,
|
|
15152
|
+
borderStyleDropdown,
|
|
15153
|
+
borderWidthInput,
|
|
15154
|
+
borderColorInput
|
|
15155
|
+
] : [
|
|
14569
15156
|
borderRowLabel,
|
|
14570
15157
|
borderStyleDropdown,
|
|
14571
15158
|
borderColorInput,
|
|
14572
15159
|
borderWidthInput
|
|
14573
15160
|
],
|
|
14574
|
-
class:
|
|
15161
|
+
class: `ck-table-form__border-row${this.options.isTableCellTypeSupported ? ' ck-table-form__border-row_experimental' : ''}`
|
|
14575
15162
|
}));
|
|
14576
|
-
// Background.
|
|
15163
|
+
// Background and cell type.
|
|
14577
15164
|
this.children.add(new FormRowView(locale, {
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
15165
|
+
children: this.options.isTableCellTypeSupported ? [
|
|
15166
|
+
new FormRowView(locale, {
|
|
15167
|
+
labelView: cellTypeRowLabel,
|
|
15168
|
+
children: [
|
|
15169
|
+
cellTypeRowLabel,
|
|
15170
|
+
cellTypeDropdown
|
|
15171
|
+
],
|
|
15172
|
+
class: 'ck-table-form__cell-type-row'
|
|
15173
|
+
}),
|
|
15174
|
+
new FormRowView(locale, {
|
|
15175
|
+
labelView: backgroundRowLabel,
|
|
15176
|
+
children: [
|
|
15177
|
+
backgroundRowLabel,
|
|
15178
|
+
backgroundInput
|
|
15179
|
+
],
|
|
15180
|
+
class: 'ck-table-form__background-row'
|
|
15181
|
+
})
|
|
15182
|
+
] : [
|
|
15183
|
+
new FormRowView(locale, {
|
|
15184
|
+
labelView: backgroundRowLabel,
|
|
15185
|
+
children: [
|
|
15186
|
+
backgroundRowLabel,
|
|
15187
|
+
backgroundInput
|
|
15188
|
+
],
|
|
15189
|
+
class: 'ck-table-form__background-row'
|
|
15190
|
+
})
|
|
15191
|
+
]
|
|
14584
15192
|
}));
|
|
14585
15193
|
// Dimensions row and padding.
|
|
14586
15194
|
this.children.add(new FormRowView(locale, {
|
|
@@ -14630,7 +15238,9 @@ const propertyToCommandMap$1 = {
|
|
|
14630
15238
|
'ck',
|
|
14631
15239
|
'ck-form',
|
|
14632
15240
|
'ck-table-form',
|
|
14633
|
-
'ck-table-cell-properties-form'
|
|
15241
|
+
'ck-table-cell-properties-form',
|
|
15242
|
+
'ck-table-cell-properties-form_experimental',
|
|
15243
|
+
this.options.isTableCellTypeSupported ? 'ck-table-cell-properties-form_experimental-no-cell-type' : ''
|
|
14634
15244
|
],
|
|
14635
15245
|
// https://github.com/ckeditor/ckeditor5-link/issues/90
|
|
14636
15246
|
tabindex: '-1'
|
|
@@ -14658,6 +15268,7 @@ const propertyToCommandMap$1 = {
|
|
|
14658
15268
|
this.borderStyleDropdown,
|
|
14659
15269
|
this.borderColorInput,
|
|
14660
15270
|
this.borderWidthInput,
|
|
15271
|
+
this.cellTypeDropdown,
|
|
14661
15272
|
this.backgroundInput,
|
|
14662
15273
|
this.widthInput,
|
|
14663
15274
|
this.heightInput,
|
|
@@ -14812,6 +15423,46 @@ const propertyToCommandMap$1 = {
|
|
|
14812
15423
|
backgroundInput
|
|
14813
15424
|
};
|
|
14814
15425
|
}
|
|
15426
|
+
/**
|
|
15427
|
+
* Create cell type field.
|
|
15428
|
+
*
|
|
15429
|
+
* * {@link #cellTypeDropdown}.
|
|
15430
|
+
*
|
|
15431
|
+
* @internal
|
|
15432
|
+
*/ _createCellTypeField() {
|
|
15433
|
+
const locale = this.locale;
|
|
15434
|
+
const t = this.t;
|
|
15435
|
+
const cellTypeRowLabel = new LabelView(locale);
|
|
15436
|
+
cellTypeRowLabel.text = t('Cell type');
|
|
15437
|
+
const cellTypeLabels = this._cellTypeLabels;
|
|
15438
|
+
const cellTypeDropdown = new LabeledFieldView(locale, createLabeledDropdown);
|
|
15439
|
+
cellTypeDropdown.set({
|
|
15440
|
+
label: t('Cell type'),
|
|
15441
|
+
class: 'ck-table-cell-properties-form__cell-type'
|
|
15442
|
+
});
|
|
15443
|
+
cellTypeDropdown.fieldView.buttonView.set({
|
|
15444
|
+
ariaLabel: t('Cell type'),
|
|
15445
|
+
ariaLabelledBy: undefined,
|
|
15446
|
+
isOn: false,
|
|
15447
|
+
withText: true,
|
|
15448
|
+
tooltip: t('Cell type')
|
|
15449
|
+
});
|
|
15450
|
+
cellTypeDropdown.fieldView.buttonView.bind('label').to(this, 'cellType', (value)=>{
|
|
15451
|
+
return cellTypeLabels[value || 'data'];
|
|
15452
|
+
});
|
|
15453
|
+
cellTypeDropdown.fieldView.on('execute', (evt)=>{
|
|
15454
|
+
this.cellType = evt.source._cellTypeValue;
|
|
15455
|
+
});
|
|
15456
|
+
cellTypeDropdown.bind('isEmpty').to(this, 'cellType', (value)=>!value);
|
|
15457
|
+
addListToDropdown(cellTypeDropdown.fieldView, this._getCellTypeDefinitions(), {
|
|
15458
|
+
role: 'menu',
|
|
15459
|
+
ariaLabel: t('Cell type')
|
|
15460
|
+
});
|
|
15461
|
+
return {
|
|
15462
|
+
cellTypeRowLabel,
|
|
15463
|
+
cellTypeDropdown
|
|
15464
|
+
};
|
|
15465
|
+
}
|
|
14815
15466
|
/**
|
|
14816
15467
|
* Creates the following form fields:
|
|
14817
15468
|
*
|
|
@@ -14908,7 +15559,8 @@ const propertyToCommandMap$1 = {
|
|
|
14908
15559
|
horizontalAlignmentToolbar.set({
|
|
14909
15560
|
isCompact: true,
|
|
14910
15561
|
role: 'radiogroup',
|
|
14911
|
-
ariaLabel: t('Horizontal text alignment toolbar')
|
|
15562
|
+
ariaLabel: t('Horizontal text alignment toolbar'),
|
|
15563
|
+
class: 'ck-table-cell-properties-form__horizontal-alignment-toolbar'
|
|
14912
15564
|
});
|
|
14913
15565
|
fillToolbar({
|
|
14914
15566
|
view: this,
|
|
@@ -14934,7 +15586,8 @@ const propertyToCommandMap$1 = {
|
|
|
14934
15586
|
verticalAlignmentToolbar.set({
|
|
14935
15587
|
isCompact: true,
|
|
14936
15588
|
role: 'radiogroup',
|
|
14937
|
-
ariaLabel: t('Vertical text alignment toolbar')
|
|
15589
|
+
ariaLabel: t('Vertical text alignment toolbar'),
|
|
15590
|
+
class: 'ck-table-cell-properties-form__vertical-alignment-toolbar'
|
|
14938
15591
|
});
|
|
14939
15592
|
fillToolbar({
|
|
14940
15593
|
view: this,
|
|
@@ -14999,6 +15652,29 @@ const propertyToCommandMap$1 = {
|
|
|
14999
15652
|
backButton.delegate('execute').to(this, 'cancel');
|
|
15000
15653
|
return backButton;
|
|
15001
15654
|
}
|
|
15655
|
+
/**
|
|
15656
|
+
* Creates the cell type dropdown definitions.
|
|
15657
|
+
*/ _getCellTypeDefinitions() {
|
|
15658
|
+
const itemDefinitions = new Collection();
|
|
15659
|
+
const cellTypeLabels = this._cellTypeLabels;
|
|
15660
|
+
for (const type of [
|
|
15661
|
+
'data',
|
|
15662
|
+
'header'
|
|
15663
|
+
]){
|
|
15664
|
+
const definition = {
|
|
15665
|
+
type: 'button',
|
|
15666
|
+
model: new UIModel({
|
|
15667
|
+
_cellTypeValue: type,
|
|
15668
|
+
label: cellTypeLabels[type],
|
|
15669
|
+
role: 'menuitemradio',
|
|
15670
|
+
withText: true
|
|
15671
|
+
})
|
|
15672
|
+
};
|
|
15673
|
+
definition.model.bind('isOn').to(this, 'cellType', (value)=>value === type);
|
|
15674
|
+
itemDefinitions.add(definition);
|
|
15675
|
+
}
|
|
15676
|
+
return itemDefinitions;
|
|
15677
|
+
}
|
|
15002
15678
|
/**
|
|
15003
15679
|
* Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.
|
|
15004
15680
|
*/ get _horizontalAlignmentLabels() {
|
|
@@ -15035,6 +15711,15 @@ const propertyToCommandMap$1 = {
|
|
|
15035
15711
|
bottom: t('Align cell text to the bottom')
|
|
15036
15712
|
};
|
|
15037
15713
|
}
|
|
15714
|
+
/**
|
|
15715
|
+
* Provides localized labels for {@link #cellTypeDropdown}.
|
|
15716
|
+
*/ get _cellTypeLabels() {
|
|
15717
|
+
const t = this.t;
|
|
15718
|
+
return {
|
|
15719
|
+
data: t('Data cell'),
|
|
15720
|
+
header: t('Header cell')
|
|
15721
|
+
};
|
|
15722
|
+
}
|
|
15038
15723
|
}
|
|
15039
15724
|
function isBorderStyleSet(value) {
|
|
15040
15725
|
return value !== 'none';
|
|
@@ -15051,7 +15736,8 @@ const propertyToCommandMap = {
|
|
|
15051
15736
|
padding: 'tableCellPadding',
|
|
15052
15737
|
backgroundColor: 'tableCellBackgroundColor',
|
|
15053
15738
|
horizontalAlignment: 'tableCellHorizontalAlignment',
|
|
15054
|
-
verticalAlignment: 'tableCellVerticalAlignment'
|
|
15739
|
+
verticalAlignment: 'tableCellVerticalAlignment',
|
|
15740
|
+
cellType: 'tableCellType'
|
|
15055
15741
|
};
|
|
15056
15742
|
/**
|
|
15057
15743
|
* The table cell properties UI plugin. It introduces the `'tableCellProperties'` button
|
|
@@ -15138,7 +15824,7 @@ const propertyToCommandMap = {
|
|
|
15138
15824
|
tooltip: true
|
|
15139
15825
|
});
|
|
15140
15826
|
this.listenTo(view, 'execute', ()=>this._showView());
|
|
15141
|
-
const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));
|
|
15827
|
+
const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName)).filter((val)=>!!val);
|
|
15142
15828
|
view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));
|
|
15143
15829
|
return view;
|
|
15144
15830
|
});
|
|
@@ -15165,11 +15851,13 @@ const propertyToCommandMap = {
|
|
|
15165
15851
|
const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);
|
|
15166
15852
|
const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);
|
|
15167
15853
|
const hasColorPicker = config.colorPicker !== false;
|
|
15854
|
+
const isTableCellTypeSupported = !!editor.config.get('experimentalFlags.tableCellTypeSupport');
|
|
15168
15855
|
const view = new TableCellPropertiesViewExperimental(editor.locale, {
|
|
15169
15856
|
borderColors: localizedBorderColors,
|
|
15170
15857
|
backgroundColors: localizedBackgroundColors,
|
|
15171
15858
|
defaultTableCellProperties,
|
|
15172
|
-
colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false
|
|
15859
|
+
colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false,
|
|
15860
|
+
isTableCellTypeSupported
|
|
15173
15861
|
});
|
|
15174
15862
|
const t = editor.t;
|
|
15175
15863
|
// Render the view so its #element is available for the clickOutsideHandler.
|
|
@@ -15244,6 +15932,11 @@ const propertyToCommandMap = {
|
|
|
15244
15932
|
}));
|
|
15245
15933
|
view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));
|
|
15246
15934
|
view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));
|
|
15935
|
+
const cellTypeCommand = editor.commands.get('tableCellType');
|
|
15936
|
+
if (cellTypeCommand) {
|
|
15937
|
+
view.cellTypeDropdown.bind('isEnabled').to(cellTypeCommand, 'isEnabled');
|
|
15938
|
+
view.on('change:cellType', this._getPropertyChangeCallback('tableCellType'));
|
|
15939
|
+
}
|
|
15247
15940
|
return view;
|
|
15248
15941
|
}
|
|
15249
15942
|
/**
|
|
@@ -15256,12 +15949,24 @@ const propertyToCommandMap = {
|
|
|
15256
15949
|
*/ _fillViewFormFromCommandValues() {
|
|
15257
15950
|
const commands = this.editor.commands;
|
|
15258
15951
|
const borderStyleCommand = commands.get('tableCellBorderStyle');
|
|
15259
|
-
Object.entries(propertyToCommandMap).
|
|
15952
|
+
Object.entries(propertyToCommandMap).flatMap(([property, commandName])=>{
|
|
15953
|
+
const command = commands.get(commandName);
|
|
15954
|
+
if (!command) {
|
|
15955
|
+
return [];
|
|
15956
|
+
}
|
|
15260
15957
|
const propertyKey = property;
|
|
15261
|
-
|
|
15262
|
-
|
|
15958
|
+
let defaultValue;
|
|
15959
|
+
if (propertyKey === 'cellType') {
|
|
15960
|
+
defaultValue = '';
|
|
15961
|
+
} else {
|
|
15962
|
+
defaultValue = this.view === this._viewWithContentTableDefaults ? this._defaultContentTableCellProperties[propertyKey] || '' : this._defaultLayoutTableCellProperties[propertyKey] || '';
|
|
15963
|
+
}
|
|
15964
|
+
const entry = [
|
|
15263
15965
|
property,
|
|
15264
|
-
|
|
15966
|
+
command.value || defaultValue
|
|
15967
|
+
];
|
|
15968
|
+
return [
|
|
15969
|
+
entry
|
|
15265
15970
|
];
|
|
15266
15971
|
}).forEach(([property, value])=>{
|
|
15267
15972
|
// Do not set the `border-color` and `border-width` fields if `border-style:none`.
|
|
@@ -15382,5 +16087,5 @@ const propertyToCommandMap = {
|
|
|
15382
16087
|
}
|
|
15383
16088
|
}
|
|
15384
16089
|
|
|
15385
|
-
export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesUIExperimental, TableCellPropertiesView, TableCellPropertiesViewExperimental, TableCellPropertyCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesUIExperimental, TablePropertiesView, TablePropertiesViewExperimental, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar$1 as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels$1 as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator$1 as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions$1 as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute };
|
|
16090
|
+
export { InsertColumnCommand, InsertRowCommand, InsertTableCommand, InsertTableLayoutCommand, MergeCellCommand, MergeCellsCommand, PlainTableOutput, RemoveColumnCommand, RemoveRowCommand, SelectColumnCommand, SelectRowCommand, SetHeaderColumnCommand, SetHeaderRowCommand, SplitCellCommand, Table, TableAlignmentCommand, TableBackgroundColorCommand, TableBorderColorCommand, TableBorderStyleCommand, TableBorderWidthCommand, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellBackgroundColorCommand, TableCellBorderColorCommand, TableCellBorderStyleCommand, TableCellBorderWidthCommand, TableCellHeightCommand, TableCellHorizontalAlignmentCommand, TableCellPaddingCommand, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellPropertiesUIExperimental, TableCellPropertiesView, TableCellPropertiesViewExperimental, TableCellPropertyCommand, TableCellTypeCommand, TableCellVerticalAlignmentCommand, TableCellWidthCommand, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableHeightCommand, TableKeyboard, TableLayout, TableLayoutEditing, TableLayoutUI, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TablePropertiesUIExperimental, TablePropertiesView, TablePropertiesViewExperimental, TablePropertyCommand, TableSelection, TableToolbar, TableTypeCommand, TableUI, TableUtils, TableWalker, TableWidthCommand, TableWidthsCommand, ToggleTableCaptionCommand, InsertTableView as _InsertTableView, COLUMN_MIN_WIDTH_AS_PERCENTAGE as _TABLE_COLUMN_MIN_WIDTH_AS_PERCENTAGE, COLUMN_MIN_WIDTH_IN_PIXELS as _TABLE_COLUMN_MIN_WIDTH_IN_PIXELS, COLUMN_RESIZE_DISTANCE_THRESHOLD as _TABLE_COLUMN_RESIZE_DISTANCE_THRESHOLD, COLUMN_WIDTH_PRECISION as _TABLE_COLUMN_WIDTH_PRECISION, defaultColors as _TABLE_DEFAULT_COLORS, ColorInputView as _TableColorInputView, MouseEventsObserver as _TableMouseEventsObserver, addDefaultUnitToNumericValue as _addDefaultUnitToNumericValue, adjustLastColumnIndex as _adjustLastTableColumnIndex, adjustLastRowIndex as _adjustLastTableRowIndex, clamp as _clamp, colorFieldValidator as _colorTableFieldValidator, convertParagraphInTableCell as _convertParagraphInTableCell, createEmptyTableCell as _createEmptyTableCell, createFilledArray as _createFilledArray, cropTableToDimensions as _cropTableToDimensions, downcastTable as _downcastTable, downcastTableAttribute as _downcastTableAttribute, downcastAttributeToStyle as _downcastTableAttributeToStyle, downcastCell as _downcastTableCell, downcastTableResizedClass as _downcastTableResizedClass, downcastRow as _downcastTableRow, enableProperty$1 as _enableTableCellProperty, ensureParagraphInTableCell as _ensureParagraphInTableCell, fillToolbar$1 as _fillTableOrCellToolbar, getBalloonCellPositionData as _getBalloonTableCellPositionData, getBalloonTablePositionData as _getBalloonTablePositionData, getBorderStyleLabels$1 as _getBorderTableStyleLabels, getChangedResizedTables as _getChangedResizedTables, getDefaultValueAdjusted as _getDefaultTableValueAdjusted, getDomCellOuterWidth as _getDomTableCellOuterWidth, getElementWidthInPixels as _getElementWidthInPixels, getHorizontallyOverlappingCells as _getHorizontallyOverlappingTableCells, getLabeledColorInputCreator$1 as _getLabeledTableColorInputCreator, getLocalizedColorErrorText as _getLocalizedTableColorErrorText, getLocalizedLengthErrorText as _getLocalizedTableLengthErrorText, getNormalizedDefaultProperties as _getNormalizedDefaultTableBaseProperties, getNormalizedDefaultCellProperties as _getNormalizedDefaultTableCellProperties, getNormalizedDefaultTableProperties as _getNormalizedDefaultTableProperties, getSelectedTableWidget as _getSelectedTableWidget, getSelectionAffectedTable as _getSelectionAffectedTable, getSelectionAffectedTableWidget as _getSelectionAffectedTableWidget, getSingleValue as _getTableBorderBoxSingleValue, getCaptionFromTableModelElement as _getTableCaptionFromModelElement, getCaptionFromModelSelection as _getTableCaptionFromModelSelection, getColumnEdgesIndexes as _getTableColumnEdgesIndexes, getTableColumnElements as _getTableColumnElements, getColumnGroupElement as _getTableColumnGroupElement, getColumnMinWidthAsPercentage as _getTableColumnMinWidthAsPercentage, getTableColumnsWidths as _getTableColumnsWidths, getBorderStyleDefinitions$1 as _getTableOrCellBorderStyleDefinitions, getTableWidgetAncestor as _getTableWidgetAncestor, getTableWidthInPixels as _getTableWidthInPixels, getVerticallyOverlappingCells as _getVerticallyOverlappingTableCells, injectTableCaptionPostFixer as _injectTableCaptionPostFixer, injectTableCellParagraphPostFixer as _injectTableCellParagraphPostFixer, injectTableLayoutPostFixer as _injectTableLayoutPostFixer, isSingleParagraphWithoutAttributes as _isSingleTableParagraphWithoutAttributes, isHeadingColumnCell as _isTableHeadingColumnCell, isTable as _isTableModelElement, lengthFieldValidator as _lengthTableFieldValidator, lineWidthFieldValidator as _lineWidthTableFieldValidator, matchTableCaptionViewElement as _matchTableCaptionViewElement, normalizeColumnWidths as _normalizeTableColumnWidths, removeEmptyColumns as _removeEmptyTableColumns, removeEmptyRows as _removeEmptyTableRows, removeEmptyRowsColumns as _removeEmptyTableRowsColumns, repositionContextualBalloon as _repositionTableContextualBalloon, skipEmptyTableRow as _skipEmptyTableRow, splitHorizontally as _splitTableCellHorizontally, splitVertically as _splitTableCellVertically, sumArray as _sumArray, tableCellRefreshHandler as _tableCellRefreshHandler, tableHeadingsRefreshHandler as _tableHeadingsRefreshHandler, toPrecision as _toPrecision, translateColSpanAttribute as _translateTableColspanAttribute, trimTableCellIfNeeded as _trimTableCellIfNeeded, upcastStyleToAttribute as _upcastNormalizedTableStyleToAttribute, upcastTable as _upcastTable, upcastBorderStyles as _upcastTableBorderStyles, upcastColgroupElement as _upcastTableColgroupElement, upcastTableFigure as _upcastTableFigure, updateColumnElements as _updateTableColumnElements, updateNumericAttribute as _updateTableNumericAttribute };
|
|
15386
16091
|
//# sourceMappingURL=index.js.map
|