quill-table-up 3.1.2 → 3.2.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.
Files changed (111) hide show
  1. package/README.md +15 -8
  2. package/dist/index.css +1 -1
  3. package/dist/index.d.ts +168 -146
  4. package/dist/index.js +47 -47
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.umd.js +52 -52
  7. package/dist/index.umd.js.map +1 -1
  8. package/package.json +22 -24
  9. package/src/__tests__/e2e/custom-creator.test.ts +44 -44
  10. package/src/__tests__/e2e/editor-page.ts +77 -77
  11. package/src/__tests__/e2e/table-align.test.ts +104 -104
  12. package/src/__tests__/e2e/table-blots.test.ts +169 -169
  13. package/src/__tests__/e2e/table-caption.test.ts +134 -134
  14. package/src/__tests__/e2e/table-clipboard.test.ts +20 -20
  15. package/src/__tests__/e2e/table-hack.test.ts +151 -151
  16. package/src/__tests__/e2e/table-keyboard-handler.test.ts +20 -4
  17. package/src/__tests__/e2e/table-menu.test.ts +172 -172
  18. package/src/__tests__/e2e/table-resize.test.ts +654 -9
  19. package/src/__tests__/e2e/table-scrollbar.test.ts +144 -144
  20. package/src/__tests__/e2e/table-selection.test.ts +563 -563
  21. package/src/__tests__/e2e/types.d.ts +8 -7
  22. package/src/__tests__/e2e/utils.ts +52 -52
  23. package/src/__tests__/unit/table-blots.test.ts +720 -720
  24. package/src/__tests__/unit/table-caption.test.ts +234 -234
  25. package/src/__tests__/unit/table-cell-merge.test.ts +713 -724
  26. package/src/__tests__/unit/table-clipboard.test.ts +2176 -2176
  27. package/src/__tests__/unit/table-hack.test.ts +1014 -1014
  28. package/src/__tests__/unit/table-insert.test.ts +915 -926
  29. package/src/__tests__/unit/table-redo-undo.test.ts +2429 -2429
  30. package/src/__tests__/unit/table-remove.test.ts +313 -343
  31. package/src/__tests__/unit/utils.test-d.ts +49 -49
  32. package/src/__tests__/unit/utils.test.ts +711 -711
  33. package/src/__tests__/unit/utils.ts +307 -307
  34. package/src/__tests__/unit/vitest.d.ts +14 -14
  35. package/src/formats/container-format.ts +107 -107
  36. package/src/formats/overrides/block-embed.ts +72 -72
  37. package/src/formats/overrides/block.ts +95 -95
  38. package/src/formats/overrides/index.ts +3 -3
  39. package/src/formats/overrides/scroll.ts +70 -70
  40. package/src/formats/table-body-format.ts +52 -52
  41. package/src/formats/table-caption-format.ts +116 -116
  42. package/src/formats/table-cell-format.ts +304 -304
  43. package/src/formats/table-cell-inner-format.ts +403 -398
  44. package/src/formats/table-colgroup-format.ts +136 -136
  45. package/src/formats/table-foot-format.ts +7 -7
  46. package/src/formats/table-head-format.ts +7 -7
  47. package/src/formats/table-main-format.ts +1 -1
  48. package/src/formats/table-row-format.ts +218 -210
  49. package/src/formats/utils.ts +6 -6
  50. package/src/index.ts +19 -19
  51. package/src/modules/index.ts +7 -7
  52. package/src/modules/table-align.ts +131 -131
  53. package/src/modules/table-clipboard/table-clipboard.ts +6 -8
  54. package/src/modules/table-dom-selector.ts +33 -33
  55. package/src/modules/table-menu/constants.ts +223 -223
  56. package/src/modules/table-menu/index.ts +4 -4
  57. package/src/modules/table-menu/table-menu-common.ts +330 -329
  58. package/src/modules/table-menu/table-menu-contextmenu.ts +111 -118
  59. package/src/modules/table-menu/table-menu-select.ts +96 -94
  60. package/src/modules/table-resize/index.ts +5 -5
  61. package/src/modules/table-resize/table-resize-box.ts +714 -363
  62. package/src/modules/table-resize/table-resize-common.ts +246 -382
  63. package/src/modules/table-resize/table-resize-drag.ts +241 -0
  64. package/src/modules/table-resize/table-resize-line.ts +244 -182
  65. package/src/modules/table-resize/table-resize-scale.ts +174 -173
  66. package/src/modules/table-resize/utils.ts +84 -3
  67. package/src/modules/table-scrollbar.ts +292 -292
  68. package/src/modules/table-selection.ts +613 -669
  69. package/src/style/button.less +45 -45
  70. package/src/style/color-picker.less +136 -136
  71. package/src/style/dialog.less +53 -53
  72. package/src/style/functions.less +9 -9
  73. package/src/style/index.less +120 -120
  74. package/src/style/input.less +64 -64
  75. package/src/style/select-box.less +52 -52
  76. package/src/style/table-creator.less +56 -56
  77. package/src/style/table-menu.less +125 -125
  78. package/src/style/table-resize-scale.less +31 -31
  79. package/src/style/table-resize.less +249 -202
  80. package/src/style/table-scrollbar.less +49 -49
  81. package/src/style/table-selection.less +23 -23
  82. package/src/style/tooltip.less +19 -19
  83. package/src/style/variables.less +1 -1
  84. package/src/svg/arrow-up-down.svg +11 -11
  85. package/src/svg/convert-cell.svg +7 -7
  86. package/src/table-up.ts +1363 -1360
  87. package/src/types.d.ts +4 -4
  88. package/src/utils/bem.ts +23 -23
  89. package/src/utils/blot-helper.ts +101 -105
  90. package/src/utils/color.ts +109 -109
  91. package/src/utils/components/button.ts +22 -22
  92. package/src/utils/components/color-picker.ts +236 -236
  93. package/src/utils/components/dialog.ts +83 -41
  94. package/src/utils/components/index.ts +6 -6
  95. package/src/utils/components/input.ts +74 -74
  96. package/src/utils/components/table/creator.ts +89 -89
  97. package/src/utils/components/table/index.ts +2 -2
  98. package/src/utils/components/table/select-box.ts +78 -78
  99. package/src/utils/components/tooltip.ts +179 -189
  100. package/src/utils/constants.ts +125 -124
  101. package/src/utils/drag-helper.ts +112 -0
  102. package/src/utils/index.ts +15 -14
  103. package/src/utils/is.ts +9 -9
  104. package/src/utils/position.ts +60 -60
  105. package/src/utils/resize-observer-helper.ts +47 -47
  106. package/src/utils/scroll.ts +145 -47
  107. package/src/utils/style-helper.ts +47 -47
  108. package/src/utils/transformer.ts +10 -10
  109. package/src/utils/transition-event-helper.ts +8 -8
  110. package/src/utils/types.ts +156 -157
  111. package/src/utils/utils.ts +12 -12
