roosterjs-content-model-plugins 0.26.3 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +2 -2
  2. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  3. package/lib/autoFormat/keyboardListTrigger.d.ts +2 -2
  4. package/lib/autoFormat/keyboardListTrigger.js.map +1 -1
  5. package/lib/edit/EditPlugin.d.ts +3 -3
  6. package/lib/edit/EditPlugin.js +1 -1
  7. package/lib/edit/EditPlugin.js.map +1 -1
  8. package/lib/edit/deleteSteps/deleteCollapsedSelection.js +20 -1
  9. package/lib/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  10. package/lib/edit/handleKeyboardEventCommon.d.ts +2 -2
  11. package/lib/edit/handleKeyboardEventCommon.js.map +1 -1
  12. package/lib/edit/inputSteps/handleEnterOnList.js +40 -10
  13. package/lib/edit/inputSteps/handleEnterOnList.js.map +1 -1
  14. package/lib/edit/keyboardDelete.d.ts +3 -3
  15. package/lib/edit/keyboardDelete.js +1 -1
  16. package/lib/edit/keyboardDelete.js.map +1 -1
  17. package/lib/edit/keyboardInput.d.ts +2 -2
  18. package/lib/edit/keyboardInput.js.map +1 -1
  19. package/lib/edit/keyboardTab.d.ts +2 -2
  20. package/lib/edit/keyboardTab.js +19 -11
  21. package/lib/edit/keyboardTab.js.map +1 -1
  22. package/lib/edit/tabUtils/handleTabOnList.d.ts +7 -0
  23. package/lib/edit/tabUtils/handleTabOnList.js +34 -0
  24. package/lib/edit/tabUtils/handleTabOnList.js.map +1 -0
  25. package/lib/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  26. package/lib/edit/tabUtils/handleTabOnParagraph.js +81 -0
  27. package/lib/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  28. package/lib/index.d.ts +4 -0
  29. package/lib/index.js +18 -1
  30. package/lib/index.js.map +1 -1
  31. package/lib/paste/PastePlugin.d.ts +2 -3
  32. package/lib/paste/PastePlugin.js +0 -1
  33. package/lib/paste/PastePlugin.js.map +1 -1
  34. package/lib/shortcut/ShortcutCommand.d.ts +44 -0
  35. package/lib/shortcut/ShortcutCommand.js +3 -0
  36. package/lib/shortcut/ShortcutCommand.js.map +1 -0
  37. package/lib/shortcut/ShortcutPlugin.d.ts +51 -0
  38. package/lib/shortcut/ShortcutPlugin.js +118 -0
  39. package/lib/shortcut/ShortcutPlugin.js.map +1 -0
  40. package/lib/shortcut/shortcuts.d.ts +73 -0
  41. package/lib/shortcut/shortcuts.js +178 -0
  42. package/lib/shortcut/shortcuts.js.map +1 -0
  43. package/lib/tableEdit/TableEditPlugin.d.ts +47 -0
  44. package/lib/tableEdit/TableEditPlugin.js +156 -0
  45. package/lib/tableEdit/TableEditPlugin.js.map +1 -0
  46. package/lib/tableEdit/editors/TableEditor.d.ts +73 -0
  47. package/lib/tableEdit/editors/TableEditor.js +294 -0
  48. package/lib/tableEdit/editors/TableEditor.js.map +1 -0
  49. package/lib/tableEdit/editors/features/CellResizer.d.ts +6 -0
  50. package/lib/tableEdit/editors/features/CellResizer.js +169 -0
  51. package/lib/tableEdit/editors/features/CellResizer.js.map +1 -0
  52. package/lib/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  53. package/lib/tableEdit/editors/features/TableEditorFeature.js +17 -0
  54. package/lib/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  55. package/lib/tableEdit/editors/features/TableInserter.d.ts +6 -0
  56. package/lib/tableEdit/editors/features/TableInserter.js +113 -0
  57. package/lib/tableEdit/editors/features/TableInserter.js.map +1 -0
  58. package/lib/tableEdit/editors/features/TableMover.d.ts +8 -0
  59. package/lib/tableEdit/editors/features/TableMover.js +83 -0
  60. package/lib/tableEdit/editors/features/TableMover.js.map +1 -0
  61. package/lib/tableEdit/editors/features/TableResizer.d.ts +6 -0
  62. package/lib/tableEdit/editors/features/TableResizer.js +163 -0
  63. package/lib/tableEdit/editors/features/TableResizer.js.map +1 -0
  64. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +2 -2
  65. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  66. package/lib-amd/autoFormat/keyboardListTrigger.d.ts +2 -2
  67. package/lib-amd/autoFormat/keyboardListTrigger.js.map +1 -1
  68. package/lib-amd/edit/EditPlugin.d.ts +3 -3
  69. package/lib-amd/edit/EditPlugin.js +1 -1
  70. package/lib-amd/edit/EditPlugin.js.map +1 -1
  71. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js +19 -1
  72. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  73. package/lib-amd/edit/handleKeyboardEventCommon.d.ts +2 -2
  74. package/lib-amd/edit/handleKeyboardEventCommon.js.map +1 -1
  75. package/lib-amd/edit/inputSteps/handleEnterOnList.js +40 -10
  76. package/lib-amd/edit/inputSteps/handleEnterOnList.js.map +1 -1
  77. package/lib-amd/edit/keyboardDelete.d.ts +3 -3
  78. package/lib-amd/edit/keyboardDelete.js +1 -1
  79. package/lib-amd/edit/keyboardDelete.js.map +1 -1
  80. package/lib-amd/edit/keyboardInput.d.ts +2 -2
  81. package/lib-amd/edit/keyboardInput.js.map +1 -1
  82. package/lib-amd/edit/keyboardTab.d.ts +2 -2
  83. package/lib-amd/edit/keyboardTab.js +18 -12
  84. package/lib-amd/edit/keyboardTab.js.map +1 -1
  85. package/lib-amd/edit/tabUtils/handleTabOnList.d.ts +7 -0
  86. package/lib-amd/edit/tabUtils/handleTabOnList.js +34 -0
  87. package/lib-amd/edit/tabUtils/handleTabOnList.js.map +1 -0
  88. package/lib-amd/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  89. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js +81 -0
  90. package/lib-amd/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  91. package/lib-amd/index.d.ts +4 -0
  92. package/lib-amd/index.js +16 -2
  93. package/lib-amd/index.js.map +1 -1
  94. package/lib-amd/paste/PastePlugin.d.ts +2 -3
  95. package/lib-amd/paste/PastePlugin.js +0 -1
  96. package/lib-amd/paste/PastePlugin.js.map +1 -1
  97. package/lib-amd/shortcut/ShortcutCommand.d.ts +44 -0
  98. package/lib-amd/shortcut/ShortcutCommand.js +5 -0
  99. package/lib-amd/shortcut/ShortcutCommand.js.map +1 -0
  100. package/lib-amd/shortcut/ShortcutPlugin.d.ts +51 -0
  101. package/lib-amd/shortcut/ShortcutPlugin.js +118 -0
  102. package/lib-amd/shortcut/ShortcutPlugin.js.map +1 -0
  103. package/lib-amd/shortcut/shortcuts.d.ts +73 -0
  104. package/lib-amd/shortcut/shortcuts.js +178 -0
  105. package/lib-amd/shortcut/shortcuts.js.map +1 -0
  106. package/lib-amd/tableEdit/TableEditPlugin.d.ts +47 -0
  107. package/lib-amd/tableEdit/TableEditPlugin.js +155 -0
  108. package/lib-amd/tableEdit/TableEditPlugin.js.map +1 -0
  109. package/lib-amd/tableEdit/editors/TableEditor.d.ts +73 -0
  110. package/lib-amd/tableEdit/editors/TableEditor.js +289 -0
  111. package/lib-amd/tableEdit/editors/TableEditor.js.map +1 -0
  112. package/lib-amd/tableEdit/editors/features/CellResizer.d.ts +6 -0
  113. package/lib-amd/tableEdit/editors/features/CellResizer.js +165 -0
  114. package/lib-amd/tableEdit/editors/features/CellResizer.js.map +1 -0
  115. package/lib-amd/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  116. package/lib-amd/tableEdit/editors/features/TableEditorFeature.js +19 -0
  117. package/lib-amd/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  118. package/lib-amd/tableEdit/editors/features/TableInserter.d.ts +6 -0
  119. package/lib-amd/tableEdit/editors/features/TableInserter.js +110 -0
  120. package/lib-amd/tableEdit/editors/features/TableInserter.js.map +1 -0
  121. package/lib-amd/tableEdit/editors/features/TableMover.d.ts +8 -0
  122. package/lib-amd/tableEdit/editors/features/TableMover.js +80 -0
  123. package/lib-amd/tableEdit/editors/features/TableMover.js.map +1 -0
  124. package/lib-amd/tableEdit/editors/features/TableResizer.d.ts +6 -0
  125. package/lib-amd/tableEdit/editors/features/TableResizer.js +160 -0
  126. package/lib-amd/tableEdit/editors/features/TableResizer.js.map +1 -0
  127. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +2 -2
  128. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  129. package/lib-mjs/autoFormat/keyboardListTrigger.d.ts +2 -2
  130. package/lib-mjs/autoFormat/keyboardListTrigger.js.map +1 -1
  131. package/lib-mjs/edit/EditPlugin.d.ts +3 -3
  132. package/lib-mjs/edit/EditPlugin.js +1 -1
  133. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  134. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js +20 -1
  135. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  136. package/lib-mjs/edit/handleKeyboardEventCommon.d.ts +2 -2
  137. package/lib-mjs/edit/handleKeyboardEventCommon.js.map +1 -1
  138. package/lib-mjs/edit/inputSteps/handleEnterOnList.js +42 -12
  139. package/lib-mjs/edit/inputSteps/handleEnterOnList.js.map +1 -1
  140. package/lib-mjs/edit/keyboardDelete.d.ts +3 -3
  141. package/lib-mjs/edit/keyboardDelete.js +1 -1
  142. package/lib-mjs/edit/keyboardDelete.js.map +1 -1
  143. package/lib-mjs/edit/keyboardInput.d.ts +2 -2
  144. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  145. package/lib-mjs/edit/keyboardTab.d.ts +2 -2
  146. package/lib-mjs/edit/keyboardTab.js +19 -11
  147. package/lib-mjs/edit/keyboardTab.js.map +1 -1
  148. package/lib-mjs/edit/tabUtils/handleTabOnList.d.ts +7 -0
  149. package/lib-mjs/edit/tabUtils/handleTabOnList.js +30 -0
  150. package/lib-mjs/edit/tabUtils/handleTabOnList.js.map +1 -0
  151. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.d.ts +17 -0
  152. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js +77 -0
  153. package/lib-mjs/edit/tabUtils/handleTabOnParagraph.js.map +1 -0
  154. package/lib-mjs/index.d.ts +4 -0
  155. package/lib-mjs/index.js +3 -0
  156. package/lib-mjs/index.js.map +1 -1
  157. package/lib-mjs/paste/PastePlugin.d.ts +2 -3
  158. package/lib-mjs/paste/PastePlugin.js +0 -1
  159. package/lib-mjs/paste/PastePlugin.js.map +1 -1
  160. package/lib-mjs/shortcut/ShortcutCommand.d.ts +44 -0
  161. package/lib-mjs/shortcut/ShortcutCommand.js +2 -0
  162. package/lib-mjs/shortcut/ShortcutCommand.js.map +1 -0
  163. package/lib-mjs/shortcut/ShortcutPlugin.d.ts +51 -0
  164. package/lib-mjs/shortcut/ShortcutPlugin.js +115 -0
  165. package/lib-mjs/shortcut/ShortcutPlugin.js.map +1 -0
  166. package/lib-mjs/shortcut/shortcuts.d.ts +73 -0
  167. package/lib-mjs/shortcut/shortcuts.js +175 -0
  168. package/lib-mjs/shortcut/shortcuts.js.map +1 -0
  169. package/lib-mjs/tableEdit/TableEditPlugin.d.ts +47 -0
  170. package/lib-mjs/tableEdit/TableEditPlugin.js +153 -0
  171. package/lib-mjs/tableEdit/TableEditPlugin.js.map +1 -0
  172. package/lib-mjs/tableEdit/editors/TableEditor.d.ts +73 -0
  173. package/lib-mjs/tableEdit/editors/TableEditor.js +292 -0
  174. package/lib-mjs/tableEdit/editors/TableEditor.js.map +1 -0
  175. package/lib-mjs/tableEdit/editors/features/CellResizer.d.ts +6 -0
  176. package/lib-mjs/tableEdit/editors/features/CellResizer.js +166 -0
  177. package/lib-mjs/tableEdit/editors/features/CellResizer.js.map +1 -0
  178. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.d.ts +13 -0
  179. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.js +13 -0
  180. package/lib-mjs/tableEdit/editors/features/TableEditorFeature.js.map +1 -0
  181. package/lib-mjs/tableEdit/editors/features/TableInserter.d.ts +6 -0
  182. package/lib-mjs/tableEdit/editors/features/TableInserter.js +110 -0
  183. package/lib-mjs/tableEdit/editors/features/TableInserter.js.map +1 -0
  184. package/lib-mjs/tableEdit/editors/features/TableMover.d.ts +8 -0
  185. package/lib-mjs/tableEdit/editors/features/TableMover.js +80 -0
  186. package/lib-mjs/tableEdit/editors/features/TableMover.js.map +1 -0
  187. package/lib-mjs/tableEdit/editors/features/TableResizer.d.ts +6 -0
  188. package/lib-mjs/tableEdit/editors/features/TableResizer.js +160 -0
  189. package/lib-mjs/tableEdit/editors/features/TableResizer.js.map +1 -0
  190. package/package.json +5 -5
