@worktile/theia 15.2.1 → 15.3.1
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/constants/default.d.ts +1 -1
- package/esm2020/components/column-resize/column-resize.directive.mjs +5 -1
- package/esm2020/constants/default.mjs +2 -2
- package/esm2020/interfaces/image.mjs +1 -1
- package/esm2020/plugins/image/image.editor.mjs +6 -2
- package/esm2020/plugins/link/edit/link-edit.component.mjs +3 -5
- package/esm2020/plugins/table/components/table.component.mjs +33 -22
- package/esm2020/plugins/table/components/td/td.component.mjs +48 -40
- package/esm2020/plugins/table/components/toolbar/table-options.component.mjs +5 -6
- package/esm2020/plugins/table/components/toolbar/table-toolbar.component.mjs +3 -3
- package/esm2020/plugins/table/table.service.mjs +55 -8
- package/esm2020/plugins/table/table.store.mjs +164 -131
- package/esm2020/plugins/table/utils/cell-position.mjs +31 -10
- package/esm2020/plugins/table/utils/get-min-max-cell-index.mjs +16 -11
- package/esm2020/plugins/table/utils/get-select-cell-node.mjs +8 -1
- package/esm2020/plugins/table/utils/index.mjs +17 -9
- package/esm2020/plugins/table/utils/remove-row-column.mjs +47 -0
- package/esm2020/plugins/table/utils/set-node-options.mjs +11 -0
- package/esm2020/services/table-contextmenu.service.mjs +10 -3
- package/esm2020/utils/dom.mjs +2 -2
- package/esm2020/utils/index.mjs +2 -1
- package/fesm2015/worktile-theia.mjs +1043 -851
- package/fesm2015/worktile-theia.mjs.map +1 -1
- package/fesm2020/worktile-theia.mjs +1047 -857
- package/fesm2020/worktile-theia.mjs.map +1 -1
- package/interfaces/image.d.ts +1 -0
- package/package.json +1 -1
- package/plugins/link/edit/link-edit.component.d.ts +0 -1
- package/plugins/table/components/table.component.d.ts +4 -2
- package/plugins/table/components/td/td.component.d.ts +5 -5
- package/plugins/table/components/toolbar/table-options.component.d.ts +1 -3
- package/plugins/table/table.editor.d.ts +1 -4
- package/plugins/table/table.service.d.ts +22 -4
- package/plugins/table/table.store.d.ts +35 -16
- package/plugins/table/utils/cell-position.d.ts +24 -2
- package/plugins/table/utils/get-min-max-cell-index.d.ts +6 -1
- package/plugins/table/utils/get-select-cell-node.d.ts +1 -0
- package/plugins/table/utils/index.d.ts +16 -8
- package/plugins/table/utils/remove-row-column.d.ts +6 -0
- package/plugins/table/utils/set-node-options.d.ts +3 -0
- package/utils/index.d.ts +1 -0
|
@@ -8,7 +8,7 @@ import * as i1 from 'slate-angular';
|
|
|
8
8
|
import { BaseElementComponent, BaseTextComponent, NODE_TO_PARENT, NODE_TO_INDEX, AngularEditor, hotkeys, IS_SAFARI, ELEMENT_TO_COMPONENT, hasBlockCard, isCardLeft, FAKE_RIGHT_BLOCK_CARD_OFFSET, getPlainText as getPlainText$1, EDITOR_TO_ELEMENT, defaultScrollSelectionIntoView, withAngular, SlateModule } from 'slate-angular';
|
|
9
9
|
import { Range, Element as Element$1, Editor, Node, Span, Path, Text, Point, Transforms, Operation, createEditor } from 'slate';
|
|
10
10
|
import { map, cloneDeep, assign, defaults, groupBy, uniq, isEqual } from 'lodash';
|
|
11
|
-
import { isObject, isArray, isString } from 'ngx-tethys/util';
|
|
11
|
+
import { isObject, isArray, isString, isUndefined } from 'ngx-tethys/util';
|
|
12
12
|
import { TheiaConverter } from '@atinc/selene';
|
|
13
13
|
import { HistoryEditor, withHistory } from 'slate-history';
|
|
14
14
|
import * as i1$1 from 'ngx-tethys/popover';
|
|
@@ -61,8 +61,8 @@ import * as i6$2 from 'ngx-tethys/button';
|
|
|
61
61
|
import { ThyButtonModule } from 'ngx-tethys/button';
|
|
62
62
|
import * as i7$1 from 'ngx-tethys/input-number';
|
|
63
63
|
import { ThyInputNumberModule } from 'ngx-tethys/input-number';
|
|
64
|
-
import { coerceCssPixelValue } from '@angular/cdk/coercion';
|
|
65
64
|
import { PortalInjector, ComponentPortal } from '@angular/cdk/portal';
|
|
65
|
+
import { coerceCssPixelValue } from '@angular/cdk/coercion';
|
|
66
66
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
67
67
|
import { ThyAutocompleteModule } from 'ngx-tethys/autocomplete';
|
|
68
68
|
import { ThyAvatarModule } from 'ngx-tethys/avatar';
|
|
@@ -130,7 +130,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
130
130
|
}] } });
|
|
131
131
|
|
|
132
132
|
const PICTURE_ACCEPTED_UPLOAD_MIME = ['image/png', 'image/jpeg', 'image/gif', 'image/bmp'];
|
|
133
|
-
const PICTURE_ACCEPTED_UPLOAD_SIZE =
|
|
133
|
+
const PICTURE_ACCEPTED_UPLOAD_SIZE = 30;
|
|
134
134
|
const A_TAG_REL_ATTR = 'noopener noreferrer nofollow external ugc';
|
|
135
135
|
const LINK_DEFAULT_TEXT = '链接';
|
|
136
136
|
const TAB_SPACE = ' ';
|
|
@@ -2191,7 +2191,7 @@ function getElementWidth(element) {
|
|
|
2191
2191
|
return coercePixelsFromCssValue(element.style.width) || element.getBoundingClientRect().width;
|
|
2192
2192
|
}
|
|
2193
2193
|
function getElementHeight(element) {
|
|
2194
|
-
return element.getBoundingClientRect().height;
|
|
2194
|
+
return coercePixelsFromCssValue(element.style.height) || element.getBoundingClientRect().height;
|
|
2195
2195
|
}
|
|
2196
2196
|
function getColsTotalWidth(cols) {
|
|
2197
2197
|
return cols.reduce((total, col) => {
|
|
@@ -2436,6 +2436,21 @@ function insertDataByInvalidType(editor, fragment) {
|
|
|
2436
2436
|
return true;
|
|
2437
2437
|
}
|
|
2438
2438
|
|
|
2439
|
+
const isColorPanel = (element) => {
|
|
2440
|
+
const pickerPanel = element.closest('.thy-color-picker-panel');
|
|
2441
|
+
const customPickerPanel = element.closest('.thy-color-picker-custom-panel');
|
|
2442
|
+
if (pickerPanel || customPickerPanel) {
|
|
2443
|
+
return true;
|
|
2444
|
+
}
|
|
2445
|
+
return false;
|
|
2446
|
+
};
|
|
2447
|
+
const isColorIndicator = (element) => {
|
|
2448
|
+
return element.closest('.indicator-hue-alp');
|
|
2449
|
+
};
|
|
2450
|
+
const isColorInput = (element) => {
|
|
2451
|
+
return element.closest('.thy-color-inputs');
|
|
2452
|
+
};
|
|
2453
|
+
|
|
2439
2454
|
const toolbarInitialize = (toolbarItems, global = DefaultGlobalToolbarDefinition, inline = DefaultInlineToolbarDefinition) => {
|
|
2440
2455
|
const toolbarDefinition = {
|
|
2441
2456
|
global,
|
|
@@ -3770,264 +3785,594 @@ function isInside(cellRect, rowIndex, columnIndex) {
|
|
|
3770
3785
|
return false;
|
|
3771
3786
|
}
|
|
3772
3787
|
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3788
|
+
function isVirtualKey(e) {
|
|
3789
|
+
const isMod = e.ctrlKey || e.metaKey;
|
|
3790
|
+
const isAlt = isKeyHotkey('alt', e);
|
|
3791
|
+
const isShift = isKeyHotkey('shift', e);
|
|
3792
|
+
const isCapsLock = e.key.includes('CapsLock');
|
|
3793
|
+
const isTab = e.key.includes('Tab');
|
|
3794
|
+
const isEsc = e.key.includes('Escape');
|
|
3795
|
+
const isF = e.key.startsWith('F');
|
|
3796
|
+
const isArrow = e.key.includes('Arrow') ? true : false;
|
|
3797
|
+
return isCapsLock || isMod || isAlt || isArrow || isShift || isTab || isEsc || isF;
|
|
3798
|
+
}
|
|
3799
|
+
|
|
3800
|
+
/**
|
|
3801
|
+
* 获取标题行网格列宽值
|
|
3802
|
+
* @param editor
|
|
3803
|
+
* @param headerRow 标题行
|
|
3804
|
+
* @param cellsWidth
|
|
3805
|
+
* @returns string
|
|
3806
|
+
*/
|
|
3807
|
+
const getGridColumns = (headerRow, cellsWidth) => {
|
|
3808
|
+
let result = '';
|
|
3809
|
+
Array.from(headerRow.childNodes)
|
|
3810
|
+
.filter((n) => n.nodeType === 1)
|
|
3811
|
+
.forEach((node, i) => {
|
|
3812
|
+
const col = node.getAttribute('colspan');
|
|
3813
|
+
const display = node.style.display;
|
|
3814
|
+
if (display === 'none') {
|
|
3815
|
+
return;
|
|
3816
|
+
}
|
|
3817
|
+
if (col) {
|
|
3818
|
+
const colSpan = Number(col) ?? 1;
|
|
3819
|
+
let width = 0;
|
|
3820
|
+
Array.from({ length: colSpan }, (_, j) => {
|
|
3821
|
+
width += cellsWidth[i + j];
|
|
3822
|
+
});
|
|
3823
|
+
result += width + 'px ';
|
|
3824
|
+
}
|
|
3825
|
+
else {
|
|
3826
|
+
result += cellsWidth[i] + 'px ';
|
|
3827
|
+
}
|
|
3778
3828
|
});
|
|
3829
|
+
return result;
|
|
3779
3830
|
};
|
|
3780
|
-
|
|
3781
|
-
const
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
for (const key in marks) {
|
|
3789
|
-
Editor.removeMark(editor, key);
|
|
3831
|
+
const getColumnsWidth = (cellRow, isColgroup = false) => {
|
|
3832
|
+
const result = [];
|
|
3833
|
+
Array.from(cellRow.childNodes)
|
|
3834
|
+
.filter((n) => n.nodeType === 1)
|
|
3835
|
+
.forEach((item) => {
|
|
3836
|
+
if (isColgroup && IS_SAFARI) {
|
|
3837
|
+
result.push(item.offsetWidth);
|
|
3838
|
+
return;
|
|
3790
3839
|
}
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
});
|
|
3797
|
-
setMarks(editor, unsetMarks);
|
|
3798
|
-
}
|
|
3840
|
+
if (item.getBoundingClientRect) {
|
|
3841
|
+
result.push(item.getBoundingClientRect().width);
|
|
3842
|
+
}
|
|
3843
|
+
});
|
|
3844
|
+
return result;
|
|
3799
3845
|
};
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
const
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
});
|
|
3821
|
-
return;
|
|
3822
|
-
}
|
|
3823
|
-
const nextPath = Path.next([anchorBlockPath[0]]);
|
|
3824
|
-
Transforms.insertNodes(editor, elements, { at: nextPath });
|
|
3825
|
-
if (isEmpty && anchorBlockPath.length === 1) {
|
|
3826
|
-
Transforms.delete(editor, { at: anchorBlockPath });
|
|
3827
|
-
Transforms.select(editor, Editor.start(editor, anchorBlockPath));
|
|
3846
|
+
/**
|
|
3847
|
+
* 计算表格列宽
|
|
3848
|
+
* @param isReadonly
|
|
3849
|
+
* @param element
|
|
3850
|
+
* @param tableWidth
|
|
3851
|
+
* @param mode
|
|
3852
|
+
* @returns number[]
|
|
3853
|
+
*/
|
|
3854
|
+
const calcColumnGroups = (isReadonly, element, tableWidth, mode) => {
|
|
3855
|
+
const columns = element?.columns;
|
|
3856
|
+
if (isReadonly) {
|
|
3857
|
+
if (columns) {
|
|
3858
|
+
const opts = new TableOptions();
|
|
3859
|
+
const isPrint = mode === TheMode.print;
|
|
3860
|
+
const newColumns = isPrint
|
|
3861
|
+
? calcPrintColumnWidth(element, opts.minWidthPx)
|
|
3862
|
+
: calcColumnWidth(element, tableWidth, opts.minWidthPx);
|
|
3863
|
+
return newColumns;
|
|
3864
|
+
}
|
|
3865
|
+
return [];
|
|
3828
3866
|
}
|
|
3829
3867
|
else {
|
|
3830
|
-
|
|
3868
|
+
return columns;
|
|
3831
3869
|
}
|
|
3832
3870
|
};
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3871
|
+
/**
|
|
3872
|
+
* 计算表格列宽
|
|
3873
|
+
* @param element
|
|
3874
|
+
* @param tableWidth
|
|
3875
|
+
* @param minWidthPx
|
|
3876
|
+
* @returns number[]
|
|
3877
|
+
*/
|
|
3878
|
+
const calcColumnWidth = (element, tableWidth, minWidthPx) => {
|
|
3879
|
+
const columns = element?.columns;
|
|
3880
|
+
const numberedColumnWidth = element?.options?.numberedColumn ? TABLE_NUMBER_COLUMN : 0;
|
|
3881
|
+
const columnsWidth = columns.reduce((a, b) => a + b.width, 0);
|
|
3882
|
+
// 总列宽大于当前表格宽度时,按照设置时的总列宽计算
|
|
3883
|
+
const columnTotalWidth = Math.max(columnsWidth, tableWidth - numberedColumnWidth);
|
|
3884
|
+
return columns.map(column => {
|
|
3885
|
+
const cellWidth = (column.width / columnsWidth) * columnTotalWidth;
|
|
3886
|
+
return { width: Math.max(cellWidth, minWidthPx) };
|
|
3887
|
+
});
|
|
3836
3888
|
};
|
|
3837
|
-
|
|
3838
3889
|
/**
|
|
3839
|
-
*
|
|
3890
|
+
* 打印模式下,按照原宽度比例基于当前表格宽度计算列宽
|
|
3891
|
+
* 1. 所有列的最小列宽总和大于表格宽度时,所有列返回最小宽度
|
|
3892
|
+
* @param element
|
|
3893
|
+
* @param minWidthPx
|
|
3894
|
+
* @returns number[]
|
|
3840
3895
|
*/
|
|
3841
|
-
const
|
|
3842
|
-
|
|
3843
|
-
|
|
3896
|
+
const calcPrintColumnWidth = (element, minWidthPx) => {
|
|
3897
|
+
const columns = element?.columns;
|
|
3898
|
+
const numberedColumnWidth = element?.options?.numberedColumn ? TABLE_NUMBER_COLUMN : 0;
|
|
3899
|
+
// 按照 DPI 96 的 A4 纸宽度是 794, 打印时左右 80px 的边距,所以这里取 794 - 80 * 2 = 634
|
|
3900
|
+
// 如果存在序号列,还需要在 634 基础上减去序号列的宽度,剩下的才是内容区域的宽度
|
|
3901
|
+
let columnTotalWidth = 634 - numberedColumnWidth;
|
|
3902
|
+
const columnsWidth = columns.reduce((a, b) => a + b.width, 0);
|
|
3903
|
+
// 计算所有列的 minWidth 总和
|
|
3904
|
+
const totalMinWidth = minWidthPx * columns.length;
|
|
3905
|
+
if (totalMinWidth > columnTotalWidth) {
|
|
3906
|
+
// 如果所有列的 minWidth 总和大于 columnTotalWidth,所有列返回最小宽度
|
|
3907
|
+
return columns.map(() => ({ width: minWidthPx }));
|
|
3844
3908
|
}
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3909
|
+
// 在剩余的宽度中按比例分配
|
|
3910
|
+
const remainingWidth = columnTotalWidth - totalMinWidth;
|
|
3911
|
+
const remainingWidthRatio = columns.map(column => column.width / columnsWidth);
|
|
3912
|
+
// 为什么减 1, 因为这个宽度是内容区域宽度,但 td 右侧还有一个边框,所以减去 1
|
|
3913
|
+
let newColumnsWidth = remainingWidthRatio.map(ratio => minWidthPx + Math.floor(ratio * remainingWidth) - 1);
|
|
3914
|
+
return columns.map((_, index) => ({
|
|
3915
|
+
width: newColumnsWidth[index]
|
|
3916
|
+
}));
|
|
3849
3917
|
};
|
|
3850
3918
|
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
onReset(editor);
|
|
3862
|
-
reset = true;
|
|
3863
|
-
}
|
|
3864
|
-
}
|
|
3865
|
-
});
|
|
3919
|
+
/* cell-position 有关的函数 */
|
|
3920
|
+
/**
|
|
3921
|
+
* 判断是否选中了所有的单元格
|
|
3922
|
+
* @param editor 编辑器对象
|
|
3923
|
+
* @param selectedCellPositions 选中的单元格位置数组
|
|
3924
|
+
* @returns 是否选中了所有的单元格
|
|
3925
|
+
*/
|
|
3926
|
+
const isSelectedAllCell = (editor, selectedCellPositions) => {
|
|
3927
|
+
if (!AngularEditor.isFocused(editor)) {
|
|
3928
|
+
return false;
|
|
3866
3929
|
}
|
|
3867
|
-
|
|
3930
|
+
const pos = createTablePosition(editor);
|
|
3931
|
+
return !!selectedCellPositions.length && pos.getHeight() * pos.getWidth() === selectedCellPositions.length;
|
|
3868
3932
|
};
|
|
3869
|
-
|
|
3870
3933
|
/**
|
|
3871
|
-
*
|
|
3934
|
+
* 获取选中的单元格位置数组
|
|
3935
|
+
* @param editor 编辑器对象
|
|
3936
|
+
* @param selectedCells 选中的单元格
|
|
3937
|
+
* @returns 选中的单元格位置
|
|
3872
3938
|
*/
|
|
3873
|
-
const
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3939
|
+
const getSelectedCellPositions = (editor, selectedCells) => {
|
|
3940
|
+
return selectedCells?.map((cell) => {
|
|
3941
|
+
const path = AngularEditor.findPath(editor, cell);
|
|
3942
|
+
const [row, col] = path.slice(-2);
|
|
3943
|
+
return { row, col };
|
|
3944
|
+
});
|
|
3945
|
+
};
|
|
3946
|
+
/**
|
|
3947
|
+
* 获取一定范围内所有的单元格位置
|
|
3948
|
+
* @param startRow 起始行
|
|
3949
|
+
* @param startCol 起始列
|
|
3950
|
+
* @param endRow 结束行
|
|
3951
|
+
* @param endCol 结束列
|
|
3952
|
+
* @returns 单元格位置
|
|
3953
|
+
*/
|
|
3954
|
+
const getCellPositionsFromRange = (startRow, startCol, endRow, endCol) => {
|
|
3955
|
+
const positions = [];
|
|
3956
|
+
for (let row = startRow; row < endRow; row++) {
|
|
3957
|
+
for (let col = startCol; col < endCol; col++) {
|
|
3958
|
+
positions.push({ row, col });
|
|
3885
3959
|
}
|
|
3886
3960
|
}
|
|
3887
|
-
return
|
|
3888
|
-
};
|
|
3889
|
-
|
|
3890
|
-
const insertParagraph = (editor, at) => {
|
|
3891
|
-
Transforms.insertNodes(editor, createEmptyParagraph(), { at });
|
|
3961
|
+
return positions;
|
|
3892
3962
|
};
|
|
3893
|
-
|
|
3894
3963
|
/**
|
|
3895
|
-
*
|
|
3964
|
+
* 过滤重复的单元格位置
|
|
3965
|
+
* @param cells 单元格数组
|
|
3966
|
+
* @param selectedCellPositions 选中的单元格位置数组
|
|
3967
|
+
* @returns 过滤后的单元格位置数组
|
|
3896
3968
|
*/
|
|
3897
|
-
const
|
|
3898
|
-
const
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3969
|
+
const uniqueCellPosition = (cells, selectedCellPositions) => {
|
|
3970
|
+
const positions = [];
|
|
3971
|
+
const modCells = new Set();
|
|
3972
|
+
cells.concat(selectedCellPositions).forEach(cell => modCells.add(JSON.stringify(cell)));
|
|
3973
|
+
modCells.forEach((cell) => positions.push(JSON.parse(cell)));
|
|
3974
|
+
return positions;
|
|
3975
|
+
};
|
|
3976
|
+
|
|
3977
|
+
/**
|
|
3978
|
+
* 计算最小行跨距单元格
|
|
3979
|
+
* @param element TableElement
|
|
3980
|
+
* @returns
|
|
3981
|
+
*/
|
|
3982
|
+
const calculateMinRowSpanCellForRows = (element) => {
|
|
3983
|
+
const cells = element.children.map((row, index) => {
|
|
3984
|
+
const noHiddenCells = row.children.filter(cell => !cell.hidden);
|
|
3985
|
+
if (noHiddenCells.length > 0) {
|
|
3986
|
+
const minRowspan = Math.min.apply(Math, noHiddenCells.map(cell => {
|
|
3987
|
+
return cell.rowspan || 1;
|
|
3988
|
+
}));
|
|
3989
|
+
const cell = row.children.find(item => !item.hidden && (item.rowspan || 1) === minRowspan);
|
|
3990
|
+
return {
|
|
3991
|
+
cell,
|
|
3992
|
+
rowIndex: index
|
|
3993
|
+
};
|
|
3902
3994
|
}
|
|
3903
3995
|
else {
|
|
3904
|
-
|
|
3996
|
+
return {
|
|
3997
|
+
rowIndex: index
|
|
3998
|
+
};
|
|
3905
3999
|
}
|
|
3906
|
-
}
|
|
3907
|
-
if (!isAncestor(node)) {
|
|
3908
|
-
return;
|
|
3909
|
-
}
|
|
3910
|
-
node.children.forEach((child) => {
|
|
3911
|
-
applyDeepToNodes({ node: child, source, apply, query });
|
|
3912
4000
|
});
|
|
4001
|
+
return cells;
|
|
3913
4002
|
};
|
|
3914
|
-
|
|
3915
4003
|
/**
|
|
3916
|
-
*
|
|
4004
|
+
* 计算行控件的平均高度
|
|
4005
|
+
* @param previousCombineRowIndex
|
|
4006
|
+
* @param previousRowIndex
|
|
4007
|
+
* @param rowControls
|
|
3917
4008
|
*/
|
|
3918
|
-
const
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
const
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
});
|
|
4009
|
+
const calculateRowControlsAvgHeight = (previousCombineRowIndex, previousRowIndex, rowControls) => {
|
|
4010
|
+
const rowControl = rowControls[previousRowIndex];
|
|
4011
|
+
const count = previousCombineRowIndex - previousRowIndex;
|
|
4012
|
+
const avgHeight = Math.floor(rowControl.height / (count + 1));
|
|
4013
|
+
const firstHeight = rowControl.height - avgHeight * count;
|
|
4014
|
+
rowControl.height = firstHeight;
|
|
4015
|
+
rowControls
|
|
4016
|
+
.filter((_, index) => index > previousRowIndex && index <= previousCombineRowIndex)
|
|
4017
|
+
.forEach(rowControl => {
|
|
4018
|
+
rowControl.height = avgHeight;
|
|
3929
4019
|
});
|
|
3930
4020
|
};
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
4021
|
+
const getBelowRowHeight = (editor, cells, index, rowIndex, rowspan) => {
|
|
4022
|
+
let belowRowlHeight = 0;
|
|
4023
|
+
cells.slice(index + 1, cells.length).map(item => {
|
|
4024
|
+
if (!item.cell) {
|
|
4025
|
+
return;
|
|
4026
|
+
}
|
|
4027
|
+
if (rowIndex + rowspan > item.rowIndex) {
|
|
4028
|
+
const cellDom = AngularEditor.toDOMNode(editor, item.cell);
|
|
4029
|
+
if (item.cell.rowspan > 1) {
|
|
4030
|
+
// 如果下方单元格的rowspan > 1,递归计算
|
|
4031
|
+
const height = getBelowRowHeight(editor, cells, cells.findIndex(cell => cell.rowIndex === item.rowIndex), item.rowIndex, item.cell.rowspan);
|
|
4032
|
+
belowRowlHeight += getElementHeight(cellDom) - height;
|
|
4033
|
+
}
|
|
4034
|
+
else {
|
|
4035
|
+
belowRowlHeight += getElementHeight(cellDom);
|
|
4036
|
+
}
|
|
4037
|
+
}
|
|
4038
|
+
});
|
|
4039
|
+
return belowRowlHeight;
|
|
3938
4040
|
};
|
|
3939
|
-
|
|
3940
|
-
const
|
|
3941
|
-
const
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
4041
|
+
const calculateRowControls = (editor, element) => {
|
|
4042
|
+
const minRowSpanCellForRows = calculateMinRowSpanCellForRows(element);
|
|
4043
|
+
const rowControls = [];
|
|
4044
|
+
let previousRowIndex = 0;
|
|
4045
|
+
let previousCombineRowIndex = 0;
|
|
4046
|
+
minRowSpanCellForRows.forEach((cellInfo, index) => {
|
|
4047
|
+
if (!cellInfo.cell) {
|
|
4048
|
+
rowControls.push({
|
|
4049
|
+
height: 0,
|
|
4050
|
+
rowIndex: index
|
|
4051
|
+
});
|
|
4052
|
+
previousCombineRowIndex = index;
|
|
4053
|
+
if (index === minRowSpanCellForRows.length - 1) {
|
|
4054
|
+
calculateRowControlsAvgHeight(previousCombineRowIndex, previousRowIndex, rowControls);
|
|
4055
|
+
}
|
|
4056
|
+
return;
|
|
4057
|
+
}
|
|
4058
|
+
// calculate combine row height
|
|
4059
|
+
if (previousCombineRowIndex > previousRowIndex) {
|
|
4060
|
+
calculateRowControlsAvgHeight(previousCombineRowIndex, previousRowIndex, rowControls);
|
|
4061
|
+
previousCombineRowIndex = 0;
|
|
4062
|
+
}
|
|
4063
|
+
const cellDom = AngularEditor.toDOMNode(editor, cellInfo.cell);
|
|
4064
|
+
let height = getElementHeight(cellDom);
|
|
4065
|
+
// 当cell为合并的单元格(rowspan > 1),计算其实际高度(当前单元格的高度 - 下方合并单元格的高度)
|
|
4066
|
+
if (cellInfo.cell.rowspan > 1) {
|
|
4067
|
+
const calcHeight = height - getBelowRowHeight(editor, minRowSpanCellForRows, index, cellInfo.rowIndex, cellInfo.cell.rowspan);
|
|
4068
|
+
rowControls.push({
|
|
4069
|
+
height: calcHeight,
|
|
4070
|
+
rowIndex: cellInfo.rowIndex
|
|
4071
|
+
});
|
|
4072
|
+
}
|
|
4073
|
+
else {
|
|
4074
|
+
rowControls.push({
|
|
4075
|
+
height,
|
|
4076
|
+
rowIndex: cellInfo.rowIndex
|
|
4077
|
+
});
|
|
4078
|
+
}
|
|
4079
|
+
previousRowIndex = index;
|
|
4080
|
+
});
|
|
4081
|
+
return rowControls;
|
|
3945
4082
|
};
|
|
3946
4083
|
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
4084
|
+
/**
|
|
4085
|
+
* compatible with old data
|
|
4086
|
+
* @returns
|
|
4087
|
+
*/
|
|
4088
|
+
function isHeaderRow(element) {
|
|
4089
|
+
if (element?.options?.headerRow) {
|
|
4090
|
+
return true;
|
|
3951
4091
|
}
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
const highestBlock = aboveResult[0];
|
|
3956
|
-
const lowestBlock = anchorBlock(editor);
|
|
3957
|
-
const wrapBlockType = highestBlock.type;
|
|
3958
|
-
if (lowestBlock && Editor.isStart(editor, editor.selection.anchor, aboveResult[1])) {
|
|
3959
|
-
if (wrapBlockType === type) {
|
|
3960
|
-
if (highestBlock.children[0] === lowestBlock) {
|
|
3961
|
-
unWrap(editor, wrapBlockType);
|
|
3962
|
-
return true;
|
|
3963
|
-
}
|
|
3964
|
-
}
|
|
4092
|
+
// compat old data
|
|
4093
|
+
if (element?.children[0].header) {
|
|
4094
|
+
return true;
|
|
3965
4095
|
}
|
|
3966
|
-
return false;
|
|
3967
4096
|
}
|
|
3968
4097
|
|
|
3969
|
-
function
|
|
3970
|
-
const
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
unWrap(editor, wrapBlock.type);
|
|
3980
|
-
return true;
|
|
3981
|
-
}
|
|
4098
|
+
function getSelectCellNode(editor, selectedCells) {
|
|
4099
|
+
const pos = createTablePosition(editor);
|
|
4100
|
+
return selectedCells
|
|
4101
|
+
.map(item => {
|
|
4102
|
+
const node = pos.findCellByPath(item);
|
|
4103
|
+
if (node) {
|
|
4104
|
+
return {
|
|
4105
|
+
...item,
|
|
4106
|
+
node: node
|
|
4107
|
+
};
|
|
3982
4108
|
}
|
|
3983
|
-
}
|
|
3984
|
-
|
|
4109
|
+
})
|
|
4110
|
+
.filter(item => item);
|
|
4111
|
+
}
|
|
4112
|
+
function focusCell(editor, path) {
|
|
4113
|
+
const at = Editor.start(editor, path);
|
|
4114
|
+
TheEditor.focus(editor);
|
|
4115
|
+
Transforms.select(editor, at);
|
|
3985
4116
|
}
|
|
3986
4117
|
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
handleContinualInsertBreak: handleContinualInsertBreak,
|
|
3995
|
-
insertElements: insertElements,
|
|
3996
|
-
insertParagraph: insertParagraph,
|
|
3997
|
-
mergeDeepToNodes: mergeDeepToNodes,
|
|
3998
|
-
moveChildren: moveChildren,
|
|
3999
|
-
onKeyDownResetBlockType: onKeyDownResetBlockType,
|
|
4000
|
-
setEndSelection: setEndSelection,
|
|
4001
|
-
setMarks: setMarks,
|
|
4002
|
-
setNode: setNode,
|
|
4003
|
-
unWrap: unWrap,
|
|
4004
|
-
unwrapNodesByType: unwrapNodesByType
|
|
4005
|
-
});
|
|
4118
|
+
const setMarks = (editor, marks, at) => {
|
|
4119
|
+
Transforms.setNodes(editor, marks, {
|
|
4120
|
+
at,
|
|
4121
|
+
match: Text.isText,
|
|
4122
|
+
split: true
|
|
4123
|
+
});
|
|
4124
|
+
};
|
|
4006
4125
|
|
|
4007
|
-
|
|
4008
|
-
* Insert a new table
|
|
4009
|
-
*/
|
|
4010
|
-
function insertTable(opts, editor, rows = 3, columns = 3, getCellContent) {
|
|
4126
|
+
const clearMarks = (editor) => {
|
|
4011
4127
|
const { selection } = editor;
|
|
4012
|
-
if (!selection
|
|
4128
|
+
if (!selection) {
|
|
4013
4129
|
return;
|
|
4014
4130
|
}
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4131
|
+
if (Range.isCollapsed(selection)) {
|
|
4132
|
+
const marks = Editor.marks(editor);
|
|
4133
|
+
for (const key in marks) {
|
|
4134
|
+
Editor.removeMark(editor, key);
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4137
|
+
else {
|
|
4138
|
+
const unsetMarks = {};
|
|
4139
|
+
MarkProps.forEach(key => {
|
|
4140
|
+
unsetMarks[key] = null;
|
|
4141
|
+
});
|
|
4142
|
+
setMarks(editor, unsetMarks);
|
|
4143
|
+
}
|
|
4144
|
+
};
|
|
4019
4145
|
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
const
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4146
|
+
const insertElements = (editor, elements) => {
|
|
4147
|
+
if (!editor.selection) {
|
|
4148
|
+
refocus(editor);
|
|
4149
|
+
}
|
|
4150
|
+
if (Range.isExpanded(editor.selection)) {
|
|
4151
|
+
Editor.deleteFragment(editor);
|
|
4152
|
+
}
|
|
4153
|
+
const type = !isArray(elements) ? elements.type : elements[0].type; // 后期处理复制粘贴需要修改
|
|
4154
|
+
const allowParentTypes = getPluginOptions(editor, type)?.allowParentTypes || [];
|
|
4155
|
+
const insertNodePath = getInsertElementsPath(editor, allowParentTypes);
|
|
4156
|
+
const [anchorBlock, anchorBlockPath] = anchorBlockEntry(editor);
|
|
4157
|
+
let isEmpty = Editor.isEmpty(editor, anchorBlock);
|
|
4158
|
+
if (insertNodePath) {
|
|
4159
|
+
Editor.withoutNormalizing(editor, () => {
|
|
4160
|
+
Transforms.insertNodes(editor, elements, { at: insertNodePath });
|
|
4161
|
+
Transforms.select(editor, Editor.start(editor, insertNodePath));
|
|
4162
|
+
if (isEmpty) {
|
|
4163
|
+
Transforms.removeNodes(editor, { at: anchorBlockPath });
|
|
4164
|
+
}
|
|
4165
|
+
});
|
|
4166
|
+
return;
|
|
4167
|
+
}
|
|
4168
|
+
const nextPath = Path.next([anchorBlockPath[0]]);
|
|
4169
|
+
Transforms.insertNodes(editor, elements, { at: nextPath });
|
|
4170
|
+
if (isEmpty && anchorBlockPath.length === 1) {
|
|
4171
|
+
Transforms.delete(editor, { at: anchorBlockPath });
|
|
4172
|
+
Transforms.select(editor, Editor.start(editor, anchorBlockPath));
|
|
4173
|
+
}
|
|
4174
|
+
else {
|
|
4175
|
+
Transforms.select(editor, Editor.start(editor, nextPath));
|
|
4176
|
+
}
|
|
4177
|
+
};
|
|
4178
|
+
|
|
4179
|
+
const setNode = (editor, props, origin) => {
|
|
4180
|
+
Transforms.setNodes(editor, props, { at: findPath(editor, origin) });
|
|
4181
|
+
};
|
|
4182
|
+
|
|
4183
|
+
/**
|
|
4184
|
+
* Unwrap nodes by type
|
|
4185
|
+
*/
|
|
4186
|
+
const unwrapNodesByType = (editor, types, options = {}) => {
|
|
4187
|
+
if (!Array.isArray(types)) {
|
|
4188
|
+
types = [types];
|
|
4189
|
+
}
|
|
4190
|
+
Transforms.unwrapNodes(editor, {
|
|
4191
|
+
match: n => Element$1.isElement(n) && types.includes(n.type),
|
|
4192
|
+
...options
|
|
4193
|
+
});
|
|
4194
|
+
};
|
|
4195
|
+
|
|
4196
|
+
const onKeyDownResetBlockType = ({ rules }) => (event, editor) => {
|
|
4197
|
+
let reset;
|
|
4198
|
+
if (editor.selection && isCollapsed(editor.selection)) {
|
|
4199
|
+
rules.forEach(({ types, defaultType, hotkey, predicate, onReset }) => {
|
|
4200
|
+
if (!event || (hotkey && isKeyHotkey(hotkey, event))) {
|
|
4201
|
+
if (predicate(editor) && isNodeTypeIn(editor, types)) {
|
|
4202
|
+
if (event !== null) {
|
|
4203
|
+
event.preventDefault();
|
|
4204
|
+
}
|
|
4205
|
+
Transforms.setNodes(editor, { type: defaultType });
|
|
4206
|
+
onReset(editor);
|
|
4207
|
+
reset = true;
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
return reset;
|
|
4213
|
+
};
|
|
4214
|
+
|
|
4215
|
+
/**
|
|
4216
|
+
* 将节点的子级移动到路径。 返回移动的子级数。
|
|
4217
|
+
*/
|
|
4218
|
+
const moveChildren = (editor, { at, to, match, start = 0 }) => {
|
|
4219
|
+
let moved = 0;
|
|
4220
|
+
const parentPath = Path.isPath(at) ? at : at[1];
|
|
4221
|
+
const parentNode = Path.isPath(at) ? Node.get(editor, parentPath) : at[0];
|
|
4222
|
+
if (!Editor.isBlock(editor, parentNode))
|
|
4223
|
+
return moved;
|
|
4224
|
+
for (let i = parentNode.children.length - 1; i >= start; i--) {
|
|
4225
|
+
const childPath = [...parentPath, i];
|
|
4226
|
+
const childNode = getNode(editor, childPath);
|
|
4227
|
+
if (!match || (childNode && match([childNode, childPath]))) {
|
|
4228
|
+
Transforms.moveNodes(editor, { at: childPath, to });
|
|
4229
|
+
moved++;
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
return moved;
|
|
4233
|
+
};
|
|
4234
|
+
|
|
4235
|
+
const insertParagraph = (editor, at) => {
|
|
4236
|
+
Transforms.insertNodes(editor, createEmptyParagraph(), { at });
|
|
4237
|
+
};
|
|
4238
|
+
|
|
4239
|
+
/**
|
|
4240
|
+
* Recursively apply an operation to children nodes with a query.
|
|
4241
|
+
*/
|
|
4242
|
+
const applyDeepToNodes = ({ node, source, apply, query }) => {
|
|
4243
|
+
const entry = [node, []];
|
|
4244
|
+
if (isNodeType(entry, query)) {
|
|
4245
|
+
if (source instanceof Function) {
|
|
4246
|
+
apply(node, source());
|
|
4247
|
+
}
|
|
4248
|
+
else {
|
|
4249
|
+
apply(node, source);
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
if (!isAncestor(node)) {
|
|
4253
|
+
return;
|
|
4254
|
+
}
|
|
4255
|
+
node.children.forEach((child) => {
|
|
4256
|
+
applyDeepToNodes({ node: child, source, apply, query });
|
|
4257
|
+
});
|
|
4258
|
+
};
|
|
4259
|
+
|
|
4260
|
+
/**
|
|
4261
|
+
* Recursively merge a source object to children nodes with a query.
|
|
4262
|
+
*/
|
|
4263
|
+
const mergeDeepToNodes = (options) => {
|
|
4264
|
+
applyDeepToNodes({ ...options, apply: defaults });
|
|
4265
|
+
};
|
|
4266
|
+
|
|
4267
|
+
const unWrap = (editor, kind) => {
|
|
4268
|
+
Editor.withoutNormalizing(editor, () => {
|
|
4269
|
+
Transforms.setNodes(editor, { type: ElementKinds.paragraph });
|
|
4270
|
+
Transforms.unwrapNodes(editor, {
|
|
4271
|
+
match: n => Element$1.isElement(n) && n.type === kind,
|
|
4272
|
+
split: true
|
|
4273
|
+
});
|
|
4274
|
+
});
|
|
4275
|
+
};
|
|
4276
|
+
|
|
4277
|
+
const deleteElement = (editor, element) => {
|
|
4278
|
+
const at = findPath(editor, element);
|
|
4279
|
+
Transforms.insertNodes(editor, createEmptyParagraph(), { at });
|
|
4280
|
+
AngularEditor.focus(editor);
|
|
4281
|
+
Transforms.select(editor, at);
|
|
4282
|
+
Transforms.removeNodes(editor, { at: Path.next(at) });
|
|
4283
|
+
};
|
|
4284
|
+
|
|
4285
|
+
const setEndSelection = (editor) => {
|
|
4286
|
+
const lastNode = getLastNode(editor, 1);
|
|
4287
|
+
const end = Editor.end(editor, lastNode[1]);
|
|
4288
|
+
Transforms.select(editor, end);
|
|
4289
|
+
AngularEditor.focus(editor);
|
|
4290
|
+
};
|
|
4291
|
+
|
|
4292
|
+
const closeConversionHint = (editor) => {
|
|
4293
|
+
const hintRef = THE_EDITOR_CONVERSION_HINT_REF.get(editor);
|
|
4294
|
+
if (hintRef) {
|
|
4295
|
+
hintRef.close();
|
|
4296
|
+
}
|
|
4297
|
+
};
|
|
4298
|
+
|
|
4299
|
+
function handleContinualDeleteBackward(editor, aboveResult, type) {
|
|
4300
|
+
const highestBlock = aboveResult[0];
|
|
4301
|
+
const lowestBlock = anchorBlock(editor);
|
|
4302
|
+
const wrapBlockType = highestBlock.type;
|
|
4303
|
+
if (lowestBlock && Editor.isStart(editor, editor.selection.anchor, aboveResult[1])) {
|
|
4304
|
+
if (wrapBlockType === type) {
|
|
4305
|
+
if (highestBlock.children[0] === lowestBlock) {
|
|
4306
|
+
unWrap(editor, wrapBlockType);
|
|
4307
|
+
return true;
|
|
4308
|
+
}
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
return false;
|
|
4312
|
+
}
|
|
4313
|
+
|
|
4314
|
+
function handleContinualInsertBreak(editor, lowestBlock, type) {
|
|
4315
|
+
const isEmpty = Editor.isEmpty(editor, lowestBlock);
|
|
4316
|
+
const isEnd = Editor.isEnd(editor, editor.selection.anchor, editor.selection.focus.path);
|
|
4317
|
+
const aboveResult = Editor.above(editor, {
|
|
4318
|
+
match: n => Editor.isBlock(editor, n) && n.type === type
|
|
4319
|
+
});
|
|
4320
|
+
if (aboveResult && aboveResult[0] && isEnd && isEmpty) {
|
|
4321
|
+
const wrapBlock = aboveResult[0];
|
|
4322
|
+
if (wrapBlock.type === type) {
|
|
4323
|
+
if (wrapBlock.children[wrapBlock.children.length - 1] === lowestBlock) {
|
|
4324
|
+
unWrap(editor, wrapBlock.type);
|
|
4325
|
+
return true;
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4329
|
+
return false;
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4332
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
4333
|
+
__proto__: null,
|
|
4334
|
+
applyDeepToNodes: applyDeepToNodes,
|
|
4335
|
+
clearMarks: clearMarks,
|
|
4336
|
+
closeConversionHint: closeConversionHint,
|
|
4337
|
+
deleteElement: deleteElement,
|
|
4338
|
+
handleContinualDeleteBackward: handleContinualDeleteBackward,
|
|
4339
|
+
handleContinualInsertBreak: handleContinualInsertBreak,
|
|
4340
|
+
insertElements: insertElements,
|
|
4341
|
+
insertParagraph: insertParagraph,
|
|
4342
|
+
mergeDeepToNodes: mergeDeepToNodes,
|
|
4343
|
+
moveChildren: moveChildren,
|
|
4344
|
+
onKeyDownResetBlockType: onKeyDownResetBlockType,
|
|
4345
|
+
setEndSelection: setEndSelection,
|
|
4346
|
+
setMarks: setMarks,
|
|
4347
|
+
setNode: setNode,
|
|
4348
|
+
unWrap: unWrap,
|
|
4349
|
+
unwrapNodesByType: unwrapNodesByType
|
|
4350
|
+
});
|
|
4351
|
+
|
|
4352
|
+
/**
|
|
4353
|
+
* Insert a new table
|
|
4354
|
+
*/
|
|
4355
|
+
function insertTable(opts, editor, rows = 3, columns = 3, getCellContent) {
|
|
4356
|
+
const { selection } = editor;
|
|
4357
|
+
if (!selection?.anchor) {
|
|
4358
|
+
return;
|
|
4359
|
+
}
|
|
4360
|
+
// Create the table node
|
|
4361
|
+
const table = createTable(opts, columns, rows, getCellContent);
|
|
4362
|
+
insertElements(editor, table);
|
|
4363
|
+
}
|
|
4364
|
+
|
|
4365
|
+
function getInsertRowState(opts, editor, count = 1, at) {
|
|
4366
|
+
const tablePosition = createTablePosition(editor);
|
|
4367
|
+
let table = tablePosition.table;
|
|
4368
|
+
let tableEntry = tablePosition.tableEntry;
|
|
4369
|
+
// Create a new row with the right count of cells
|
|
4370
|
+
const columns = table.children[0].children.length;
|
|
4371
|
+
const rowIndex = tablePosition.getRowIndex();
|
|
4372
|
+
const insertRowIndex = typeof at === 'undefined' ? rowIndex + 1 : at;
|
|
4373
|
+
return { table, tableEntry, columns, rowIndex, insertRowIndex };
|
|
4374
|
+
}
|
|
4375
|
+
function packNewRow(opts, editor, count = 1, at) {
|
|
4031
4376
|
const { table, tableEntry, columns, insertRowIndex } = getInsertRowState(opts, editor, count, at);
|
|
4032
4377
|
const rowspan = calcSpanForRow(table, insertRowIndex);
|
|
4033
4378
|
const newRow = createRow(opts, columns);
|
|
@@ -4538,7 +4883,9 @@ const ImageEditor = {
|
|
|
4538
4883
|
});
|
|
4539
4884
|
return false;
|
|
4540
4885
|
}
|
|
4541
|
-
|
|
4886
|
+
const acceptedUploadSize = getPluginOptions(editor, PluginKeys.image)?.acceptedUploadSize ?? PICTURE_ACCEPTED_UPLOAD_SIZE;
|
|
4887
|
+
console.log(acceptedUploadSize);
|
|
4888
|
+
if (image.size / 1000000 >= acceptedUploadSize) {
|
|
4542
4889
|
editor.onError({
|
|
4543
4890
|
code: ErrorCodes.IMAGE_ERR_SIZE_LIMIT
|
|
4544
4891
|
});
|
|
@@ -7403,21 +7750,6 @@ const createBlockCardPlugin = createPluginFactory({
|
|
|
7403
7750
|
withOverrides: withBlockCard
|
|
7404
7751
|
});
|
|
7405
7752
|
|
|
7406
|
-
const isColorPanel = (element) => {
|
|
7407
|
-
const pickerPanel = element.closest('.thy-color-picker-panel');
|
|
7408
|
-
const customPickerPanel = element.closest('.thy-color-picker-custom-panel');
|
|
7409
|
-
if (pickerPanel || customPickerPanel) {
|
|
7410
|
-
return true;
|
|
7411
|
-
}
|
|
7412
|
-
return false;
|
|
7413
|
-
};
|
|
7414
|
-
const isColorIndicator = (element) => {
|
|
7415
|
-
return element.closest('.indicator-hue-alp');
|
|
7416
|
-
};
|
|
7417
|
-
const isColorInput = (element) => {
|
|
7418
|
-
return element.closest('.thy-color-inputs');
|
|
7419
|
-
};
|
|
7420
|
-
|
|
7421
7753
|
const withInternalCommon = (editor) => {
|
|
7422
7754
|
const { globalMousedown, onKeydown } = editor;
|
|
7423
7755
|
editor.globalMousedown = (event) => {
|
|
@@ -9011,15 +9343,12 @@ class TheLinkEditComponent {
|
|
|
9011
9343
|
}
|
|
9012
9344
|
});
|
|
9013
9345
|
}
|
|
9014
|
-
linkRegExp(val) {
|
|
9015
|
-
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(val);
|
|
9016
|
-
}
|
|
9017
9346
|
closePopover(type) {
|
|
9018
9347
|
this.thyPopoverRef.close(type);
|
|
9019
9348
|
}
|
|
9020
9349
|
applyLink(form) {
|
|
9021
9350
|
const link = this.link.trim();
|
|
9022
|
-
if (
|
|
9351
|
+
if (isUrl(link)) {
|
|
9023
9352
|
const linkPath = findPath(this.editor, this.node);
|
|
9024
9353
|
if (this.originLink !== link) {
|
|
9025
9354
|
Transforms.setNodes(this.editor, { url: link }, { at: linkPath });
|
|
@@ -10970,58 +11299,6 @@ function resetTableCell(editor, table, cell, cellRow, cellCol) {
|
|
|
10970
11299
|
});
|
|
10971
11300
|
}
|
|
10972
11301
|
|
|
10973
|
-
function getSelectCellNode(editor, selectedCells) {
|
|
10974
|
-
const pos = createTablePosition(editor);
|
|
10975
|
-
return selectedCells
|
|
10976
|
-
.map(item => {
|
|
10977
|
-
const node = pos.findCellByPath(item);
|
|
10978
|
-
if (node) {
|
|
10979
|
-
return {
|
|
10980
|
-
...item,
|
|
10981
|
-
node: node
|
|
10982
|
-
};
|
|
10983
|
-
}
|
|
10984
|
-
})
|
|
10985
|
-
.filter(item => item);
|
|
10986
|
-
}
|
|
10987
|
-
|
|
10988
|
-
/* cell-position 有关的函数 */
|
|
10989
|
-
const isSelectedAllCell = (editor, selectedCellPositions) => {
|
|
10990
|
-
if (!AngularEditor.isFocused(editor)) {
|
|
10991
|
-
return false;
|
|
10992
|
-
}
|
|
10993
|
-
const pos = createTablePosition(editor);
|
|
10994
|
-
return !!selectedCellPositions.length && pos.getHeight() * pos.getWidth() === selectedCellPositions.length;
|
|
10995
|
-
};
|
|
10996
|
-
const getSelectedCellPositions = (editor, selectedCells) => {
|
|
10997
|
-
return selectedCells?.map((cell) => {
|
|
10998
|
-
const path = AngularEditor.findPath(editor, cell);
|
|
10999
|
-
const [row, col] = path.slice(-2);
|
|
11000
|
-
return { row, col };
|
|
11001
|
-
});
|
|
11002
|
-
};
|
|
11003
|
-
/* 获取一定范围内所有的单元格 */
|
|
11004
|
-
const getCellPositionsFromRange = (startRow, startCol, endRow, endCol) => {
|
|
11005
|
-
const result = [];
|
|
11006
|
-
for (let row = startRow; row < endRow; row++) {
|
|
11007
|
-
for (let col = startCol; col < endCol; col++) {
|
|
11008
|
-
result.push({ row, col });
|
|
11009
|
-
}
|
|
11010
|
-
}
|
|
11011
|
-
return result;
|
|
11012
|
-
};
|
|
11013
|
-
/**
|
|
11014
|
-
* 去重重复的单元格位置
|
|
11015
|
-
* @returns
|
|
11016
|
-
*/
|
|
11017
|
-
const uniqueCellPosition = (cells, selectedCellPositions) => {
|
|
11018
|
-
const result = [];
|
|
11019
|
-
const modCells = new Set();
|
|
11020
|
-
cells.concat(selectedCellPositions).forEach(cell => modCells.add(JSON.stringify(cell)));
|
|
11021
|
-
modCells.forEach((cell) => result.push(JSON.parse(cell)));
|
|
11022
|
-
return result;
|
|
11023
|
-
};
|
|
11024
|
-
|
|
11025
11302
|
function isSelectedCellMerged(editor) {
|
|
11026
11303
|
if (editor && editor.selection) {
|
|
11027
11304
|
const opts = new TableOptions();
|
|
@@ -11271,13 +11548,61 @@ const setSelectedCellsBackgroundColor = (editor, color, tableStore) => {
|
|
|
11271
11548
|
}
|
|
11272
11549
|
};
|
|
11273
11550
|
|
|
11551
|
+
function setTableOptions(editor, newOptions) {
|
|
11552
|
+
const tablePosition = createTablePosition(editor);
|
|
11553
|
+
const tablePath = getTablePath(editor);
|
|
11554
|
+
const table = tablePosition.table;
|
|
11555
|
+
const options = { ...table.options, ...newOptions };
|
|
11556
|
+
Transforms.setNodes(editor, { options }, { at: tablePath });
|
|
11557
|
+
}
|
|
11558
|
+
|
|
11559
|
+
function removeColumnOrRows(editor, tableStore, options) {
|
|
11560
|
+
const { isSelectedTable } = tableStore;
|
|
11561
|
+
const selectedRowsIndex = options?.selectedRowsIndex || tableStore.selectedRowsIndex;
|
|
11562
|
+
const selectedColumnsIndex = options?.selectedColumnsIndex || tableStore.selectedColumnsIndex;
|
|
11563
|
+
const tablePosition = createTablePosition(editor);
|
|
11564
|
+
if (isSelectedTable) {
|
|
11565
|
+
TableEditor.removeTable(editor);
|
|
11566
|
+
return;
|
|
11567
|
+
}
|
|
11568
|
+
const tableComponent = ELEMENT_TO_COMPONENT.get(tablePosition.table);
|
|
11569
|
+
if (selectedRowsIndex.length > 0 && selectedColumnsIndex.length === 0) {
|
|
11570
|
+
// 删除行时取消标题行
|
|
11571
|
+
if (tablePosition.table && tableComponent.headerRow && selectedRowsIndex.includes(0)) {
|
|
11572
|
+
setTableOptions(editor, { headerRow: false });
|
|
11573
|
+
// headerRow 兼容代码, 取消标题行的时候同时设置 row 中的 header 属性
|
|
11574
|
+
if (tablePosition.table.children[0].header) {
|
|
11575
|
+
const rowPath = TheEditor.findPath(editor, tablePosition.table.children[0]);
|
|
11576
|
+
Transforms.setNodes(editor, { header: null }, { at: rowPath });
|
|
11577
|
+
}
|
|
11578
|
+
}
|
|
11579
|
+
selectedRowsIndex
|
|
11580
|
+
.sort((a, b) => b - a)
|
|
11581
|
+
.forEach(index => {
|
|
11582
|
+
TableEditor.removeRow(editor, index);
|
|
11583
|
+
});
|
|
11584
|
+
tableStore.changeCells();
|
|
11585
|
+
}
|
|
11586
|
+
if (selectedColumnsIndex.length > 0 && selectedRowsIndex.length === 0) {
|
|
11587
|
+
// 删除列时取消标题列
|
|
11588
|
+
if (tablePosition.table && tablePosition.table.options?.headerColumn && selectedColumnsIndex.includes(0)) {
|
|
11589
|
+
setTableOptions(editor, { headerColumn: false });
|
|
11590
|
+
}
|
|
11591
|
+
selectedColumnsIndex
|
|
11592
|
+
.sort((a, b) => b - a)
|
|
11593
|
+
.forEach(index => {
|
|
11594
|
+
TableEditor.removeColumn(editor, index);
|
|
11595
|
+
});
|
|
11596
|
+
tableStore.changeCells();
|
|
11597
|
+
}
|
|
11598
|
+
}
|
|
11599
|
+
|
|
11274
11600
|
const getMinAndMaxCellIndex = (editor, selectedCellPositions, maxRow, maxCol, minRow, minCol, table) => {
|
|
11275
11601
|
const beforeCols = [];
|
|
11276
11602
|
const beforeRows = [];
|
|
11277
11603
|
let spanSelectedCells = [];
|
|
11278
11604
|
if (selectedCellPositions.length) {
|
|
11279
|
-
spanSelectedCells = selectedCellPositions
|
|
11280
|
-
.map(item => {
|
|
11605
|
+
spanSelectedCells = selectedCellPositions.map(item => {
|
|
11281
11606
|
const { row, col } = item;
|
|
11282
11607
|
const node = table.children[row].children[col];
|
|
11283
11608
|
if (!node.hidden) {
|
|
@@ -11287,20 +11612,26 @@ const getMinAndMaxCellIndex = (editor, selectedCellPositions, maxRow, maxCol, mi
|
|
|
11287
11612
|
rowspan: node.rowspan || 1
|
|
11288
11613
|
};
|
|
11289
11614
|
}
|
|
11290
|
-
|
|
11291
|
-
|
|
11615
|
+
else {
|
|
11616
|
+
return {
|
|
11617
|
+
...item,
|
|
11618
|
+
colspan: 1,
|
|
11619
|
+
rowspan: 1
|
|
11620
|
+
};
|
|
11621
|
+
}
|
|
11622
|
+
});
|
|
11292
11623
|
}
|
|
11293
|
-
table.children.
|
|
11624
|
+
table.children.forEach((row, rowIndex) => {
|
|
11294
11625
|
if (rowIndex <= maxRow) {
|
|
11295
|
-
row.children.
|
|
11626
|
+
row.children.forEach((cell, colIndex) => {
|
|
11296
11627
|
if (colIndex <= maxCol) {
|
|
11297
11628
|
const cellRowIndex = rowIndex + (cell.rowspan || 1) - 1;
|
|
11298
11629
|
const cellColIndex = colIndex + (cell.colspan || 1) - 1;
|
|
11299
11630
|
if (spanSelectedCells.length) {
|
|
11300
|
-
const { row: selectRow, col: selectCol, rowspan:
|
|
11301
|
-
if (selectRow +
|
|
11302
|
-
minRow = Math.min(
|
|
11303
|
-
minCol = Math.min(
|
|
11631
|
+
const { row: selectRow, col: selectCol, rowspan: selectRowSpan, colspan: selectColSpan } = spanSelectedCells[0];
|
|
11632
|
+
if (selectRow + selectRowSpan - 1 >= minRow && selectCol + selectColSpan - 1 >= minCol) {
|
|
11633
|
+
minRow = Math.min(selectRow, minRow);
|
|
11634
|
+
minCol = Math.min(selectCol, minCol);
|
|
11304
11635
|
}
|
|
11305
11636
|
}
|
|
11306
11637
|
if (cell.colspan && cell.colspan > 1) {
|
|
@@ -11353,17 +11684,17 @@ class TableStore {
|
|
|
11353
11684
|
this.isRightClicking = false;
|
|
11354
11685
|
this.isFocusedInput = false;
|
|
11355
11686
|
this.pointerSelection = false;
|
|
11356
|
-
this.
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
const selectedCellPositions = this.getSelectedCellPositions();
|
|
11361
|
-
return !!selectedCellPositions.length && pos.getHeight() * pos.getWidth() === selectedCellPositions.length;
|
|
11362
|
-
};
|
|
11687
|
+
this.areaSelection = false;
|
|
11688
|
+
}
|
|
11689
|
+
initEditor(editor) {
|
|
11690
|
+
this.editor = editor;
|
|
11363
11691
|
}
|
|
11364
11692
|
getSelectedCellPositions() {
|
|
11365
11693
|
return getSelectedCellPositions(this.editor, this.selectedCells$.getValue());
|
|
11366
11694
|
}
|
|
11695
|
+
publishDangerousCells(value) {
|
|
11696
|
+
return this.dangerousCells$.next(value);
|
|
11697
|
+
}
|
|
11367
11698
|
setSelectedColumnsAndRowIndex() {
|
|
11368
11699
|
if (!this.editor?.selection) {
|
|
11369
11700
|
return;
|
|
@@ -11410,29 +11741,52 @@ class TableStore {
|
|
|
11410
11741
|
this.selectedCells$.next(cellElements);
|
|
11411
11742
|
this.setSelectedColumnsAndRowIndex();
|
|
11412
11743
|
}
|
|
11413
|
-
initEditor(editor) {
|
|
11414
|
-
this.editor = editor;
|
|
11415
|
-
}
|
|
11416
11744
|
selectRow(editor, index) {
|
|
11417
|
-
this.clearLastFocusPath();
|
|
11418
11745
|
const pos = createTablePosition(editor);
|
|
11419
|
-
const
|
|
11420
|
-
this.
|
|
11421
|
-
this.
|
|
11746
|
+
const rangeCells = getCellPositionsFromRange(index, 0, index + 1, pos.getWidth());
|
|
11747
|
+
this.clearLastFocusPath();
|
|
11748
|
+
if (this.areaSelection) {
|
|
11749
|
+
this.areaSelectRowAndColumn(rangeCells);
|
|
11750
|
+
}
|
|
11751
|
+
else {
|
|
11752
|
+
this.setSelectedCells(rangeCells, pos);
|
|
11753
|
+
this.focusCell(pos.tableEntry[1].concat([index, 0]));
|
|
11754
|
+
}
|
|
11422
11755
|
}
|
|
11423
11756
|
selectColumn(editor, index) {
|
|
11424
|
-
this.clearLastFocusPath();
|
|
11425
11757
|
const pos = createTablePosition(editor);
|
|
11426
|
-
const
|
|
11427
|
-
this.
|
|
11428
|
-
this.
|
|
11758
|
+
const rangeCells = getCellPositionsFromRange(0, index, pos.getHeight(), index + 1);
|
|
11759
|
+
this.clearLastFocusPath();
|
|
11760
|
+
if (this.areaSelection) {
|
|
11761
|
+
this.areaSelectRowAndColumn(rangeCells);
|
|
11762
|
+
}
|
|
11763
|
+
else {
|
|
11764
|
+
this.setSelectedCells(rangeCells, pos);
|
|
11765
|
+
this.focusCell(pos.tableEntry[1].concat([0, index]));
|
|
11766
|
+
}
|
|
11429
11767
|
}
|
|
11430
11768
|
selectTable(editor) {
|
|
11431
|
-
this.isSelectedTable = true;
|
|
11432
11769
|
const pos = createTablePosition(editor);
|
|
11433
11770
|
const cells = getCellPositionsFromRange(0, 0, pos.getHeight(), pos.getWidth());
|
|
11771
|
+
const lastCell = cells[cells.length - 1];
|
|
11772
|
+
const anchorCellPath = pos.tableEntry[1].concat([lastCell.row, lastCell.col]);
|
|
11773
|
+
this.isSelectedTable = true;
|
|
11434
11774
|
this.setSelectedCells(cells, pos);
|
|
11435
|
-
this.
|
|
11775
|
+
this.setAreaAnchorCellPath(anchorCellPath);
|
|
11776
|
+
this.focusCell(pos.tableEntry[1].concat([0, 0]));
|
|
11777
|
+
}
|
|
11778
|
+
// 拖选开始 || 记录聚焦点
|
|
11779
|
+
selectCellStart(cell, editor) {
|
|
11780
|
+
const node = AngularEditor.toSlateNode(editor, cell);
|
|
11781
|
+
const path = AngularEditor.findPath(editor, node);
|
|
11782
|
+
this.isPrepareSelecting = true;
|
|
11783
|
+
this.anchorCellPath = path;
|
|
11784
|
+
this.focusCellPath = path;
|
|
11785
|
+
this.focusCellElement = cell;
|
|
11786
|
+
this.lastFocusCellPath = path;
|
|
11787
|
+
if (!this.preFocusCellPath) {
|
|
11788
|
+
this.preFocusCellPath = this.anchorCellPath;
|
|
11789
|
+
}
|
|
11436
11790
|
}
|
|
11437
11791
|
// 拖选
|
|
11438
11792
|
selectCells(editor) {
|
|
@@ -11453,6 +11807,13 @@ class TableStore {
|
|
|
11453
11807
|
const cells = getCellPositionsFromRange(minRow, minCol, maxRow + 1, maxCol + 1);
|
|
11454
11808
|
this.setSelectedCells(cells, pos);
|
|
11455
11809
|
}
|
|
11810
|
+
selectFirstCell() {
|
|
11811
|
+
const selectedCellPositions = this.getSelectedCellPositions();
|
|
11812
|
+
const { row, col } = selectedCellPositions[0];
|
|
11813
|
+
const tablePath = getTablePath(this.editor);
|
|
11814
|
+
const path = Editor.start(this.editor, [...tablePath, row, col]);
|
|
11815
|
+
Transforms.select(this.editor, path);
|
|
11816
|
+
}
|
|
11456
11817
|
// 选择单元格
|
|
11457
11818
|
selectCell(cell, editor) {
|
|
11458
11819
|
const node = AngularEditor.toSlateNode(editor, cell);
|
|
@@ -11462,80 +11823,38 @@ class TableStore {
|
|
|
11462
11823
|
this.focusCellElement = cell;
|
|
11463
11824
|
const [row, col] = path.slice(-2);
|
|
11464
11825
|
const pos = createTablePosition(editor);
|
|
11465
|
-
const
|
|
11826
|
+
const cells = [{ row, col }];
|
|
11466
11827
|
const selectedCellPositions = this.getSelectedCellPositions();
|
|
11467
11828
|
if (this.pointerSelection) {
|
|
11468
|
-
|
|
11829
|
+
cells.push(...selectedCellPositions);
|
|
11469
11830
|
// 处理单元格选中时,处理为选中多单元格
|
|
11470
11831
|
const selectedCells = getCellPositionsBeforeMerge(this.editor, { row, col });
|
|
11471
|
-
|
|
11832
|
+
cells.push(...selectedCells);
|
|
11472
11833
|
// 已聚焦的单元格在多选模式下选中(暂存上次聚焦的单元格数据)
|
|
11473
11834
|
const focusCell = this.lastFocusCellPath?.slice(-2);
|
|
11474
11835
|
if (focusCell) {
|
|
11475
11836
|
const focusCells = getCellPositionsBeforeMerge(this.editor, { row: focusCell[0], col: focusCell[1] });
|
|
11476
|
-
|
|
11837
|
+
cells.push(...focusCells);
|
|
11477
11838
|
}
|
|
11478
11839
|
}
|
|
11479
|
-
this.setSelectedCells(
|
|
11480
|
-
}
|
|
11481
|
-
selectedCellsChange() {
|
|
11482
|
-
return this.selectedCells$.asObservable().pipe(skip(1));
|
|
11483
|
-
}
|
|
11484
|
-
cellsPositionChange() {
|
|
11485
|
-
return this.cellsChangeObject$.asObservable();
|
|
11486
|
-
}
|
|
11487
|
-
changeCells() {
|
|
11488
|
-
this.cellsChangeObject$.next();
|
|
11489
|
-
}
|
|
11490
|
-
emitTableChange() {
|
|
11491
|
-
this.tableChange$.next();
|
|
11492
|
-
}
|
|
11493
|
-
tableChange() {
|
|
11494
|
-
return this.tableChange$.asObservable();
|
|
11495
|
-
}
|
|
11496
|
-
clearSelectedCells() {
|
|
11497
|
-
this.selectedColumnsIndex = [];
|
|
11498
|
-
this.selectedRowsIndex = [];
|
|
11499
|
-
this.isSelectedTable = false;
|
|
11500
|
-
this.isCellSelecting = false;
|
|
11501
|
-
this.isRightClicking = false;
|
|
11502
|
-
this.isFocusedInput = false;
|
|
11503
|
-
this.selectedCells$.next([]);
|
|
11504
|
-
}
|
|
11505
|
-
clearLastFocusPath() {
|
|
11506
|
-
this.lastFocusCellPath = null;
|
|
11507
|
-
}
|
|
11508
|
-
// 拖选开始 || 记录聚焦点
|
|
11509
|
-
selectCellStart(cell, editor) {
|
|
11510
|
-
this.isPrepareSelecting = true;
|
|
11511
|
-
const node = AngularEditor.toSlateNode(editor, cell);
|
|
11512
|
-
const path = AngularEditor.findPath(editor, node);
|
|
11513
|
-
this.anchorCellPath = path;
|
|
11514
|
-
this.lastFocusCellPath = path;
|
|
11515
|
-
if (!this.preFocusCellPath) {
|
|
11516
|
-
this.preFocusCellPath = this.anchorCellPath;
|
|
11517
|
-
}
|
|
11840
|
+
this.setSelectedCells(cells, pos);
|
|
11518
11841
|
}
|
|
11519
11842
|
selectCellOngoing(cell, editor) {
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
}
|
|
11523
|
-
if (!editor.selection) {
|
|
11843
|
+
const pos = createTablePosition(editor);
|
|
11844
|
+
if (AngularEditor.isReadonly(editor) || !editor.selection || !pos?.table) {
|
|
11524
11845
|
return;
|
|
11525
11846
|
}
|
|
11526
11847
|
let isChanged;
|
|
11527
11848
|
if (cell) {
|
|
11528
11849
|
const node = AngularEditor.toSlateNode(editor, cell);
|
|
11529
11850
|
const path = AngularEditor.findPath(editor, node);
|
|
11530
|
-
isChanged = !this.focusCellPath || this.focusCellPath
|
|
11851
|
+
isChanged = !this.focusCellPath || !Path.equals(this.focusCellPath, path);
|
|
11531
11852
|
this.focusCellPath = path;
|
|
11532
11853
|
this.focusCellElement = cell;
|
|
11533
11854
|
}
|
|
11534
11855
|
else {
|
|
11535
11856
|
const selectedCellPositions = this.getSelectedCellPositions();
|
|
11536
|
-
isChanged =
|
|
11537
|
-
!this.focusCellPath ||
|
|
11538
|
-
(this.focusCellPath.toString() === this.anchorCellPath.toString() && selectedCellPositions.length === 0);
|
|
11857
|
+
isChanged = !this.focusCellPath || (Path.equals(this.focusCellPath, this.anchorCellPath) && selectedCellPositions.length === 0);
|
|
11539
11858
|
}
|
|
11540
11859
|
if (this.isPrepareSelecting && isChanged) {
|
|
11541
11860
|
if (JSON.stringify(this.preFocusCellPath) !== JSON.stringify(this.focusCellPath)) {
|
|
@@ -11545,18 +11864,40 @@ class TableStore {
|
|
|
11545
11864
|
}
|
|
11546
11865
|
}
|
|
11547
11866
|
}
|
|
11867
|
+
clearSelectedCells() {
|
|
11868
|
+
this.selectedColumnsIndex = [];
|
|
11869
|
+
this.selectedRowsIndex = [];
|
|
11870
|
+
this.isSelectedTable = false;
|
|
11871
|
+
this.isCellSelecting = false;
|
|
11872
|
+
this.isRightClicking = false;
|
|
11873
|
+
this.isFocusedInput = false;
|
|
11874
|
+
this.selectedCells$.next([]);
|
|
11875
|
+
}
|
|
11876
|
+
clearLastFocusPath() {
|
|
11877
|
+
this.lastFocusCellPath = null;
|
|
11878
|
+
}
|
|
11879
|
+
selectedCellsChange() {
|
|
11880
|
+
return this.selectedCells$.asObservable().pipe(skip(1));
|
|
11881
|
+
}
|
|
11882
|
+
cellsPositionChange() {
|
|
11883
|
+
return this.cellsChangeObject$.asObservable();
|
|
11884
|
+
}
|
|
11885
|
+
changeCells() {
|
|
11886
|
+
this.cellsChangeObject$.next();
|
|
11887
|
+
}
|
|
11888
|
+
emitTableChange() {
|
|
11889
|
+
this.tableChange$.next();
|
|
11890
|
+
}
|
|
11891
|
+
tableChange() {
|
|
11892
|
+
return this.tableChange$.asObservable();
|
|
11893
|
+
}
|
|
11548
11894
|
selectCellEnd(editor) {
|
|
11549
11895
|
if (this.isCellSelecting) {
|
|
11550
|
-
this.focusCell(
|
|
11896
|
+
this.focusCell(this.focusCellPath);
|
|
11551
11897
|
}
|
|
11552
11898
|
this.isPrepareSelecting = false;
|
|
11553
11899
|
this.preFocusCellPath = null;
|
|
11554
11900
|
}
|
|
11555
|
-
focusCell(editor, path) {
|
|
11556
|
-
const at = Editor.start(editor, path);
|
|
11557
|
-
TheEditor.focus(this.editor);
|
|
11558
|
-
Transforms.select(editor, at);
|
|
11559
|
-
}
|
|
11560
11901
|
dangerousCellsChange() {
|
|
11561
11902
|
return this.dangerousCells$.asObservable().pipe(skip(1));
|
|
11562
11903
|
}
|
|
@@ -11628,13 +11969,6 @@ class TableStore {
|
|
|
11628
11969
|
this.dangerousColumnsIndex = [...Array(pos.getWidth())].map((_, i) => i);
|
|
11629
11970
|
this.dangerousCells$.next(cells);
|
|
11630
11971
|
}
|
|
11631
|
-
selectFirstCell() {
|
|
11632
|
-
const selectedCellPositions = this.getSelectedCellPositions();
|
|
11633
|
-
const { row, col } = selectedCellPositions[0];
|
|
11634
|
-
const tablePath = getTablePath(this.editor);
|
|
11635
|
-
const path = Editor.start(this.editor, [...tablePath, row, col]);
|
|
11636
|
-
Transforms.select(this.editor, path);
|
|
11637
|
-
}
|
|
11638
11972
|
setSelectedCellsBackgroundColor(backgroundColor) {
|
|
11639
11973
|
const cells = this.selectedCells$.getValue();
|
|
11640
11974
|
Editor.withoutNormalizing(this.editor, () => {
|
|
@@ -11658,53 +11992,83 @@ class TableStore {
|
|
|
11658
11992
|
Transforms.select(this.editor, Editor.start(this.editor, tablePosition.cellEntry[1]));
|
|
11659
11993
|
}
|
|
11660
11994
|
}
|
|
11661
|
-
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
const
|
|
11666
|
-
|
|
11995
|
+
/**
|
|
11996
|
+
* 聚焦单元格并设置聚焦相关路径及元素
|
|
11997
|
+
*/
|
|
11998
|
+
focusCell(path) {
|
|
11999
|
+
const node = Node.get(this.editor, path);
|
|
12000
|
+
const cellHTMLElement = AngularEditor.toDOMNode(this.editor, node);
|
|
12001
|
+
this.preFocusCellPath = this.focusCellPath;
|
|
12002
|
+
this.focusCellPath = path;
|
|
12003
|
+
this.focusCellElement = cellHTMLElement;
|
|
12004
|
+
focusCell(this.editor, path);
|
|
11667
12005
|
}
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
12006
|
+
/**
|
|
12007
|
+
* 区域选择开始
|
|
12008
|
+
* @param editor 编辑器对象
|
|
12009
|
+
* @param cell 单元格元素
|
|
12010
|
+
*/
|
|
12011
|
+
areaSelectionStart(cell, editor) {
|
|
12012
|
+
const node = AngularEditor.toSlateNode(editor, cell);
|
|
12013
|
+
const path = AngularEditor.findPath(editor, node);
|
|
12014
|
+
this.isPrepareSelecting = true;
|
|
12015
|
+
this.lastFocusCellPath = path;
|
|
12016
|
+
if (!this?.anchorCellPath) {
|
|
12017
|
+
this.anchorCellPath = path;
|
|
12018
|
+
}
|
|
12019
|
+
if (!this?.focusCellPath) {
|
|
12020
|
+
this.focusCellPath = path;
|
|
12021
|
+
}
|
|
12022
|
+
if (!this.preFocusCellPath) {
|
|
12023
|
+
this.preFocusCellPath = this.anchorCellPath;
|
|
12024
|
+
}
|
|
11671
12025
|
}
|
|
11672
|
-
|
|
11673
|
-
|
|
11674
|
-
|
|
11675
|
-
|
|
11676
|
-
|
|
12026
|
+
/**
|
|
12027
|
+
* 设置区域选择的单元格
|
|
12028
|
+
* @param cellElement 单元格元素
|
|
12029
|
+
*/
|
|
12030
|
+
setAreaSelectionCells(cellElement) {
|
|
12031
|
+
if (AngularEditor.isReadonly(this.editor) || !this.editor.selection || !this.isPrepareSelecting) {
|
|
11677
12032
|
return;
|
|
11678
12033
|
}
|
|
11679
|
-
const
|
|
11680
|
-
|
|
11681
|
-
|
|
11682
|
-
|
|
11683
|
-
|
|
11684
|
-
|
|
11685
|
-
if (tablePosition.table.children[0].header) {
|
|
11686
|
-
const rowPath = TheEditor.findPath(this.editor, tablePosition.table.children[0]);
|
|
11687
|
-
Transforms.setNodes(this.editor, { header: null }, { at: rowPath });
|
|
11688
|
-
}
|
|
11689
|
-
}
|
|
11690
|
-
selectedRowIndexs
|
|
11691
|
-
.sort((a, b) => b - a)
|
|
11692
|
-
.forEach(index => {
|
|
11693
|
-
TableEditor.removeRow(this.editor, index);
|
|
11694
|
-
});
|
|
11695
|
-
this.changeCells();
|
|
12034
|
+
const currentCellPath = AngularEditor.findPath(this.editor, cellElement);
|
|
12035
|
+
const selectedCellPositions = this.getSelectedCellPositions();
|
|
12036
|
+
const selectEqual = Path.equals(currentCellPath, this.anchorCellPath);
|
|
12037
|
+
// 不可以区域选择单一单元格
|
|
12038
|
+
if (selectedCellPositions.length <= 1 && selectEqual) {
|
|
12039
|
+
return;
|
|
11696
12040
|
}
|
|
11697
|
-
|
|
11698
|
-
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
|
|
12041
|
+
this.isCellSelecting = true;
|
|
12042
|
+
this.focusCell(currentCellPath);
|
|
12043
|
+
this.selectCells(this.editor);
|
|
12044
|
+
}
|
|
12045
|
+
/**
|
|
12046
|
+
* 处理区域选择启用时选择整行/整列
|
|
12047
|
+
* @param cells 选择的单元格
|
|
12048
|
+
*/
|
|
12049
|
+
areaSelectRowAndColumn(cells) {
|
|
12050
|
+
const pos = createTablePosition(this.editor);
|
|
12051
|
+
const [row, col] = this.focusCellPath.slice(-2);
|
|
12052
|
+
const selectCells = [{ row, col }, ...cells];
|
|
12053
|
+
const sortRows = selectCells.map(item => item.row).sort((m, n) => m - n);
|
|
12054
|
+
const sortCols = selectCells.map(item => item.col).sort((m, n) => m - n);
|
|
12055
|
+
const startRow = sortRows[0];
|
|
12056
|
+
const startCol = sortCols[0];
|
|
12057
|
+
const endRow = sortCols[sortCols.length - 1];
|
|
12058
|
+
const endCol = sortRows[sortRows.length - 1];
|
|
12059
|
+
const anchorCellPath = pos.tableEntry[1].concat([endCol, endRow]);
|
|
12060
|
+
const focusCellPath = pos.tableEntry[1].concat([startRow, startCol]);
|
|
12061
|
+
this.setAreaAnchorCellPath(anchorCellPath);
|
|
12062
|
+
this.focusCell(focusCellPath);
|
|
12063
|
+
this.selectCells(this.editor);
|
|
12064
|
+
}
|
|
12065
|
+
/**
|
|
12066
|
+
* 设置区域选择触发时的指定 anchorCellPath
|
|
12067
|
+
* @param path 路径
|
|
12068
|
+
*/
|
|
12069
|
+
setAreaAnchorCellPath(path) {
|
|
12070
|
+
if (this.areaSelection && path) {
|
|
12071
|
+
this.anchorCellPath = path;
|
|
11708
12072
|
}
|
|
11709
12073
|
}
|
|
11710
12074
|
}
|
|
@@ -11839,7 +12203,10 @@ class TheTableContextMenuService {
|
|
|
11839
12203
|
name: '删除所在行',
|
|
11840
12204
|
visibility: true,
|
|
11841
12205
|
actionHandle: () => {
|
|
11842
|
-
this.tableStore
|
|
12206
|
+
removeColumnOrRows(this.editor, this.tableStore, {
|
|
12207
|
+
selectedColumnsIndex: this.tableStore.dangerousColumnsIndex,
|
|
12208
|
+
selectedRowsIndex: this.tableStore.dangerousRowsIndex
|
|
12209
|
+
});
|
|
11843
12210
|
this.tableStore.clearDangerousCells();
|
|
11844
12211
|
this.tableStore.clearSelectedCells();
|
|
11845
12212
|
},
|
|
@@ -11854,7 +12221,10 @@ class TheTableContextMenuService {
|
|
|
11854
12221
|
name: '删除所在列',
|
|
11855
12222
|
visibility: true,
|
|
11856
12223
|
actionHandle: () => {
|
|
11857
|
-
this.tableStore
|
|
12224
|
+
removeColumnOrRows(this.editor, this.tableStore, {
|
|
12225
|
+
selectedColumnsIndex: this.tableStore.dangerousColumnsIndex,
|
|
12226
|
+
selectedRowsIndex: this.tableStore.dangerousRowsIndex
|
|
12227
|
+
});
|
|
11858
12228
|
this.tableStore.clearDangerousCells();
|
|
11859
12229
|
this.tableStore.clearSelectedCells();
|
|
11860
12230
|
},
|
|
@@ -12013,7 +12383,7 @@ class TheTableOptionsComponent {
|
|
|
12013
12383
|
currentOption.isActive = !option.isActive;
|
|
12014
12384
|
const tableOption = {};
|
|
12015
12385
|
tableOption[option.key] = currentOption.isActive || false;
|
|
12016
|
-
|
|
12386
|
+
setTableOptions(this.editor, { ...tableOption });
|
|
12017
12387
|
// headerRow 兼容代码, 取消标题行的时候同时设置 row 中的 header 属性
|
|
12018
12388
|
if (option.key === TableOperations.headerRow && !tableOption[option.key] && this.table.children[0].header) {
|
|
12019
12389
|
const rowPath = TheEditor.findPath(this.editor, this.table.children[0]);
|
|
@@ -12022,7 +12392,7 @@ class TheTableOptionsComponent {
|
|
|
12022
12392
|
}
|
|
12023
12393
|
}
|
|
12024
12394
|
TheTableOptionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TheTableOptionsComponent, deps: [{ token: i1$1.ThyPopoverRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
12025
|
-
TheTableOptionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TheTableOptionsComponent, selector: "the-table-options", inputs: {
|
|
12395
|
+
TheTableOptionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TheTableOptionsComponent, selector: "the-table-options", inputs: { editor: "editor" }, ngImport: i0, template: `
|
|
12026
12396
|
<div class="thy-dropdown-menu table-drop-menu">
|
|
12027
12397
|
<ng-container *ngFor="let option of tableDropdownList">
|
|
12028
12398
|
<a thyDropdownMenuItem href="javascript:;" (mousedown)="setTableOptions($event, option)">
|
|
@@ -12051,9 +12421,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
12051
12421
|
</div>
|
|
12052
12422
|
`
|
|
12053
12423
|
}]
|
|
12054
|
-
}], ctorParameters: function () { return [{ type: i1$1.ThyPopoverRef }]; }, propDecorators: {
|
|
12055
|
-
type: Input
|
|
12056
|
-
}], editor: [{
|
|
12424
|
+
}], ctorParameters: function () { return [{ type: i1$1.ThyPopoverRef }]; }, propDecorators: { editor: [{
|
|
12057
12425
|
type: Input
|
|
12058
12426
|
}] } });
|
|
12059
12427
|
|
|
@@ -12144,7 +12512,7 @@ class TheTableToolbarComponent {
|
|
|
12144
12512
|
}
|
|
12145
12513
|
onDelete(event) {
|
|
12146
12514
|
event.preventDefault();
|
|
12147
|
-
this.tableStore
|
|
12515
|
+
removeColumnOrRows(this.editor, this.tableStore);
|
|
12148
12516
|
this.tableStore.clearDangerousCells();
|
|
12149
12517
|
this.tableStore.clearSelectedCells();
|
|
12150
12518
|
this.popoverRef.close();
|
|
@@ -12192,7 +12560,6 @@ class TheTableToolbarComponent {
|
|
|
12192
12560
|
this.thyPopover.open(TheTableOptionsComponent, {
|
|
12193
12561
|
origin: event.currentTarget,
|
|
12194
12562
|
initialState: {
|
|
12195
|
-
tableStore: this.tableStore,
|
|
12196
12563
|
editor: this.editor
|
|
12197
12564
|
},
|
|
12198
12565
|
minWidth: 0,
|
|
@@ -12209,404 +12576,198 @@ TheTableToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0",
|
|
|
12209
12576
|
TheTableToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: TheTableToolbarComponent, selector: "the-table-toolbar", inputs: { tableStore: "tableStore", tableElement: "tableElement" }, ngImport: i0, template: "<thy-actions thySize=\"xxs\">\n <ng-container *ngFor=\"let item of cellMenuList\">\n <a\n *ngIf=\"item.visibility\"\n href=\"javascript:;\"\n thyAction\n [thyActionIcon]=\"item.icon\"\n [thyTooltip]=\"item.name\"\n (mousedown)=\"item.actionHandle()\"\n ></a>\n </ng-container>\n <thy-divider *ngIf=\"hasDivider\" class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"> </thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyTooltip=\"\u5355\u5143\u683C\u80CC\u666F\"\n thyColorPicker\n [(ngModel)]=\"selectedColor\"\n (ngModelChange)=\"changeColor($event)\"\n (mousedown)=\"openColorPanel($event)\"\n thyPlacement=\"bottomLeft\"\n [thyHasBackdrop]=\"false\"\n >\n <thy-icon thyIconName=\"background-tt\" thyIconType=\"twotone\" [thyTwotoneColor]=\"selectedColor\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && !isColumnEqual\"\n thyAction\n thyTooltip=\"\u5217\u7B49\u5BBD\"\n (mousedown)=\"setEquallyColumnHandle($event)\"\n >\n <thy-icon thyIconName=\"table-column-equal-width\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && tableOptions?.showFullscreen\"\n thyAction\n thyTooltip=\"\u5168\u5C4F\"\n (mousedown)=\"setFullscreen($event)\"\n >\n <thy-icon thyIconName=\"arrows-alt\"></thy-icon>\n </a>\n <a\n *ngIf=\"tableStore.isSelectedTable && !tableStore?.isFullscreen\"\n class=\"fullscreen-hidden\"\n href=\"javascript:;\"\n thyAction\n thyActionIcon=\"copy\"\n thyTooltip=\"\u590D\u5236\"\n (mousedown)=\"onCopy($event)\"\n ></a>\n <ng-container *ngIf=\"tableStore.isSelectedTable\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a href=\"javascript:;\" class=\"link-with-down\" thyAction (mousedown)=\"mousedown($event)\" (click)=\"openTableOptionMenu($event)\">\n <span>\u8868\u683C\u9009\u9879</span>\n <thy-icon class=\"font-size-sm text-desc ml-1\" thyIconName=\"caret-down\"></thy-icon>\n </a>\n </ng-container>\n <ng-container *ngIf=\"tableStore?.isFullscreen ? deleteIcon && !tableStore.isSelectedTable : deleteIcon\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyType=\"danger\"\n [thyActionIcon]=\"deleteIcon\"\n [thyTooltip]=\"iconName\"\n (mousedown)=\"onDelete($event)\"\n (mouseenter)=\"onEnterDelete($event)\"\n (mouseleave)=\"onLeaveDelete($event)\"\n ></a>\n </ng-container>\n</thy-actions>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.ThyIconComponent, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "directive", type: i8.ThyTooltipDirective, selector: "[thyTooltip],[thy-tooltip]", inputs: ["thyTooltip", "thyTooltipPlacement", "thyTooltipClass", "thyTooltipShowDelay", "thyTooltipHideDelay", "thyTooltipTrigger", "thyTooltipDisabled", "thyTooltipTemplateContext", "thyTooltipOffset", "thyTooltipPin"], exportAs: ["thyTooltip"] }, { kind: "component", type: i7.ThyActionComponent, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "component", type: i7.ThyActionsComponent, selector: "thy-actions", inputs: ["thySize"] }, { kind: "component", type: i8$1.ThyDividerComponent, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: i5.ThyColorPickerDirective, selector: "[thyColorPicker]", inputs: ["thyOffset", "thyHasBackdrop", "thyDefaultColor", "thyTransparentColorSelectable", "thyPresetColors", "thyPlacement", "thyTrigger", "thyShowDelay", "thyHideDelay"], outputs: ["thyPanelOpen", "thyPanelClose"] }] });
|
|
12210
12577
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TheTableToolbarComponent, decorators: [{
|
|
12211
12578
|
type: Component,
|
|
12212
|
-
args: [{ selector: 'the-table-toolbar', template: "<thy-actions thySize=\"xxs\">\n <ng-container *ngFor=\"let item of cellMenuList\">\n <a\n *ngIf=\"item.visibility\"\n href=\"javascript:;\"\n thyAction\n [thyActionIcon]=\"item.icon\"\n [thyTooltip]=\"item.name\"\n (mousedown)=\"item.actionHandle()\"\n ></a>\n </ng-container>\n <thy-divider *ngIf=\"hasDivider\" class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"> </thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyTooltip=\"\u5355\u5143\u683C\u80CC\u666F\"\n thyColorPicker\n [(ngModel)]=\"selectedColor\"\n (ngModelChange)=\"changeColor($event)\"\n (mousedown)=\"openColorPanel($event)\"\n thyPlacement=\"bottomLeft\"\n [thyHasBackdrop]=\"false\"\n >\n <thy-icon thyIconName=\"background-tt\" thyIconType=\"twotone\" [thyTwotoneColor]=\"selectedColor\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && !isColumnEqual\"\n thyAction\n thyTooltip=\"\u5217\u7B49\u5BBD\"\n (mousedown)=\"setEquallyColumnHandle($event)\"\n >\n <thy-icon thyIconName=\"table-column-equal-width\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && tableOptions?.showFullscreen\"\n thyAction\n thyTooltip=\"\u5168\u5C4F\"\n (mousedown)=\"setFullscreen($event)\"\n >\n <thy-icon thyIconName=\"arrows-alt\"></thy-icon>\n </a>\n <a\n *ngIf=\"tableStore.isSelectedTable && !tableStore?.isFullscreen\"\n class=\"fullscreen-hidden\"\n href=\"javascript:;\"\n thyAction\n thyActionIcon=\"copy\"\n thyTooltip=\"\u590D\u5236\"\n (mousedown)=\"onCopy($event)\"\n ></a>\n <ng-container *ngIf=\"tableStore.isSelectedTable\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a href=\"javascript:;\" class=\"link-with-down\" thyAction (mousedown)=\"mousedown($event)\" (click)=\"openTableOptionMenu($event)\">\n <span>\u8868\u683C\u9009\u9879</span>\n <thy-icon class=\"font-size-sm text-desc ml-1\" thyIconName=\"caret-down\"></thy-icon>\n </a>\n </ng-container>\n <ng-container *ngIf=\"tableStore?.isFullscreen ? deleteIcon && !tableStore.isSelectedTable : deleteIcon\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyType=\"danger\"\n [thyActionIcon]=\"deleteIcon\"\n [thyTooltip]=\"iconName\"\n (mousedown)=\"onDelete($event)\"\n (mouseenter)=\"onEnterDelete($event)\"\n (mouseleave)=\"onLeaveDelete($event)\"\n ></a>\n </ng-container>\n</thy-actions>\n" }]
|
|
12213
|
-
}], ctorParameters: function () { return [{ type: i1$1.ThyPopover }, { type: i1$1.ThyPopoverRef }, { type: i1$2.ThyNotifyService }]; }, propDecorators: { tableStore: [{
|
|
12214
|
-
type: Input
|
|
12215
|
-
}], tableElement: [{
|
|
12216
|
-
type: Input
|
|
12217
|
-
}] } });
|
|
12218
|
-
var DeleteIcon;
|
|
12219
|
-
(function (DeleteIcon) {
|
|
12220
|
-
DeleteIcon["table-delete-rows"] = "table-delete-rows";
|
|
12221
|
-
DeleteIcon["table-delete-columns"] = "table-delete-columns";
|
|
12222
|
-
DeleteIcon["trash"] = "trash";
|
|
12223
|
-
})(DeleteIcon || (DeleteIcon = {}));
|
|
12224
|
-
|
|
12225
|
-
class TableService {
|
|
12226
|
-
get isOpened() {
|
|
12227
|
-
return this.toolbarRef && this.toolbarRef.componentInstance;
|
|
12228
|
-
}
|
|
12229
|
-
constructor(thyPopover, overlay, tableStore,
|
|
12230
|
-
this.thyPopover = thyPopover;
|
|
12231
|
-
this.overlay = overlay;
|
|
12232
|
-
this.tableStore = tableStore;
|
|
12233
|
-
this.
|
|
12234
|
-
this.
|
|
12235
|
-
this.
|
|
12236
|
-
this.
|
|
12237
|
-
this.
|
|
12238
|
-
this.
|
|
12239
|
-
this.
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
this.toolbarRef.close();
|
|
12248
|
-
}
|
|
12249
|
-
this.toolbarRef = this.thyPopover.open(TheTableToolbarComponent, {
|
|
12250
|
-
initialState: {
|
|
12251
|
-
tableStore: this.tableStore,
|
|
12252
|
-
tableElement
|
|
12253
|
-
},
|
|
12254
|
-
viewContainerRef: this.theContextService.getOptions().viewContainerRef,
|
|
12255
|
-
origin: this.getOrigin(origin),
|
|
12256
|
-
backdropClosable: this.backdropClosable,
|
|
12257
|
-
panelClass: 'the-plugin-toolbar-popover',
|
|
12258
|
-
placement: this.placement,
|
|
12259
|
-
offset: this.offset,
|
|
12260
|
-
hasBackdrop: this.hasBackdrop,
|
|
12261
|
-
insideClosable: this.insideClosable,
|
|
12262
|
-
minWidth: 0,
|
|
12263
|
-
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
12264
|
-
manualClosure: true
|
|
12265
|
-
});
|
|
12266
|
-
if (this.toolbarRef) {
|
|
12267
|
-
this.toolbarRef
|
|
12268
|
-
.getOverlayRef()
|
|
12269
|
-
.outsidePointerEvents()
|
|
12270
|
-
.pipe(skip(1))
|
|
12271
|
-
.subscribe(event => {
|
|
12272
|
-
if (isColorPanel(event.target)) {
|
|
12273
|
-
return;
|
|
12274
|
-
}
|
|
12275
|
-
if (!this.toolbarRef.getOverlayRef().hostElement.contains(event.target)) {
|
|
12276
|
-
this.closeToolbar();
|
|
12277
|
-
}
|
|
12278
|
-
});
|
|
12279
|
-
}
|
|
12280
|
-
}
|
|
12281
|
-
afterSelectedCells(origin, element) {
|
|
12282
|
-
this.theTableContextMenuService.closeContextMenu();
|
|
12283
|
-
this.openToolbar(origin, element);
|
|
12284
|
-
}
|
|
12285
|
-
getOrigin(origin) {
|
|
12286
|
-
if (origin instanceof HTMLTableCellElement && origin.tagName !== 'TH') {
|
|
12287
|
-
const { selectedRowsIndex, selectedColumnsIndex, focusCellPath, isSelectedTable, focusCellElement } = this.tableStore;
|
|
12288
|
-
const [row, col] = focusCellPath.slice(-2);
|
|
12289
|
-
const tableElement = focusCellElement.closest('.the-table-container');
|
|
12290
|
-
if (isSelectedTable && col === 0 && row === 0) {
|
|
12291
|
-
return tableElement.querySelector('.the-table-corner-controls');
|
|
12292
|
-
}
|
|
12293
|
-
if (selectedColumnsIndex.length > 0 && row === 0) {
|
|
12294
|
-
return tableElement.querySelectorAll('.the-table-col-controls')[col];
|
|
12295
|
-
}
|
|
12296
|
-
if (selectedRowsIndex.length > 0 && col === 0) {
|
|
12297
|
-
return tableElement.querySelectorAll('.the-table-row-controls-button-wrap')[row];
|
|
12298
|
-
}
|
|
12299
|
-
}
|
|
12300
|
-
return origin;
|
|
12301
|
-
}
|
|
12302
|
-
closeToolbar() {
|
|
12303
|
-
if (this.isOpened) {
|
|
12304
|
-
this.ngZone.run(() => {
|
|
12305
|
-
this.toolbarRef.close();
|
|
12306
|
-
});
|
|
12307
|
-
return this.toolbarRef.afterClosed();
|
|
12308
|
-
}
|
|
12309
|
-
}
|
|
12310
|
-
}
|
|
12311
|
-
TableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService, deps: [{ token: i1$1.ThyPopover }, { token: i2$1.Overlay }, { token: TableStore }, { token: TheTableContextMenuService }, { token: i0.NgZone }, { token: TheContextService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
12312
|
-
TableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService });
|
|
12313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService, decorators: [{
|
|
12314
|
-
type: Injectable
|
|
12315
|
-
}], ctorParameters: function () { return [{ type: i1$1.ThyPopover }, { type: i2$1.Overlay }, { type: TableStore }, { type: TheTableContextMenuService }, { type: i0.NgZone }, { type: TheContextService }]; } });
|
|
12316
|
-
|
|
12317
|
-
function isVirtualKey(e) {
|
|
12318
|
-
const isMod = e.ctrlKey || e.metaKey;
|
|
12319
|
-
const isAlt = isKeyHotkey('alt', e);
|
|
12320
|
-
const isShift = isKeyHotkey('shift', e);
|
|
12321
|
-
const isCapsLock = e.key.includes('CapsLock');
|
|
12322
|
-
const isTab = e.key.includes('Tab');
|
|
12323
|
-
const isEsc = e.key.includes('Escape');
|
|
12324
|
-
const isF = e.key.startsWith('F');
|
|
12325
|
-
const isArrow = e.key.includes('Arrow') ? true : false;
|
|
12326
|
-
return isCapsLock || isMod || isAlt || isArrow || isShift || isTab || isEsc || isF;
|
|
12327
|
-
}
|
|
12328
|
-
|
|
12329
|
-
class TableFreezeColumnPipe {
|
|
12330
|
-
transform(table, tablePluginOptions) {
|
|
12331
|
-
const rows = table.children?.map(item => item.children);
|
|
12332
|
-
const headerColumnWidth = table.columns && table.columns[0].width;
|
|
12333
|
-
const tableComponent = ELEMENT_TO_COMPONENT.get(table);
|
|
12334
|
-
let stickyColumn = true;
|
|
12335
|
-
let buffer = TABLE_CONTROL;
|
|
12336
|
-
if (table.options?.numberedColumn) {
|
|
12337
|
-
buffer = TABLE_NUMBER_COLUMN + TABLE_CONTROL;
|
|
12338
|
-
}
|
|
12339
|
-
if (tableComponent) {
|
|
12340
|
-
const tableWidth = getElementWidth(tableComponent.elementRef.nativeElement);
|
|
12341
|
-
stickyColumn = headerColumnWidth + buffer < tableWidth;
|
|
12342
|
-
}
|
|
12343
|
-
// 标题列存在合并的列时,取消冻结
|
|
12344
|
-
const mergeColumnCells = rows && rows.map(cells => cells[0]).filter(item => item.colspan && item.colspan !== 1);
|
|
12345
|
-
return !!(tablePluginOptions?.freezeColumnHeader && table.options?.headerColumn && !mergeColumnCells.length && stickyColumn);
|
|
12346
|
-
}
|
|
12347
|
-
}
|
|
12348
|
-
TableFreezeColumnPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
12349
|
-
TableFreezeColumnPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, name: "freezeColumn" });
|
|
12350
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, decorators: [{
|
|
12351
|
-
type: Pipe,
|
|
12352
|
-
args: [{ name: 'freezeColumn' }]
|
|
12353
|
-
}] });
|
|
12354
|
-
class TableFreezeRowPipe {
|
|
12355
|
-
transform(table, headerRow, tablePluginOptions) {
|
|
12356
|
-
// 标题行存在合并的行时,取消冻结
|
|
12357
|
-
if (table.children) {
|
|
12358
|
-
const mergeRows = table.children[0]?.children.filter(item => item.rowspan && item.rowspan !== 1);
|
|
12359
|
-
return !!(headerRow && !mergeRows.length && tablePluginOptions?.freezeRowHeader);
|
|
12360
|
-
}
|
|
12361
|
-
return false;
|
|
12362
|
-
}
|
|
12363
|
-
}
|
|
12364
|
-
TableFreezeRowPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
12365
|
-
TableFreezeRowPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, name: "freezeRow" });
|
|
12366
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, decorators: [{
|
|
12367
|
-
type: Pipe,
|
|
12368
|
-
args: [{ name: 'freezeRow' }]
|
|
12369
|
-
}] });
|
|
12370
|
-
|
|
12371
|
-
/**
|
|
12372
|
-
* 获取标题行网格列宽值
|
|
12373
|
-
* @param editor
|
|
12374
|
-
* @param headerRow 标题行
|
|
12375
|
-
* @param cellsWidth
|
|
12376
|
-
* @returns string
|
|
12377
|
-
*/
|
|
12378
|
-
const getGridColumns = (headerRow, cellsWidth) => {
|
|
12379
|
-
let result = '';
|
|
12380
|
-
Array.from(headerRow.childNodes)
|
|
12381
|
-
.filter((n) => n.nodeType === 1)
|
|
12382
|
-
.forEach((node, i) => {
|
|
12383
|
-
const col = node.getAttribute('colspan');
|
|
12384
|
-
const display = node.style.display;
|
|
12385
|
-
if (display === 'none') {
|
|
12386
|
-
return;
|
|
12387
|
-
}
|
|
12388
|
-
if (col) {
|
|
12389
|
-
const colSpan = Number(col) ?? 1;
|
|
12390
|
-
let width = 0;
|
|
12391
|
-
Array.from({ length: colSpan }, (_, j) => {
|
|
12392
|
-
width += cellsWidth[i + j];
|
|
12393
|
-
});
|
|
12394
|
-
result += width + 'px ';
|
|
12395
|
-
}
|
|
12396
|
-
else {
|
|
12397
|
-
result += cellsWidth[i] + 'px ';
|
|
12398
|
-
}
|
|
12399
|
-
});
|
|
12400
|
-
return result;
|
|
12401
|
-
};
|
|
12402
|
-
const getColumnsWidth = (cellRow, isColgroup = false) => {
|
|
12403
|
-
const result = [];
|
|
12404
|
-
Array.from(cellRow.childNodes)
|
|
12405
|
-
.filter((n) => n.nodeType === 1)
|
|
12406
|
-
.forEach((item) => {
|
|
12407
|
-
if (isColgroup && IS_SAFARI) {
|
|
12408
|
-
result.push(item.offsetWidth);
|
|
12409
|
-
return;
|
|
12410
|
-
}
|
|
12411
|
-
if (item.getBoundingClientRect) {
|
|
12412
|
-
result.push(item.getBoundingClientRect().width);
|
|
12413
|
-
}
|
|
12414
|
-
});
|
|
12415
|
-
return result;
|
|
12416
|
-
};
|
|
12417
|
-
/**
|
|
12418
|
-
* 计算表格列宽
|
|
12419
|
-
* @param isReadonly
|
|
12420
|
-
* @param element
|
|
12421
|
-
* @param tableWidth
|
|
12422
|
-
* @param mode
|
|
12423
|
-
* @returns number[]
|
|
12424
|
-
*/
|
|
12425
|
-
const calcColumnGroups = (isReadonly, element, tableWidth, mode) => {
|
|
12426
|
-
const columns = element?.columns;
|
|
12427
|
-
if (isReadonly) {
|
|
12428
|
-
if (columns) {
|
|
12429
|
-
const opts = new TableOptions();
|
|
12430
|
-
const isPrint = mode === TheMode.print;
|
|
12431
|
-
const newColumns = isPrint
|
|
12432
|
-
? calcPrintColumnWidth(element, opts.minWidthPx)
|
|
12433
|
-
: calcColumnWidth(element, tableWidth, opts.minWidthPx);
|
|
12434
|
-
return newColumns;
|
|
12435
|
-
}
|
|
12436
|
-
return [];
|
|
12437
|
-
}
|
|
12438
|
-
else {
|
|
12439
|
-
return columns;
|
|
12440
|
-
}
|
|
12441
|
-
};
|
|
12442
|
-
/**
|
|
12443
|
-
* 计算表格列宽
|
|
12444
|
-
* @param element
|
|
12445
|
-
* @param tableWidth
|
|
12446
|
-
* @param minWidthPx
|
|
12447
|
-
* @returns number[]
|
|
12448
|
-
*/
|
|
12449
|
-
const calcColumnWidth = (element, tableWidth, minWidthPx) => {
|
|
12450
|
-
const columns = element?.columns;
|
|
12451
|
-
const numberedColumnWidth = element?.options?.numberedColumn ? TABLE_NUMBER_COLUMN : 0;
|
|
12452
|
-
const columnsWidth = columns.reduce((a, b) => a + b.width, 0);
|
|
12453
|
-
// 总列宽大于当前表格宽度时,按照设置时的总列宽计算
|
|
12454
|
-
const columnTotalWidth = Math.max(columnsWidth, tableWidth - numberedColumnWidth);
|
|
12455
|
-
return columns.map(column => {
|
|
12456
|
-
const cellWidth = (column.width / columnsWidth) * columnTotalWidth;
|
|
12457
|
-
return { width: Math.max(cellWidth, minWidthPx) };
|
|
12458
|
-
});
|
|
12459
|
-
};
|
|
12460
|
-
/**
|
|
12461
|
-
* 打印模式下,按照原宽度比例基于当前表格宽度计算列宽
|
|
12462
|
-
* 1. 所有列的最小列宽总和大于表格宽度时,所有列返回最小宽度
|
|
12463
|
-
* @param element
|
|
12464
|
-
* @param minWidthPx
|
|
12465
|
-
* @returns number[]
|
|
12466
|
-
*/
|
|
12467
|
-
const calcPrintColumnWidth = (element, minWidthPx) => {
|
|
12468
|
-
const columns = element?.columns;
|
|
12469
|
-
const numberedColumnWidth = element?.options?.numberedColumn ? TABLE_NUMBER_COLUMN : 0;
|
|
12470
|
-
// 按照 DPI 96 的 A4 纸宽度是 794, 打印时左右 80px 的边距,所以这里取 794 - 80 * 2 = 634
|
|
12471
|
-
// 如果存在序号列,还需要在 634 基础上减去序号列的宽度,剩下的才是内容区域的宽度
|
|
12472
|
-
let columnTotalWidth = 634 - numberedColumnWidth;
|
|
12473
|
-
const columnsWidth = columns.reduce((a, b) => a + b.width, 0);
|
|
12474
|
-
// 计算所有列的 minWidth 总和
|
|
12475
|
-
const totalMinWidth = minWidthPx * columns.length;
|
|
12476
|
-
if (totalMinWidth > columnTotalWidth) {
|
|
12477
|
-
// 如果所有列的 minWidth 总和大于 columnTotalWidth,所有列返回最小宽度
|
|
12478
|
-
return columns.map(() => ({ width: minWidthPx }));
|
|
12479
|
-
}
|
|
12480
|
-
// 在剩余的宽度中按比例分配
|
|
12481
|
-
const remainingWidth = columnTotalWidth - totalMinWidth;
|
|
12482
|
-
const remainingWidthRatio = columns.map(column => column.width / columnsWidth);
|
|
12483
|
-
// 为什么减 1, 因为这个宽度是内容区域宽度,但 td 右侧还有一个边框,所以减去 1
|
|
12484
|
-
let newColumnsWidth = remainingWidthRatio.map(ratio => minWidthPx + Math.floor(ratio * remainingWidth) - 1);
|
|
12485
|
-
return columns.map((_, index) => ({
|
|
12486
|
-
width: newColumnsWidth[index]
|
|
12487
|
-
}));
|
|
12488
|
-
};
|
|
12489
|
-
|
|
12490
|
-
/**
|
|
12491
|
-
* 计算最小行跨距单元格
|
|
12492
|
-
* @param element TableElement
|
|
12493
|
-
* @returns
|
|
12494
|
-
*/
|
|
12495
|
-
const calculateMinRowSpanCellForRows = (element) => {
|
|
12496
|
-
const cells = element.children.map((row, index) => {
|
|
12497
|
-
const noHiddenCells = row.children.filter(cell => !cell.hidden);
|
|
12498
|
-
if (noHiddenCells.length > 0) {
|
|
12499
|
-
const minRowspan = Math.min.apply(Math, noHiddenCells.map(cell => {
|
|
12500
|
-
return cell.rowspan || 1;
|
|
12501
|
-
}));
|
|
12502
|
-
const cell = row.children.find(item => !item.hidden && (item.rowspan || 1) === minRowspan);
|
|
12503
|
-
return {
|
|
12504
|
-
cell,
|
|
12505
|
-
rowIndex: index
|
|
12506
|
-
};
|
|
12507
|
-
}
|
|
12508
|
-
else {
|
|
12509
|
-
return {
|
|
12510
|
-
rowIndex: index
|
|
12511
|
-
};
|
|
12579
|
+
args: [{ selector: 'the-table-toolbar', template: "<thy-actions thySize=\"xxs\">\n <ng-container *ngFor=\"let item of cellMenuList\">\n <a\n *ngIf=\"item.visibility\"\n href=\"javascript:;\"\n thyAction\n [thyActionIcon]=\"item.icon\"\n [thyTooltip]=\"item.name\"\n (mousedown)=\"item.actionHandle()\"\n ></a>\n </ng-container>\n <thy-divider *ngIf=\"hasDivider\" class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"> </thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyTooltip=\"\u5355\u5143\u683C\u80CC\u666F\"\n thyColorPicker\n [(ngModel)]=\"selectedColor\"\n (ngModelChange)=\"changeColor($event)\"\n (mousedown)=\"openColorPanel($event)\"\n thyPlacement=\"bottomLeft\"\n [thyHasBackdrop]=\"false\"\n >\n <thy-icon thyIconName=\"background-tt\" thyIconType=\"twotone\" [thyTwotoneColor]=\"selectedColor\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && !isColumnEqual\"\n thyAction\n thyTooltip=\"\u5217\u7B49\u5BBD\"\n (mousedown)=\"setEquallyColumnHandle($event)\"\n >\n <thy-icon thyIconName=\"table-column-equal-width\"></thy-icon>\n </a>\n <a\n href=\"javascript:;\"\n *ngIf=\"tableStore.isSelectedTable && tableOptions?.showFullscreen\"\n thyAction\n thyTooltip=\"\u5168\u5C4F\"\n (mousedown)=\"setFullscreen($event)\"\n >\n <thy-icon thyIconName=\"arrows-alt\"></thy-icon>\n </a>\n <a\n *ngIf=\"tableStore.isSelectedTable && !tableStore?.isFullscreen\"\n class=\"fullscreen-hidden\"\n href=\"javascript:;\"\n thyAction\n thyActionIcon=\"copy\"\n thyTooltip=\"\u590D\u5236\"\n (mousedown)=\"onCopy($event)\"\n ></a>\n <ng-container *ngIf=\"tableStore.isSelectedTable\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a href=\"javascript:;\" class=\"link-with-down\" thyAction (mousedown)=\"mousedown($event)\" (click)=\"openTableOptionMenu($event)\">\n <span>\u8868\u683C\u9009\u9879</span>\n <thy-icon class=\"font-size-sm text-desc ml-1\" thyIconName=\"caret-down\"></thy-icon>\n </a>\n </ng-container>\n <ng-container *ngIf=\"tableStore?.isFullscreen ? deleteIcon && !tableStore.isSelectedTable : deleteIcon\">\n <thy-divider class=\"mr-2 ml-1 align-self-center\" [thyVertical]=\"true\"></thy-divider>\n <a\n href=\"javascript:;\"\n thyAction\n thyType=\"danger\"\n [thyActionIcon]=\"deleteIcon\"\n [thyTooltip]=\"iconName\"\n (mousedown)=\"onDelete($event)\"\n (mouseenter)=\"onEnterDelete($event)\"\n (mouseleave)=\"onLeaveDelete($event)\"\n ></a>\n </ng-container>\n</thy-actions>\n" }]
|
|
12580
|
+
}], ctorParameters: function () { return [{ type: i1$1.ThyPopover }, { type: i1$1.ThyPopoverRef }, { type: i1$2.ThyNotifyService }]; }, propDecorators: { tableStore: [{
|
|
12581
|
+
type: Input
|
|
12582
|
+
}], tableElement: [{
|
|
12583
|
+
type: Input
|
|
12584
|
+
}] } });
|
|
12585
|
+
var DeleteIcon;
|
|
12586
|
+
(function (DeleteIcon) {
|
|
12587
|
+
DeleteIcon["table-delete-rows"] = "table-delete-rows";
|
|
12588
|
+
DeleteIcon["table-delete-columns"] = "table-delete-columns";
|
|
12589
|
+
DeleteIcon["trash"] = "trash";
|
|
12590
|
+
})(DeleteIcon || (DeleteIcon = {}));
|
|
12591
|
+
|
|
12592
|
+
class TableService {
|
|
12593
|
+
get isOpened() {
|
|
12594
|
+
return this.toolbarRef && this.toolbarRef.componentInstance;
|
|
12595
|
+
}
|
|
12596
|
+
constructor(thyPopover, overlay, tableStore, ngZone, theContextService) {
|
|
12597
|
+
this.thyPopover = thyPopover;
|
|
12598
|
+
this.overlay = overlay;
|
|
12599
|
+
this.tableStore = tableStore;
|
|
12600
|
+
this.ngZone = ngZone;
|
|
12601
|
+
this.theContextService = theContextService;
|
|
12602
|
+
this.backdropClosable = false;
|
|
12603
|
+
this.hasBackdrop = false;
|
|
12604
|
+
this.insideClosable = false;
|
|
12605
|
+
this.placement = 'topLeft';
|
|
12606
|
+
this.offset = 8;
|
|
12607
|
+
}
|
|
12608
|
+
openToolbar(origin, tableElement) {
|
|
12609
|
+
if (this.isOpened) {
|
|
12610
|
+
if (this.toolbarRef.containerInstance.config.origin === origin) {
|
|
12611
|
+
return;
|
|
12612
|
+
}
|
|
12613
|
+
this.toolbarRef.close();
|
|
12512
12614
|
}
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
.
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12615
|
+
this.toolbarRef = this.thyPopover.open(TheTableToolbarComponent, {
|
|
12616
|
+
initialState: {
|
|
12617
|
+
tableStore: this.tableStore,
|
|
12618
|
+
tableElement
|
|
12619
|
+
},
|
|
12620
|
+
viewContainerRef: this.theContextService.getOptions().viewContainerRef,
|
|
12621
|
+
origin: this.getOrigin(origin),
|
|
12622
|
+
backdropClosable: this.backdropClosable,
|
|
12623
|
+
panelClass: 'the-plugin-toolbar-popover',
|
|
12624
|
+
placement: this.placement,
|
|
12625
|
+
offset: this.offset,
|
|
12626
|
+
hasBackdrop: this.hasBackdrop,
|
|
12627
|
+
insideClosable: this.insideClosable,
|
|
12628
|
+
minWidth: 0,
|
|
12629
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
12630
|
+
manualClosure: true
|
|
12631
|
+
});
|
|
12632
|
+
if (this.toolbarRef) {
|
|
12633
|
+
this.toolbarRef
|
|
12634
|
+
.getOverlayRef()
|
|
12635
|
+
.outsidePointerEvents()
|
|
12636
|
+
.pipe(skip(1))
|
|
12637
|
+
.subscribe(event => {
|
|
12638
|
+
if (isColorPanel(event.target)) {
|
|
12639
|
+
return;
|
|
12640
|
+
}
|
|
12641
|
+
if (!this.toolbarRef.getOverlayRef().hostElement.contains(event.target)) {
|
|
12642
|
+
this.closeToolbar();
|
|
12643
|
+
}
|
|
12644
|
+
});
|
|
12539
12645
|
}
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12646
|
+
}
|
|
12647
|
+
afterSelectedCells(origin, element) {
|
|
12648
|
+
this.openToolbar(origin, element);
|
|
12649
|
+
}
|
|
12650
|
+
getOrigin(origin) {
|
|
12651
|
+
if (origin instanceof HTMLTableCellElement && origin.tagName !== 'TH') {
|
|
12652
|
+
const { selectedRowsIndex, selectedColumnsIndex, focusCellPath, isSelectedTable, focusCellElement } = this.tableStore;
|
|
12653
|
+
const [row, col] = focusCellPath.slice(-2);
|
|
12654
|
+
const tableElement = focusCellElement.closest('.the-table-container');
|
|
12655
|
+
if (isSelectedTable && col === 0 && row === 0) {
|
|
12656
|
+
return tableElement.querySelector('.the-table-corner-controls');
|
|
12546
12657
|
}
|
|
12547
|
-
|
|
12548
|
-
|
|
12658
|
+
if (selectedColumnsIndex.length > 0 && row === 0) {
|
|
12659
|
+
return tableElement.querySelectorAll('.the-table-col-controls')[col];
|
|
12660
|
+
}
|
|
12661
|
+
if (selectedRowsIndex.length > 0 && col === 0) {
|
|
12662
|
+
return tableElement.querySelectorAll('.the-table-row-controls-button-wrap')[row];
|
|
12549
12663
|
}
|
|
12550
12664
|
}
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
let previousRowIndex = 0;
|
|
12558
|
-
let previousCombineRowIndex = 0;
|
|
12559
|
-
minRowSpanCellForRows.forEach((cellInfo, index) => {
|
|
12560
|
-
if (!cellInfo.cell) {
|
|
12561
|
-
rowControls.push({
|
|
12562
|
-
height: 0,
|
|
12563
|
-
rowIndex: index
|
|
12665
|
+
return origin;
|
|
12666
|
+
}
|
|
12667
|
+
closeToolbar() {
|
|
12668
|
+
if (this.isOpened) {
|
|
12669
|
+
this.ngZone.run(() => {
|
|
12670
|
+
this.toolbarRef.close();
|
|
12564
12671
|
});
|
|
12565
|
-
|
|
12566
|
-
if (index === minRowSpanCellForRows.length - 1) {
|
|
12567
|
-
calculateRowControlsAvgHeight(previousCombineRowIndex, previousRowIndex, rowControls);
|
|
12568
|
-
}
|
|
12569
|
-
return;
|
|
12672
|
+
return this.toolbarRef.afterClosed();
|
|
12570
12673
|
}
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12674
|
+
}
|
|
12675
|
+
/**
|
|
12676
|
+
* 判断是否触发了点选,并处理点选状态
|
|
12677
|
+
* @param e 事件对象
|
|
12678
|
+
* @param tbody tbody元素
|
|
12679
|
+
*/
|
|
12680
|
+
handleKeydownForPointerSelection(e, tbody) {
|
|
12681
|
+
const cell = tbody?.querySelector('.focused-cell') || this.tableStore.focusCellElement;
|
|
12682
|
+
if (cell) {
|
|
12683
|
+
this.tableStore.pointerSelection = true;
|
|
12684
|
+
this.tableStore.selectCellStart(cell, this.tableStore.editor);
|
|
12575
12685
|
}
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12686
|
+
}
|
|
12687
|
+
/**
|
|
12688
|
+
* 判断是否触发了区域选择,并处理区域选择状态
|
|
12689
|
+
* @param e 事件对象
|
|
12690
|
+
* @param tbody tbody元素
|
|
12691
|
+
*/
|
|
12692
|
+
handleKeydownForAreaSelection(e, tbody) {
|
|
12693
|
+
const isTable = TableEditor.isActive(this.tableStore.editor);
|
|
12694
|
+
const cell = tbody?.querySelector('.focused-cell') || this.tableStore.focusCellElement;
|
|
12695
|
+
if (isTable && cell) {
|
|
12696
|
+
this.tableStore.areaSelectionStart(cell, this.tableStore.editor);
|
|
12697
|
+
this.tableStore.areaSelection = true;
|
|
12585
12698
|
}
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
});
|
|
12699
|
+
}
|
|
12700
|
+
cancelPointerSelection() {
|
|
12701
|
+
if (this.tableStore.pointerSelection) {
|
|
12702
|
+
this.tableStore.pointerSelection = false;
|
|
12591
12703
|
}
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12704
|
+
}
|
|
12705
|
+
cancelAreaSelection() {
|
|
12706
|
+
if (this.tableStore.areaSelection) {
|
|
12707
|
+
this.tableStore.areaSelection = false;
|
|
12708
|
+
this.tableStore.selectCellEnd(this.tableStore.editor);
|
|
12709
|
+
}
|
|
12710
|
+
}
|
|
12711
|
+
/**
|
|
12712
|
+
* 进行区域选择时,阻止默认的选区事件
|
|
12713
|
+
* @param e 事件对象
|
|
12714
|
+
* @param editor 编辑器对象
|
|
12715
|
+
*/
|
|
12716
|
+
selectStartPreventDefault(e) {
|
|
12717
|
+
const isReadonly = AngularEditor.isReadonly(this.tableStore.editor);
|
|
12718
|
+
const cells = this.tableStore.getSelectedCellPositions();
|
|
12719
|
+
if (!isReadonly && this.tableStore.areaSelection && cells.length > 1) {
|
|
12720
|
+
e.preventDefault();
|
|
12721
|
+
}
|
|
12722
|
+
}
|
|
12723
|
+
}
|
|
12724
|
+
TableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService, deps: [{ token: i1$1.ThyPopover }, { token: i2$1.Overlay }, { token: TableStore }, { token: i0.NgZone }, { token: TheContextService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
12725
|
+
TableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService });
|
|
12726
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableService, decorators: [{
|
|
12727
|
+
type: Injectable
|
|
12728
|
+
}], ctorParameters: function () { return [{ type: i1$1.ThyPopover }, { type: i2$1.Overlay }, { type: TableStore }, { type: i0.NgZone }, { type: TheContextService }]; } });
|
|
12596
12729
|
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12730
|
+
class TableFreezeColumnPipe {
|
|
12731
|
+
transform(table, tablePluginOptions) {
|
|
12732
|
+
const rows = table.children?.map(item => item.children);
|
|
12733
|
+
const headerColumnWidth = table.columns && table.columns[0].width;
|
|
12734
|
+
const tableComponent = ELEMENT_TO_COMPONENT.get(table);
|
|
12735
|
+
let stickyColumn = true;
|
|
12736
|
+
let buffer = TABLE_CONTROL;
|
|
12737
|
+
if (table.options?.numberedColumn) {
|
|
12738
|
+
buffer = TABLE_NUMBER_COLUMN + TABLE_CONTROL;
|
|
12739
|
+
}
|
|
12740
|
+
if (tableComponent) {
|
|
12741
|
+
const tableWidth = getElementWidth(tableComponent.elementRef.nativeElement);
|
|
12742
|
+
stickyColumn = headerColumnWidth + buffer < tableWidth;
|
|
12743
|
+
}
|
|
12744
|
+
// 标题列存在合并的列时,取消冻结
|
|
12745
|
+
const mergeColumnCells = rows && rows.map(cells => cells[0]).filter(item => item.colspan && item.colspan !== 1);
|
|
12746
|
+
return !!(tablePluginOptions?.freezeColumnHeader && table.options?.headerColumn && !mergeColumnCells.length && stickyColumn);
|
|
12604
12747
|
}
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12748
|
+
}
|
|
12749
|
+
TableFreezeColumnPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
12750
|
+
TableFreezeColumnPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, name: "freezeColumn" });
|
|
12751
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeColumnPipe, decorators: [{
|
|
12752
|
+
type: Pipe,
|
|
12753
|
+
args: [{ name: 'freezeColumn' }]
|
|
12754
|
+
}] });
|
|
12755
|
+
class TableFreezeRowPipe {
|
|
12756
|
+
transform(table, headerRow, tablePluginOptions) {
|
|
12757
|
+
// 标题行存在合并的行时,取消冻结
|
|
12758
|
+
if (table.children) {
|
|
12759
|
+
const mergeRows = table.children[0]?.children.filter(item => item.rowspan && item.rowspan !== 1);
|
|
12760
|
+
return !!(headerRow && !mergeRows.length && tablePluginOptions?.freezeRowHeader);
|
|
12761
|
+
}
|
|
12762
|
+
return false;
|
|
12608
12763
|
}
|
|
12609
12764
|
}
|
|
12765
|
+
TableFreezeRowPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
12766
|
+
TableFreezeRowPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, name: "freezeRow" });
|
|
12767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TableFreezeRowPipe, decorators: [{
|
|
12768
|
+
type: Pipe,
|
|
12769
|
+
args: [{ name: 'freezeRow' }]
|
|
12770
|
+
}] });
|
|
12610
12771
|
|
|
12611
12772
|
const TABLE_SELECTOR = '.the-table';
|
|
12612
12773
|
const TABLE_WRAPPER_SELECTOR = '.the-table-wrapper';
|
|
@@ -12676,6 +12837,10 @@ class TheColumnResizeDirective {
|
|
|
12676
12837
|
merge(this.resizeNotifier.resizeCanceled, this.resizeNotifier.resizeCompleted)
|
|
12677
12838
|
.pipe(takeUntil(this.destroyed))
|
|
12678
12839
|
.subscribe(() => {
|
|
12840
|
+
// 如果没有进行拖拽就不要进行后续表格宽高计算了
|
|
12841
|
+
if (!this.resizeStarted) {
|
|
12842
|
+
return;
|
|
12843
|
+
}
|
|
12679
12844
|
this.resizeStarted = false;
|
|
12680
12845
|
if (this.position === Position.left || this.position === Position.right) {
|
|
12681
12846
|
this.theTableComponent.transformColumnsWidth();
|
|
@@ -12907,8 +13072,10 @@ class TheTableComponent extends TheBaseElementComponent {
|
|
|
12907
13072
|
this.subscribeCellPositionChange();
|
|
12908
13073
|
this.listenTableContextMenuEvent();
|
|
12909
13074
|
this.listenOnSelectedCells();
|
|
12910
|
-
this.
|
|
13075
|
+
this.listenKeydownEvent();
|
|
13076
|
+
this.listenKeyupEvent();
|
|
12911
13077
|
this.listenTableWrapperScroll();
|
|
13078
|
+
this.listenSelectstartEvent();
|
|
12912
13079
|
this.getColumnGroups();
|
|
12913
13080
|
this.bindTableScrollingShadow();
|
|
12914
13081
|
if (this.element.options?.numberedColumn) {
|
|
@@ -13405,7 +13572,7 @@ class TheTableComponent extends TheBaseElementComponent {
|
|
|
13405
13572
|
this.tableStore.clearSelectedCellsContent();
|
|
13406
13573
|
}
|
|
13407
13574
|
const isCurrentTableElement = this.nativeElement.contains(e.target);
|
|
13408
|
-
if (!isCurrentTableElement || !this.tableStore.pointerSelection) {
|
|
13575
|
+
if (!isCurrentTableElement || (!this.tableStore.pointerSelection && !this.tableStore.areaSelection)) {
|
|
13409
13576
|
this.tableStore.clearSelectedCells();
|
|
13410
13577
|
}
|
|
13411
13578
|
if (!isCurrentTableElement) {
|
|
@@ -13414,21 +13581,36 @@ class TheTableComponent extends TheBaseElementComponent {
|
|
|
13414
13581
|
this.theTableContextMenuService.closeContextMenu();
|
|
13415
13582
|
});
|
|
13416
13583
|
}
|
|
13417
|
-
|
|
13584
|
+
listenKeydownEvent() {
|
|
13418
13585
|
this.ngZone.runOutsideAngular(() => {
|
|
13419
13586
|
fromEvent(document, 'keydown')
|
|
13420
13587
|
.pipe(takeUntil(this.destroy$), filter((e) => !!e))
|
|
13421
13588
|
.subscribe((event) => {
|
|
13422
|
-
if (isKeyHotkey('mod', event)
|
|
13423
|
-
this.
|
|
13424
|
-
|
|
13425
|
-
|
|
13589
|
+
if (!this.readonly && isKeyHotkey('mod', event)) {
|
|
13590
|
+
this.tableService.handleKeydownForPointerSelection(event, this.tbodyNativeElement);
|
|
13591
|
+
}
|
|
13592
|
+
if (!this.readonly && isKeyHotkey('shift', event)) {
|
|
13593
|
+
this.tableService.handleKeydownForAreaSelection(event, this.tbodyNativeElement);
|
|
13426
13594
|
}
|
|
13427
13595
|
});
|
|
13596
|
+
});
|
|
13597
|
+
}
|
|
13598
|
+
listenKeyupEvent() {
|
|
13599
|
+
this.ngZone.runOutsideAngular(() => {
|
|
13428
13600
|
fromEvent(document, 'keyup')
|
|
13429
13601
|
.pipe(takeUntil(this.destroy$), filter((e) => !!e))
|
|
13430
13602
|
.subscribe(() => {
|
|
13431
|
-
this.
|
|
13603
|
+
this.tableService.cancelPointerSelection();
|
|
13604
|
+
this.tableService.cancelAreaSelection();
|
|
13605
|
+
});
|
|
13606
|
+
});
|
|
13607
|
+
}
|
|
13608
|
+
listenSelectstartEvent() {
|
|
13609
|
+
this.ngZone.runOutsideAngular(() => {
|
|
13610
|
+
fromEvent(document, 'selectstart')
|
|
13611
|
+
.pipe(takeUntil(this.destroy$))
|
|
13612
|
+
.subscribe((event) => {
|
|
13613
|
+
this.tableService.selectStartPreventDefault(event);
|
|
13432
13614
|
});
|
|
13433
13615
|
});
|
|
13434
13616
|
}
|
|
@@ -14039,19 +14221,19 @@ const POSITION_MAP = {
|
|
|
14039
14221
|
};
|
|
14040
14222
|
class TheTdComponent extends TheBaseElementComponent {
|
|
14041
14223
|
get tableStore() {
|
|
14042
|
-
return this.tableComponent
|
|
14224
|
+
return this.tableComponent?.tableStore;
|
|
14043
14225
|
}
|
|
14044
14226
|
get tableService() {
|
|
14045
|
-
return this.tableComponent
|
|
14227
|
+
return this.tableComponent?.tableService;
|
|
14046
14228
|
}
|
|
14047
14229
|
get eventDispatcher() {
|
|
14048
|
-
return this.tableComponent
|
|
14230
|
+
return this.tableComponent?.eventDispatcher;
|
|
14049
14231
|
}
|
|
14050
14232
|
get resizeNotifier() {
|
|
14051
|
-
return this.tableComponent
|
|
14233
|
+
return this.tableComponent?.resizeNotifier;
|
|
14052
14234
|
}
|
|
14053
14235
|
get tableElement() {
|
|
14054
|
-
return this.tableComponent
|
|
14236
|
+
return this.tableComponent?.theTableElement?.nativeElement;
|
|
14055
14237
|
}
|
|
14056
14238
|
get scrollableElementTop() {
|
|
14057
14239
|
const containerElement = this.elementRef.nativeElement.closest(this.editor.options?.scrollContainer || DEFAULT_SCROLL_CONTAINER);
|
|
@@ -14071,7 +14253,7 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14071
14253
|
return this.tableComponent.tableWrapper.nativeElement.scrollLeft;
|
|
14072
14254
|
}
|
|
14073
14255
|
get isXAxisHover() {
|
|
14074
|
-
return [Position.left, Position.right].includes(this.
|
|
14256
|
+
return [Position.left, Position.right].includes(this.hoveredDirection);
|
|
14075
14257
|
}
|
|
14076
14258
|
get rowResizeClass() {
|
|
14077
14259
|
return [
|
|
@@ -14103,11 +14285,7 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14103
14285
|
}
|
|
14104
14286
|
ngOnInit() {
|
|
14105
14287
|
super.ngOnInit();
|
|
14106
|
-
this.
|
|
14107
|
-
this.useSpan();
|
|
14108
|
-
this.useDisplay();
|
|
14109
|
-
this.useFocus();
|
|
14110
|
-
useElementStyle(this.elementRef.nativeElement, this.element);
|
|
14288
|
+
this.useState();
|
|
14111
14289
|
}
|
|
14112
14290
|
ngAfterViewInit() {
|
|
14113
14291
|
this.ngZone.onStable.pipe(take(1)).subscribe(() => {
|
|
@@ -14220,16 +14398,22 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14220
14398
|
fromEvent(element, 'mousedown')
|
|
14221
14399
|
.pipe(takeUntil(this.destroy$), filter((e) => e.button !== 2), map$1(event => event.target.closest(SLA_TABLE_CELL_SELECTOR)), filter(cell => !!cell))
|
|
14222
14400
|
.subscribe((cell) => {
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14401
|
+
if (!this.readonly) {
|
|
14402
|
+
if (this.tableStore.pointerSelection) {
|
|
14403
|
+
this.tableStore.selectCell(cell, this.editor);
|
|
14404
|
+
}
|
|
14405
|
+
if (this.tableStore.areaSelection) {
|
|
14406
|
+
this.tableStore.setAreaSelectionCells(this.element);
|
|
14407
|
+
}
|
|
14408
|
+
else {
|
|
14409
|
+
this.tableStore.selectCellStart(cell, this.editor);
|
|
14410
|
+
}
|
|
14411
|
+
if (this.overlayRef) {
|
|
14412
|
+
this.overlayRef.detach();
|
|
14413
|
+
}
|
|
14414
|
+
// 拖选
|
|
14415
|
+
this.listenCellMouseEvents();
|
|
14230
14416
|
}
|
|
14231
|
-
// 拖选
|
|
14232
|
-
this.listenCellMouseEvents();
|
|
14233
14417
|
});
|
|
14234
14418
|
});
|
|
14235
14419
|
}
|
|
@@ -14245,14 +14429,16 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14245
14429
|
this.tableStore.selectCellOngoing(cell, this.editor);
|
|
14246
14430
|
});
|
|
14247
14431
|
fromEvent(document, 'mouseup')
|
|
14248
|
-
.pipe(take(1))
|
|
14432
|
+
.pipe(take(1), takeUntil(this.destroy$))
|
|
14249
14433
|
.subscribe(() => {
|
|
14250
|
-
this.tableStore.selectCellEnd(this.editor);
|
|
14251
14434
|
if (this.tableStore.isCellSelecting || this.tableStore.pointerSelection) {
|
|
14252
14435
|
this.ngZone.run(() => {
|
|
14253
14436
|
this.tableComponent.tableService.afterSelectedCells(this.tableStore.focusCellElement, this.tableComponent.element);
|
|
14254
14437
|
});
|
|
14255
14438
|
}
|
|
14439
|
+
if (!this.tableStore.areaSelection) {
|
|
14440
|
+
this.tableStore.selectCellEnd(this.editor);
|
|
14441
|
+
}
|
|
14256
14442
|
mouseoverObservable.unsubscribe();
|
|
14257
14443
|
});
|
|
14258
14444
|
}
|
|
@@ -14274,13 +14460,13 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14274
14460
|
}))
|
|
14275
14461
|
.subscribe(hoveredCellInfo => {
|
|
14276
14462
|
if (hoveredCellInfo && hoveredCellInfo.position) {
|
|
14277
|
-
this.
|
|
14463
|
+
this.hoveredDirection = hoveredCellInfo.position;
|
|
14278
14464
|
}
|
|
14279
14465
|
else {
|
|
14280
|
-
this.
|
|
14466
|
+
this.hoveredDirection = null;
|
|
14281
14467
|
}
|
|
14282
14468
|
if (hoveredCellInfo) {
|
|
14283
|
-
this.
|
|
14469
|
+
this.hoveredDirection = hoveredCellInfo.position;
|
|
14284
14470
|
if (!this.overlayRef || !this.overlayRef.hasAttached()) {
|
|
14285
14471
|
this.overlayRef = this._createOverlayForHandle();
|
|
14286
14472
|
this._showHandleOverlay();
|
|
@@ -14300,16 +14486,20 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14300
14486
|
merge(this.resizeNotifier.resizeCanceled, this.resizeNotifier.triggerResize)
|
|
14301
14487
|
.pipe(takeUntilDestroyed, filter(columnSize => columnSize.tableCell === this.elementRef.nativeElement))
|
|
14302
14488
|
.subscribe(({ deltaSize, previousSize, completeImmediately }) => {
|
|
14489
|
+
// 如果偏移的值不存在就不要进行后续的计算了
|
|
14490
|
+
if (isUndefined(deltaSize) || isUndefined(previousSize)) {
|
|
14491
|
+
return;
|
|
14492
|
+
}
|
|
14303
14493
|
const { top, left, height, width } = this.elementRef.nativeElement.getBoundingClientRect();
|
|
14304
14494
|
const { clientY, clientX } = event;
|
|
14305
14495
|
let isPreventApplySize = false;
|
|
14306
14496
|
// 向下,或者向右移动(deltaSize > 0),鼠标位置不在当前单元格拖拽线上,阻止应用拖拽尺寸
|
|
14307
14497
|
if (this.isXAxisHover) {
|
|
14308
|
-
const cellWidth = this.
|
|
14498
|
+
const cellWidth = this.hoveredDirection === Position.left ? 0 : width;
|
|
14309
14499
|
isPreventApplySize = deltaSize > 0 && left + cellWidth - clientX > 0;
|
|
14310
14500
|
}
|
|
14311
14501
|
else {
|
|
14312
|
-
const cellHeight = this.
|
|
14502
|
+
const cellHeight = this.hoveredDirection === Position.top ? 0 : height;
|
|
14313
14503
|
isPreventApplySize = deltaSize > 0 && top + cellHeight - clientY > 0;
|
|
14314
14504
|
}
|
|
14315
14505
|
if (isPreventApplySize) {
|
|
@@ -14358,7 +14548,7 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14358
14548
|
this.isXAxisHover ? this.updateOverlayHandleColumnSize() : this.updateOverlayHandleRowSize();
|
|
14359
14549
|
this.overlayRef?.updatePositionStrategy(this.createPositionStrategy());
|
|
14360
14550
|
this.resizeRef.setDirection(this.isXAxisHover ? 'X' : 'Y');
|
|
14361
|
-
this.resizeRef.setPosition(this.
|
|
14551
|
+
this.resizeRef.setPosition(this.hoveredDirection);
|
|
14362
14552
|
}
|
|
14363
14553
|
updateOverlayHandleColumnSize() {
|
|
14364
14554
|
let height = 0;
|
|
@@ -14433,8 +14623,8 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14433
14623
|
let offsetY = this.calculateOverlayHandleOffsetY();
|
|
14434
14624
|
let offsetX = this.calculateOverlayHandleOffsetX();
|
|
14435
14625
|
const position = this.isXAxisHover
|
|
14436
|
-
? { ...POSITION_MAP[this.
|
|
14437
|
-
: { ...POSITION_MAP[this.
|
|
14626
|
+
? { ...POSITION_MAP[this.hoveredDirection], offsetY }
|
|
14627
|
+
: { ...POSITION_MAP[this.hoveredDirection], offsetX };
|
|
14438
14628
|
return this.overlay
|
|
14439
14629
|
.position()
|
|
14440
14630
|
.flexibleConnectedTo(this.elementRef.nativeElement)
|
|
@@ -14470,7 +14660,7 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14470
14660
|
this.resizingStore.storeTableWidth(cols);
|
|
14471
14661
|
this.resizingStore.initDirection(deltaX);
|
|
14472
14662
|
let cellIndex = this.elementRef.nativeElement.cellIndex;
|
|
14473
|
-
if (this.
|
|
14663
|
+
if (this.hoveredDirection === 'left') {
|
|
14474
14664
|
cellIndex = cellIndex - 1;
|
|
14475
14665
|
}
|
|
14476
14666
|
const colspan = this.elementRef.nativeElement.getAttribute('colspan') || 1;
|
|
@@ -14564,7 +14754,7 @@ class TheTdComponent extends TheBaseElementComponent {
|
|
|
14564
14754
|
this.resizingStore.storeTableHeight(rows);
|
|
14565
14755
|
this.resizingStore.initDirection(deltaY, this.isXAxisHover);
|
|
14566
14756
|
let rowIndex = this.elementRef.nativeElement.parentElement.rowIndex - 1; // subtract thead's tr
|
|
14567
|
-
if (this.
|
|
14757
|
+
if (this.hoveredDirection === Position.top) {
|
|
14568
14758
|
rowIndex = rowIndex - 1;
|
|
14569
14759
|
}
|
|
14570
14760
|
const rowSpan = this.elementRef.nativeElement.rowSpan;
|
|
@@ -16432,5 +16622,5 @@ const withTestPlugin = (plugins, initValue) => {
|
|
|
16432
16622
|
* Generated bundle index. Do not edit.
|
|
16433
16623
|
*/
|
|
16434
16624
|
|
|
16435
|
-
export { ALIGN_BLOCK_TYPES, A_TAG_REL_ATTR, AlignEditor, Alignment, BLOCK_DELETE_BACKWARD_TYPES, BlockquoteEditor, CLIPBOARD_FORMAT_KEY, CODEMIRROR_PADDING_TOP, CODE_MODES, COMPONENTS, CONTAINER_BLOCKS, CONTROL_KEY, CodeEditor, ColorEditor, ColumnResizeNotifierSource, DEFAULT_LANGUAGE, DEFAULT_SCROLL_CONTAINER, DISABLED_OPERATE_TYPES, DefaultElementOptions, DefaultGlobalToolbarDefinition, DefaultInlineToolbarDefinition, DefaultPluginMenu, DropdownMode, ELEMENT_UNIQUE_ID, ElementKinds, ErrorCodes, FontSizeTypes, FontSizes, HEADING_TYPES, HeadingEditor, HoveredCellInfo, HrEditor, IS_MAC, ImageEditor, IndentEditor, Indents, InlineCodeEditor, LINK_DEFAULT_TEXT, LIST_BLOCK_TYPES, LayoutTypes, LinkEditor, ListEditor, MarkEditor, MarkProps, MarkTypes, MentionEditor, PICTURE_ACCEPTED_UPLOAD_MIME, PICTURE_ACCEPTED_UPLOAD_SIZE, PLUGIN_COMPONENTS, PluginKeys, PluginMenuIcons, PluginMenuSvgs, Position, QuickInsertEditor, STANDARD_HEADING_TYPES, ScrollDirection, SpecialBackgroundColor, TAB_SPACE, THE_EDITOR_CONVERSION_HINT_REF, THE_EDITOR_ORIGIN_ANCHOR, THE_EDITOR_POPOVER_REF, THE_EDITOR_PREVIOUS_SELECTION, THE_EDITOR_UUID, THE_INLINE_TOOLBAR_TYPES, THE_LISTBOX_PARENT_GROUP_TOKEN, THE_LISTBOX_PARENT_OPTION_TOKEN, THE_LISTBOX_TOKEN, THE_MODE_PROVIDER, THE_MODE_TOKEN, THE_PLUGIN_MENU_REF, THE_UPLOAD_SERVICE_TOKEN, TableCellEventDispatcher, TableEditor, TableHeaderBackgroundColor, TheBaseElementComponent, TheBaseSuggestion, TheBaseToolbarDropdown, TheBaseToolbarItem, TheContextService, TheDataMode, TheDefaultElementComponent, TheEditor, TheEditorComponent, TheEditorModule, TheImageComponent, TheListboxDirective, TheListboxGroupDirective, TheListboxOptionDirective, TheMode, TheModeConfig, ThePluginMenu, ThePluginMenuComponent, ThePluginMenuItemType, ThePreventDefaultDirective, index$1 as TheQueries, TheToolbarComponent, TheToolbarDropdownComponent, TheToolbarGroupComponent, TheToolbarGroupToken, TheToolbarItemComponent, TheToolbarService, index as TheTransforms, TodoItemEditor, ToolbarActionTypes, ToolbarAlignment, ToolbarItemType, ToolbarMoreGroup, VOID_BLOCK_TYPES, VerticalAlignEditor, VerticalAlignment, ZERO_WIDTH_CHAR, autoFocus, base64toBlob, buildPluginMenu, buildPluginMenuItemMap, coercePixelsFromCssValue, combinePlugins, copyNode, copyNodeForSafari, createEmptyParagraph, createMentionPlugin, createPluginFactory, createToolbar, createVerticalAlignPlugin, dataDeserialize, dataSerializing, deleteElementKey, extractFragment, filterTextFormat, flattenDeepPlugins, getColsTotalWidth, getEditorUUID, getElementClassByPrefix, getElementHeight, getElementWidth, getEndBlock, getPlugin, getPluginOptions, getPlugins, getRowsTotalHeight, getStartBlock, getToolbarClass, headingOptions, htmlToTheia, idCreator, inValidTypes, initializeDefaultMenuIcons, insertDataByInvalidType, internalPlugins, isCleanEmptyParagraph, isDirectionKeydown, isPureEmptyParagraph, mergeArray, mergeDeepPlugins, mergeElementOptions, mergeOptions, nestedStructureByKey, plainToTheia, pluginsByKey, reSelection, recursionNodes, refocus, scrollIntoView, setEditorUUID, useElementStyle, withMention, withTestPlugin, withTheia };
|
|
16625
|
+
export { ALIGN_BLOCK_TYPES, A_TAG_REL_ATTR, AlignEditor, Alignment, BLOCK_DELETE_BACKWARD_TYPES, BlockquoteEditor, CLIPBOARD_FORMAT_KEY, CODEMIRROR_PADDING_TOP, CODE_MODES, COMPONENTS, CONTAINER_BLOCKS, CONTROL_KEY, CodeEditor, ColorEditor, ColumnResizeNotifierSource, DEFAULT_LANGUAGE, DEFAULT_SCROLL_CONTAINER, DISABLED_OPERATE_TYPES, DefaultElementOptions, DefaultGlobalToolbarDefinition, DefaultInlineToolbarDefinition, DefaultPluginMenu, DropdownMode, ELEMENT_UNIQUE_ID, ElementKinds, ErrorCodes, FontSizeTypes, FontSizes, HEADING_TYPES, HeadingEditor, HoveredCellInfo, HrEditor, IS_MAC, ImageEditor, IndentEditor, Indents, InlineCodeEditor, LINK_DEFAULT_TEXT, LIST_BLOCK_TYPES, LayoutTypes, LinkEditor, ListEditor, MarkEditor, MarkProps, MarkTypes, MentionEditor, PICTURE_ACCEPTED_UPLOAD_MIME, PICTURE_ACCEPTED_UPLOAD_SIZE, PLUGIN_COMPONENTS, PluginKeys, PluginMenuIcons, PluginMenuSvgs, Position, QuickInsertEditor, STANDARD_HEADING_TYPES, ScrollDirection, SpecialBackgroundColor, TAB_SPACE, THE_EDITOR_CONVERSION_HINT_REF, THE_EDITOR_ORIGIN_ANCHOR, THE_EDITOR_POPOVER_REF, THE_EDITOR_PREVIOUS_SELECTION, THE_EDITOR_UUID, THE_INLINE_TOOLBAR_TYPES, THE_LISTBOX_PARENT_GROUP_TOKEN, THE_LISTBOX_PARENT_OPTION_TOKEN, THE_LISTBOX_TOKEN, THE_MODE_PROVIDER, THE_MODE_TOKEN, THE_PLUGIN_MENU_REF, THE_UPLOAD_SERVICE_TOKEN, TableCellEventDispatcher, TableEditor, TableHeaderBackgroundColor, TheBaseElementComponent, TheBaseSuggestion, TheBaseToolbarDropdown, TheBaseToolbarItem, TheContextService, TheDataMode, TheDefaultElementComponent, TheEditor, TheEditorComponent, TheEditorModule, TheImageComponent, TheListboxDirective, TheListboxGroupDirective, TheListboxOptionDirective, TheMode, TheModeConfig, ThePluginMenu, ThePluginMenuComponent, ThePluginMenuItemType, ThePreventDefaultDirective, index$1 as TheQueries, TheToolbarComponent, TheToolbarDropdownComponent, TheToolbarGroupComponent, TheToolbarGroupToken, TheToolbarItemComponent, TheToolbarService, index as TheTransforms, TodoItemEditor, ToolbarActionTypes, ToolbarAlignment, ToolbarItemType, ToolbarMoreGroup, VOID_BLOCK_TYPES, VerticalAlignEditor, VerticalAlignment, ZERO_WIDTH_CHAR, autoFocus, base64toBlob, buildPluginMenu, buildPluginMenuItemMap, coercePixelsFromCssValue, combinePlugins, copyNode, copyNodeForSafari, createEmptyParagraph, createMentionPlugin, createPluginFactory, createToolbar, createVerticalAlignPlugin, dataDeserialize, dataSerializing, deleteElementKey, extractFragment, filterTextFormat, flattenDeepPlugins, getColsTotalWidth, getEditorUUID, getElementClassByPrefix, getElementHeight, getElementWidth, getEndBlock, getPlugin, getPluginOptions, getPlugins, getRowsTotalHeight, getStartBlock, getToolbarClass, headingOptions, htmlToTheia, idCreator, inValidTypes, initializeDefaultMenuIcons, insertDataByInvalidType, internalPlugins, isCleanEmptyParagraph, isColorIndicator, isColorInput, isColorPanel, isDirectionKeydown, isPureEmptyParagraph, mergeArray, mergeDeepPlugins, mergeElementOptions, mergeOptions, nestedStructureByKey, plainToTheia, pluginsByKey, reSelection, recursionNodes, refocus, scrollIntoView, setEditorUUID, useElementStyle, withMention, withTestPlugin, withTheia };
|
|
16436
16626
|
//# sourceMappingURL=worktile-theia.mjs.map
|