@visactor/vtable-sheet 1.20.0-alpha.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 (231) hide show
  1. package/cjs/components/vtable-sheet.d.ts +78 -0
  2. package/cjs/components/vtable-sheet.js +474 -0
  3. package/cjs/components/vtable-sheet.js.map +1 -0
  4. package/cjs/core/WorkSheet.d.ts +69 -0
  5. package/cjs/core/WorkSheet.js +298 -0
  6. package/cjs/core/WorkSheet.js.map +1 -0
  7. package/cjs/core/table-plugins.d.ts +3 -0
  8. package/cjs/core/table-plugins.js +171 -0
  9. package/cjs/core/table-plugins.js.map +1 -0
  10. package/cjs/event/event-manager.d.ts +29 -0
  11. package/cjs/event/event-manager.js +71 -0
  12. package/cjs/event/event-manager.js.map +1 -0
  13. package/cjs/event/event-target.d.ts +12 -0
  14. package/cjs/event/event-target.js +50 -0
  15. package/cjs/event/event-target.js.map +1 -0
  16. package/cjs/formula/cell-highlight-manager.d.ts +29 -0
  17. package/cjs/formula/cell-highlight-manager.js +141 -0
  18. package/cjs/formula/cell-highlight-manager.js.map +1 -0
  19. package/cjs/formula/formula-autocomplete.d.ts +39 -0
  20. package/cjs/formula/formula-autocomplete.js +239 -0
  21. package/cjs/formula/formula-autocomplete.js.map +1 -0
  22. package/cjs/formula/formula-editor.d.ts +21 -0
  23. package/cjs/formula/formula-editor.js +162 -0
  24. package/cjs/formula/formula-editor.js.map +1 -0
  25. package/cjs/formula/formula-helper.d.ts +8 -0
  26. package/cjs/formula/formula-helper.js +66 -0
  27. package/cjs/formula/formula-helper.js.map +1 -0
  28. package/cjs/formula/formula-range-selector.d.ts +19 -0
  29. package/cjs/formula/formula-range-selector.js +201 -0
  30. package/cjs/formula/formula-range-selector.js.map +1 -0
  31. package/cjs/formula/formula-throttle.d.ts +10 -0
  32. package/cjs/formula/formula-throttle.js +39 -0
  33. package/cjs/formula/formula-throttle.js.map +1 -0
  34. package/cjs/formula/formula-ui-manager.d.ts +19 -0
  35. package/cjs/formula/formula-ui-manager.js +226 -0
  36. package/cjs/formula/formula-ui-manager.js.map +1 -0
  37. package/cjs/formula/index.d.ts +5 -0
  38. package/cjs/formula/index.js +23 -0
  39. package/cjs/formula/index.js.map +1 -0
  40. package/cjs/index.d.ts +6 -0
  41. package/cjs/index.js +50 -0
  42. package/cjs/index.js.map +1 -0
  43. package/cjs/managers/formula-manager.d.ts +82 -0
  44. package/cjs/managers/formula-manager.js +445 -0
  45. package/cjs/managers/formula-manager.js.map +1 -0
  46. package/cjs/managers/menu-manager.d.ts +12 -0
  47. package/cjs/managers/menu-manager.js +89 -0
  48. package/cjs/managers/menu-manager.js.map +1 -0
  49. package/cjs/managers/sheet-manager.d.ts +21 -0
  50. package/cjs/managers/sheet-manager.js +74 -0
  51. package/cjs/managers/sheet-manager.js.map +1 -0
  52. package/cjs/managers/tab-drag-manager.d.ts +24 -0
  53. package/cjs/managers/tab-drag-manager.js +121 -0
  54. package/cjs/managers/tab-drag-manager.js.map +1 -0
  55. package/cjs/sheet-helper.d.ts +16 -0
  56. package/cjs/sheet-helper.js +64 -0
  57. package/cjs/sheet-helper.js.map +1 -0
  58. package/cjs/styles/common.d.ts +1 -0
  59. package/cjs/styles/common.js +17 -0
  60. package/cjs/styles/common.js.map +1 -0
  61. package/cjs/styles/formula-autocomplete.d.ts +1 -0
  62. package/cjs/styles/formula-autocomplete.js +17 -0
  63. package/cjs/styles/formula-autocomplete.js.map +1 -0
  64. package/cjs/styles/formula-bar.d.ts +1 -0
  65. package/cjs/styles/formula-bar.js +17 -0
  66. package/cjs/styles/formula-bar.js.map +1 -0
  67. package/cjs/styles/menu.d.ts +1 -0
  68. package/cjs/styles/menu.js +17 -0
  69. package/cjs/styles/menu.js.map +1 -0
  70. package/cjs/styles/sheet-tab.d.ts +1 -0
  71. package/cjs/styles/sheet-tab.js +17 -0
  72. package/cjs/styles/sheet-tab.js.map +1 -0
  73. package/cjs/styles/sheet.d.ts +1 -0
  74. package/cjs/styles/sheet.js +17 -0
  75. package/cjs/styles/sheet.js.map +1 -0
  76. package/cjs/styles/style-manager.d.ts +1 -0
  77. package/cjs/styles/style-manager.js +15 -0
  78. package/cjs/styles/style-manager.js.map +1 -0
  79. package/cjs/test/formula-complete.test.d.ts +1 -0
  80. package/cjs/test/formula-complete.test.js +42 -0
  81. package/cjs/test/formula-complete.test.js.map +1 -0
  82. package/cjs/tools/env.d.ts +20 -0
  83. package/cjs/tools/env.js +59 -0
  84. package/cjs/tools/env.js.map +1 -0
  85. package/cjs/tools/index.d.ts +3 -0
  86. package/cjs/tools/index.js +16 -0
  87. package/cjs/tools/index.js.map +1 -0
  88. package/cjs/tools/ui/snackbar.d.ts +1 -0
  89. package/cjs/tools/ui/snackbar.js +20 -0
  90. package/cjs/tools/ui/snackbar.js.map +1 -0
  91. package/cjs/ts-types/base.d.ts +44 -0
  92. package/cjs/ts-types/base.js +14 -0
  93. package/cjs/ts-types/base.js.map +1 -0
  94. package/cjs/ts-types/event.d.ts +79 -0
  95. package/cjs/ts-types/event.js +6 -0
  96. package/cjs/ts-types/event.js.map +1 -0
  97. package/cjs/ts-types/events.d.ts +1 -0
  98. package/cjs/ts-types/events.js +3 -0
  99. package/cjs/ts-types/events.js.map +1 -0
  100. package/cjs/ts-types/filter.d.ts +58 -0
  101. package/cjs/ts-types/filter.js +16 -0
  102. package/cjs/ts-types/filter.js.map +1 -0
  103. package/cjs/ts-types/formula.d.ts +51 -0
  104. package/cjs/ts-types/formula.js +6 -0
  105. package/cjs/ts-types/formula.js.map +1 -0
  106. package/cjs/ts-types/index.d.ts +67 -0
  107. package/cjs/ts-types/index.js +37 -0
  108. package/cjs/ts-types/index.js.map +1 -0
  109. package/cjs/ts-types/sheet.d.ts +45 -0
  110. package/cjs/ts-types/sheet.js +6 -0
  111. package/cjs/ts-types/sheet.js.map +1 -0
  112. package/cjs/vtable.d.ts +1 -0
  113. package/cjs/vtable.js +35 -0
  114. package/cjs/vtable.js.map +1 -0
  115. package/dist/vtable-sheet.js +114494 -0
  116. package/dist/vtable-sheet.min.js +853 -0
  117. package/es/components/vtable-sheet.d.ts +78 -0
  118. package/es/components/vtable-sheet.js +462 -0
  119. package/es/components/vtable-sheet.js.map +1 -0
  120. package/es/core/WorkSheet.d.ts +69 -0
  121. package/es/core/WorkSheet.js +298 -0
  122. package/es/core/WorkSheet.js.map +1 -0
  123. package/es/core/table-plugins.d.ts +3 -0
  124. package/es/core/table-plugins.js +164 -0
  125. package/es/core/table-plugins.js.map +1 -0
  126. package/es/event/event-manager.d.ts +29 -0
  127. package/es/event/event-manager.js +63 -0
  128. package/es/event/event-manager.js.map +1 -0
  129. package/es/event/event-target.d.ts +12 -0
  130. package/es/event/event-target.js +42 -0
  131. package/es/event/event-target.js.map +1 -0
  132. package/es/formula/cell-highlight-manager.d.ts +29 -0
  133. package/es/formula/cell-highlight-manager.js +133 -0
  134. package/es/formula/cell-highlight-manager.js.map +1 -0
  135. package/es/formula/formula-autocomplete.d.ts +39 -0
  136. package/es/formula/formula-autocomplete.js +231 -0
  137. package/es/formula/formula-autocomplete.js.map +1 -0
  138. package/es/formula/formula-editor.d.ts +21 -0
  139. package/es/formula/formula-editor.js +135 -0
  140. package/es/formula/formula-editor.js.map +1 -0
  141. package/es/formula/formula-helper.d.ts +8 -0
  142. package/es/formula/formula-helper.js +60 -0
  143. package/es/formula/formula-helper.js.map +1 -0
  144. package/es/formula/formula-range-selector.d.ts +19 -0
  145. package/es/formula/formula-range-selector.js +195 -0
  146. package/es/formula/formula-range-selector.js.map +1 -0
  147. package/es/formula/formula-throttle.d.ts +10 -0
  148. package/es/formula/formula-throttle.js +31 -0
  149. package/es/formula/formula-throttle.js.map +1 -0
  150. package/es/formula/formula-ui-manager.d.ts +19 -0
  151. package/es/formula/formula-ui-manager.js +218 -0
  152. package/es/formula/formula-ui-manager.js.map +1 -0
  153. package/es/formula/index.d.ts +5 -0
  154. package/es/formula/index.js +10 -0
  155. package/es/formula/index.js.map +1 -0
  156. package/es/index.d.ts +6 -0
  157. package/es/index.js +13 -0
  158. package/es/index.js.map +1 -0
  159. package/es/managers/formula-manager.d.ts +82 -0
  160. package/es/managers/formula-manager.js +441 -0
  161. package/es/managers/formula-manager.js.map +1 -0
  162. package/es/managers/menu-manager.d.ts +12 -0
  163. package/es/managers/menu-manager.js +81 -0
  164. package/es/managers/menu-manager.js.map +1 -0
  165. package/es/managers/sheet-manager.d.ts +21 -0
  166. package/es/managers/sheet-manager.js +66 -0
  167. package/es/managers/sheet-manager.js.map +1 -0
  168. package/es/managers/tab-drag-manager.d.ts +24 -0
  169. package/es/managers/tab-drag-manager.js +113 -0
  170. package/es/managers/tab-drag-manager.js.map +1 -0
  171. package/es/sheet-helper.d.ts +16 -0
  172. package/es/sheet-helper.js +54 -0
  173. package/es/sheet-helper.js.map +1 -0
  174. package/es/styles/common.d.ts +1 -0
  175. package/es/styles/common.js +9 -0
  176. package/es/styles/common.js.map +1 -0
  177. package/es/styles/formula-autocomplete.d.ts +1 -0
  178. package/es/styles/formula-autocomplete.js +9 -0
  179. package/es/styles/formula-autocomplete.js.map +1 -0
  180. package/es/styles/formula-bar.d.ts +1 -0
  181. package/es/styles/formula-bar.js +9 -0
  182. package/es/styles/formula-bar.js.map +1 -0
  183. package/es/styles/menu.d.ts +1 -0
  184. package/es/styles/menu.js +9 -0
  185. package/es/styles/menu.js.map +1 -0
  186. package/es/styles/sheet-tab.d.ts +1 -0
  187. package/es/styles/sheet-tab.js +9 -0
  188. package/es/styles/sheet-tab.js.map +1 -0
  189. package/es/styles/sheet.d.ts +1 -0
  190. package/es/styles/sheet.js +9 -0
  191. package/es/styles/sheet.js.map +1 -0
  192. package/es/styles/style-manager.d.ts +1 -0
  193. package/es/styles/style-manager.js +17 -0
  194. package/es/styles/style-manager.js.map +1 -0
  195. package/es/test/formula-complete.test.d.ts +1 -0
  196. package/es/test/formula-complete.test.js +36 -0
  197. package/es/test/formula-complete.test.js.map +1 -0
  198. package/es/tools/env.d.ts +20 -0
  199. package/es/tools/env.js +53 -0
  200. package/es/tools/env.js.map +1 -0
  201. package/es/tools/index.d.ts +3 -0
  202. package/es/tools/index.js +9 -0
  203. package/es/tools/index.js.map +1 -0
  204. package/es/tools/ui/snackbar.d.ts +1 -0
  205. package/es/tools/ui/snackbar.js +14 -0
  206. package/es/tools/ui/snackbar.js.map +1 -0
  207. package/es/ts-types/base.d.ts +44 -0
  208. package/es/ts-types/base.js +14 -0
  209. package/es/ts-types/base.js.map +1 -0
  210. package/es/ts-types/event.d.ts +79 -0
  211. package/es/ts-types/event.js +2 -0
  212. package/es/ts-types/event.js.map +1 -0
  213. package/es/ts-types/events.d.ts +1 -0
  214. package/es/ts-types/events.js +3 -0
  215. package/es/ts-types/events.js.map +1 -0
  216. package/es/ts-types/filter.d.ts +58 -0
  217. package/es/ts-types/filter.js +16 -0
  218. package/es/ts-types/filter.js.map +1 -0
  219. package/es/ts-types/formula.d.ts +51 -0
  220. package/es/ts-types/formula.js +2 -0
  221. package/es/ts-types/formula.js.map +1 -0
  222. package/es/ts-types/index.d.ts +67 -0
  223. package/es/ts-types/index.js +14 -0
  224. package/es/ts-types/index.js.map +1 -0
  225. package/es/ts-types/sheet.d.ts +45 -0
  226. package/es/ts-types/sheet.js +2 -0
  227. package/es/ts-types/sheet.js.map +1 -0
  228. package/es/vtable.d.ts +1 -0
  229. package/es/vtable.js +2 -0
  230. package/es/vtable.js.map +1 -0
  231. package/package.json +120 -0