@@ -0,0 +1,73 @@
1
+ import type { IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ *
5
+ * A table has 6 hot areas to be resized/edited (take LTR example):
6
+ *
7
+ * [6] [ ]
8
+ * +[ 1 ]+--------------------+
9
+ * |[ ]| |
10
+ * [ ] [ ] |
11
+ * [ ] [ ] |
12
+ * [2] [3] |
13
+ * [ ] [ ] |
14
+ * [ ][ 4 ]| |
15
+ * +------------------+--------------------+
16
+ * | | |
17
+ * | | |
18
+ * | | |
19
+ * +------------------+--------------------+
20
+ * [5]
21
+ *
22
+ * 1 - Hover area to show insert column button
23
+ * 2 - Hover area to show insert row button
24
+ * 3 - Hover area to show vertical resizing bar
25
+ * 4 - Hover area to show horizontal resizing bar
26
+ * 5 - Hover area to show whole table resize handle
27
+ * 6 - Hover area to show whole table mover handle
28
+ *
29
+ * When set a different current table or change current TD, we need to update these areas
30
+ */
31
+ export default class TableEditor {
32
+ private editor;
33
+ readonly table: HTMLTableElement;
34
+ private onChanged;
35
+ private anchorContainer?;
36
+ private contentDiv?;
37
+ private horizontalInserter;
38
+ private verticalInserter;
39
+ private horizontalResizer;
40
+ private verticalResizer;
41
+ private tableResizer;
42
+ private tableMover;
43
+ private isRTL;
44
+ private range;
45
+ private isCurrentlyEditing;
46
+ constructor(editor: IEditor, table: HTMLTableElement, onChanged: () => void, anchorContainer?: HTMLElement | undefined, contentDiv?: EventTarget | null | undefined);
47
+ dispose(): void;
48
+ isEditing(): boolean;
49
+ isOwnedElement(node: Node): boolean;
50
+ onMouseMove(x: number, y: number): void;
51
+ private setEditorFeatures;
52
+ private setResizingTd;
53
+ /**
54
+ * create or remove TableInserter
55
+ * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)
56
+ */
57
+ private setInserterTd;
58
+ private disposeTableResizer;
59
+ private disposeTableInserter;
60
+ private disposeCellResizers;
61
+ private disposeTableMover;
62
+ private onFinishEditing;
63
+ private onStartTableResize;
64
+ private onStartCellResize;
65
+ private onStartResize;
66
+ private onInserted;
67
+ /**
68
+ * Public only for testing purposes
69
+ * @param table the table to select
70
+ */
71
+ onSelect: (table: HTMLTableElement) => void;
72
+ private getOnMouseOut;
73
+ }
@@ -0,0 +1,292 @@
1
+ import createCellResizer from './features/CellResizer';
2
+ import createTableInserter from './features/TableInserter';
3
+ import createTableMover from './features/TableMover';
4
+ import createTableResizer from './features/TableResizer';
5
+ import normalizeRect from '../../pluginUtils/Rect/normalizeRect';
6
+ import { disposeTableEditFeature } from './features/TableEditorFeature';
7
+ import { isNodeOfType } from 'roosterjs-content-model-dom';
8
+ var INSERTER_HOVER_OFFSET = 6;
9
+ var TOP_OR_SIDE;
10
+ (function (TOP_OR_SIDE) {
11
+ TOP_OR_SIDE[TOP_OR_SIDE["top"] = 0] = "top";
12
+ TOP_OR_SIDE[TOP_OR_SIDE["side"] = 1] = "side";
13
+ })(TOP_OR_SIDE || (TOP_OR_SIDE = {}));
14
+ /**
15
+ * @internal
16
+ *
17
+ * A table has 6 hot areas to be resized/edited (take LTR example):
18
+ *
19
+ * [6] [ ]
20
+ * +[ 1 ]+--------------------+
21
+ * |[ ]| |
22
+ * [ ] [ ] |
23
+ * [ ] [ ] |
24
+ * [2] [3] |
25
+ * [ ] [ ] |
26
+ * [ ][ 4 ]| |
27
+ * +------------------+--------------------+
28
+ * | | |
29
+ * | | |
30
+ * | | |
31
+ * +------------------+--------------------+
32
+ * [5]
33
+ *
34
+ * 1 - Hover area to show insert column button
35
+ * 2 - Hover area to show insert row button
36
+ * 3 - Hover area to show vertical resizing bar
37
+ * 4 - Hover area to show horizontal resizing bar
38
+ * 5 - Hover area to show whole table resize handle
39
+ * 6 - Hover area to show whole table mover handle
40
+ *
41
+ * When set a different current table or change current TD, we need to update these areas
42
+ */
43
+ var TableEditor = /** @class */ (function () {
44
+ function TableEditor(editor, table, onChanged, anchorContainer, contentDiv) {
45
+ var _this = this;
46
+ var _a;
47
+ this.editor = editor;
48
+ this.table = table;
49
+ this.onChanged = onChanged;
50
+ this.anchorContainer = anchorContainer;
51
+ this.contentDiv = contentDiv;
52
+ // 1, 2 - Insert a column or a row
53
+ this.horizontalInserter = null;
54
+ this.verticalInserter = null;
55
+ // 3, 4 - Resize a column or a row from a cell
56
+ this.horizontalResizer = null;
57
+ this.verticalResizer = null;
58
+ // 5 - Resize whole table
59
+ this.tableResizer = null;
60
+ // 6 - Move as well as select whole table
61
+ this.tableMover = null;
62
+ this.range = null;
63
+ this.onFinishEditing = function () {
64
+ _this.editor.focus();
65
+ if (_this.range) {
66
+ _this.editor.setDOMSelection({ type: 'range', range: _this.range, isReverted: false });
67
+ }
68
+ _this.editor.takeSnapshot(); // Pass in an empty callback to make sure ContentChangedEvent is triggered
69
+ _this.onChanged();
70
+ _this.isCurrentlyEditing = false;
71
+ return false;
72
+ };
73
+ this.onStartTableResize = function () {
74
+ _this.isCurrentlyEditing = true;
75
+ _this.onStartResize();
76
+ };
77
+ this.onStartCellResize = function () {
78
+ _this.isCurrentlyEditing = true;
79
+ _this.disposeTableResizer();
80
+ _this.onStartResize();
81
+ };
82
+ this.onInserted = function () {
83
+ _this.disposeTableResizer();
84
+ _this.onFinishEditing();
85
+ };
86
+ /**
87
+ * Public only for testing purposes
88
+ * @param table the table to select
89
+ */
90
+ this.onSelect = function (table) {
91
+ _this.editor.focus();
92
+ if (table) {
93
+ var selection = {
94
+ table: table,
95
+ firstRow: 0,
96
+ firstColumn: 0,
97
+ lastRow: table.rows.length - 1,
98
+ lastColumn: table.rows[table.rows.length - 1].cells.length - 1,
99
+ type: 'table',
100
+ };
101
+ _this.editor.setDOMSelection(selection);
102
+ }
103
+ };
104
+ this.getOnMouseOut = function (feature) {
105
+ return function (ev) {
106
+ if (feature &&
107
+ ev.relatedTarget != feature &&
108
+ isNodeOfType(_this.contentDiv, 'ELEMENT_NODE') &&
109
+ isNodeOfType(ev.relatedTarget, 'ELEMENT_NODE') &&
110
+ !(_this.contentDiv == ev.relatedTarget)) {
111
+ _this.dispose();
112
+ }
113
+ };
114
+ };
115
+ this.isRTL = ((_a = editor.getDocument().defaultView) === null || _a === void 0 ? void 0 : _a.getComputedStyle(table).direction) == 'rtl';
116
+ this.setEditorFeatures();
117
+ this.isCurrentlyEditing = false;
118
+ }
119
+ TableEditor.prototype.dispose = function () {
120
+ this.disposeTableResizer();
121
+ this.disposeCellResizers();
122
+ this.disposeTableInserter();
123
+ this.disposeTableMover();
124
+ };
125
+ TableEditor.prototype.isEditing = function () {
126
+ return this.isCurrentlyEditing;
127
+ };
128
+ TableEditor.prototype.isOwnedElement = function (node) {
129
+ return [
130
+ this.tableResizer,
131
+ this.tableMover,
132
+ this.horizontalInserter,
133
+ this.verticalInserter,
134
+ this.horizontalResizer,
135
+ this.verticalResizer,
136
+ ]
137
+ .filter(function (feature) { return !!(feature === null || feature === void 0 ? void 0 : feature.div); })
138
+ .some(function (feature) { return (feature === null || feature === void 0 ? void 0 : feature.div) == node; });
139
+ };
140
+ TableEditor.prototype.onMouseMove = function (x, y) {
141
+ var _a;
142
+ // Get whole table rect
143
+ var tableRect = normalizeRect(this.table.getBoundingClientRect());
144
+ //console.log('>>>tableRect', tableRect);
145
+ if (!tableRect) {
146
+ return;
147
+ }
148
+ // Determine if cursor is on top or side
149
+ var topOrSide = y <= tableRect.top + INSERTER_HOVER_OFFSET
150
+ ? 0 /* top */
151
+ : this.isRTL
152
+ ? x >= tableRect.right - INSERTER_HOVER_OFFSET
153
+ ? 1 /* side */
154
+ : undefined
155
+ : x <= tableRect.left + INSERTER_HOVER_OFFSET
156
+ ? 1 /* side */
157
+ : undefined;
158
+ var topOrSideBinary = topOrSide ? 1 : 0;
159
+ // i is row index, j is column index
160
+ for (var i = 0; i < this.table.rows.length; i++) {
161
+ var tr = this.table.rows[i];
162
+ var j = 0;
163
+ for (; j < tr.cells.length; j++) {
164
+ var td = tr.cells[j];
165
+ var tdRect = normalizeRect(td.getBoundingClientRect());
166
+ if (!tdRect || !tableRect) {
167
+ continue;
168
+ }
169
+ // Determine the cell the cursor is in range of
170
+ // Offset is only used for first row and column
171
+ var lessThanBottom = y <= tdRect.bottom;
172
+ var lessThanRight = this.isRTL
173
+ ? x <= tdRect.right + INSERTER_HOVER_OFFSET * topOrSideBinary
174
+ : x <= tdRect.right;
175
+ var moreThanLeft = this.isRTL
176
+ ? x >= tdRect.left
177
+ : x >= tdRect.left - INSERTER_HOVER_OFFSET * topOrSideBinary;
178
+ if (lessThanBottom && lessThanRight && moreThanLeft) {
179
+ if (i === 0 && topOrSide == 0 /* top */) {
180
+ var center = (tdRect.left + tdRect.right) / 2;
181
+ var isOnRightHalf = this.isRTL ? x < center : x > center;
182
+ this.setInserterTd(isOnRightHalf ? td : tr.cells[j - 1], false /*isHorizontal*/);
183
+ }
184
+ else if (j === 0 && topOrSide == 1 /* side */) {
185
+ var tdAbove = (_a = this.table.rows[i - 1]) === null || _a === void 0 ? void 0 : _a.cells[0];
186
+ var tdAboveRect = tdAbove
187
+ ? normalizeRect(tdAbove.getBoundingClientRect())
188
+ : null;
189
+ var isTdNotAboveMerged = !tdAboveRect
190
+ ? null
191
+ : this.isRTL
192
+ ? tdAboveRect.right === tdRect.right
193
+ : tdAboveRect.left === tdRect.left;
194
+ this.setInserterTd(y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged
195
+ ? tdAbove
196
+ : td, true /*isHorizontal*/);
197
+ }
198
+ else {
199
+ this.setInserterTd(null);
200
+ }
201
+ this.setResizingTd(td);
202
+ //Cell found
203
+ break;
204
+ }
205
+ }
206
+ if (j < tr.cells.length) {
207
+ break;
208
+ }
209
+ }
210
+ // Create Mover and Resizer
211
+ this.setEditorFeatures();
212
+ };
213
+ TableEditor.prototype.setEditorFeatures = function () {
214
+ if (!this.tableMover) {
215
+ this.tableMover = createTableMover(this.table, this.editor, this.isRTL, this.onSelect, this.getOnMouseOut, this.contentDiv, this.anchorContainer);
216
+ }
217
+ if (!this.tableResizer) {
218
+ this.tableResizer = createTableResizer(this.table, this.editor, this.isRTL, this.onStartTableResize, this.onFinishEditing, this.contentDiv, this.anchorContainer);
219
+ }
220
+ };
221
+ TableEditor.prototype.setResizingTd = function (td) {
222
+ if (this.horizontalResizer && this.horizontalResizer.node != td) {
223
+ this.disposeCellResizers();
224
+ }
225
+ if (!this.horizontalResizer && td) {
226
+ this.horizontalResizer = createCellResizer(this.editor, td, this.table, this.isRTL, true /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer);
227
+ this.verticalResizer = createCellResizer(this.editor, td, this.table, this.isRTL, false /*isHorizontal*/, this.onStartCellResize, this.onFinishEditing, this.anchorContainer);
228
+ }
229
+ };
230
+ /**
231
+ * create or remove TableInserter
232
+ * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)
233
+ */
234
+ TableEditor.prototype.setInserterTd = function (td, isHorizontal) {
235
+ var inserter = isHorizontal ? this.horizontalInserter : this.verticalInserter;
236
+ if (td === null || (inserter && inserter.node != td)) {
237
+ this.disposeTableInserter();
238
+ }
239
+ if (!this.horizontalInserter && !this.verticalInserter && td) {
240
+ var newInserter = createTableInserter(this.editor, td, this.table, this.isRTL, !!isHorizontal, this.onInserted, this.getOnMouseOut, this.anchorContainer);
241
+ if (isHorizontal) {
242
+ this.horizontalInserter = newInserter;
243
+ }
244
+ else {
245
+ this.verticalInserter = newInserter;
246
+ }
247
+ }
248
+ };
249
+ TableEditor.prototype.disposeTableResizer = function () {
250
+ if (this.tableResizer) {
251
+ disposeTableEditFeature(this.tableResizer);
252
+ this.tableResizer = null;
253
+ }
254
+ };
255
+ TableEditor.prototype.disposeTableInserter = function () {
256
+ if (this.horizontalInserter) {
257
+ disposeTableEditFeature(this.horizontalInserter);
258
+ this.horizontalInserter = null;
259
+ }
260
+ if (this.verticalInserter) {
261
+ disposeTableEditFeature(this.verticalInserter);
262
+ this.verticalInserter = null;
263
+ }
264
+ };
265
+ TableEditor.prototype.disposeCellResizers = function () {
266
+ if (this.horizontalResizer) {
267
+ disposeTableEditFeature(this.horizontalResizer);
268
+ this.horizontalResizer = null;
269
+ }
270
+ if (this.verticalResizer) {
271
+ disposeTableEditFeature(this.verticalResizer);
272
+ this.verticalResizer = null;
273
+ }
274
+ };
275
+ TableEditor.prototype.disposeTableMover = function () {
276
+ if (this.tableMover) {
277
+ disposeTableEditFeature(this.tableMover);
278
+ this.tableMover = null;
279
+ }
280
+ };
281
+ TableEditor.prototype.onStartResize = function () {
282
+ this.isCurrentlyEditing = true;
283
+ var range = this.editor.getDOMSelection();
284
+ if (range && range.type == 'range') {
285
+ this.range = range.range;
286
+ }
287
+ this.editor.takeSnapshot();
288
+ };
289
+ return TableEditor;
290
+ }());
291
+ export default TableEditor;
292
+ //# sourceMappingURL=TableEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableEditor.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/tableEdit/editors/TableEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import createCellResizer from './features/CellResizer';\nimport createTableInserter from './features/TableInserter';\nimport createTableMover from './features/TableMover';\nimport createTableResizer from './features/TableResizer';\nimport normalizeRect from '../../pluginUtils/Rect/normalizeRect';\nimport { disposeTableEditFeature } from './features/TableEditorFeature';\nimport { isNodeOfType } from 'roosterjs-content-model-dom';\nimport type TableEditFeature from './features/TableEditorFeature';\nimport type { IEditor, TableSelection } from 'roosterjs-content-model-types';\n\nconst INSERTER_HOVER_OFFSET = 6;\nconst enum TOP_OR_SIDE {\n top = 0,\n side = 1,\n}\n/**\n * @internal\n *\n * A table has 6 hot areas to be resized/edited (take LTR example):\n *\n * [6] [ ]\n * +[ 1 ]+--------------------+\n * |[ ]| |\n * [ ] [ ] |\n * [ ] [ ] |\n * [2] [3] |\n * [ ] [ ] |\n * [ ][ 4 ]| |\n * +------------------+--------------------+\n * | | |\n * | | |\n * | | |\n * +------------------+--------------------+\n * [5]\n *\n * 1 - Hover area to show insert column button\n * 2 - Hover area to show insert row button\n * 3 - Hover area to show vertical resizing bar\n * 4 - Hover area to show horizontal resizing bar\n * 5 - Hover area to show whole table resize handle\n * 6 - Hover area to show whole table mover handle\n *\n * When set a different current table or change current TD, we need to update these areas\n */\nexport default class TableEditor {\n // 1, 2 - Insert a column or a row\n private horizontalInserter: TableEditFeature | null = null;\n private verticalInserter: TableEditFeature | null = null;\n\n // 3, 4 - Resize a column or a row from a cell\n private horizontalResizer: TableEditFeature | null = null;\n private verticalResizer: TableEditFeature | null = null;\n\n // 5 - Resize whole table\n private tableResizer: TableEditFeature | null = null;\n\n // 6 - Move as well as select whole table\n private tableMover: TableEditFeature | null = null;\n\n private isRTL: boolean;\n private range: Range | null = null;\n private isCurrentlyEditing: boolean;\n\n constructor(\n private editor: IEditor,\n public readonly table: HTMLTableElement,\n private onChanged: () => void,\n private anchorContainer?: HTMLElement,\n private contentDiv?: EventTarget | null\n ) {\n this.isRTL = editor.getDocument().defaultView?.getComputedStyle(table).direction == 'rtl';\n this.setEditorFeatures();\n this.isCurrentlyEditing = false;\n }\n\n dispose() {\n this.disposeTableResizer();\n this.disposeCellResizers();\n this.disposeTableInserter();\n this.disposeTableMover();\n }\n\n isEditing(): boolean {\n return this.isCurrentlyEditing;\n }\n\n isOwnedElement(node: Node) {\n return [\n this.tableResizer,\n this.tableMover,\n this.horizontalInserter,\n this.verticalInserter,\n this.horizontalResizer,\n this.verticalResizer,\n ]\n .filter(feature => !!feature?.div)\n .some(feature => feature?.div == node);\n }\n\n onMouseMove(x: number, y: number) {\n // Get whole table rect\n const tableRect = normalizeRect(this.table.getBoundingClientRect());\n\n //console.log('>>>tableRect', tableRect);\n if (!tableRect) {\n return;\n }\n\n // Determine if cursor is on top or side\n const topOrSide =\n y <= tableRect.top + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.top\n : this.isRTL\n ? x >= tableRect.right - INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined\n : x <= tableRect.left + INSERTER_HOVER_OFFSET\n ? TOP_OR_SIDE.side\n : undefined;\n const topOrSideBinary = topOrSide ? 1 : 0;\n\n // i is row index, j is column index\n for (let i = 0; i < this.table.rows.length; i++) {\n const tr = this.table.rows[i];\n let j = 0;\n for (; j < tr.cells.length; j++) {\n const td = tr.cells[j];\n const tdRect = normalizeRect(td.getBoundingClientRect());\n\n if (!tdRect || !tableRect) {\n continue;\n }\n\n // Determine the cell the cursor is in range of\n // Offset is only used for first row and column\n const lessThanBottom = y <= tdRect.bottom;\n const lessThanRight = this.isRTL\n ? x <= tdRect.right + INSERTER_HOVER_OFFSET * topOrSideBinary\n : x <= tdRect.right;\n const moreThanLeft = this.isRTL\n ? x >= tdRect.left\n : x >= tdRect.left - INSERTER_HOVER_OFFSET * topOrSideBinary;\n\n if (lessThanBottom && lessThanRight && moreThanLeft) {\n if (i === 0 && topOrSide == TOP_OR_SIDE.top) {\n const center = (tdRect.left + tdRect.right) / 2;\n const isOnRightHalf = this.isRTL ? x < center : x > center;\n this.setInserterTd(\n isOnRightHalf ? td : tr.cells[j - 1],\n false /*isHorizontal*/\n );\n } else if (j === 0 && topOrSide == TOP_OR_SIDE.side) {\n const tdAbove = this.table.rows[i - 1]?.cells[0];\n const tdAboveRect = tdAbove\n ? normalizeRect(tdAbove.getBoundingClientRect())\n : null;\n\n const isTdNotAboveMerged = !tdAboveRect\n ? null\n : this.isRTL\n ? tdAboveRect.right === tdRect.right\n : tdAboveRect.left === tdRect.left;\n\n this.setInserterTd(\n y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged\n ? tdAbove\n : td,\n true /*isHorizontal*/\n );\n } else {\n this.setInserterTd(null);\n }\n\n this.setResizingTd(td);\n\n //Cell found\n break;\n }\n }\n\n if (j < tr.cells.length) {\n break;\n }\n }\n\n // Create Mover and Resizer\n this.setEditorFeatures();\n }\n\n private setEditorFeatures() {\n if (!this.tableMover) {\n this.tableMover = createTableMover(\n this.table,\n this.editor,\n this.isRTL,\n this.onSelect,\n this.getOnMouseOut,\n this.contentDiv,\n this.anchorContainer\n );\n }\n\n if (!this.tableResizer) {\n this.tableResizer = createTableResizer(\n this.table,\n this.editor,\n this.isRTL,\n this.onStartTableResize,\n this.onFinishEditing,\n this.contentDiv,\n this.anchorContainer\n );\n }\n }\n\n private setResizingTd(td: HTMLTableCellElement) {\n if (this.horizontalResizer && this.horizontalResizer.node != td) {\n this.disposeCellResizers();\n }\n\n if (!this.horizontalResizer && td) {\n this.horizontalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n true /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer\n );\n this.verticalResizer = createCellResizer(\n this.editor,\n td,\n this.table,\n this.isRTL,\n false /*isHorizontal*/,\n this.onStartCellResize,\n this.onFinishEditing,\n this.anchorContainer\n );\n }\n }\n\n /**\n * create or remove TableInserter\n * @param td td to attach to, set this to null to remove inserters (both horizontal and vertical)\n */\n private setInserterTd(td: HTMLTableCellElement | null, isHorizontal?: boolean) {\n const inserter = isHorizontal ? this.horizontalInserter : this.verticalInserter;\n if (td === null || (inserter && inserter.node != td)) {\n this.disposeTableInserter();\n }\n\n if (!this.horizontalInserter && !this.verticalInserter && td) {\n const newInserter = createTableInserter(\n this.editor,\n td,\n this.table,\n this.isRTL,\n !!isHorizontal,\n this.onInserted,\n this.getOnMouseOut,\n this.anchorContainer\n );\n if (isHorizontal) {\n this.horizontalInserter = newInserter;\n } else {\n this.verticalInserter = newInserter;\n }\n }\n }\n\n private disposeTableResizer() {\n if (this.tableResizer) {\n disposeTableEditFeature(this.tableResizer);\n this.tableResizer = null;\n }\n }\n\n private disposeTableInserter() {\n if (this.horizontalInserter) {\n disposeTableEditFeature(this.horizontalInserter);\n this.horizontalInserter = null;\n }\n if (this.verticalInserter) {\n disposeTableEditFeature(this.verticalInserter);\n this.verticalInserter = null;\n }\n }\n\n private disposeCellResizers() {\n if (this.horizontalResizer) {\n disposeTableEditFeature(this.horizontalResizer);\n this.horizontalResizer = null;\n }\n if (this.verticalResizer) {\n disposeTableEditFeature(this.verticalResizer);\n this.verticalResizer = null;\n }\n }\n\n private disposeTableMover() {\n if (this.tableMover) {\n disposeTableEditFeature(this.tableMover);\n this.tableMover = null;\n }\n }\n\n private onFinishEditing = (): false => {\n this.editor.focus();\n\n if (this.range) {\n this.editor.setDOMSelection({ type: 'range', range: this.range, isReverted: false });\n }\n\n this.editor.takeSnapshot(); // Pass in an empty callback to make sure ContentChangedEvent is triggered\n this.onChanged();\n this.isCurrentlyEditing = false;\n\n return false;\n };\n\n private onStartTableResize = () => {\n this.isCurrentlyEditing = true;\n this.onStartResize();\n };\n\n private onStartCellResize = () => {\n this.isCurrentlyEditing = true;\n this.disposeTableResizer();\n this.onStartResize();\n };\n\n private onStartResize() {\n this.isCurrentlyEditing = true;\n const range = this.editor.getDOMSelection();\n\n if (range && range.type == 'range') {\n this.range = range.range;\n }\n\n this.editor.takeSnapshot();\n }\n\n private onInserted = () => {\n this.disposeTableResizer();\n this.onFinishEditing();\n };\n\n /**\n * Public only for testing purposes\n * @param table the table to select\n */\n public onSelect = (table: HTMLTableElement) => {\n this.editor.focus();\n\n if (table) {\n const selection: TableSelection = {\n table: table,\n firstRow: 0,\n firstColumn: 0,\n lastRow: table.rows.length - 1,\n lastColumn: table.rows[table.rows.length - 1].cells.length - 1,\n type: 'table',\n };\n\n this.editor.setDOMSelection(selection);\n }\n };\n\n private getOnMouseOut = (feature: HTMLElement) => {\n return (ev: MouseEvent) => {\n if (\n feature &&\n ev.relatedTarget != feature &&\n isNodeOfType(this.contentDiv as Node, 'ELEMENT_NODE') &&\n isNodeOfType(ev.relatedTarget as Node, 'ELEMENT_NODE') &&\n !(this.contentDiv == ev.relatedTarget)\n ) {\n this.dispose();\n }\n };\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { IEditor } from 'roosterjs-content-model-types';
2
+ import type TableEditFeature from './TableEditorFeature';
3
+ /**
4
+ * @internal
5
+ */
6
+ export default function createCellResizer(editor: IEditor, td: HTMLTableCellElement, table: HTMLTableElement, isRTL: boolean, isHorizontal: boolean, onStart: () => void, onEnd: () => false, anchorContainer?: HTMLElement): TableEditFeature | null;
@@ -0,0 +1,166 @@
1
+ import { __read, __spreadArray } from "tslib";
2
+ import createElement from '../../../pluginUtils/CreateElement/createElement';
3
+ import DragAndDropHelper from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';
4
+ import normalizeRect from '../../../pluginUtils/Rect/normalizeRect';
5
+ import { isElementOfType } from 'roosterjs-content-model-dom';
6
+ import { getFirstSelectedTable, MIN_ALLOWED_TABLE_CELL_WIDTH, normalizeTable, } from 'roosterjs-content-model-core';
7
+ var CELL_RESIZER_WIDTH = 4;
8
+ /**
9
+ * @internal
10
+ */
11
+ export default function createCellResizer(editor, td, table, isRTL, isHorizontal, onStart, onEnd, anchorContainer) {
12
+ var document = td.ownerDocument;
13
+ var createElementData = {
14
+ tag: 'div',
15
+ style: "position: fixed; cursor: " + (isHorizontal ? 'row' : 'col') + "-resize; user-select: none",
16
+ };
17
+ var zoomScale = editor.getDOMHelper().calculateZoomScale();
18
+ var div = createElement(createElementData, document);
19
+ (anchorContainer || document.body).appendChild(div);
20
+ var context = { editor: editor, td: td, table: table, isRTL: isRTL, zoomScale: zoomScale, onStart: onStart };
21
+ var setPosition = isHorizontal ? setHorizontalPosition : setVerticalPosition;
22
+ setPosition(context, div);
23
+ var handler = {
24
+ onDragStart: onDragStart,
25
+ // Horizontal modifies row height, vertical modifies column width
26
+ onDragging: isHorizontal ? onDraggingHorizontal : onDraggingVertical,
27
+ onDragEnd: onEnd,
28
+ };
29
+ var featureHandler = new DragAndDropHelper(div, context, setPosition, handler, zoomScale, editor.getEnvironment().isMobileOrTablet);
30
+ return { node: td, div: div, featureHandler: featureHandler };
31
+ }
32
+ function onDragStart(context, event) {
33
+ var td = context.td, onStart = context.onStart;
34
+ var rect = normalizeRect(td.getBoundingClientRect());
35
+ // Get cell coordinates
36
+ var columnIndex = td.cellIndex;
37
+ var row = td.parentElement && isElementOfType(td.parentElement, 'tr') ? td.parentElement : undefined;
38
+ var rowIndex = row === null || row === void 0 ? void 0 : row.rowIndex;
39
+ if (rowIndex == undefined) {
40
+ return {
41
+ cmTable: undefined,
42
+ anchorColumn: undefined,
43
+ anchorRow: undefined,
44
+ anchorRowHeight: -1,
45
+ allWidths: [],
46
+ }; // Just a fallback
47
+ }
48
+ var editor = context.editor, table = context.table;
49
+ // Get current selection
50
+ var selection = editor.getDOMSelection();
51
+ // Select first cell of the table
52
+ editor.setDOMSelection({
53
+ type: 'table',
54
+ firstColumn: 0,
55
+ firstRow: 0,
56
+ lastColumn: 0,
57
+ lastRow: 0,
58
+ table: table,
59
+ });
60
+ // Get the table content model
61
+ var cmTable = getFirstSelectedTable(editor.getContentModelCopy('disconnected'))[0];
62
+ // Restore selection
63
+ editor.setDOMSelection(selection);
64
+ if (rect && cmTable) {
65
+ onStart();
66
+ return {
67
+ cmTable: cmTable,
68
+ anchorColumn: columnIndex,
69
+ anchorRow: rowIndex,
70
+ anchorRowHeight: cmTable.rows[rowIndex].height,
71
+ allWidths: __spreadArray([], __read(cmTable.widths), false),
72
+ };
73
+ }
74
+ else {
75
+ return {
76
+ cmTable: cmTable,
77
+ anchorColumn: undefined,
78
+ anchorRow: undefined,
79
+ anchorRowHeight: -1,
80
+ allWidths: [],
81
+ }; // Just a fallback
82
+ }
83
+ }
84
+ function onDraggingHorizontal(context, event, initValue, deltaX, deltaY) {
85
+ var table = context.table;
86
+ var cmTable = initValue.cmTable, anchorRow = initValue.anchorRow, anchorRowHeight = initValue.anchorRowHeight;
87
+ // Assign new widths and heights to the CM table
88
+ if (cmTable && anchorRow != undefined) {
89
+ // Modify the CM Table size
90
+ cmTable.rows[anchorRow].height = (anchorRowHeight !== null && anchorRowHeight !== void 0 ? anchorRowHeight : 0) + deltaY;
91
+ // Normalize the table
92
+ normalizeTable(cmTable);
93
+ // Writeback CM Table size changes to DOM Table
94
+ var tableRow = table.rows[anchorRow];
95
+ for (var col = 0; col < tableRow.cells.length; col++) {
96
+ var td = tableRow.cells[col];
97
+ td.style.height = cmTable.rows[anchorRow].height + 'px';
98
+ }
99
+ return true;
100
+ }
101
+ else {
102
+ return false;
103
+ }
104
+ }
105
+ function onDraggingVertical(context, event, initValue, deltaX) {
106
+ var table = context.table, isRTL = context.isRTL;
107
+ var cmTable = initValue.cmTable, anchorColumn = initValue.anchorColumn, allWidths = initValue.allWidths;
108
+ // Assign new widths and heights to the CM table
109
+ if (cmTable && anchorColumn != undefined) {
110
+ // Modify the CM Table size
111
+ var lastColumn = anchorColumn == cmTable.widths.length - 1;
112
+ var change = deltaX * (isRTL ? -1 : 1);
113
+ // This is the last column
114
+ if (lastColumn) {
115
+ // Only the last column changes
116
+ cmTable.widths[anchorColumn] = allWidths[anchorColumn] + change;
117
+ }
118
+ else {
119
+ // Any other two columns
120
+ var anchorChange = allWidths[anchorColumn] + change;
121
+ var nextAnchorChange = allWidths[anchorColumn + 1] - change;
122
+ if (anchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH ||
123
+ nextAnchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH) {
124
+ return false;
125
+ }
126
+ cmTable.widths[anchorColumn] = anchorChange;
127
+ cmTable.widths[anchorColumn + 1] = nextAnchorChange;
128
+ }
129
+ // Normalize the table
130
+ normalizeTable(cmTable);
131
+ // Writeback CM Table size changes to DOM Table
132
+ for (var row = 0; row < table.rows.length; row++) {
133
+ var tableRow = table.rows[row];
134
+ for (var col = 0; col < tableRow.cells.length; col++) {
135
+ tableRow.cells[col].style.width = cmTable.widths[col] + 'px';
136
+ }
137
+ }
138
+ return true;
139
+ }
140
+ else {
141
+ return false;
142
+ }
143
+ }
144
+ function setHorizontalPosition(context, trigger) {
145
+ var td = context.td;
146
+ var rect = normalizeRect(td.getBoundingClientRect());
147
+ if (rect) {
148
+ trigger.id = 'horizontalResizer';
149
+ trigger.style.top = rect.bottom - CELL_RESIZER_WIDTH + 'px';
150
+ trigger.style.left = rect.left + 'px';
151
+ trigger.style.width = rect.right - rect.left + 'px';
152
+ trigger.style.height = CELL_RESIZER_WIDTH + 'px';
153
+ }
154
+ }
155
+ function setVerticalPosition(context, trigger) {
156
+ var td = context.td, isRTL = context.isRTL;
157
+ var rect = normalizeRect(td.getBoundingClientRect());
158
+ if (rect) {
159
+ trigger.id = 'verticalResizer';
160
+ trigger.style.top = rect.top + 'px';
161
+ trigger.style.left = (isRTL ? rect.left : rect.right) - CELL_RESIZER_WIDTH + 1 + 'px';
162
+ trigger.style.width = CELL_RESIZER_WIDTH + 'px';
163
+ trigger.style.height = rect.bottom - rect.top + 'px';
164
+ }
165
+ }
166
+ //# sourceMappingURL=CellResizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellResizer.js","sourceRoot":"","sources":["../../../../../../packages-content-model/roosterjs-content-model-plugins/lib/tableEdit/editors/features/CellResizer.ts"],"names":[],"mappings":";AAAA,OAAO,aAAa,MAAM,kDAAkD,CAAC;AAC7E,OAAO,iBAAiB,MAAM,oDAAoD,CAAC;AACnF,OAAO,aAAa,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACH,qBAAqB,EACrB,4BAA4B,EAC5B,cAAc,GACjB,MAAM,8BAA8B,CAAC;AAKtC,IAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACrC,MAAe,EACf,EAAwB,EACxB,KAAuB,EACvB,KAAc,EACd,YAAqB,EACrB,OAAmB,EACnB,KAAkB,EAClB,eAA6B;IAE7B,IAAM,QAAQ,GAAG,EAAE,CAAC,aAAa,CAAC;IAClC,IAAM,iBAAiB,GAAG;QACtB,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,+BAA4B,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,gCAA4B;KAC9F,CAAC;IACF,IAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC,kBAAkB,EAAE,CAAC;IAE7D,IAAM,GAAG,GAAG,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAmB,CAAC;IAEzE,CAAC,eAAe,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAEpD,IAAM,OAAO,GAAuB,EAAE,MAAM,QAAA,EAAE,EAAE,IAAA,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,SAAS,WAAA,EAAE,OAAO,SAAA,EAAE,CAAC;IACrF,IAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAC/E,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAE1B,IAAM,OAAO,GAAiE;QAC1E,WAAW,aAAA;QACX,iEAAiE;QACjE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,kBAAkB;QACpE,SAAS,EAAE,KAAK;KACnB,CAAC;IAEF,IAAM,cAAc,GAAG,IAAI,iBAAiB,CACxC,GAAG,EACH,OAAO,EACP,WAAW,EACX,OAAO,EACP,SAAS,EACT,MAAM,CAAC,cAAc,EAAE,CAAC,gBAAgB,CAC3C,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAA,EAAE,cAAc,gBAAA,EAAE,CAAC;AAC7C,CAAC;AAmBD,SAAS,WAAW,CAAC,OAA2B,EAAE,KAAiB;IACvD,IAAA,EAAE,GAAc,OAAO,GAArB,EAAE,OAAO,GAAK,OAAO,QAAZ,CAAa;IAChC,IAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEvD,uBAAuB;IACvB,IAAM,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC;IACjC,IAAM,GAAG,GACL,EAAE,CAAC,aAAa,IAAI,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,IAAM,QAAQ,GAAG,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,CAAC;IAE/B,IAAI,QAAQ,IAAI,SAAS,EAAE;QACvB,OAAO;YACH,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,SAAS;YACvB,SAAS,EAAE,SAAS;YACpB,eAAe,EAAE,CAAC,CAAC;YACnB,SAAS,EAAE,EAAE;SAChB,CAAC,CAAC,kBAAkB;KACxB;IAEO,IAAA,MAAM,GAAY,OAAO,OAAnB,EAAE,KAAK,GAAK,OAAO,MAAZ,CAAa;IAElC,wBAAwB;IACxB,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,iCAAiC;IACjC,MAAM,CAAC,eAAe,CAAC;QACnB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,8BAA8B;IAC9B,IAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,oBAAoB;IACpB,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAElC,IAAI,IAAI,IAAI,OAAO,EAAE;QACjB,OAAO,EAAE,CAAC;QAEV,OAAO;YACH,OAAO,SAAA;YACP,YAAY,EAAE,WAAW;YACzB,SAAS,EAAE,QAAQ;YACnB,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM;YAC9C,SAAS,2BAAM,OAAO,CAAC,MAAM,SAAC;SACjC,CAAC;KACL;SAAM;QACH,OAAO;YACH,OAAO,SAAA;YACP,YAAY,EAAE,SAAS;YACvB,SAAS,EAAE,SAAS;YACpB,eAAe,EAAE,CAAC,CAAC;YACnB,SAAS,EAAE,EAAE;SAChB,CAAC,CAAC,kBAAkB;KACxB;AACL,CAAC;AAED,SAAS,oBAAoB,CACzB,OAA2B,EAC3B,KAAiB,EACjB,SAA+B,EAC/B,MAAc,EACd,MAAc;IAEN,IAAA,KAAK,GAAK,OAAO,MAAZ,CAAa;IAClB,IAAA,OAAO,GAAiC,SAAS,QAA1C,EAAE,SAAS,GAAsB,SAAS,UAA/B,EAAE,eAAe,GAAK,SAAS,gBAAd,CAAe;IAE1D,gDAAgD;IAChD,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,EAAE;QACnC,2BAA2B;QAC3B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,eAAe,aAAf,eAAe,cAAf,eAAe,GAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QAEjE,sBAAsB;QACtB,cAAc,CAAC,OAAO,CAAC,CAAC;QAExB,+CAA+C;QAC/C,IAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YAClD,IAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;SAC3D;QAED,OAAO,IAAI,CAAC;KACf;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC;AAED,SAAS,kBAAkB,CACvB,OAA2B,EAC3B,KAAiB,EACjB,SAA+B,EAC/B,MAAc;IAEN,IAAA,KAAK,GAAY,OAAO,MAAnB,EAAE,KAAK,GAAK,OAAO,MAAZ,CAAa;IACzB,IAAA,OAAO,GAA8B,SAAS,QAAvC,EAAE,YAAY,GAAgB,SAAS,aAAzB,EAAE,SAAS,GAAK,SAAS,UAAd,CAAe;IAEvD,gDAAgD;IAChD,IAAI,OAAO,IAAI,YAAY,IAAI,SAAS,EAAE;QACtC,2BAA2B;QAC3B,IAAM,UAAU,GAAG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7D,IAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,0BAA0B;QAC1B,IAAI,UAAU,EAAE;YACZ,+BAA+B;YAC/B,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC;SACnE;aAAM;YACH,wBAAwB;YACxB,IAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC;YACtD,IAAM,gBAAgB,GAAG,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;YAC9D,IACI,YAAY,GAAG,4BAA4B;gBAC3C,gBAAgB,GAAG,4BAA4B,EACjD;gBACE,OAAO,KAAK,CAAC;aAChB;YACD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;YAC5C,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAC;SACvD;QAED,sBAAsB;QACtB,cAAc,CAAC,OAAO,CAAC,CAAC;QAExB,+CAA+C;QAC/C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YAC9C,IAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;gBAClD,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;aAChE;SACJ;QAED,OAAO,IAAI,CAAC;KACf;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,OAA2B,EAAE,OAAoB;IACpE,IAAA,EAAE,GAAK,OAAO,GAAZ,CAAa;IACvB,IAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACvD,IAAI,IAAI,EAAE;QACN,OAAO,CAAC,EAAE,GAAG,mBAAmB,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;KACpD;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA2B,EAAE,OAAoB;IAClE,IAAA,EAAE,GAAY,OAAO,GAAnB,EAAE,KAAK,GAAK,OAAO,MAAZ,CAAa;IAC9B,IAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACvD,IAAI,IAAI,EAAE;QACN,OAAO,CAAC,EAAE,GAAG,iBAAiB,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,kBAAkB,GAAG,CAAC,GAAG,IAAI,CAAC;QACtF,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,kBAAkB,GAAG,IAAI,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;KACxD;AACL,CAAC","sourcesContent":["import createElement from '../../../pluginUtils/CreateElement/createElement';\nimport DragAndDropHelper from '../../../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport normalizeRect from '../../../pluginUtils/Rect/normalizeRect';\nimport { isElementOfType } from 'roosterjs-content-model-dom';\nimport {\n getFirstSelectedTable,\n MIN_ALLOWED_TABLE_CELL_WIDTH,\n normalizeTable,\n} from 'roosterjs-content-model-core';\nimport type DragAndDropHandler from '../../../pluginUtils/DragAndDrop/DragAndDropHandler';\nimport type { ContentModelTable, IEditor } from 'roosterjs-content-model-types';\nimport type TableEditFeature from './TableEditorFeature';\n\nconst CELL_RESIZER_WIDTH = 4;\n\n/**\n * @internal\n */\nexport default function createCellResizer(\n editor: IEditor,\n td: HTMLTableCellElement,\n table: HTMLTableElement,\n isRTL: boolean,\n isHorizontal: boolean,\n onStart: () => void,\n onEnd: () => false,\n anchorContainer?: HTMLElement\n): TableEditFeature | null {\n const document = td.ownerDocument;\n const createElementData = {\n tag: 'div',\n style: `position: fixed; cursor: ${isHorizontal ? 'row' : 'col'}-resize; user-select: none`,\n };\n const zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n const div = createElement(createElementData, document) as HTMLDivElement;\n\n (anchorContainer || document.body).appendChild(div);\n\n const context: DragAndDropContext = { editor, td, table, isRTL, zoomScale, onStart };\n const setPosition = isHorizontal ? setHorizontalPosition : setVerticalPosition;\n setPosition(context, div);\n\n const handler: DragAndDropHandler<DragAndDropContext, DragAndDropInitValue> = {\n onDragStart,\n // Horizontal modifies row height, vertical modifies column width\n onDragging: isHorizontal ? onDraggingHorizontal : onDraggingVertical,\n onDragEnd: onEnd,\n };\n\n const featureHandler = new DragAndDropHelper<DragAndDropContext, DragAndDropInitValue>(\n div,\n context,\n setPosition,\n handler,\n zoomScale,\n editor.getEnvironment().isMobileOrTablet\n );\n\n return { node: td, div, featureHandler };\n}\n\ninterface DragAndDropContext {\n editor: IEditor;\n td: HTMLTableCellElement;\n table: HTMLTableElement;\n isRTL: boolean;\n zoomScale: number;\n onStart: () => void;\n}\n\ninterface DragAndDropInitValue {\n cmTable: ContentModelTable | undefined;\n anchorColumn: number | undefined;\n anchorRow: number | undefined;\n anchorRowHeight: number;\n allWidths: number[];\n}\n\nfunction onDragStart(context: DragAndDropContext, event: MouseEvent): DragAndDropInitValue {\n const { td, onStart } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n\n // Get cell coordinates\n const columnIndex = td.cellIndex;\n const row =\n td.parentElement && isElementOfType(td.parentElement, 'tr') ? td.parentElement : undefined;\n const rowIndex = row?.rowIndex;\n\n if (rowIndex == undefined) {\n return {\n cmTable: undefined,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n\n const { editor, table } = context;\n\n // Get current selection\n const selection = editor.getDOMSelection();\n\n // Select first cell of the table\n editor.setDOMSelection({\n type: 'table',\n firstColumn: 0,\n firstRow: 0,\n lastColumn: 0,\n lastRow: 0,\n table: table,\n });\n\n // Get the table content model\n const cmTable = getFirstSelectedTable(editor.getContentModelCopy('disconnected'))[0];\n\n // Restore selection\n editor.setDOMSelection(selection);\n\n if (rect && cmTable) {\n onStart();\n\n return {\n cmTable,\n anchorColumn: columnIndex,\n anchorRow: rowIndex,\n anchorRowHeight: cmTable.rows[rowIndex].height,\n allWidths: [...cmTable.widths],\n };\n } else {\n return {\n cmTable,\n anchorColumn: undefined,\n anchorRow: undefined,\n anchorRowHeight: -1,\n allWidths: [],\n }; // Just a fallback\n }\n}\n\nfunction onDraggingHorizontal(\n context: DragAndDropContext,\n event: MouseEvent,\n initValue: DragAndDropInitValue,\n deltaX: number,\n deltaY: number\n) {\n const { table } = context;\n const { cmTable, anchorRow, anchorRowHeight } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorRow != undefined) {\n // Modify the CM Table size\n cmTable.rows[anchorRow].height = (anchorRowHeight ?? 0) + deltaY;\n\n // Normalize the table\n normalizeTable(cmTable);\n\n // Writeback CM Table size changes to DOM Table\n const tableRow = table.rows[anchorRow];\n for (let col = 0; col < tableRow.cells.length; col++) {\n const td = tableRow.cells[col];\n td.style.height = cmTable.rows[anchorRow].height + 'px';\n }\n\n return true;\n } else {\n return false;\n }\n}\n\nfunction onDraggingVertical(\n context: DragAndDropContext,\n event: MouseEvent,\n initValue: DragAndDropInitValue,\n deltaX: number\n) {\n const { table, isRTL } = context;\n const { cmTable, anchorColumn, allWidths } = initValue;\n\n // Assign new widths and heights to the CM table\n if (cmTable && anchorColumn != undefined) {\n // Modify the CM Table size\n const lastColumn = anchorColumn == cmTable.widths.length - 1;\n const change = deltaX * (isRTL ? -1 : 1);\n // This is the last column\n if (lastColumn) {\n // Only the last column changes\n cmTable.widths[anchorColumn] = allWidths[anchorColumn] + change;\n } else {\n // Any other two columns\n const anchorChange = allWidths[anchorColumn] + change;\n const nextAnchorChange = allWidths[anchorColumn + 1] - change;\n if (\n anchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH ||\n nextAnchorChange < MIN_ALLOWED_TABLE_CELL_WIDTH\n ) {\n return false;\n }\n cmTable.widths[anchorColumn] = anchorChange;\n cmTable.widths[anchorColumn + 1] = nextAnchorChange;\n }\n\n // Normalize the table\n normalizeTable(cmTable);\n\n // Writeback CM Table size changes to DOM Table\n for (let row = 0; row < table.rows.length; row++) {\n const tableRow = table.rows[row];\n for (let col = 0; col < tableRow.cells.length; col++) {\n tableRow.cells[col].style.width = cmTable.widths[col] + 'px';\n }\n }\n\n return true;\n } else {\n return false;\n }\n}\n\nfunction setHorizontalPosition(context: DragAndDropContext, trigger: HTMLElement) {\n const { td } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = 'horizontalResizer';\n trigger.style.top = rect.bottom - CELL_RESIZER_WIDTH + 'px';\n trigger.style.left = rect.left + 'px';\n trigger.style.width = rect.right - rect.left + 'px';\n trigger.style.height = CELL_RESIZER_WIDTH + 'px';\n }\n}\n\nfunction setVerticalPosition(context: DragAndDropContext, trigger: HTMLElement) {\n const { td, isRTL } = context;\n const rect = normalizeRect(td.getBoundingClientRect());\n if (rect) {\n trigger.id = 'verticalResizer';\n trigger.style.top = rect.top + 'px';\n trigger.style.left = (isRTL ? rect.left : rect.right) - CELL_RESIZER_WIDTH + 1 + 'px';\n trigger.style.width = CELL_RESIZER_WIDTH + 'px';\n trigger.style.height = rect.bottom - rect.top + 'px';\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type Disposable from '../../../pluginUtils/Disposable';
2
+ /**
3
+ * @internal
4
+ */
5
+ export default interface TableEditFeature {
6
+ node: Node;
7
+ div: HTMLDivElement | null;
8
+ featureHandler: Disposable | null;
9
+ }
10
+ /**
11
+ * @internal
12
+ */
13
+ export declare function disposeTableEditFeature(resizer: TableEditFeature | null): void;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export function disposeTableEditFeature(resizer) {
5
+ var _a, _b, _c;
6
+ if (resizer) {
7
+ (_b = (_a = resizer.div) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(resizer.div);
8
+ resizer.div = null;
9
+ (_c = resizer.featureHandler) === null || _c === void 0 ? void 0 : _c.dispose();
10
+ resizer.featureHandler = null;
11
+ }
12
+ }
13
+ //# sourceMappingURL=TableEditorFeature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableEditorFeature.js","sourceRoot":"","sources":["../../../../../../packages-content-model/roosterjs-content-model-plugins/lib/tableEdit/editors/features/TableEditorFeature.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAgC;;IACpE,IAAI,OAAO,EAAE;QACT,MAAA,MAAA,OAAO,CAAC,GAAG,0CAAE,UAAU,0CAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;QACnB,MAAA,OAAO,CAAC,cAAc,0CAAE,OAAO,EAAE,CAAC;QAClC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;KACjC;AACL,CAAC","sourcesContent":["import type Disposable from '../../../pluginUtils/Disposable';\n\n/**\n * @internal\n */\nexport default interface TableEditFeature {\n node: Node;\n div: HTMLDivElement | null;\n featureHandler: Disposable | null;\n}\n\n/**\n * @internal\n */\nexport function disposeTableEditFeature(resizer: TableEditFeature | null) {\n if (resizer) {\n resizer.div?.parentNode?.removeChild(resizer.div);\n resizer.div = null;\n resizer.featureHandler?.dispose();\n resizer.featureHandler = null;\n }\n}\n"]}