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,107 +1,107 @@
1
- import type { Parchment as TypeParchment } from 'quill';
2
- import Quill from 'quill';
3
- import { blotName, isFunction } from '../utils';
4
-
5
- const Parchment = Quill.import('parchment');
6
- const Container = Quill.import('blots/container') as typeof TypeParchment.ContainerBlot;
7
- const Block = Quill.import('blots/block') as TypeParchment.BlotConstructor;
8
- const BlockEmbed = Quill.import('blots/block/embed') as TypeParchment.BlotConstructor;
9
-
10
- export class ContainerFormat extends Container {
11
- static tagName: string;
12
- static blotName: string = blotName.container;
13
- static scope = Parchment.Scope.BLOCK_BLOT;
14
- static allowedChildren?: TypeParchment.BlotConstructor[] = [Block, BlockEmbed, Container];
15
- static requiredContainer: TypeParchment.BlotConstructor;
16
- static defaultChild?: TypeParchment.BlotConstructor;
17
-
18
- static allowAttrs = new Set<string>([]);
19
- static allowDataAttrs = new Set<string>([]);
20
- // handle the attribute change when use `setFormatValue`
21
- static allowDataAttrsChangeHandler: Record<string, string> = {};
22
-
23
- static create(_value?: unknown) {
24
- const node = document.createElement(this.tagName);
25
- if (this.className) {
26
- node.classList.add(this.className);
27
- }
28
- return node;
29
- }
30
-
31
- setFormatValue(name: string, value?: any) {
32
- if (this.statics.allowAttrs.has(name) || this.statics.allowDataAttrs.has(name)) {
33
- let attrName = name;
34
- if (this.statics.allowDataAttrs.has(name)) {
35
- attrName = `data-${name}`;
36
- }
37
- if (value) {
38
- this.domNode.setAttribute(attrName, value);
39
- }
40
- else {
41
- this.domNode.removeAttribute(attrName);
42
- }
43
- const methodName = this.statics.allowDataAttrsChangeHandler[name] as keyof this;
44
- if (methodName && isFunction(this[methodName])) {
45
- (this[methodName] as Function)(value);
46
- }
47
- }
48
- }
49
-
50
- public optimize(_context: Record<string, any>) {
51
- if (this.children.length === 0) {
52
- if (this.statics.defaultChild != null) {
53
- const child = this.scroll.create(this.statics.defaultChild.blotName);
54
- this.appendChild(child);
55
- }
56
- else {
57
- this.remove();
58
- }
59
- }
60
-
61
- if (this.children.length > 0 && this.next != null && this.checkMerge()) {
62
- this.next.moveChildren(this);
63
- this.next.remove();
64
- }
65
- }
66
-
67
- public enforceAllowedChildren(): void {
68
- // the origin `enforceAllowedChildren` only unwrap the first block
69
- // remove flag `done`. all block format in table container need be unwrap
70
-
71
- // eslint-disable-next-line unicorn/no-array-for-each
72
- this.children.forEach((child: TypeParchment.Blot) => {
73
- const allowed = this.statics.allowedChildren.some(
74
- (def: TypeParchment.BlotConstructor) => child instanceof def,
75
- );
76
- if (allowed) {
77
- return;
78
- }
79
- if (child.statics.scope === Parchment.Scope.BLOCK_BLOT) {
80
- // only child is in table format need keep split blot. else use the origin method
81
- if (child.parent instanceof ContainerFormat) {
82
- if (child.next != null) {
83
- child.parent.splitAfter(child);
84
- }
85
- if (child.prev != null) {
86
- child.parent.splitAfter(child.prev);
87
- }
88
- }
89
- else {
90
- if (child.next != null) {
91
- this.splitAfter(child);
92
- }
93
- if (child.prev != null) {
94
- this.splitAfter(child.prev);
95
- }
96
- }
97
- child.parent.unwrap();
98
- }
99
- else if (child instanceof Parchment.ParentBlot) {
100
- child.unwrap();
101
- }
102
- else {
103
- child.remove();
104
- }
105
- });
106
- }
107
- }
1
+ import type { Parchment as TypeParchment } from 'quill';
2
+ import Quill from 'quill';
3
+ import { blotName, isFunction } from '../utils';
4
+
5
+ const Parchment = Quill.import('parchment');
6
+ const Container = Quill.import('blots/container') as typeof TypeParchment.ContainerBlot;
7
+ const Block = Quill.import('blots/block') as TypeParchment.BlotConstructor;
8
+ const BlockEmbed = Quill.import('blots/block/embed') as TypeParchment.BlotConstructor;
9
+
10
+ export class ContainerFormat extends Container {
11
+ static tagName: string;
12
+ static blotName: string = blotName.container;
13
+ static scope = Parchment.Scope.BLOCK_BLOT;
14
+ static allowedChildren?: TypeParchment.BlotConstructor[] = [Block, BlockEmbed, Container];
15
+ static requiredContainer: TypeParchment.BlotConstructor;
16
+ static defaultChild?: TypeParchment.BlotConstructor;
17
+
18
+ static allowAttrs = new Set<string>([]);
19
+ static allowDataAttrs = new Set<string>([]);
20
+ // handle the attribute change when use `setFormatValue`
21
+ static allowDataAttrsChangeHandler: Record<string, string> = {};
22
+
23
+ static create(_value?: unknown) {
24
+ const node = document.createElement(this.tagName);
25
+ if (this.className) {
26
+ node.classList.add(this.className);
27
+ }
28
+ return node;
29
+ }
30
+
31
+ setFormatValue(name: string, value?: any) {
32
+ if (this.statics.allowAttrs.has(name) || this.statics.allowDataAttrs.has(name)) {
33
+ let attrName = name;
34
+ if (this.statics.allowDataAttrs.has(name)) {
35
+ attrName = `data-${name}`;
36
+ }
37
+ if (value) {
38
+ this.domNode.setAttribute(attrName, value);
39
+ }
40
+ else {
41
+ this.domNode.removeAttribute(attrName);
42
+ }
43
+ const methodName = this.statics.allowDataAttrsChangeHandler[name] as keyof this;
44
+ if (methodName && isFunction(this[methodName])) {
45
+ (this[methodName] as Function)(value);
46
+ }
47
+ }
48
+ }
49
+
50
+ public optimize(_context: Record<string, any>) {
51
+ if (this.children.length === 0) {
52
+ if (this.statics.defaultChild != null) {
53
+ const child = this.scroll.create(this.statics.defaultChild.blotName);
54
+ this.appendChild(child);
55
+ }
56
+ else {
57
+ this.remove();
58
+ }
59
+ }
60
+
61
+ if (this.children.length > 0 && this.next != null && this.checkMerge()) {
62
+ this.next.moveChildren(this);
63
+ this.next.remove();
64
+ }
65
+ }
66
+
67
+ public enforceAllowedChildren(): void {
68
+ // the origin `enforceAllowedChildren` only unwrap the first block
69
+ // remove flag `done`. all block format in table container need be unwrap
70
+
71
+ // eslint-disable-next-line unicorn/no-array-for-each
72
+ this.children.forEach((child: TypeParchment.Blot) => {
73
+ const allowed = this.statics.allowedChildren.some(
74
+ (def: TypeParchment.BlotConstructor) => child instanceof def,
75
+ );
76
+ if (allowed) {
77
+ return;
78
+ }
79
+ if (child.statics.scope === Parchment.Scope.BLOCK_BLOT) {
80
+ // only child is in table format need keep split blot. else use the origin method
81
+ if (child.parent instanceof ContainerFormat) {
82
+ if (child.next != null) {
83
+ child.parent.splitAfter(child);
84
+ }
85
+ if (child.prev != null) {
86
+ child.parent.splitAfter(child.prev);
87
+ }
88
+ }
89
+ else {
90
+ if (child.next != null) {
91
+ this.splitAfter(child);
92
+ }
93
+ if (child.prev != null) {
94
+ this.splitAfter(child.prev);
95
+ }
96
+ }
97
+ child.parent.unwrap();
98
+ }
99
+ else if (child instanceof Parchment.ParentBlot) {
100
+ child.unwrap();
101
+ }
102
+ else {
103
+ child.remove();
104
+ }
105
+ });
106
+ }
107
+ }
@@ -1,72 +1,72 @@
1
- import type { Parchment as TypeParchment } from 'quill';
2
- import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block';
3
- import type { TableCellInnerFormat } from '../table-cell-inner-format';
4
- import Quill from 'quill';
5
- import { blotName, findParentBlot } from '../../utils';
6
-
7
- const BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed;
8
-
9
- export class BlockEmbedOverride extends BlockEmbed {
10
- delta() {
11
- // if BlockEmbed is the last line of the tableCellInner. need to add value in delta
12
- const delta = super.delta();
13
- const formats = bubbleFormats(this);
14
- if (formats[blotName.tableCellInner]) {
15
- delta.insert('\n', { [blotName.tableCellInner]: formats[blotName.tableCellInner] });
16
- }
17
- return delta;
18
- }
19
-
20
- length() {
21
- const formats = bubbleFormats(this);
22
- if (formats[blotName.tableCellInner]) {
23
- return super.length() + 1;
24
- }
25
- return super.length();
26
- }
27
-
28
- formatAt(index: number, length: number, name: string, value: unknown) {
29
- if (name === blotName.tableCellInner) {
30
- try {
31
- const currentCellInner = findParentBlot(this, blotName.tableCellInner);
32
- const newCellInner = this.scroll.create(blotName.tableCellInner, value) as TableCellInnerFormat;
33
- currentCellInner.insertBefore(newCellInner, this);
34
- newCellInner.appendChild(this);
35
- if (currentCellInner.length() === 0) {
36
- currentCellInner.remove();
37
- }
38
- }
39
- catch {}
40
- }
41
- else {
42
- this.format(name, value);
43
- }
44
- }
45
- }
46
-
47
- // copy from `quill/blots/block`
48
- function bubbleFormats(
49
- blot: TypeParchment.Blot | null,
50
- formats: Record<string, unknown> = {},
51
- filter = true,
52
- ): Record<string, unknown> {
53
- if (blot == null) return formats;
54
- if ('formats' in blot && typeof blot.formats === 'function') {
55
- formats = {
56
- ...formats,
57
- ...blot.formats(),
58
- };
59
- if (filter) {
60
- // exclude syntax highlighting from deltas and getFormat()
61
- delete formats['code-token'];
62
- }
63
- }
64
- if (
65
- blot.parent == null
66
- || blot.parent.statics.blotName === 'scroll'
67
- || blot.parent.statics.scope !== blot.statics.scope
68
- ) {
69
- return formats;
70
- }
71
- return bubbleFormats(blot.parent, formats, filter);
72
- }
1
+ import type { Parchment as TypeParchment } from 'quill';
2
+ import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block';
3
+ import type { TableCellInnerFormat } from '../table-cell-inner-format';
4
+ import Quill from 'quill';
5
+ import { blotName, findParentBlot } from '../../utils';
6
+
7
+ const BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed;
8
+
9
+ export class BlockEmbedOverride extends BlockEmbed {
10
+ delta() {
11
+ // if BlockEmbed is the last line of the tableCellInner. need to add value in delta
12
+ const delta = super.delta();
13
+ const formats = bubbleFormats(this);
14
+ if (formats[blotName.tableCellInner]) {
15
+ delta.insert('\n', { [blotName.tableCellInner]: formats[blotName.tableCellInner] });
16
+ }
17
+ return delta;
18
+ }
19
+
20
+ length() {
21
+ const formats = bubbleFormats(this);
22
+ if (formats[blotName.tableCellInner]) {
23
+ return super.length() + 1;
24
+ }
25
+ return super.length();
26
+ }
27
+
28
+ formatAt(index: number, length: number, name: string, value: unknown) {
29
+ if (name === blotName.tableCellInner) {
30
+ try {
31
+ const currentCellInner = findParentBlot(this, blotName.tableCellInner);
32
+ const newCellInner = this.scroll.create(blotName.tableCellInner, value) as TableCellInnerFormat;
33
+ currentCellInner.insertBefore(newCellInner, this);
34
+ newCellInner.appendChild(this);
35
+ if (currentCellInner.length() === 0) {
36
+ currentCellInner.remove();
37
+ }
38
+ }
39
+ catch {}
40
+ }
41
+ else {
42
+ this.format(name, value);
43
+ }
44
+ }
45
+ }
46
+
47
+ // copy from `quill/blots/block`
48
+ function bubbleFormats(
49
+ blot: TypeParchment.Blot | null,
50
+ formats: Record<string, unknown> = {},
51
+ filter = true,
52
+ ): Record<string, unknown> {
53
+ if (blot == null) return formats;
54
+ if ('formats' in blot && typeof blot.formats === 'function') {
55
+ formats = {
56
+ ...formats,
57
+ ...blot.formats(),
58
+ };
59
+ if (filter) {
60
+ // exclude syntax highlighting from deltas and getFormat()
61
+ delete formats['code-token'];
62
+ }
63
+ }
64
+ if (
65
+ blot.parent == null
66
+ || blot.parent.statics.blotName === 'scroll'
67
+ || blot.parent.statics.scope !== blot.statics.scope
68
+ ) {
69
+ return formats;
70
+ }
71
+ return bubbleFormats(blot.parent, formats, filter);
72
+ }
@@ -1,95 +1,95 @@
1
- import type { Parchment as TypeParchment } from 'quill';
2
- import type TypeBlock from 'quill/blots/block';
3
- import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block';
4
- import type TypeContainer from 'quill/blots/container';
5
- import type { TableCellInnerFormat } from '../table-cell-inner-format';
6
- import Quill from 'quill';
7
- import { blotName, findParentBlot, isString } from '../../utils';
8
- import { isSameCellValue } from '../utils';
9
-
10
- const Parchment = Quill.import('parchment');
11
- const Block = Quill.import('blots/block') as typeof TypeBlock;
12
- const BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed;
13
- const Container = Quill.import('blots/container') as typeof TypeContainer;
14
-
15
- export class BlockOverride extends Block {
16
- replaceWith(name: string | TypeParchment.Blot, value?: any): TypeParchment.Blot {
17
- const replacement = isString(name) ? this.scroll.create(name, value) : name;
18
- if (replacement instanceof Parchment.ParentBlot) {
19
- // replace block to TableCellInner length is 0 when setContents
20
- // that will set text direct in TableCellInner but not in block
21
- // so we need to set text in block and block in TableCellInner
22
- // wrap with TableCellInner.formatAt when length is 0 will create a new block
23
- // that can make sure TableCellInner struct correctly
24
- if (replacement.statics.blotName === blotName.tableCellInner) {
25
- // skip if current block already in same TableCellInner
26
- let currentTableCellInner: TableCellInnerFormat | null = null;
27
- try {
28
- currentTableCellInner = findParentBlot(this, blotName.tableCellInner);
29
- const cellValue = currentTableCellInner.formats();
30
- const replacementValue = (replacement as TableCellInnerFormat).formats();
31
- if (isSameCellValue(cellValue, replacementValue)) {
32
- return currentTableCellInner;
33
- }
34
- }
35
- catch {}
36
-
37
- if (currentTableCellInner) {
38
- // use TableCellInner insertBefore to find the correct position
39
- currentTableCellInner.insertBefore(replacement, this);
40
- replacement.appendChild(this);
41
- if (currentTableCellInner.children.length === 0) {
42
- currentTableCellInner.remove();
43
- }
44
- }
45
- else {
46
- // find the first parent not container
47
- let currentParent = this as TypeParchment.Parent;
48
- let lastParent = currentParent;
49
- while (currentParent.parent !== this.scroll && currentParent.parent instanceof Container) {
50
- lastParent = currentParent;
51
- currentParent = currentParent.parent;
52
- }
53
- // if parent all container until scroll. use the last container
54
- if (currentParent === this.scroll) {
55
- currentParent = lastParent;
56
- }
57
- // split current block as a separate "line" and wrap tableCellInner
58
- const index = this.offset(currentParent);
59
- const length = this.length();
60
- const selfParent = currentParent.isolate(index, length);
61
- if (selfParent && selfParent.parent) {
62
- selfParent.parent.insertBefore(replacement, selfParent.next);
63
- }
64
- replacement.appendChild(this);
65
- }
66
- return replacement;
67
- }
68
- else {
69
- this.moveChildren(replacement);
70
- }
71
- }
72
- if (this.parent !== null) {
73
- this.parent.insertBefore(replacement, this.next);
74
- this.remove();
75
- }
76
- this.attributes.copy(replacement as TypeParchment.BlockBlot);
77
- return replacement;
78
- }
79
-
80
- format(name: string, value: any): void {
81
- if (name === blotName.tableCellInner && this.parent.statics.blotName === name && !value) {
82
- if (this.prev && this.prev instanceof BlockEmbed) return;
83
- try {
84
- const cellInner = findParentBlot(this, blotName.tableCellInner);
85
- cellInner.unwrap();
86
- }
87
- catch {
88
- console.error('unwrap TableCellInner error');
89
- }
90
- }
91
- else {
92
- super.format(name, value);
93
- }
94
- }
95
- }
1
+ import type { Parchment as TypeParchment } from 'quill';
2
+ import type TypeBlock from 'quill/blots/block';
3
+ import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block';
4
+ import type TypeContainer from 'quill/blots/container';
5
+ import type { TableCellInnerFormat } from '../table-cell-inner-format';
6
+ import Quill from 'quill';
7
+ import { blotName, findParentBlot, isString } from '../../utils';
8
+ import { isSameCellValue } from '../utils';
9
+
10
+ const Parchment = Quill.import('parchment');
11
+ const Block = Quill.import('blots/block') as typeof TypeBlock;
12
+ const BlockEmbed = Quill.import('blots/block/embed') as typeof TypeBlockEmbed;
13
+ const Container = Quill.import('blots/container') as typeof TypeContainer;
14
+
15
+ export class BlockOverride extends Block {
16
+ replaceWith(name: string | TypeParchment.Blot, value?: any): TypeParchment.Blot {
17
+ const replacement = isString(name) ? this.scroll.create(name, value) : name;
18
+ if (replacement instanceof Parchment.ParentBlot) {
19
+ // replace block to TableCellInner length is 0 when setContents
20
+ // that will set text direct in TableCellInner but not in block
21
+ // so we need to set text in block and block in TableCellInner
22
+ // wrap with TableCellInner.formatAt when length is 0 will create a new block
23
+ // that can make sure TableCellInner struct correctly
24
+ if (replacement.statics.blotName === blotName.tableCellInner) {
25
+ // skip if current block already in same TableCellInner
26
+ let currentTableCellInner: TableCellInnerFormat | null = null;
27
+ try {
28
+ currentTableCellInner = findParentBlot(this, blotName.tableCellInner);
29
+ const cellValue = currentTableCellInner.formats();
30
+ const replacementValue = (replacement as TableCellInnerFormat).formats();
31
+ if (isSameCellValue(cellValue, replacementValue)) {
32
+ return currentTableCellInner;
33
+ }
34
+ }
35
+ catch {}
36
+
37
+ if (currentTableCellInner) {
38
+ // use TableCellInner insertBefore to find the correct position
39
+ currentTableCellInner.insertBefore(replacement, this);
40
+ replacement.appendChild(this);
41
+ if (currentTableCellInner.children.length === 0) {
42
+ currentTableCellInner.remove();
43
+ }
44
+ }
45
+ else {
46
+ // find the first parent not container
47
+ let currentParent = this as TypeParchment.Parent;
48
+ let lastParent = currentParent;
49
+ while (currentParent.parent !== this.scroll && currentParent.parent instanceof Container) {
50
+ lastParent = currentParent;
51
+ currentParent = currentParent.parent;
52
+ }
53
+ // if parent all container until scroll. use the last container
54
+ if (currentParent === this.scroll) {
55
+ currentParent = lastParent;
56
+ }
57
+ // split current block as a separate "line" and wrap tableCellInner
58
+ const index = this.offset(currentParent);
59
+ const length = this.length();
60
+ const selfParent = currentParent.isolate(index, length);
61
+ if (selfParent?.parent) {
62
+ selfParent.parent.insertBefore(replacement, selfParent.next);
63
+ }
64
+ replacement.appendChild(this);
65
+ }
66
+ return replacement;
67
+ }
68
+ else {
69
+ this.moveChildren(replacement);
70
+ }
71
+ }
72
+ if (this.parent !== null) {
73
+ this.parent.insertBefore(replacement, this.next);
74
+ this.remove();
75
+ }
76
+ this.attributes.copy(replacement as TypeParchment.BlockBlot);
77
+ return replacement;
78
+ }
79
+
80
+ format(name: string, value: any): void {
81
+ if (name === blotName.tableCellInner && this.parent.statics.blotName === name && !value) {
82
+ if (this.prev && this.prev instanceof BlockEmbed) return;
83
+ try {
84
+ const cellInner = findParentBlot(this, blotName.tableCellInner);
85
+ cellInner.unwrap();
86
+ }
87
+ catch {
88
+ console.error('unwrap TableCellInner error');
89
+ }
90
+ }
91
+ else {
92
+ super.format(name, value);
93
+ }
94
+ }
95
+ }
@@ -1,3 +1,3 @@
1
- export * from './block';
2
- export * from './block-embed';
3
- export * from './scroll';
1
+ export * from './block';
2
+ export * from './block-embed';
3
+ export * from './scroll';