@@ -0,0 +1,195 @@
1
+ import { FormulaThrottle } from "./formula-throttle";
2
+
3
+ import { detectFunctionParameterPosition } from "./formula-helper";
4
+
5
+ export class FormulaRangeSelector {
6
+ constructor(formulaManager) {
7
+ this.formulaManager = formulaManager;
8
+ }
9
+ selectionsToA1Notation(selections, addressFromCoord) {
10
+ if (!selections || 0 === selections.length) return "";
11
+ const ranges = [];
12
+ for (const range of selections) {
13
+ const startAddr = addressFromCoord(range.startRow, range.startCol), endAddr = addressFromCoord(range.endRow, range.endCol);
14
+ range.startRow === range.endRow && range.startCol === range.endCol ? ranges.push(startAddr) : ranges.push(`${startAddr}:${endAddr}`);
15
+ }
16
+ return ranges.join(",");
17
+ }
18
+ insertA1ReferenceInFunction(formulaInput, a1Notation, isCtrlAddSelection) {
19
+ if (!this.formulaManager.inputIsParamMode.inParamMode) return;
20
+ const currentValue = formulaInput.value, cursorPos = this.formulaManager.lastKnownCursorPosInFormulaInput, argPosition = this.findCurrentArgumentPosition(currentValue, cursorPos);
21
+ let newValue;
22
+ if (argPosition) if (isCtrlAddSelection) {
23
+ newValue = currentValue.substring(argPosition.start, argPosition.end).trim() ? currentValue.slice(0, argPosition.end) + ("," === currentValue[argPosition.end - 1] ? " " : ", ") + a1Notation + currentValue.slice(argPosition.end) : currentValue.slice(0, argPosition.start) + a1Notation + currentValue.slice(argPosition.end);
24
+ } else newValue = currentValue.slice(0, argPosition.start) + a1Notation + currentValue.slice(argPosition.end); else newValue = currentValue;
25
+ formulaInput.value = newValue, this.formulaManager.setCellContent({
26
+ sheet: this.formulaManager.sheet.getActiveSheet().getKey(),
27
+ row: this.formulaManager.sheet.getActiveSheet().editingCell.row,
28
+ col: this.formulaManager.sheet.getActiveSheet().editingCell.col
29
+ }, newValue);
30
+ const newCursorPos = isCtrlAddSelection ? this.formulaManager.lastKnownCursorPosInFormulaInput + (newValue.length - currentValue.length) : argPosition ? argPosition.start + a1Notation.length : cursorPos;
31
+ formulaInput.setSelectionRange(newCursorPos, newCursorPos), setTimeout((() => {
32
+ this.ensureCursorVisible(formulaInput, newCursorPos);
33
+ })), this.formulaManager.inputIsParamMode.functionParamPosition = {
34
+ start: newCursorPos,
35
+ end: newCursorPos
36
+ };
37
+ const inputEvent = new Event("input", {
38
+ bubbles: !0
39
+ });
40
+ Object.defineProperty(inputEvent, "isFormulaInsertion", {
41
+ value: !0
42
+ }), formulaInput.dispatchEvent(inputEvent);
43
+ }
44
+ findCurrentArgumentPosition(formula, cursorPos) {
45
+ if (cursorPos > 1 && cursorPos <= formula.length) {
46
+ const prevChar = formula[cursorPos - 1];
47
+ if ([ "+", "-", "*", "/", "=", ">", "<", "&", "|", "^" ].includes(prevChar)) return {
48
+ start: cursorPos,
49
+ end: cursorPos
50
+ };
51
+ }
52
+ if (!formula.includes("(")) return null;
53
+ let lastOpenParenBeforeCursor = -1, nestLevel = 0, inQuote = !1;
54
+ for (let i = 0; i < cursorPos; i++) {
55
+ const char = formula[i];
56
+ '"' !== char || 0 !== i && "\\" === formula[i - 1] ? inQuote || ("(" === char ? (nestLevel++,
57
+ lastOpenParenBeforeCursor = i) : ")" === char && nestLevel--) : inQuote = !inQuote;
58
+ }
59
+ if (-1 === lastOpenParenBeforeCursor || nestLevel <= 0) return formula.startsWith("=") && 1 === cursorPos ? {
60
+ start: cursorPos,
61
+ end: cursorPos
62
+ } : null;
63
+ if (cursorPos === lastOpenParenBeforeCursor + 1) return {
64
+ start: cursorPos,
65
+ end: cursorPos
66
+ };
67
+ if (cursorPos > 0 && "," === formula[cursorPos - 1]) return {
68
+ start: cursorPos,
69
+ end: cursorPos
70
+ };
71
+ let argumentStart = lastOpenParenBeforeCursor + 1, argumentEnd = cursorPos;
72
+ nestLevel = 1, inQuote = !1;
73
+ for (let i = argumentStart; i < cursorPos; i++) {
74
+ const char = formula[i];
75
+ if ('"' !== char || 0 !== i && "\\" === formula[i - 1]) {
76
+ if (!inQuote) if ("(" === char) nestLevel++; else if (")" === char) {
77
+ if (nestLevel--, 0 === nestLevel) break;
78
+ } else "," === char && 1 === nestLevel && (argumentStart = i + 1);
79
+ } else inQuote = !inQuote;
80
+ }
81
+ nestLevel = 0, inQuote = !1;
82
+ for (let i = 0; i < cursorPos; i++) '"' !== formula[i] || 0 !== i && "\\" === formula[i - 1] ? inQuote || ("(" === formula[i] && nestLevel++,
83
+ ")" === formula[i] && nestLevel--) : inQuote = !inQuote;
84
+ argumentEnd = formula.length;
85
+ for (let i = cursorPos; i < formula.length; i++) {
86
+ const char = formula[i];
87
+ if ('"' !== char || 0 !== i && "\\" === formula[i - 1]) {
88
+ if (!inQuote) if ("(" === char) nestLevel++; else if (")" === char) {
89
+ if (nestLevel--, 0 === nestLevel) {
90
+ argumentEnd = i;
91
+ break;
92
+ }
93
+ } else if ("," === char && 1 === nestLevel) {
94
+ argumentEnd = i;
95
+ break;
96
+ }
97
+ } else inQuote = !inQuote;
98
+ }
99
+ const paramContentBefore = formula.substring(argumentStart, cursorPos).trim(), paramContentAfter = formula.substring(cursorPos, argumentEnd).trim();
100
+ return "" === paramContentBefore && cursorPos === argumentStart ? {
101
+ start: argumentStart,
102
+ end: argumentStart
103
+ } : ("" === paramContentAfter && cursorPos < argumentEnd && (argumentEnd = cursorPos),
104
+ {
105
+ start: argumentStart,
106
+ end: argumentEnd
107
+ });
108
+ }
109
+ handleSelectionChanged(selections, formulaInput, isCtrlAddSelection, addressFromCoord) {
110
+ if (!this.formulaManager.inputIsParamMode.inParamMode || !selections || 0 === selections.length) return;
111
+ const a1Notation = this.selectionsToA1Notation(selections, addressFromCoord);
112
+ a1Notation && this.insertA1ReferenceInFunction(formulaInput, a1Notation, isCtrlAddSelection);
113
+ }
114
+ handleCellValueChanged(event) {
115
+ var _a, _b, _c;
116
+ const activeWorkSheet = this.formulaManager.sheet.getActiveSheet(), formulaManager = this.formulaManager.sheet.formulaManager;
117
+ if (activeWorkSheet && !this.formulaManager.formulaWorkingOnCell) try {
118
+ const newValue = event.newValue;
119
+ if ("string" == typeof newValue && newValue.startsWith("=") && newValue.length > 1) try {
120
+ const currentCellAddress = activeWorkSheet.addressFromCoord(event.row, event.col);
121
+ if (new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`).test(newValue)) return null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(event.col, event.row, "#CYCLE!", !0, !1),
122
+ void (this.formulaManager.formulaWorkingOnCell = null);
123
+ formulaManager.setCellContent({
124
+ sheet: activeWorkSheet.getKey(),
125
+ row: event.row,
126
+ col: event.col
127
+ }, newValue);
128
+ const result = formulaManager.getCellValue({
129
+ sheet: activeWorkSheet.getKey(),
130
+ row: event.row,
131
+ col: event.col
132
+ });
133
+ null === (_b = activeWorkSheet.tableInstance) || void 0 === _b || _b.changeCellValue(event.col, event.row, result.value, !0, !1),
134
+ this.formulaManager.formulaWorkingOnCell = null;
135
+ } catch (error) {
136
+ null === (_c = activeWorkSheet.tableInstance) || void 0 === _c || _c.changeCellValue(event.col, event.row, "#ERROR!", !0, !1),
137
+ this.formulaManager.formulaWorkingOnCell = null;
138
+ } else formulaManager.setCellContent({
139
+ sheet: activeWorkSheet.getKey(),
140
+ row: event.row,
141
+ col: event.col
142
+ }, newValue);
143
+ const formulaThrottle = FormulaThrottle.getInstance();
144
+ if (this.hasFormulaDependents({
145
+ sheet: activeWorkSheet.getKey(),
146
+ row: event.row,
147
+ col: event.col
148
+ })) {
149
+ formulaManager.getCellDependents({
150
+ sheet: activeWorkSheet.getKey(),
151
+ row: event.row,
152
+ col: event.col
153
+ }).forEach((dependent => {
154
+ const result = formulaManager.getCellValue(dependent);
155
+ activeWorkSheet && activeWorkSheet.setCellValue(dependent.row, dependent.col, result.value);
156
+ })), formulaThrottle.immediateRebuildAndRecalculate(formulaManager);
157
+ } else formulaThrottle.throttledRebuildAndRecalculate(formulaManager);
158
+ } catch (error) {}
159
+ }
160
+ handleSelectionChangedForRangeMode(event) {
161
+ var _a;
162
+ const activeWorkSheet = this.formulaManager.sheet.getActiveSheet(), formulaWorkingOnCell = this.formulaManager.formulaWorkingOnCell, formulaManager = this.formulaManager.sheet.formulaManager;
163
+ if (!activeWorkSheet || !formulaWorkingOnCell) return;
164
+ const formulaInput = this.formulaManager.inputingElement;
165
+ if (!formulaInput) return;
166
+ if (this.formulaManager.inputIsParamMode = detectFunctionParameterPosition(formulaInput.value, this.formulaManager.lastKnownCursorPosInFormulaInput),
167
+ !this.formulaManager.inputIsParamMode.inParamMode) return;
168
+ document.activeElement !== formulaInput && formulaInput.focus();
169
+ const selections = activeWorkSheet.getMultipleSelections(), todoSelection = selections[selections.length - 1];
170
+ let isCtrlAddSelection = !1;
171
+ if ((null == selections ? void 0 : selections.length) > (null === (_a = formulaManager.lastSelectionRangesOfHandling) || void 0 === _a ? void 0 : _a.length) && (isCtrlAddSelection = !0),
172
+ formulaManager.lastSelectionRangesOfHandling = selections, !selections || 0 === selections.length) return;
173
+ const editCell = formulaManager.formulaWorkingOnCell, safeSelections = this.formulaManager.sheet.excludeEditCellFromSelection(todoSelection, (null == editCell ? void 0 : editCell.row) || 0, (null == editCell ? void 0 : editCell.col) || 0);
174
+ this.handleSelectionChanged([ safeSelections ], formulaInput, isCtrlAddSelection, ((row, col) => activeWorkSheet.addressFromCoord(row, col)));
175
+ }
176
+ hasFormulaDependents(cell) {
177
+ try {
178
+ return this.formulaManager.getCellDependents(cell).length > 0;
179
+ } catch (error) {
180
+ return !1;
181
+ }
182
+ }
183
+ ensureCursorVisible(input, cursorPos) {
184
+ const tempSpan = document.createElement("span"), inputStyle = window.getComputedStyle(input);
185
+ tempSpan.style.font = inputStyle.font, tempSpan.style.letterSpacing = inputStyle.letterSpacing,
186
+ tempSpan.style.position = "absolute", tempSpan.style.visibility = "hidden", tempSpan.style.whiteSpace = "pre",
187
+ tempSpan.textContent = input.value.substring(0, cursorPos), document.body.appendChild(tempSpan);
188
+ const cursorOffset = tempSpan.offsetWidth;
189
+ document.body.removeChild(tempSpan);
190
+ const inputScrollLeft = input.scrollLeft, inputWidth = input.clientWidth, paddingLeft = parseFloat(inputStyle.paddingLeft), paddingRight = parseFloat(inputStyle.paddingRight), visibleWidth = inputWidth - paddingLeft - paddingRight;
191
+ cursorOffset < inputScrollLeft + paddingLeft ? input.scrollLeft = Math.max(0, cursorOffset - paddingLeft) : cursorOffset > inputScrollLeft + visibleWidth && (input.scrollLeft = cursorOffset - visibleWidth + paddingRight);
192
+ }
193
+ release() {}
194
+ }
195
+ //# sourceMappingURL=formula-range-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/formula/formula-range-selector.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AAOnE,MAAM,OAAO,oBAAoB;IAE/B,YAAY,cAA8B;QACxC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAQD,sBAAsB,CAAC,UAAiB,EAAE,gBAAsD;QAC9F,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1C,OAAO,EAAE,CAAC;SACX;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;YAC9B,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAG7D,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,EAAE;gBACtE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACxB;iBAAM;gBAEL,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC;aACxC;SACF;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,2BAA2B,CAAC,YAA8B,EAAE,UAAkB,EAAE,kBAA2B;QACzG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE;YACrD,OAAO;SACR;QAED,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,gCAAgC,CAAC;QAGvE,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAG9E,IAAI,QAAQ,CAAC;QAEb,IAAI,WAAW,EAAE;YACf,IAAI,kBAAkB,EAAE;gBAEtB,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBAErF,IAAI,UAAU,EAAE;oBAEd,QAAQ;wBACN,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC;4BACtC,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;4BACxD,UAAU;4BACV,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;iBACvC;qBAAM;oBAEL,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;iBACxG;aACF;iBAAM;gBAEL,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;aACxG;SACF;aAAM;YAEL,QAAQ,GAAG,YAAY,CAAC;SACzB;QAED,YAAY,CAAC,KAAK,GAAG,QAAQ,CAAC;QAE9B,IAAI,CAAC,cAAc,CAAC,cAAc,CAChC;YACE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE;YAC1D,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,WAAW,CAAC,GAAG;YAC/D,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,WAAW,CAAC,GAAG;SAChE,EACD,QAAQ,CACT,CAAC;QAEF,MAAM,YAAY,GAAG,kBAAkB;YACrC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,gCAAgC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;YAChG,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,WAAW,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM;gBACvC,CAAC,CAAC,SAAS,CAAC;QAEd,YAAY,CAAC,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC3D,UAAU,CAAC,GAAG,EAAE;YAEd,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,qBAAqB,GAAG;YAC3D,KAAK,EAAE,YAAY;YACnB,GAAG,EAAE,YAAY;SAClB,CAAC;QAGF,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAOO,2BAA2B,CAAC,OAAe,EAAE,SAAiB;QAEpE,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE;YAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;gBAEzE,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,GAAG,EAAE,SAAS;iBACf,CAAC;aACH;SACF;QAGD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAC1B,OAAO,IAAI,CAAC;SACb;QAGD,IAAI,yBAAyB,GAAG,CAAC,CAAC,CAAC;QACnC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,OAAO,GAAG,KAAK,CAAC;QAGpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAGxB,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBACxD,OAAO,GAAG,CAAC,OAAO,CAAC;gBACnB,SAAS;aACV;YAGD,IAAI,OAAO,EAAE;gBACX,SAAS;aACV;YAED,IAAI,IAAI,KAAK,GAAG,EAAE;gBAChB,SAAS,EAAE,CAAC;gBACZ,yBAAyB,GAAG,CAAC,CAAC;aAC/B;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE;gBACvB,SAAS,EAAE,CAAC;aACb;SACF;QAGD,IAAI,yBAAyB,KAAK,CAAC,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE;YAEtD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,KAAK,CAAC,EAAE;gBAC9C,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,GAAG,EAAE,SAAS;iBACf,CAAC;aACH;YAED,OAAO,IAAI,CAAC;SACb;QAGD,IAAI,SAAS,KAAK,yBAAyB,GAAG,CAAC,EAAE;YAC/C,OAAO;gBACL,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,SAAS;aACf,CAAC;SACH;QAGD,IAAI,SAAS,GAAG,CAAC,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;YACnD,OAAO;gBACL,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,SAAS;aACf,CAAC;SACH;QAGD,IAAI,aAAa,GAAG,yBAAyB,GAAG,CAAC,CAAC;QAClD,IAAI,WAAW,GAAG,SAAS,CAAC;QAG5B,SAAS,GAAG,CAAC,CAAC;QACd,OAAO,GAAG,KAAK,CAAC;QAGhB,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBACxD,OAAO,GAAG,CAAC,OAAO,CAAC;gBACnB,SAAS;aACV;YACD,IAAI,OAAO,EAAE;gBACX,SAAS;aACV;YAED,IAAI,IAAI,KAAK,GAAG,EAAE;gBAChB,SAAS,EAAE,CAAC;aACb;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE;gBACvB,SAAS,EAAE,CAAC;gBACZ,IAAI,SAAS,KAAK,CAAC,EAAE;oBAEnB,MAAM;iBACP;aACF;iBAAM,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,KAAK,CAAC,EAAE;gBAE1C,aAAa,GAAG,CAAC,GAAG,CAAC,CAAC;aACvB;SACF;QAGD,SAAS,GAAG,CAAC,CAAC;QACd,OAAO,GAAG,KAAK,CAAC;QAGhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAClC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBAC9D,OAAO,GAAG,CAAC,OAAO,CAAC;gBACnB,SAAS;aACV;YACD,IAAI,OAAO,EAAE;gBACX,SAAS;aACV;YAED,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBACtB,SAAS,EAAE,CAAC;aACb;YACD,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBACtB,SAAS,EAAE,CAAC;aACb;SACF;QAGD,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE;gBACxD,OAAO,GAAG,CAAC,OAAO,CAAC;gBACnB,SAAS;aACV;YACD,IAAI,OAAO,EAAE;gBACX,SAAS;aACV;YAED,IAAI,IAAI,KAAK,GAAG,EAAE;gBAChB,SAAS,EAAE,CAAC;aACb;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE;gBACvB,SAAS,EAAE,CAAC;gBAEZ,IAAI,SAAS,KAAK,CAAC,EAAE;oBACnB,WAAW,GAAG,CAAC,CAAC;oBAChB,MAAM;iBACP;aACF;iBAAM,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,KAAK,CAAC,EAAE;gBAE1C,WAAW,GAAG,CAAC,CAAC;gBAChB,MAAM;aACP;SACF;QAGD,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9E,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;QAE3E,IAAI,kBAAkB,KAAK,EAAE,IAAI,SAAS,KAAK,aAAa,EAAE;YAE5D,OAAO;gBACL,KAAK,EAAE,aAAa;gBACpB,GAAG,EAAE,aAAa;aACnB,CAAC;SACH;QAED,IAAI,iBAAiB,KAAK,EAAE,IAAI,SAAS,GAAG,WAAW,EAAE;YAEvD,WAAW,GAAG,SAAS,CAAC;SACzB;QAED,OAAO;YACL,KAAK,EAAE,aAAa;YACpB,GAAG,EAAE,WAAW;SACjB,CAAC;IACJ,CAAC;IAOD,sBAAsB,CACpB,UAAuB,EACvB,YAA8B,EAC9B,kBAA2B,EAC3B,gBAAsD;QAEtD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,WAAW,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/F,OAAO;SACR;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;QAC7E,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,2BAA2B,CAAC,YAAY,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;SAChF;IACH,CAAC;IAMD,sBAAsB,CAAC,KAA4B;;QACjD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QACnE,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC;QAEhE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE;YAChE,OAAO;SACR;QAED,IAAI;YAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAChC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;gBACnF,IAAI;oBAEF,MAAM,kBAAkB,GAAG,eAAe,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;oBAElF,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,mBAAmB,kBAAkB,kBAAkB,CAAC,CAAC;oBACtF,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;wBAC5B,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;wBACvF,MAAA,eAAe,CAAC,aAAa,0CAAE,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;wBAC7F,IAAI,CAAC,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;wBAChD,OAAO;qBACR;oBAGD,cAAc,CAAC,cAAc,CAC3B;wBACE,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;wBAC/B,GAAG,EAAE,KAAK,CAAC,GAAG;wBACd,GAAG,EAAE,KAAK,CAAC,GAAG;qBACf,EACD,QAAQ,CACT,CAAC;oBAGF,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,CAAC;wBACzC,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;wBAC/B,GAAG,EAAE,KAAK,CAAC,GAAG;wBACd,GAAG,EAAE,KAAK,CAAC,GAAG;qBACf,CAAC,CAAC;oBAOH,MAAA,eAAe,CAAC,aAAa,0CAAE,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;oBAChG,IAAI,CAAC,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;iBACjD;gBAAC,OAAO,KAAK,EAAE;oBACd,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;oBAEjD,MAAA,eAAe,CAAC,aAAa,0CAAE,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;oBAC7F,IAAI,CAAC,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC;iBACjD;aACF;iBAAM;gBAEL,cAAc,CAAC,cAAc,CAC3B;oBACE,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;oBAC/B,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,GAAG,EAAE,KAAK,CAAC,GAAG;iBACf,EACD,QAAQ,CACT,CAAC;aACH;YAGD,MAAM,eAAe,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;YAEtD,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,CAAC;gBACpD,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;gBAC/B,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;YACH,IAAI,mBAAmB,EAAE;gBAEvB,MAAM,UAAU,GAAG,cAAc,CAAC,iBAAiB,CAAC;oBAClD,KAAK,EAAE,eAAe,CAAC,MAAM,EAAE;oBAC/B,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,GAAG,EAAE,KAAK,CAAC,GAAG;iBACf,CAAC,CAAC;gBAGH,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;oBAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;oBACtD,IAAI,eAAe,EAAE;wBACnB,eAAe,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;qBAC1E;gBACH,CAAC,CAAC,CAAC;gBAEH,eAAe,CAAC,8BAA8B,CAAC,cAAc,CAAC,CAAC;aAChE;iBAAM;gBAEL,eAAe,CAAC,8BAA8B,CAAC,cAAc,CAAC,CAAC;aAChE;SAOF;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;SAC1D;IACH,CAAC;IAKD,kCAAkC,CAAC,KAAU;;QAC3C,OAAO,CAAC,GAAG,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QACzD,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC;QACtE,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,cAAc,CAAC;QAChE,IAAI,CAAC,eAAe,IAAI,CAAC,oBAAoB,EAAE;YAC7C,OAAO;SACR;QAGD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;QAKzD,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO;SACR;QAID,IAAI,CAAC,cAAc,CAAC,gBAAgB,GAAG,+BAA+B,CACpE,YAAY,CAAC,KAAK,EAClB,IAAI,CAAC,cAAc,CAAC,gCAAgC,CACrD,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE;YACrD,OAAO;SACR;QAED,IAAI,QAAQ,CAAC,aAAa,KAAK,YAAY,EAAE;YAC3C,YAAY,CAAC,KAAK,EAAE,CAAC;SACtB;QAGD,MAAM,UAAU,GAAG,eAAe,CAAC,qBAAqB,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,KAAG,MAAA,cAAc,CAAC,6BAA6B,0CAAE,MAAM,CAAA,EAAE;YAC7E,kBAAkB,GAAG,IAAI,CAAC;SAC3B;QACD,cAAc,CAAC,6BAA6B,GAAG,UAAU,CAAC;QAC1D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1C,OAAO;SACR;QAGD,MAAM,QAAQ,GAAG,cAAc,CAAC,oBAAoB,CAAC;QAIrD,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,4BAA4B,CAC3E,aAAa,EACb,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,GAAG,KAAI,CAAC,EAClB,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,GAAG,KAAI,CAAC,CACnB,CAAC;QAEF,IAAI,CAAC,sBAAsB,CAAC,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE,CAC3G,eAAgB,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAC5C,CAAC;IAGJ,CAAC;IAOO,oBAAoB,CAAC,IAAiB;QAC5C,IAAI;YACF,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC/D,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;SAC9B;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC;SACd;IACH,CAAC;IAOO,mBAAmB,CAAC,KAAuB,EAAE,SAAiB;QAEpE,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAGlD,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QACtC,QAAQ,CAAC,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC;QACxD,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACrC,QAAQ,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC;QACrC,QAAQ,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;QAGlC,QAAQ,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC3D,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAGpC,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAGpC,MAAM,eAAe,GAAG,KAAK,CAAC,UAAU,CAAC;QACzC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC;QACrC,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACzD,MAAM,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;QAG7D,IAAI,YAAY,GAAG,eAAe,GAAG,WAAW,EAAE;YAEhD,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;SAC5D;aAAM,IAAI,YAAY,GAAG,eAAe,GAAG,YAAY,EAAE;YAExD,KAAK,CAAC,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;SAC/D;IACH,CAAC;IAED,OAAO;IAEP,CAAC;CACF","file":"formula-range-selector.js","sourcesContent":["/**\n * 公式范围选择器\n * 实现Excel风格的公式输入体验:用户输入\"=sum(\"后,选择单元格范围自动插入A1引用\n */\n\nimport { FormulaThrottle } from './formula-throttle';\nimport type { FormulaManager } from '../managers/formula-manager';\nimport type { CellRange, CellValueChangedEvent, FormulaCell } from '../ts-types';\nimport { detectFunctionParameterPosition } from './formula-helper';\n\nexport interface FunctionParamPosition {\n start: number;\n end: number;\n}\n\nexport class FormulaRangeSelector {\n private formulaManager: FormulaManager;\n constructor(formulaManager: FormulaManager) {\n this.formulaManager = formulaManager;\n }\n\n /**\n * 将选择范围转换为A1格式\n * @param selections 选择范围数组\n * @param addressFromCoord 坐标转地址函数\n * @returns A1格式字符串\n */\n selectionsToA1Notation(selections: any[], addressFromCoord: (row: number, col: number) => string): string {\n if (!selections || selections.length === 0) {\n return '';\n }\n\n const ranges: string[] = [];\n\n for (const range of selections) {\n const startAddr = addressFromCoord(range.startRow, range.startCol);\n const endAddr = addressFromCoord(range.endRow, range.endCol);\n\n // 如果是单个单元格(start和end相同)\n if (range.startRow === range.endRow && range.startCol === range.endCol) {\n ranges.push(startAddr);\n } else {\n // 如果是范围,使用冒号分隔\n ranges.push(`${startAddr}:${endAddr}`);\n }\n }\n\n return ranges.join(',');\n }\n\n insertA1ReferenceInFunction(formulaInput: HTMLInputElement, a1Notation: string, isCtrlAddSelection: boolean): void {\n if (!this.formulaManager.inputIsParamMode.inParamMode) {\n return;\n }\n\n const currentValue = formulaInput.value;\n const cursorPos = this.formulaManager.lastKnownCursorPosInFormulaInput;\n\n // 找到当前光标所处的参数位置\n const argPosition = this.findCurrentArgumentPosition(currentValue, cursorPos);\n\n // 在函数参数位置插入或替换A1引用\n let newValue;\n\n if (argPosition) {\n if (isCtrlAddSelection) {\n // Ctrl模式:追加而非替换\n const currentArg = currentValue.substring(argPosition.start, argPosition.end).trim();\n\n if (currentArg) {\n // 如果当前参数不为空,追加逗号和新引用\n newValue =\n currentValue.slice(0, argPosition.end) +\n (currentValue[argPosition.end - 1] === ',' ? ' ' : ', ') +\n a1Notation +\n currentValue.slice(argPosition.end);\n } else {\n // 如果当前参数为空,直接插入新引用\n newValue = currentValue.slice(0, argPosition.start) + a1Notation + currentValue.slice(argPosition.end);\n }\n } else {\n // 替换模式:完全替换当前参数\n newValue = currentValue.slice(0, argPosition.start) + a1Notation + currentValue.slice(argPosition.end);\n }\n } else {\n // 防止newValue未定义\n newValue = currentValue;\n }\n\n formulaInput.value = newValue;\n // 首先设置公式内容\n this.formulaManager.setCellContent(\n {\n sheet: this.formulaManager.sheet.getActiveSheet().getKey(),\n row: this.formulaManager.sheet.getActiveSheet().editingCell.row,\n col: this.formulaManager.sheet.getActiveSheet().editingCell.col\n },\n newValue\n );\n // 设置光标位置到插入内容之后\n const newCursorPos = isCtrlAddSelection\n ? this.formulaManager.lastKnownCursorPosInFormulaInput + (newValue.length - currentValue.length)\n : argPosition\n ? argPosition.start + a1Notation.length\n : cursorPos;\n\n formulaInput.setSelectionRange(newCursorPos, newCursorPos);\n setTimeout(() => {\n // 确保光标位置在可视区域内\n this.ensureCursorVisible(formulaInput, newCursorPos);\n });\n // 更新函数参数位置\n this.formulaManager.inputIsParamMode.functionParamPosition = {\n start: newCursorPos,\n end: newCursorPos\n };\n\n // 触发输入事件以更新高亮\n const inputEvent = new Event('input', { bubbles: true });\n Object.defineProperty(inputEvent, 'isFormulaInsertion', { value: true });\n formulaInput.dispatchEvent(inputEvent);\n }\n /**\n * 找到光标所在的参数位置\n * @param formula 公式文本\n * @param cursorPos 光标位置\n * @returns 参数的起始和结束位置\n */\n private findCurrentArgumentPosition(formula: string, cursorPos: number): { start: number; end: number } | null {\n // 首先检查光标是否在操作符后面\n if (cursorPos > 1 && cursorPos <= formula.length) {\n const prevChar = formula[cursorPos - 1];\n if (['+', '-', '*', '/', '=', '>', '<', '&', '|', '^'].includes(prevChar)) {\n // 光标在操作符后面,将光标位置视为参数的起始和结束位置\n return {\n start: cursorPos,\n end: cursorPos\n };\n }\n }\n\n // 检查公式是否包含括号\n if (!formula.includes('(')) {\n return null;\n }\n\n // 从后向前查找最接近光标的左括号\n let lastOpenParenBeforeCursor = -1;\n let nestLevel = 0;\n let inQuote = false;\n\n // 第一阶段:找到光标所在的函数调用\n for (let i = 0; i < cursorPos; i++) {\n const char = formula[i];\n\n // 处理引号内的内容\n if (char === '\"' && (i === 0 || formula[i - 1] !== '\\\\')) {\n inQuote = !inQuote;\n continue;\n }\n\n // 如果在引号内,忽略所有特殊字符\n if (inQuote) {\n continue;\n }\n\n if (char === '(') {\n nestLevel++;\n lastOpenParenBeforeCursor = i;\n } else if (char === ')') {\n nestLevel--;\n }\n }\n\n // 如果没有找到左括号或者光标不在任何括号内\n if (lastOpenParenBeforeCursor === -1 || nestLevel <= 0) {\n // 检查是否在公式开始位置\n if (formula.startsWith('=') && cursorPos === 1) {\n return {\n start: cursorPos,\n end: cursorPos\n };\n }\n\n return null;\n }\n\n // 特殊处理:光标恰好在左括号后面\n if (cursorPos === lastOpenParenBeforeCursor + 1) {\n return {\n start: cursorPos,\n end: cursorPos\n };\n }\n\n // 特殊处理:光标在逗号后面\n if (cursorPos > 0 && formula[cursorPos - 1] === ',') {\n return {\n start: cursorPos,\n end: cursorPos\n };\n }\n\n // 找到当前参数的起始位置\n let argumentStart = lastOpenParenBeforeCursor + 1;\n let argumentEnd = cursorPos;\n\n // 重置状态\n nestLevel = 1; // 从左括号开始,嵌套级别为1\n inQuote = false;\n\n // 从找到的左括号位置向光标方向扫描,找到当前参数的起始位置\n for (let i = argumentStart; i < cursorPos; i++) {\n const char = formula[i];\n\n if (char === '\"' && (i === 0 || formula[i - 1] !== '\\\\')) {\n inQuote = !inQuote;\n continue;\n }\n if (inQuote) {\n continue;\n }\n\n if (char === '(') {\n nestLevel++;\n } else if (char === ')') {\n nestLevel--;\n if (nestLevel === 0) {\n // 如果回到了函数最外层,则这个右括号后面的内容不再是当前函数的参数\n break;\n }\n } else if (char === ',' && nestLevel === 1) {\n // 如果是当前函数层级的参数分隔符,更新参数开始位置\n argumentStart = i + 1;\n }\n }\n\n // 重置状态,准备从光标位置向后扫描\n nestLevel = 0;\n inQuote = false;\n\n // 重新计算光标位置的嵌套级别\n for (let i = 0; i < cursorPos; i++) {\n if (formula[i] === '\"' && (i === 0 || formula[i - 1] !== '\\\\')) {\n inQuote = !inQuote;\n continue;\n }\n if (inQuote) {\n continue;\n }\n\n if (formula[i] === '(') {\n nestLevel++;\n }\n if (formula[i] === ')') {\n nestLevel--;\n }\n }\n\n // 从光标位置向后查找参数结束位置\n argumentEnd = formula.length;\n for (let i = cursorPos; i < formula.length; i++) {\n const char = formula[i];\n\n if (char === '\"' && (i === 0 || formula[i - 1] !== '\\\\')) {\n inQuote = !inQuote;\n continue;\n }\n if (inQuote) {\n continue;\n }\n\n if (char === '(') {\n nestLevel++;\n } else if (char === ')') {\n nestLevel--;\n // 如果回到了当前函数的右括号\n if (nestLevel === 0) {\n argumentEnd = i;\n break;\n }\n } else if (char === ',' && nestLevel === 1) {\n // 找到下一个同级参数的分隔符\n argumentEnd = i;\n break;\n }\n }\n\n // 处理空参数的情况\n const paramContentBefore = formula.substring(argumentStart, cursorPos).trim();\n const paramContentAfter = formula.substring(cursorPos, argumentEnd).trim();\n\n if (paramContentBefore === '' && cursorPos === argumentStart) {\n // 光标在参数起始位置,且参数为空\n return {\n start: argumentStart,\n end: argumentStart\n };\n }\n\n if (paramContentAfter === '' && cursorPos < argumentEnd) {\n // 光标后面到结束位置都是空白\n argumentEnd = cursorPos;\n }\n\n return {\n start: argumentStart,\n end: argumentEnd\n };\n }\n /**\n * 处理单元格选择变化\n * @param selections 当前选择范围\n * @param formulaInput 公式输入框\n * @param addressFromCoord 坐标转地址函数\n */\n handleSelectionChanged(\n selections: CellRange[],\n formulaInput: HTMLInputElement,\n isCtrlAddSelection: boolean,\n addressFromCoord: (row: number, col: number) => string\n ): void {\n if (!this.formulaManager.inputIsParamMode.inParamMode || !selections || selections.length === 0) {\n return;\n }\n\n const a1Notation = this.selectionsToA1Notation(selections, addressFromCoord);\n if (a1Notation) {\n this.insertA1ReferenceInFunction(formulaInput, a1Notation, isCtrlAddSelection);\n }\n }\n\n /**\n * 处理单元格值变更事件\n * @param event 事件\n */\n handleCellValueChanged(event: CellValueChangedEvent): void {\n console.log('handleCellValueChanged', event);\n const activeWorkSheet = this.formulaManager.sheet.getActiveSheet();\n const formulaManager = this.formulaManager.sheet.formulaManager;\n\n if (!activeWorkSheet || this.formulaManager.formulaWorkingOnCell) {\n return;\n }\n\n try {\n // 检查新输入的值是否为公式\n const newValue = event.newValue;\n if (typeof newValue === 'string' && newValue.startsWith('=') && newValue.length > 1) {\n try {\n // 检查是否包含循环引用\n const currentCellAddress = activeWorkSheet.addressFromCoord(event.row, event.col);\n // 使用正则表达式来精确匹配单元格引用\n const cellRegex = new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`);\n if (cellRegex.test(newValue)) {\n console.warn('Circular reference detected:', newValue, 'contains', currentCellAddress);\n activeWorkSheet.tableInstance?.changeCellValue(event.col, event.row, '#CYCLE!', true, false);\n this.formulaManager.formulaWorkingOnCell = null;\n return;\n }\n\n // 首先设置公式内容\n formulaManager.setCellContent(\n {\n sheet: activeWorkSheet.getKey(),\n row: event.row,\n col: event.col\n },\n newValue\n );\n\n // 获取计算结果\n const result = formulaManager.getCellValue({\n sheet: activeWorkSheet.getKey(),\n row: event.row,\n col: event.col\n });\n // // 检查当前单元格是否正在编辑(是否在公式栏中编辑)\n // const formulaInput = this.formulaManager.inputingElement;\n // const isEditing = document.activeElement === formulaInput;\n\n // 更新单元格显示 - 如果正在编辑则显示公式,否则显示计算结果\n // activeWorkSheet.tableInstance?.changeCellValue(event.col, event.row, isEditing ? newValue : result.value);\n activeWorkSheet.tableInstance?.changeCellValue(event.col, event.row, result.value, true, false);\n this.formulaManager.formulaWorkingOnCell = null;\n } catch (error) {\n console.warn('Formula processing error:', error);\n // 显示错误状态\n activeWorkSheet.tableInstance?.changeCellValue(event.col, event.row, '#ERROR!', true, false);\n this.formulaManager.formulaWorkingOnCell = null;\n }\n } else {\n // 非公式值,同步到HyperFormula\n formulaManager.setCellContent(\n {\n sheet: activeWorkSheet.getKey(),\n row: event.row,\n col: event.col\n },\n newValue\n );\n }\n\n // 使用FormulaThrottle来优化公式重新计算\n const formulaThrottle = FormulaThrottle.getInstance();\n // 判断是否需要立即更新\n const needImmediateUpdate = this.hasFormulaDependents({\n sheet: activeWorkSheet.getKey(),\n row: event.row,\n col: event.col\n });\n if (needImmediateUpdate) {\n // 更新依赖的公式\n const dependents = formulaManager.getCellDependents({\n sheet: activeWorkSheet.getKey(),\n row: event.row,\n col: event.col\n });\n\n // 重新计算依赖该单元格的所有公式\n dependents.forEach(dependent => {\n const result = formulaManager.getCellValue(dependent);\n if (activeWorkSheet) {\n activeWorkSheet.setCellValue(dependent.row, dependent.col, result.value);\n }\n });\n // 立即执行完整重新计算\n formulaThrottle.immediateRebuildAndRecalculate(formulaManager);\n } else {\n // 使用节流方式进行公式计算\n formulaThrottle.throttledRebuildAndRecalculate(formulaManager);\n }\n\n // // 如果当前编辑的单元格就是选中的单元格,更新 fx 输入框\n // const selection = this.activeWorkSheet.getSelection();\n // if (selection && selection.startRow === event.row && selection.startCol === event.col) {\n // this.updateFormulaBar();\n // }\n } catch (error) {\n console.error('Error in handleCellValueChanged:', error);\n }\n }\n\n /**\n * 处理范围选择模式下的单元格选中事件\n */\n handleSelectionChangedForRangeMode(event: any): void {\n console.log('handleSelectionChangedForRangeMode', event);\n const activeWorkSheet = this.formulaManager.sheet.getActiveSheet();\n const formulaWorkingOnCell = this.formulaManager.formulaWorkingOnCell;\n const formulaManager = this.formulaManager.sheet.formulaManager;\n if (!activeWorkSheet || !formulaWorkingOnCell) {\n return;\n }\n\n // const formulaInput = this.formulaInput;\n const formulaInput = this.formulaManager.inputingElement;\n // if (!formulaInput || this.formulaManager.isUpdatingFromFormula) {\n // return;\n // }\n // TODO 尝试全部去掉isUpdatingFromFormula的判断和赋值\n if (!formulaInput) {\n return;\n }\n\n // 不依赖 event.type 字符串,selection-end 已在上层绑定,这里直接处理\n\n this.formulaManager.inputIsParamMode = detectFunctionParameterPosition(\n formulaInput.value,\n this.formulaManager.lastKnownCursorPosInFormulaInput\n );\n if (!this.formulaManager.inputIsParamMode.inParamMode) {\n return;\n }\n\n if (document.activeElement !== formulaInput) {\n formulaInput.focus();\n }\n\n // 获取所有选择范围(支持Ctrl/Cmd多选)\n const selections = activeWorkSheet.getMultipleSelections();\n const todoSelection = selections[selections.length - 1];\n let isCtrlAddSelection = false;\n if (selections?.length > formulaManager.lastSelectionRangesOfHandling?.length) {\n isCtrlAddSelection = true;\n }\n formulaManager.lastSelectionRangesOfHandling = selections;\n if (!selections || selections.length === 0) {\n return;\n }\n\n // 排除当前编辑单元格,避免形成自引用导致 #CYCLE!\n const editCell = formulaManager.formulaWorkingOnCell;\n // const safeSelections = selections\n // .map(selection => this.excludeEditCellFromSelection(selection, editCell?.row || 0, editCell?.col || 0))\n // .filter(selection => selection.startRow >= 0 && selection.startCol >= 0); // 过滤掉无效选择\n const safeSelections = this.formulaManager.sheet.excludeEditCellFromSelection(\n todoSelection,\n editCell?.row || 0,\n editCell?.col || 0\n );\n\n this.handleSelectionChanged([safeSelections], formulaInput, isCtrlAddSelection, (row: number, col: number) =>\n activeWorkSheet!.addressFromCoord(row, col)\n );\n\n // 写入后不再刷新公式栏,以免覆盖刚插入的引用\n }\n\n /**\n * 检查单元格是否有公式依赖\n * @param cell 单元格\n * @returns 是否有公式依赖\n */\n private hasFormulaDependents(cell: FormulaCell): boolean {\n try {\n const dependents = this.formulaManager.getCellDependents(cell);\n return dependents.length > 0;\n } catch (error) {\n console.warn('Error checking formula dependents:', error);\n return false;\n }\n }\n\n /**\n * 确保光标位置在输入框的可视区域内\n * @param input 输入框元素\n * @param cursorPos 光标位置\n */\n private ensureCursorVisible(input: HTMLInputElement, cursorPos: number): void {\n // 创建一个临时元素来计算光标位置\n const tempSpan = document.createElement('span');\n const inputStyle = window.getComputedStyle(input);\n\n // 复制输入框的样式到临时元素\n tempSpan.style.font = inputStyle.font;\n tempSpan.style.letterSpacing = inputStyle.letterSpacing;\n tempSpan.style.position = 'absolute';\n tempSpan.style.visibility = 'hidden';\n tempSpan.style.whiteSpace = 'pre';\n\n // 设置文本内容为光标位置前的文本\n tempSpan.textContent = input.value.substring(0, cursorPos);\n document.body.appendChild(tempSpan);\n\n // 计算光标位置\n const cursorOffset = tempSpan.offsetWidth;\n document.body.removeChild(tempSpan);\n\n // 计算可视区域\n const inputScrollLeft = input.scrollLeft;\n const inputWidth = input.clientWidth;\n const paddingLeft = parseFloat(inputStyle.paddingLeft);\n const paddingRight = parseFloat(inputStyle.paddingRight);\n const visibleWidth = inputWidth - paddingLeft - paddingRight;\n\n // 调整滚动位置确保光标可见\n if (cursorOffset < inputScrollLeft + paddingLeft) {\n // 光标在可视区域左侧\n input.scrollLeft = Math.max(0, cursorOffset - paddingLeft);\n } else if (cursorOffset > inputScrollLeft + visibleWidth) {\n // 光标在可视区域右侧\n input.scrollLeft = cursorOffset - visibleWidth + paddingRight;\n }\n }\n\n release(): void {\n //do nothing\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { FormulaManager } from '../managers/formula-manager';
2
+ export declare class FormulaThrottle {
3
+ private static instance;
4
+ private recalcTimer;
5
+ private pendingRecalc;
6
+ private throttleDelay;
7
+ static getInstance(): FormulaThrottle;
8
+ throttledRebuildAndRecalculate(formulaManager: FormulaManager): void;
9
+ immediateRebuildAndRecalculate(formulaManager: FormulaManager): void;
10
+ }
@@ -0,0 +1,31 @@
1
+ export class FormulaThrottle {
2
+ constructor() {
3
+ this.recalcTimer = null, this.pendingRecalc = !1, this.throttleDelay = 150;
4
+ }
5
+ static getInstance() {
6
+ return FormulaThrottle.instance || (FormulaThrottle.instance = new FormulaThrottle),
7
+ FormulaThrottle.instance;
8
+ }
9
+ throttledRebuildAndRecalculate(formulaManager) {
10
+ if (formulaManager) if (null === this.recalcTimer) {
11
+ if (!this.pendingRecalc) try {
12
+ formulaManager.rebuildAndRecalculate();
13
+ } catch (e) {}
14
+ this.pendingRecalc = !1, this.recalcTimer = window.setTimeout((() => {
15
+ if (this.recalcTimer = null, this.pendingRecalc) try {
16
+ formulaManager.rebuildAndRecalculate(), this.pendingRecalc = !1;
17
+ } catch (e) {}
18
+ }), this.throttleDelay);
19
+ } else this.pendingRecalc = !0;
20
+ }
21
+ immediateRebuildAndRecalculate(formulaManager) {
22
+ if (formulaManager) {
23
+ null !== this.recalcTimer && (window.clearTimeout(this.recalcTimer), this.recalcTimer = null),
24
+ this.pendingRecalc = !1;
25
+ try {
26
+ formulaManager.rebuildAndRecalculate();
27
+ } catch (e) {}
28
+ }
29
+ }
30
+ }
31
+ //# sourceMappingURL=formula-throttle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/formula/formula-throttle.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,eAAe;IAA5B;QAEU,gBAAW,GAAkB,IAAI,CAAC;QAClC,kBAAa,GAAG,KAAK,CAAC;QACtB,kBAAa,GAAG,GAAG,CAAC;IAsE9B,CAAC;IApEC,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE;YAC7B,eAAe,CAAC,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;SAClD;QACD,OAAO,eAAe,CAAC,QAAQ,CAAC;IAClC,CAAC;IAMD,8BAA8B,CAAC,cAA8B;QAC3D,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO;SACR;QAGD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE;YAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,OAAO;SACR;QAGD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACvB,IAAI;gBACF,cAAc,CAAC,qBAAqB,EAAE,CAAC;aACxC;YAAC,OAAO,CAAC,EAAE;gBACV,OAAO,CAAC,IAAI,CAAC,+CAA+C,EAAE,CAAC,CAAC,CAAC;aAClE;SACF;QAED,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI;oBACF,cAAc,CAAC,qBAAqB,EAAE,CAAC;oBACvC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;iBAC5B;gBAAC,OAAO,CAAC,EAAE;oBACV,OAAO,CAAC,IAAI,CAAC,wDAAwD,EAAE,CAAC,CAAC,CAAC;iBAC3E;aACF;QACH,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACzB,CAAC;IAMD,8BAA8B,CAAC,cAA8B;QAC3D,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO;SACR;QAGD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE;YAC7B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SACzB;QAED,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAE3B,IAAI;YACF,cAAc,CAAC,qBAAqB,EAAE,CAAC;SACxC;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,IAAI,CAAC,yDAAyD,EAAE,CAAC,CAAC,CAAC;SAC5E;IACH,CAAC;CACF","file":"formula-throttle.js","sourcesContent":["import type { FormulaManager } from '../managers/formula-manager';\n\nexport class FormulaThrottle {\n private static instance: FormulaThrottle;\n private recalcTimer: number | null = null;\n private pendingRecalc = false;\n private throttleDelay = 150; // ms\n\n static getInstance(): FormulaThrottle {\n if (!FormulaThrottle.instance) {\n FormulaThrottle.instance = new FormulaThrottle();\n }\n return FormulaThrottle.instance;\n }\n\n /**\n * 节流方式调用公式重建和重新计算\n * @param formulaManager 公式管理器实例\n */\n throttledRebuildAndRecalculate(formulaManager: FormulaManager): void {\n if (!formulaManager) {\n return;\n }\n\n // 如果有定时器正在等待,直接返回\n if (this.recalcTimer !== null) {\n this.pendingRecalc = true;\n return;\n }\n\n // 如果没有待处理的重新计算,执行一次,然后设置定时器\n if (!this.pendingRecalc) {\n try {\n formulaManager.rebuildAndRecalculate();\n } catch (e) {\n console.warn('Error during formula rebuild and recalculate:', e);\n }\n }\n\n this.pendingRecalc = false;\n this.recalcTimer = window.setTimeout(() => {\n this.recalcTimer = null;\n if (this.pendingRecalc) {\n try {\n formulaManager.rebuildAndRecalculate();\n this.pendingRecalc = false;\n } catch (e) {\n console.warn('Error during formula rebuild and recalculate in timer:', e);\n }\n }\n }, this.throttleDelay);\n }\n\n /**\n * 立即执行一次计算,并取消任何待处理的计算\n * @param formulaManager 公式管理器实例\n */\n immediateRebuildAndRecalculate(formulaManager: FormulaManager): void {\n if (!formulaManager) {\n return;\n }\n\n // 清除任何待处理的计时器\n if (this.recalcTimer !== null) {\n window.clearTimeout(this.recalcTimer);\n this.recalcTimer = null;\n }\n\n this.pendingRecalc = false;\n\n try {\n formulaManager.rebuildAndRecalculate();\n } catch (e) {\n console.warn('Error during immediate formula rebuild and recalculate:', e);\n }\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type VTableSheet from '../components/vtable-sheet';
2
+ export declare class FormulaUIManager {
3
+ private sheet;
4
+ private formulaBarElement;
5
+ formulaInput: HTMLInputElement | null;
6
+ isFormulaBarShowingResult: boolean;
7
+ private isEnterKeyPressed;
8
+ constructor(sheet: VTableSheet);
9
+ createFormulaBar(): HTMLElement;
10
+ activateFormulaBar(): void;
11
+ deactivateFormulaBar(): void;
12
+ cancelFormulaEdit(): void;
13
+ confirmFormulaEdit(): void;
14
+ updateFormulaBar(): void;
15
+ private handleFormulaInput;
16
+ private handleFormulaKeydown;
17
+ clearFormula(): void;
18
+ release(): void;
19
+ }
@@ -0,0 +1,218 @@
1
+ import { detectFunctionParameterPosition } from "./formula-helper";
2
+
3
+ export class FormulaUIManager {
4
+ constructor(sheet) {
5
+ this.formulaBarElement = null, this.formulaInput = null, this.isFormulaBarShowingResult = !1,
6
+ this.isEnterKeyPressed = !1, this.sheet = sheet;
7
+ }
8
+ createFormulaBar() {
9
+ const formulaBar = document.createElement("div");
10
+ formulaBar.className = "vtable-sheet-formula-bar";
11
+ const cellAddressBox = document.createElement("div");
12
+ cellAddressBox.className = "vtable-sheet-cell-address", cellAddressBox.textContent = "",
13
+ formulaBar.appendChild(cellAddressBox);
14
+ const formulaIcon = document.createElement("div");
15
+ formulaIcon.className = "vtable-sheet-formula-icon", formulaIcon.textContent = "fx",
16
+ formulaIcon.title = "插入函数", formulaBar.appendChild(formulaIcon);
17
+ const formulaInput = document.createElement("input");
18
+ this.formulaInput = formulaInput, formulaInput.className = "vtable-sheet-formula-input",
19
+ formulaInput.placeholder = "输入公式...";
20
+ [ "click", "mouseup", "keyup", "select", "input", "focus" ].forEach((eventType => {
21
+ formulaInput.addEventListener(eventType, (e => {
22
+ const cursorPos = formulaInput.selectionStart;
23
+ null != cursorPos && (this.sheet.formulaManager.lastKnownCursorPosInFormulaInput = cursorPos,
24
+ this.sheet.formulaManager.inputingElement = formulaInput);
25
+ }));
26
+ })), formulaInput.addEventListener("input", (e => this.handleFormulaInput(e))),
27
+ formulaInput.addEventListener("keydown", (e => this.handleFormulaKeydown(e))), formulaInput.addEventListener("focus", (() => {
28
+ this.activateFormulaBar();
29
+ const activeWorkSheet = this.sheet.getActiveSheet();
30
+ if (activeWorkSheet) {
31
+ const editingCell = activeWorkSheet.editingCell;
32
+ if (editingCell && !this.sheet.formulaManager.formulaWorkingOnCell) {
33
+ const formula = this.sheet.formulaManager.getCellFormula({
34
+ sheet: editingCell.sheet,
35
+ row: editingCell.row,
36
+ col: editingCell.col
37
+ });
38
+ if (formula) {
39
+ this.sheet.formulaManager.formulaWorkingOnCell = editingCell;
40
+ const displayFormula = formula.startsWith("=") ? formula : `=${formula}`;
41
+ formulaInput.value = displayFormula, this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(displayFormula),
42
+ this.sheet.formulaManager.inputIsParamMode = detectFunctionParameterPosition(formulaInput.value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput);
43
+ }
44
+ }
45
+ }
46
+ })), formulaInput.addEventListener("blur", (() => {
47
+ var _a;
48
+ if (this.sheet.formulaManager.formulaWorkingOnCell) return;
49
+ this.deactivateFormulaBar(), this.sheet.formulaManager.cellHighlightManager.clearHighlights();
50
+ const activeWorkSheet = this.sheet.getActiveSheet();
51
+ if (activeWorkSheet) {
52
+ const selection = activeWorkSheet.getSelection();
53
+ if (selection) {
54
+ const result = this.sheet.formulaManager.getCellValue({
55
+ sheet: activeWorkSheet.getKey(),
56
+ row: selection.startRow,
57
+ col: selection.startCol
58
+ });
59
+ null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(selection.startCol, selection.startRow, result.error ? "#ERROR!" : result.value);
60
+ }
61
+ }
62
+ })), formulaBar.appendChild(formulaInput);
63
+ const formulaActions = document.createElement("div");
64
+ formulaActions.className = "vtable-sheet-formula-actions";
65
+ const cancelButton = document.createElement("button");
66
+ cancelButton.className = "vtable-sheet-formula-button vtable-sheet-formula-cancel",
67
+ cancelButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>',
68
+ cancelButton.title = "取消", cancelButton.addEventListener("click", (() => this.cancelFormulaEdit())),
69
+ formulaActions.appendChild(cancelButton);
70
+ const confirmButton = document.createElement("button");
71
+ return confirmButton.className = "vtable-sheet-formula-button vtable-sheet-formula-confirm",
72
+ confirmButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>',
73
+ confirmButton.title = "确认", confirmButton.addEventListener("click", (() => this.confirmFormulaEdit())),
74
+ formulaActions.appendChild(confirmButton), formulaBar.appendChild(formulaActions),
75
+ this.formulaBarElement = formulaBar, formulaBar;
76
+ }
77
+ activateFormulaBar() {
78
+ const formulaBar = this.formulaBarElement;
79
+ formulaBar && formulaBar.classList.add("active");
80
+ }
81
+ deactivateFormulaBar() {
82
+ const formulaBar = this.formulaBarElement;
83
+ formulaBar && formulaBar.classList.remove("active"), this.sheet.formulaManager.cellHighlightManager.clearHighlights();
84
+ }
85
+ cancelFormulaEdit() {
86
+ this.formulaInput && this.updateFormulaBar();
87
+ }
88
+ confirmFormulaEdit() {
89
+ var _a;
90
+ const formulaInput = this.formulaInput, activeWorkSheet = this.sheet.getActiveSheet();
91
+ if (formulaInput && activeWorkSheet) {
92
+ const selection = activeWorkSheet.editingCell;
93
+ if (!selection) return;
94
+ const value = formulaInput.value;
95
+ if (value.startsWith("=") && value.length > 1) try {
96
+ const currentCellAddress = activeWorkSheet.addressFromCoord(selection.row, selection.col);
97
+ if (new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`).test(value)) return activeWorkSheet.setCellValue(selection.row, selection.col, "#CYCLE!"),
98
+ null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(selection.col, selection.row, "#CYCLE!"),
99
+ formulaInput.value = "", void formulaInput.blur();
100
+ this.sheet.formulaManager.setCellContent({
101
+ sheet: activeWorkSheet.getKey(),
102
+ row: selection.row,
103
+ col: selection.col
104
+ }, value);
105
+ const result = this.sheet.formulaManager.getCellValue({
106
+ sheet: activeWorkSheet.getKey(),
107
+ row: selection.row,
108
+ col: selection.col
109
+ });
110
+ activeWorkSheet.setCellValue(selection.row, selection.col, result.value);
111
+ } catch (error) {
112
+ activeWorkSheet.setCellValue(selection.row, selection.col, "#ERROR!");
113
+ } else activeWorkSheet.setCellValue(selection.row, selection.col, value);
114
+ }
115
+ }
116
+ updateFormulaBar() {
117
+ if (!this.formulaBarElement) return;
118
+ const activeWorkSheet = this.sheet.getActiveSheet();
119
+ if (!activeWorkSheet) return void this.clearFormula();
120
+ const selection = activeWorkSheet.getSelection();
121
+ if (selection) try {
122
+ const rowCount = activeWorkSheet.getRowCount(), colCount = activeWorkSheet.getColumnCount();
123
+ if (selection.startRow < 0 || selection.startRow >= rowCount || selection.startCol < 0 || selection.startCol >= colCount) return void this.clearFormula();
124
+ const cellAddressBox = this.formulaBarElement.querySelector(".vtable-sheet-cell-address");
125
+ cellAddressBox && (cellAddressBox.textContent = activeWorkSheet.addressFromCoord(selection.startRow, selection.startCol));
126
+ const formulaInput = this.formulaInput;
127
+ if (formulaInput) {
128
+ if (this.sheet.formulaManager.inputIsParamMode = detectFunctionParameterPosition(formulaInput.value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput),
129
+ this.sheet.formulaManager.inputIsParamMode.inParamMode) return;
130
+ if (this.isFormulaBarShowingResult) return;
131
+ try {
132
+ const formula = this.sheet.formulaManager.getCellFormula({
133
+ sheet: activeWorkSheet.getKey(),
134
+ row: selection.startRow,
135
+ col: selection.startCol
136
+ });
137
+ if (formula) {
138
+ const displayFormula = formula.startsWith("=") ? formula : "=" + formula;
139
+ formulaInput.value = displayFormula;
140
+ } else {
141
+ const cellValue = activeWorkSheet.getCellValue(selection.startRow, selection.startCol);
142
+ formulaInput.value = null != cellValue ? String(cellValue) : "";
143
+ }
144
+ } catch (e) {
145
+ formulaInput.value = "";
146
+ }
147
+ }
148
+ } catch (e) {
149
+ this.clearFormula();
150
+ } else this.clearFormula();
151
+ }
152
+ handleFormulaInput(event) {
153
+ var _a;
154
+ const activeWorkSheet = this.sheet.getActiveSheet();
155
+ if (!activeWorkSheet) return;
156
+ const editingCell = activeWorkSheet.editingCell;
157
+ if (!editingCell) return;
158
+ const input = event.target, value = input.value;
159
+ this.sheet.getActiveSheet().tableInstance.editorManager.editingEditor || this.sheet.getActiveSheet().tableInstance.startEditCell(editingCell.col, editingCell.row, value),
160
+ (null === (_a = this.sheet.getActiveSheet().tableInstance.editorManager.editingEditor) || void 0 === _a ? void 0 : _a.getInputElement) && (this.sheet.getActiveSheet().tableInstance.editorManager.editingEditor.getInputElement().value = value,
161
+ input.focus()), value.startsWith("=") && this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(value),
162
+ event.isFormulaInsertion || (this.sheet.formulaManager.inputIsParamMode = detectFunctionParameterPosition(value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput),
163
+ value.startsWith("=") ? (this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(value),
164
+ this.isFormulaBarShowingResult = !1, this.sheet.formulaManager.setCellContent({
165
+ sheet: activeWorkSheet.getKey(),
166
+ row: editingCell.row,
167
+ col: editingCell.col
168
+ }, value)) : this.sheet.formulaManager.cellHighlightManager.clearHighlights(), this.sheet.formulaManager.formulaWorkingOnCell = activeWorkSheet.editingCell);
169
+ }
170
+ handleFormulaKeydown(event) {
171
+ var _a, _b, _c, _d;
172
+ const activeWorkSheet = this.sheet.getActiveSheet();
173
+ if (!activeWorkSheet) return;
174
+ const input = event.target;
175
+ if ("Enter" === event.key) {
176
+ const editingCell = activeWorkSheet.editingCell;
177
+ if (!editingCell) return;
178
+ const value = input.value;
179
+ if (value.startsWith("=") && value.length > 1) try {
180
+ const currentCellAddress = activeWorkSheet.addressFromCoord(editingCell.row, editingCell.col);
181
+ if (new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`).test(value)) return activeWorkSheet.setCellValue(editingCell.row, editingCell.col, "#CYCLE!"),
182
+ null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(editingCell.col, editingCell.row, "#CYCLE!"),
183
+ this.sheet.formulaManager.formulaWorkingOnCell = null, input.value = "", void input.blur();
184
+ this.sheet.formulaManager.setCellContent({
185
+ sheet: activeWorkSheet.getKey(),
186
+ row: editingCell.row,
187
+ col: editingCell.col
188
+ }, value);
189
+ const result = this.sheet.formulaManager.getCellValue({
190
+ sheet: activeWorkSheet.getKey(),
191
+ row: editingCell.row,
192
+ col: editingCell.col
193
+ });
194
+ null === (_b = activeWorkSheet.tableInstance) || void 0 === _b || _b.changeCellValue(editingCell.col, editingCell.row, result.error ? "#ERROR!" : result.value),
195
+ this.isFormulaBarShowingResult = !0, input.blur(), setTimeout((() => {
196
+ this.sheet.formulaManager.formulaWorkingOnCell = null, activeWorkSheet.tableInstance.clearSelected(),
197
+ this.sheet.formulaManager.cellHighlightManager.clearHighlights(), activeWorkSheet.tableInstance.selectCell(editingCell.col, editingCell.row);
198
+ }), 0);
199
+ } catch (error) {
200
+ activeWorkSheet.setCellValue(editingCell.row, editingCell.col, "#ERROR!"), null === (_c = activeWorkSheet.tableInstance) || void 0 === _c || _c.changeCellValue(editingCell.col, editingCell.row, "#ERROR!"),
201
+ this.sheet.formulaManager.formulaWorkingOnCell = null;
202
+ } else activeWorkSheet.setCellValue(editingCell.row, editingCell.col, value), null === (_d = activeWorkSheet.tableInstance) || void 0 === _d || _d.changeCellValue(editingCell.col, editingCell.row, value),
203
+ this.sheet.formulaManager.formulaWorkingOnCell = null;
204
+ this.isEnterKeyPressed = !0, event.preventDefault(), event.stopPropagation();
205
+ }
206
+ }
207
+ clearFormula() {
208
+ var _a;
209
+ const cellAddressBox = null === (_a = this.formulaBarElement) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-cell-address");
210
+ cellAddressBox && (cellAddressBox.textContent = "");
211
+ const formulaInput = this.formulaInput;
212
+ formulaInput && (formulaInput.value = "");
213
+ }
214
+ release() {
215
+ this.formulaBarElement = null, this.formulaInput = null;
216
+ }
217
+ }
218
+ //# sourceMappingURL=formula-ui-manager.js.map