@@ -1,131 +1,131 @@
1
- import type { TableMainFormat, TableWrapperFormat } from '../formats';
2
- import type { TableUp } from '../table-up';
3
- import { autoUpdate, computePosition, flip, limitShift, offset, shift } from '@floating-ui/dom';
4
- import Quill from 'quill';
5
- import { createBEM, createResizeObserver } from '../utils';
6
- import { TableDomSelector } from './table-dom-selector';
7
-
8
- export class TableAlign extends TableDomSelector {
9
- static moduleName: string = 'table-align';
10
-
11
- tableBlot?: TableMainFormat;
12
- tableWrapperBlot?: TableWrapperFormat;
13
- alignBox: HTMLElement | null;
14
- cleanup?: () => void;
15
- bem = createBEM('align');
16
- resizeObserver?: ResizeObserver;
17
-
18
- constructor(public tableModule: TableUp, public quill: Quill, _options: any) {
19
- super(tableModule, quill);
20
-
21
- this.alignBox = this.buildTools();
22
- this.hide();
23
- this.quill.on(Quill.events.EDITOR_CHANGE, this.updateWhenTextChange);
24
- }
25
-
26
- updateWhenTextChange = (eventName: string) => {
27
- if (eventName === Quill.events.TEXT_CHANGE) {
28
- if (this.table && !this.quill.root.contains(this.table)) {
29
- this.setSelectionTable(undefined);
30
- }
31
- else {
32
- this.update();
33
- }
34
- }
35
- };
36
-
37
- buildTools() {
38
- const alignBox = this.tableModule.addContainer(this.bem.b());
39
- const icons = Quill.import('ui/icons') as Record<string, any>;
40
- const alignIcons = {
41
- left: icons.align[''],
42
- center: icons.align.center,
43
- right: icons.align.right,
44
- };
45
- for (const [align, iconStr] of Object.entries(alignIcons)) {
46
- const item = document.createElement('span');
47
- item.dataset.align = align;
48
- item.classList.add(this.bem.be('item'));
49
- item.innerHTML = `<i class="icon">${iconStr}</i>`;
50
- item.addEventListener('click', this.handleAlignItemClick.bind(this));
51
- alignBox.appendChild(item);
52
- }
53
- return alignBox;
54
- }
55
-
56
- handleAlignItemClick(e: MouseEvent) {
57
- const item = e.currentTarget;
58
- if (!item) return;
59
- const value = (item as HTMLElement).dataset.align;
60
- if (value && this.tableBlot) {
61
- this.setTableAlign(this.tableBlot, value);
62
- }
63
- }
64
-
65
- setTableAlign(tableBlot: TableMainFormat, align: string) {
66
- const cols = tableBlot.getCols();
67
- for (const col of cols) {
68
- col.align = align;
69
- }
70
- }
71
-
72
- show() {
73
- if (!this.table || !this.alignBox) return;
74
- this.tableBlot = Quill.find(this.table) as TableMainFormat;
75
- this.tableWrapperBlot = this.tableBlot.parent as TableWrapperFormat;
76
- this.alignBox.classList.remove(this.bem.is('hidden'));
77
- this.resizeObserver = createResizeObserver(() => this.update(), { ignoreFirstBind: true });
78
- this.resizeObserver.observe(this.table);
79
- if (this.cleanup) {
80
- this.cleanup();
81
- }
82
- this.cleanup = autoUpdate(
83
- this.tableWrapperBlot.domNode,
84
- this.alignBox,
85
- () => this.update(),
86
- );
87
- }
88
-
89
- hide() {
90
- this.tableBlot = undefined;
91
- this.tableWrapperBlot = undefined;
92
- if (this.alignBox) {
93
- this.alignBox.classList.add(this.bem.is('hidden'));
94
- }
95
- if (this.cleanup) {
96
- this.cleanup();
97
- this.cleanup = undefined;
98
- }
99
- }
100
-
101
- update() {
102
- if (!this.alignBox || !this.tableBlot || !this.tableWrapperBlot) return;
103
- if (!this.table || this.tableBlot.full || this.tableBlot.domNode.offsetWidth >= this.quill.root.offsetWidth) {
104
- this.hide();
105
- return;
106
- }
107
-
108
- computePosition(this.tableWrapperBlot.domNode, this.alignBox, {
109
- placement: 'top',
110
- middleware: [flip(), shift({ limiter: limitShift() }), offset(16)],
111
- }).then(({ x, y }) => {
112
- Object.assign(this.alignBox!.style, {
113
- left: `${x}px`,
114
- top: `${y}px`,
115
- });
116
- });
117
- }
118
-
119
- destroy() {
120
- this.hide();
121
- if (this.resizeObserver) {
122
- this.resizeObserver.disconnect();
123
- this.resizeObserver = undefined;
124
- }
125
- this.quill.off(Quill.events.TEXT_CHANGE, this.updateWhenTextChange);
126
- if (this.alignBox) {
127
- this.alignBox.remove();
128
- this.alignBox = null;
129
- }
130
- }
131
- }
1
+ import type { TableMainFormat, TableWrapperFormat } from '../formats';
2
+ import type { TableUp } from '../table-up';
3
+ import { autoUpdate, computePosition, flip, limitShift, offset, shift } from '@floating-ui/dom';
4
+ import Quill from 'quill';
5
+ import { createBEM, createResizeObserver } from '../utils';
6
+ import { TableDomSelector } from './table-dom-selector';
7
+
8
+ export class TableAlign extends TableDomSelector {
9
+ static moduleName: string = 'table-align';
10
+
11
+ tableBlot?: TableMainFormat;
12
+ tableWrapperBlot?: TableWrapperFormat;
13
+ alignBox: HTMLElement | null;
14
+ cleanup?: () => void;
15
+ bem = createBEM('align');
16
+ resizeObserver?: ResizeObserver;
17
+
18
+ constructor(public tableModule: TableUp, public quill: Quill, _options: any) {
19
+ super(tableModule, quill);
20
+
21
+ this.alignBox = this.buildTools();
22
+ this.hide();
23
+ this.quill.on(Quill.events.EDITOR_CHANGE, this.updateWhenTextChange);
24
+ }
25
+
26
+ updateWhenTextChange = (eventName: string) => {
27
+ if (eventName === Quill.events.TEXT_CHANGE) {
28
+ if (this.table && !this.quill.root.contains(this.table)) {
29
+ this.setSelectionTable(undefined);
30
+ }
31
+ else {
32
+ this.update();
33
+ }
34
+ }
35
+ };
36
+
37
+ buildTools() {
38
+ const alignBox = this.tableModule.addContainer(this.bem.b());
39
+ const icons = Quill.import('ui/icons') as Record<string, any>;
40
+ const alignIcons = {
41
+ left: icons.align[''],
42
+ center: icons.align.center,
43
+ right: icons.align.right,
44
+ };
45
+ for (const [align, iconStr] of Object.entries(alignIcons)) {
46
+ const item = document.createElement('span');
47
+ item.dataset.align = align;
48
+ item.classList.add(this.bem.be('item'));
49
+ item.innerHTML = `<i class="icon">${iconStr}</i>`;
50
+ item.addEventListener('click', this.handleAlignItemClick.bind(this));
51
+ alignBox.appendChild(item);
52
+ }
53
+ return alignBox;
54
+ }
55
+
56
+ handleAlignItemClick(e: MouseEvent) {
57
+ const item = e.currentTarget;
58
+ if (!item) return;
59
+ const value = (item as HTMLElement).dataset.align;
60
+ if (value && this.tableBlot) {
61
+ this.setTableAlign(this.tableBlot, value);
62
+ }
63
+ }
64
+
65
+ setTableAlign(tableBlot: TableMainFormat, align: string) {
66
+ const cols = tableBlot.getCols();
67
+ for (const col of cols) {
68
+ col.align = align;
69
+ }
70
+ }
71
+
72
+ show() {
73
+ if (!this.table || !this.alignBox) return;
74
+ this.tableBlot = Quill.find(this.table) as TableMainFormat;
75
+ this.tableWrapperBlot = this.tableBlot.parent as TableWrapperFormat;
76
+ this.alignBox.classList.remove(this.bem.is('hidden'));
77
+ this.resizeObserver = createResizeObserver(() => this.update(), { ignoreFirstBind: true });
78
+ this.resizeObserver.observe(this.table);
79
+ if (this.cleanup) {
80
+ this.cleanup();
81
+ }
82
+ this.cleanup = autoUpdate(
83
+ this.tableWrapperBlot.domNode,
84
+ this.alignBox,
85
+ () => this.update(),
86
+ );
87
+ }
88
+
89
+ hide() {
90
+ this.tableBlot = undefined;
91
+ this.tableWrapperBlot = undefined;
92
+ if (this.alignBox) {
93
+ this.alignBox.classList.add(this.bem.is('hidden'));
94
+ }
95
+ if (this.cleanup) {
96
+ this.cleanup();
97
+ this.cleanup = undefined;
98
+ }
99
+ }
100
+
101
+ update() {
102
+ if (!this.alignBox || !this.tableBlot || !this.tableWrapperBlot) return;
103
+ if (!this.table || this.tableBlot.full || this.tableBlot.domNode.offsetWidth >= this.quill.root.offsetWidth) {
104
+ this.hide();
105
+ return;
106
+ }
107
+
108
+ computePosition(this.tableWrapperBlot.domNode, this.alignBox, {
109
+ placement: 'top',
110
+ middleware: [flip(), shift({ limiter: limitShift() }), offset(16)],
111
+ }).then(({ x, y }) => {
112
+ Object.assign(this.alignBox!.style, {
113
+ left: `${x}px`,
114
+ top: `${y}px`,
115
+ });
116
+ });
117
+ }
118
+
119
+ destroy() {
120
+ this.hide();
121
+ if (this.resizeObserver) {
122
+ this.resizeObserver.disconnect();
123
+ this.resizeObserver = undefined;
124
+ }
125
+ this.quill.off(Quill.events.TEXT_CHANGE, this.updateWhenTextChange);
126
+ if (this.alignBox) {
127
+ this.alignBox.remove();
128
+ this.alignBox = null;
129
+ }
130
+ }
131
+ }
@@ -194,7 +194,7 @@ export class TableClipboard extends Clipboard {
194
194
  matchThead(node: Node, delta: TypeDelta) {
195
195
  const deltaData = this.matchTbody(node, delta);
196
196
  for (const op of deltaData.ops) {
197
- if (op.attributes && op.attributes[blotName.tableCellInner]) {
197
+ if (op.attributes?.[blotName.tableCellInner]) {
198
198
  const tableCellInner = op.attributes[blotName.tableCellInner] as TableCellValue;
199
199
  tableCellInner.wrapTag = 'thead';
200
200
  }
@@ -205,7 +205,7 @@ export class TableClipboard extends Clipboard {
205
205
  matchTfoot(node: Node, delta: TypeDelta) {
206
206
  const deltaData = this.matchTbody(node, delta);
207
207
  for (const op of deltaData.ops) {
208
- if (op.attributes && op.attributes[blotName.tableCellInner]) {
208
+ if (op.attributes?.[blotName.tableCellInner]) {
209
209
  const tableCellInner = op.attributes[blotName.tableCellInner] as TableCellValue;
210
210
  tableCellInner.wrapTag = 'tfoot';
211
211
  }
@@ -215,8 +215,7 @@ export class TableClipboard extends Clipboard {
215
215
 
216
216
  matchColgroup(node: Node, delta: TypeDelta) {
217
217
  const ops: Record<string, any>[] = [];
218
- for (let i = 0; i < delta.ops.length; i++) {
219
- const op = delta.ops[i];
218
+ for (const op of delta.ops) {
220
219
  if (op && isObject(op.insert) && op.insert[blotName.tableCol]) {
221
220
  ops.push(op);
222
221
  }
@@ -321,7 +320,7 @@ export class TableClipboard extends Clipboard {
321
320
  for (const op of delta.ops) {
322
321
  const { attributes, ...other } = op;
323
322
  const tableCellInner = attributes?.[blotName.tableCellInner] as TableCellValue;
324
- if (attributes && tableCellInner && tableCellInner.style) {
323
+ if (attributes && tableCellInner?.style) {
325
324
  const { background, ...attrs } = attributes;
326
325
 
327
326
  const bgTemp = document.createElement('div');
@@ -361,10 +360,9 @@ export class TableClipboard extends Clipboard {
361
360
  }
362
361
 
363
362
  matchCaption(node: Node, delta: TypeDelta) {
364
- for (let i = 0; i < delta.ops.length; i++) {
365
- const op = delta.ops[i];
363
+ for (const op of delta.ops) {
366
364
  const { attributes } = op;
367
- if (attributes && attributes[blotName.tableCaption]) {
365
+ if (attributes?.[blotName.tableCaption]) {
368
366
  (attributes[blotName.tableCaption] as TableCaptionValue).tableId = this.tableId;
369
367
  op.attributes = attributes;
370
368
  }
@@ -1,33 +1,33 @@
1
- import type Quill from 'quill';
2
- import type { TableUp } from '../table-up';
3
-
4
- export class TableDomSelector {
5
- table?: HTMLTableElement;
6
-
7
- constructor(public tableModule: TableUp, public quill: Quill) {
8
- this.quill.root.addEventListener('mousedown', this.tableSelectHandler.bind(this));
9
- }
10
-
11
- tableSelectHandler(event: MouseEvent) {
12
- const path = event.composedPath() as HTMLElement[];
13
- if (event.button !== 0 || !path || path.length <= 0) return;
14
- const tableNode = path.find(node => node.tagName && node.tagName.toUpperCase() === 'TABLE');
15
- this.setSelectionTable(tableNode as HTMLTableElement);
16
- }
17
-
18
- setSelectionTable(table: HTMLTableElement | undefined) {
19
- if (this.table === table) return;
20
- this.hide();
21
- this.table = table;
22
- if (this.table) {
23
- this.show();
24
- }
25
- this.update();
26
- }
27
-
28
- hide() {}
29
-
30
- show() {}
31
-
32
- update() {}
33
- }
1
+ import type Quill from 'quill';
2
+ import type { TableUp } from '../table-up';
3
+
4
+ export class TableDomSelector {
5
+ table?: HTMLTableElement;
6
+
7
+ constructor(public tableModule: TableUp, public quill: Quill) {
8
+ this.quill.root.addEventListener('mousedown', this.tableSelectHandler.bind(this));
9
+ }
10
+
11
+ tableSelectHandler(event: MouseEvent) {
12
+ const path = event.composedPath() as HTMLElement[];
13
+ if (event.button !== 0 || !path || path.length <= 0) return;
14
+ const tableNode = path.find(node => node.tagName && node.tagName.toUpperCase() === 'TABLE');
15
+ this.setSelectionTable(tableNode as HTMLTableElement);
16
+ }
17
+
18
+ setSelectionTable(table: HTMLTableElement | undefined) {
19
+ if (this.table === table) return;
20
+ this.hide();
21
+ this.table = table;
22
+ if (this.table) {
23
+ this.show();
24
+ }
25
+ this.update();
26
+ }
27
+
28
+ hide() {}
29
+
30
+ show() {}
31
+
32
+ update() {}
33
+ }