@fileverse-dev/fortune-react 1.3.13-create-3 → 1.3.13-create-5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/components/FxEditor/index.js +73 -18
- package/es/components/SheetOverlay/ContentEditable.js +4 -3
- package/es/components/SheetOverlay/InputBox.js +193 -44
- package/es/components/SheetOverlay/drag_and_drop/column-helpers.js +4 -27
- package/es/components/SheetOverlay/drag_and_drop/row-helpers.js +4 -25
- package/es/components/SheetOverlay/formula-segment-boundary.js +1 -1
- package/es/components/SheetOverlay/helper.d.ts +7 -0
- package/es/components/SheetOverlay/helper.js +75 -0
- package/es/components/SheetOverlay/index.css +10 -83
- package/es/components/SheetOverlay/index.js +1 -26
- package/es/components/Toolbar/ColorPicker.js +3 -2
- package/es/components/Toolbar/CustomColor.js +7 -3
- package/es/components/Toolbar/index.js +11 -2
- package/es/hooks/useFormulaEditorHistory.d.ts +4 -4
- package/es/hooks/useFormulaEditorHistory.js +87 -59
- package/es/hooks/useRerenderOnFormulaCaret.d.ts +1 -1
- package/es/hooks/useRerenderOnFormulaCaret.js +6 -3
- package/lib/components/FxEditor/index.js +72 -17
- package/lib/components/SheetOverlay/ContentEditable.js +4 -3
- package/lib/components/SheetOverlay/InputBox.js +192 -43
- package/lib/components/SheetOverlay/drag_and_drop/column-helpers.js +3 -26
- package/lib/components/SheetOverlay/drag_and_drop/row-helpers.js +3 -24
- package/lib/components/SheetOverlay/formula-segment-boundary.js +1 -1
- package/lib/components/SheetOverlay/helper.d.ts +7 -0
- package/lib/components/SheetOverlay/helper.js +79 -0
- package/lib/components/SheetOverlay/index.css +10 -83
- package/lib/components/SheetOverlay/index.js +1 -26
- package/lib/components/Toolbar/ColorPicker.js +3 -2
- package/lib/components/Toolbar/CustomColor.js +7 -3
- package/lib/components/Toolbar/index.js +10 -1
- package/lib/hooks/useFormulaEditorHistory.d.ts +4 -4
- package/lib/hooks/useFormulaEditorHistory.js +85 -58
- package/lib/hooks/useRerenderOnFormulaCaret.d.ts +1 -1
- package/lib/hooks/useRerenderOnFormulaCaret.js +5 -2
- package/package.json +2 -2
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
export declare function moveCursorToEnd(editableDiv: HTMLDivElement): void;
|
|
2
2
|
export declare function getCursorPosition(editableDiv: HTMLDivElement): number;
|
|
3
|
+
export declare function getSelectionOffsets(editableDiv: HTMLDivElement): {
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function isEditorUndoRedoKeyEvent(e: KeyboardEvent): boolean;
|
|
8
|
+
export declare function shouldUseCustomEditorHistory(editorInnerTextTrimmed: string, historyActive: boolean): boolean;
|
|
3
9
|
export declare function setCursorPosition(editableDiv: HTMLDivElement, targetOffset: number): void;
|
|
10
|
+
export declare function setSelectionOffsets(editableDiv: HTMLDivElement, startOffset: number, endOffset: number): void;
|
|
4
11
|
export declare function buildFormulaSuggestionText(editableDiv: HTMLDivElement, formulaName: string): {
|
|
5
12
|
text: string;
|
|
6
13
|
caretOffset: number;
|
|
@@ -18,6 +18,44 @@ export function getCursorPosition(editableDiv) {
|
|
|
18
18
|
preRange.setEnd(range.endContainer, range.endOffset);
|
|
19
19
|
return preRange.toString().length;
|
|
20
20
|
}
|
|
21
|
+
export function getSelectionOffsets(editableDiv) {
|
|
22
|
+
var selection = window.getSelection();
|
|
23
|
+
if (!selection || selection.rangeCount === 0) {
|
|
24
|
+
var caret = getCursorPosition(editableDiv);
|
|
25
|
+
return {
|
|
26
|
+
start: caret,
|
|
27
|
+
end: caret
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var range = selection.getRangeAt(0);
|
|
31
|
+
if (!editableDiv.contains(range.startContainer) || !editableDiv.contains(range.endContainer)) {
|
|
32
|
+
var caret = getCursorPosition(editableDiv);
|
|
33
|
+
return {
|
|
34
|
+
start: caret,
|
|
35
|
+
end: caret
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
var startRange = range.cloneRange();
|
|
39
|
+
startRange.selectNodeContents(editableDiv);
|
|
40
|
+
startRange.setEnd(range.startContainer, range.startOffset);
|
|
41
|
+
var start = startRange.toString().length;
|
|
42
|
+
var endRange = range.cloneRange();
|
|
43
|
+
endRange.selectNodeContents(editableDiv);
|
|
44
|
+
endRange.setEnd(range.endContainer, range.endOffset);
|
|
45
|
+
var end = endRange.toString().length;
|
|
46
|
+
return {
|
|
47
|
+
start: Math.max(0, Math.min(start, end)),
|
|
48
|
+
end: Math.max(start, end)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function isEditorUndoRedoKeyEvent(e) {
|
|
52
|
+
if (!e.metaKey && !e.ctrlKey) return false;
|
|
53
|
+
if (e.code === "KeyZ" || e.code === "KeyY") return true;
|
|
54
|
+
return e.keyCode === 90 || e.keyCode === 89;
|
|
55
|
+
}
|
|
56
|
+
export function shouldUseCustomEditorHistory(editorInnerTextTrimmed, historyActive) {
|
|
57
|
+
return historyActive || editorInnerTextTrimmed.length > 0;
|
|
58
|
+
}
|
|
21
59
|
export function setCursorPosition(editableDiv, targetOffset) {
|
|
22
60
|
var _a, _b;
|
|
23
61
|
editableDiv.focus();
|
|
@@ -44,6 +82,43 @@ export function setCursorPosition(editableDiv, targetOffset) {
|
|
|
44
82
|
selection.removeAllRanges();
|
|
45
83
|
selection.addRange(range);
|
|
46
84
|
}
|
|
85
|
+
export function setSelectionOffsets(editableDiv, startOffset, endOffset) {
|
|
86
|
+
editableDiv.focus();
|
|
87
|
+
var selection = window.getSelection();
|
|
88
|
+
if (!selection) return;
|
|
89
|
+
var startTarget = Math.max(0, Math.min(startOffset, endOffset));
|
|
90
|
+
var endTarget = Math.max(startTarget, endOffset);
|
|
91
|
+
var walker = document.createTreeWalker(editableDiv, NodeFilter.SHOW_TEXT);
|
|
92
|
+
var resolve = function resolve(target) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
var remaining = target;
|
|
95
|
+
var node = walker.nextNode();
|
|
96
|
+
while (node) {
|
|
97
|
+
var len = (_b = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
98
|
+
if (remaining <= len) return {
|
|
99
|
+
node: node,
|
|
100
|
+
offset: remaining
|
|
101
|
+
};
|
|
102
|
+
remaining -= len;
|
|
103
|
+
node = walker.nextNode();
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
walker.currentNode = editableDiv;
|
|
108
|
+
var startPos = resolve(startTarget);
|
|
109
|
+
walker.currentNode = editableDiv;
|
|
110
|
+
var endPos = resolve(endTarget);
|
|
111
|
+
var range = document.createRange();
|
|
112
|
+
if (startPos && endPos) {
|
|
113
|
+
range.setStart(startPos.node, startPos.offset);
|
|
114
|
+
range.setEnd(endPos.node, endPos.offset);
|
|
115
|
+
} else {
|
|
116
|
+
range.selectNodeContents(editableDiv);
|
|
117
|
+
range.collapse(false);
|
|
118
|
+
}
|
|
119
|
+
selection.removeAllRanges();
|
|
120
|
+
selection.addRange(range);
|
|
121
|
+
}
|
|
47
122
|
export function buildFormulaSuggestionText(editableDiv, formulaName) {
|
|
48
123
|
var fullText = editableDiv.innerText || "";
|
|
49
124
|
var selection = window.getSelection();
|
|
@@ -145,12 +145,6 @@
|
|
|
145
145
|
margin: 0px 0 0 0px;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
.fortune-selection-copy .fortune-copy {
|
|
149
|
-
position: absolute;
|
|
150
|
-
z-index: 18;
|
|
151
|
-
background-color: transparent;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
148
|
.fortune-selection-copy-hc {
|
|
155
149
|
position: absolute;
|
|
156
150
|
top: 0;
|
|
@@ -330,7 +324,7 @@
|
|
|
330
324
|
max-height: 9900px;
|
|
331
325
|
max-width: 9900px;
|
|
332
326
|
border: 2px #efc703 solid;
|
|
333
|
-
padding:
|
|
327
|
+
padding: 2px 2px;
|
|
334
328
|
margin: 0;
|
|
335
329
|
resize: none;
|
|
336
330
|
overflow: hidden;
|
|
@@ -363,6 +357,14 @@
|
|
|
363
357
|
color: forestgreen;
|
|
364
358
|
}
|
|
365
359
|
|
|
360
|
+
.luckysheet-formula-text-calc,
|
|
361
|
+
.luckysheet-formula-text-lpar,
|
|
362
|
+
.luckysheet-formula-text-comma,
|
|
363
|
+
.luckysheet-formula-text-rpar {
|
|
364
|
+
padding-left: 2px;
|
|
365
|
+
padding-right: 2px;
|
|
366
|
+
}
|
|
367
|
+
|
|
366
368
|
.luckysheet-cell-flow {
|
|
367
369
|
margin: 0;
|
|
368
370
|
padding: 0;
|
|
@@ -647,50 +649,6 @@
|
|
|
647
649
|
cursor: se-resize;
|
|
648
650
|
}
|
|
649
651
|
|
|
650
|
-
.fortune-selection-copy-top {
|
|
651
|
-
left: 0;
|
|
652
|
-
right: 0;
|
|
653
|
-
height: 2px;
|
|
654
|
-
top: 0;
|
|
655
|
-
background-position: bottom;
|
|
656
|
-
/* background-image: url("EwaAntH.gif"); */
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
.fortune-selection-copy-right {
|
|
660
|
-
top: 0;
|
|
661
|
-
bottom: 0;
|
|
662
|
-
width: 2px;
|
|
663
|
-
right: 0;
|
|
664
|
-
/* background-image: url("EwaAntV.gif"); */
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
.fortune-selection-copy-bottom {
|
|
668
|
-
left: 0;
|
|
669
|
-
right: 0;
|
|
670
|
-
height: 2px;
|
|
671
|
-
bottom: 0;
|
|
672
|
-
/* background-image: url("EwaAntH.gif"); */
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
.fortune-selection-copy-left {
|
|
676
|
-
top: 0;
|
|
677
|
-
bottom: 0;
|
|
678
|
-
width: 2px;
|
|
679
|
-
left: 0;
|
|
680
|
-
background-position: right;
|
|
681
|
-
/* background-image: url("EwaAntV.gif"); */
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
.fortune-selection-copy-hc {
|
|
685
|
-
position: absolute;
|
|
686
|
-
top: 0;
|
|
687
|
-
right: 0;
|
|
688
|
-
bottom: 0;
|
|
689
|
-
left: 0;
|
|
690
|
-
border: 2px dashed #12a5ff;
|
|
691
|
-
z-index: 8;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
652
|
.luckysheet-modal-dialog-resize {
|
|
695
653
|
position: absolute;
|
|
696
654
|
border: 2px solid #0188fb;
|
|
@@ -765,39 +723,8 @@
|
|
|
765
723
|
cursor: se-resize;
|
|
766
724
|
}
|
|
767
725
|
|
|
768
|
-
.fortune-formula-functionrange-highlight
|
|
769
|
-
background-image: none;
|
|
770
|
-
background: #0188fb;
|
|
771
|
-
position: absolute;
|
|
772
|
-
z-index: 18;
|
|
726
|
+
.fortune-formula-functionrange-highlight {
|
|
773
727
|
cursor: move;
|
|
774
|
-
opacity: 0.9;
|
|
775
|
-
box-sizing: content-box;
|
|
776
|
-
/*border: 1px solid #fff;*/
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
.fortune-formula-functionrange-highlight .fortune-selection-copy-top {
|
|
780
|
-
top: -2px;
|
|
781
|
-
border-top: 2px solid #fff;
|
|
782
|
-
border-bottom: 2px solid #fff;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
.fortune-formula-functionrange-highlight .fortune-selection-copy-right {
|
|
786
|
-
right: -2px;
|
|
787
|
-
border-left: 2px solid #fff;
|
|
788
|
-
border-right: 2px solid #fff;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
.fortune-formula-functionrange-highlight .fortune-selection-copy-bottom {
|
|
792
|
-
bottom: -2px;
|
|
793
|
-
border-top: 2px solid #fff;
|
|
794
|
-
border-bottom: 2px solid #fff;
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
.fortune-formula-functionrange-highlight .fortune-selection-copy-left {
|
|
798
|
-
left: -2px;
|
|
799
|
-
border-left: 2px solid #fff;
|
|
800
|
-
border-right: 2px solid #fff;
|
|
801
728
|
}
|
|
802
729
|
|
|
803
730
|
.fortune-formula-functionrange-highlight .fortune-selection-copy-hc {
|
|
@@ -285,14 +285,6 @@ var SheetOverlay = function SheetOverlay() {
|
|
|
285
285
|
className: "fortune-selection-copy fortune-formula-functionrange-select",
|
|
286
286
|
style: context.formulaRangeSelect
|
|
287
287
|
}, /*#__PURE__*/React.createElement("div", {
|
|
288
|
-
className: "fortune-selection-copy-top fortune-copy"
|
|
289
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
290
|
-
className: "fortune-selection-copy-right fortune-copy"
|
|
291
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
292
|
-
className: "fortune-selection-copy-bottom fortune-copy"
|
|
293
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
294
|
-
className: "fortune-selection-copy-left fortune-copy"
|
|
295
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
296
288
|
className: "fortune-selection-copy-hc"
|
|
297
289
|
}))), context.formulaRangeHighlight.map(function (v) {
|
|
298
290
|
var rangeIndex = v.rangeIndex,
|
|
@@ -302,16 +294,7 @@ var SheetOverlay = function SheetOverlay() {
|
|
|
302
294
|
id: "fortune-formula-functionrange-highlight",
|
|
303
295
|
className: "fortune-selection-highlight fortune-formula-functionrange-highlight",
|
|
304
296
|
style: _.omit(v, "backgroundColor")
|
|
305
|
-
},
|
|
306
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
307
|
-
key: d,
|
|
308
|
-
"data-type": d,
|
|
309
|
-
className: "fortune-selection-copy-".concat(d, " fortune-copy"),
|
|
310
|
-
style: {
|
|
311
|
-
backgroundColor: backgroundColor
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
297
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
315
298
|
className: "fortune-selection-copy-hc",
|
|
316
299
|
style: formulaRangeHighlightHcStyle(backgroundColor)
|
|
317
300
|
}));
|
|
@@ -364,14 +347,6 @@ var SheetOverlay = function SheetOverlay() {
|
|
|
364
347
|
height: row - row_pre - 1
|
|
365
348
|
}
|
|
366
349
|
}, /*#__PURE__*/React.createElement("div", {
|
|
367
|
-
className: "fortune-selection-copy-top fortune-copy"
|
|
368
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
369
|
-
className: "fortune-selection-copy-right fortune-copy"
|
|
370
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
371
|
-
className: "fortune-selection-copy-bottom fortune-copy"
|
|
372
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
373
|
-
className: "fortune-selection-copy-left fortune-copy"
|
|
374
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
375
350
|
className: "fortune-selection-copy-hc"
|
|
376
351
|
}));
|
|
377
352
|
}))), /*#__PURE__*/React.createElement("div", {
|
|
@@ -12,8 +12,9 @@ var ColorPicker = function ColorPicker(_a) {
|
|
|
12
12
|
return /*#__PURE__*/React.createElement("div", {
|
|
13
13
|
key: c,
|
|
14
14
|
className: "fortune-toolbar-color-picker-item",
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
onMouseDown: function onMouseDown(e) {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
onPick(c);
|
|
17
18
|
},
|
|
18
19
|
tabIndex: 0,
|
|
19
20
|
style: {
|
|
@@ -6,11 +6,15 @@ export var CustomColor = function CustomColor(_a) {
|
|
|
6
6
|
var onCustomPick = _a.onCustomPick,
|
|
7
7
|
onColorPick = _a.onColorPick;
|
|
8
8
|
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
-
id: "fortune-custom-color"
|
|
9
|
+
id: "fortune-custom-color",
|
|
10
|
+
onMouseDown: function onMouseDown(e) {
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
}
|
|
10
13
|
}, /*#__PURE__*/React.createElement("div", {
|
|
11
14
|
className: "color-reset",
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
onMouseDown: function onMouseDown(e) {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
onCustomPick(undefined);
|
|
14
18
|
},
|
|
15
19
|
tabIndex: 0
|
|
16
20
|
}, /*#__PURE__*/React.createElement(SVGIcon, {
|
|
@@ -123,7 +123,7 @@ var __spreadArray = this && this.__spreadArray || function (to, from, pack) {
|
|
|
123
123
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
124
124
|
};
|
|
125
125
|
import React, { useContext, useCallback, useRef, useEffect, useState } from "react";
|
|
126
|
-
import { toolbarItemClickHandler, handleTextBackground, handleTextColor, handleTextSize, normalizedCellAttr, getFlowdata, newComment, editComment, deleteComment, showHideComment, showHideAllComments, autoSelectionFormula, handleSum, locale, handleMerge, handleBorder, toolbarItemSelectedFunc, handleFreeze, insertImage, showImgChooser, updateFormat, handleSort, handleHorizontalAlign, handleVerticalAlign, handleScreenShot, createFilter, clearFilter, applyLocation, insertDuneChart, api, getSheetIndex, is_date } from "@fileverse-dev/fortune-core";
|
|
126
|
+
import { toolbarItemClickHandler, handleTextBackground, handleTextColor, handleTextSize, normalizedCellAttr, getFlowdata, newComment, editComment, deleteComment, showHideComment, showHideAllComments, autoSelectionFormula, handleSum, locale, handleMerge, handleBorder, toolbarItemSelectedFunc, handleFreeze, insertImage, showImgChooser, updateFormat, handleSort, handleHorizontalAlign, handleVerticalAlign, handleScreenShot, createFilter, clearFilter, applyLocation, insertDuneChart, getFormulaEditorOwner, api, getSheetIndex, is_date } from "@fileverse-dev/fortune-core";
|
|
127
127
|
import _ from "lodash";
|
|
128
128
|
import { IconButton, LucideIcon, Tooltip, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from "@fileverse/ui";
|
|
129
129
|
import DataVerificationPortal from "./dataVerificationPortal";
|
|
@@ -463,6 +463,14 @@ var Toolbar = function Toolbar(_a) {
|
|
|
463
463
|
settings = _f.settings,
|
|
464
464
|
handleUndo = _f.handleUndo,
|
|
465
465
|
handleRedo = _f.handleRedo;
|
|
466
|
+
var restoreEditorFocusAfterToolbarAction = useCallback(function () {
|
|
467
|
+
if (context.luckysheetCellUpdate.length === 0) return;
|
|
468
|
+
requestAnimationFrame(function () {
|
|
469
|
+
var owner = getFormulaEditorOwner(context);
|
|
470
|
+
var target = owner === "fx" ? refs.fxInput.current : refs.cellInput.current;
|
|
471
|
+
target === null || target === void 0 ? void 0 : target.focus();
|
|
472
|
+
});
|
|
473
|
+
}, [context, refs.cellInput, refs.fxInput]);
|
|
466
474
|
var contextRef = useRef(context);
|
|
467
475
|
var containerRef = useRef(null);
|
|
468
476
|
var _g = useState(-1),
|
|
@@ -1712,7 +1720,8 @@ var Toolbar = function Toolbar(_a) {
|
|
|
1712
1720
|
return /*#__PURE__*/React.createElement("div", {
|
|
1713
1721
|
ref: containerRef,
|
|
1714
1722
|
className: "fortune-toolbar",
|
|
1715
|
-
"aria-label": toolbar.toolbar
|
|
1723
|
+
"aria-label": toolbar.toolbar,
|
|
1724
|
+
onMouseUpCapture: restoreEditorFocusAfterToolbarAction
|
|
1716
1725
|
}, /*#__PURE__*/React.createElement(DataVerificationPortal, {
|
|
1717
1726
|
visible: showDataValidation
|
|
1718
1727
|
}), /*#__PURE__*/React.createElement(ConditionalFormatPortal, {
|
|
@@ -2,22 +2,22 @@ import { type RefObject } from "react";
|
|
|
2
2
|
import { type Context } from "@fileverse-dev/fortune-core";
|
|
3
3
|
import type { SetContextOptions } from "../context";
|
|
4
4
|
export type FormulaHistoryEntry = {
|
|
5
|
-
|
|
5
|
+
html: string;
|
|
6
6
|
caret: number;
|
|
7
|
-
spanValues: string[];
|
|
8
7
|
};
|
|
9
8
|
export type FormulaEditorHistoryPrimary = "cell" | "fx";
|
|
10
9
|
type SetContext = (recipe: (ctx: Context) => void, options?: SetContextOptions) => void;
|
|
11
|
-
export declare function useFormulaEditorHistory(primaryRef: RefObject<HTMLDivElement | null>, cellInputRef: RefObject<HTMLDivElement | null>, fxInputRef: RefObject<HTMLDivElement | null>,
|
|
10
|
+
export declare function useFormulaEditorHistory(primaryRef: RefObject<HTMLDivElement | null>, cellInputRef: RefObject<HTMLDivElement | null>, fxInputRef: RefObject<HTMLDivElement | null>, _setContext: SetContext, primary: FormulaEditorHistoryPrimary): {
|
|
12
11
|
formulaHistoryRef: RefObject<{
|
|
13
12
|
active: boolean;
|
|
14
13
|
entries: FormulaHistoryEntry[];
|
|
15
14
|
index: number;
|
|
16
15
|
}>;
|
|
17
16
|
preTextRef: RefObject<string>;
|
|
18
|
-
preFormulaSpanValuesRef: RefObject<string[] | null>;
|
|
19
17
|
resetFormulaHistory: () => void;
|
|
20
18
|
handleFormulaHistoryUndoRedo: (isRedo: boolean) => boolean;
|
|
19
|
+
capturePreEditorHistoryState: () => void;
|
|
20
|
+
appendEditorHistoryFromPrimaryEditor: (getCaret: () => number) => void;
|
|
21
21
|
capturePreFormulaState: () => void;
|
|
22
22
|
appendFormulaHistoryFromPrimaryEditor: (getCaret: () => number) => void;
|
|
23
23
|
};
|
|
@@ -1,47 +1,54 @@
|
|
|
1
1
|
import { useCallback, useRef } from "react";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { setCursorPosition } from "../components/SheetOverlay/helper";
|
|
2
|
+
import { escapeScriptTag } from "@fileverse-dev/fortune-core";
|
|
3
|
+
import { getCursorPosition, getSelectionOffsets, setSelectionOffsets, setCursorPosition } from "../components/SheetOverlay/helper";
|
|
5
4
|
var MAX_FORMULA_HISTORY = 100;
|
|
6
|
-
|
|
5
|
+
function normalizeEditorHtmlSnapshot(html) {
|
|
6
|
+
var stripped = (html !== null && html !== void 0 ? html : "").replace(/\u200B/g, "").trim();
|
|
7
|
+
if (stripped === "" || stripped === "<br>" || stripped === "<div><br></div>" || stripped === "<div></div>") {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
10
|
+
return html !== null && html !== void 0 ? html : "";
|
|
11
|
+
}
|
|
12
|
+
export function useFormulaEditorHistory(primaryRef, cellInputRef, fxInputRef, _setContext, primary) {
|
|
7
13
|
var preTextRef = useRef("");
|
|
8
|
-
var
|
|
14
|
+
var preHtmlRef = useRef("");
|
|
15
|
+
var preCaretRef = useRef(0);
|
|
16
|
+
var startedFromEmptyRef = useRef(true);
|
|
9
17
|
var formulaHistoryRef = useRef({
|
|
10
18
|
active: false,
|
|
11
19
|
entries: [],
|
|
12
20
|
index: -1
|
|
13
21
|
});
|
|
22
|
+
var isApplyingHistoryRef = useRef(false);
|
|
14
23
|
var resetFormulaHistory = useCallback(function () {
|
|
15
24
|
formulaHistoryRef.current = {
|
|
16
25
|
active: false,
|
|
17
26
|
entries: [],
|
|
18
27
|
index: -1
|
|
19
28
|
};
|
|
20
|
-
|
|
29
|
+
preHtmlRef.current = "";
|
|
30
|
+
preCaretRef.current = 0;
|
|
31
|
+
startedFromEmptyRef.current = true;
|
|
21
32
|
}, []);
|
|
22
33
|
var pushFormulaHistoryEntry = useCallback(function (entry) {
|
|
23
34
|
var history = formulaHistoryRef.current;
|
|
24
35
|
var current = history.entries[history.index];
|
|
25
|
-
if (current && current.
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (current && current.spanValues.length === 0 && entry.spanValues.length === 0 && current.text === entry.text && current.caret === entry.caret) {
|
|
36
|
+
if (current && current.html === entry.html) {
|
|
29
37
|
return;
|
|
30
38
|
}
|
|
31
39
|
var nextEntries = history.entries.slice(0, history.index + 1);
|
|
32
40
|
nextEntries.push(entry);
|
|
33
|
-
if (nextEntries.length > MAX_FORMULA_HISTORY)
|
|
34
|
-
nextEntries.shift();
|
|
35
|
-
}
|
|
41
|
+
if (nextEntries.length > MAX_FORMULA_HISTORY) nextEntries.shift();
|
|
36
42
|
history.entries = nextEntries;
|
|
37
43
|
history.index = nextEntries.length - 1;
|
|
38
44
|
history.active = true;
|
|
39
45
|
}, []);
|
|
40
|
-
var applyFormulaHistoryEntry = useCallback(function (entry) {
|
|
46
|
+
var applyFormulaHistoryEntry = useCallback(function (entry, preserveSelection) {
|
|
47
|
+
var _a, _b, _c;
|
|
41
48
|
var primaryEl = primaryRef.current;
|
|
42
49
|
if (!primaryEl) return;
|
|
43
|
-
|
|
44
|
-
var html =
|
|
50
|
+
isApplyingHistoryRef.current = true;
|
|
51
|
+
var html = escapeScriptTag((_a = entry.html) !== null && _a !== void 0 ? _a : "");
|
|
45
52
|
var cell = cellInputRef.current;
|
|
46
53
|
var fx = fxInputRef.current;
|
|
47
54
|
primaryEl.innerHTML = html;
|
|
@@ -50,70 +57,91 @@ export function useFormulaEditorHistory(primaryRef, cellInputRef, fxInputRef, se
|
|
|
50
57
|
} else if (cell) {
|
|
51
58
|
cell.innerHTML = html;
|
|
52
59
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
var textLen = (_c = (_b = primaryEl.innerText) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
|
|
61
|
+
if (preserveSelection && preserveSelection.end > preserveSelection.start && textLen > 0) {
|
|
62
|
+
var start = Math.max(0, Math.min(preserveSelection.start, textLen));
|
|
63
|
+
var end = Math.max(start, Math.min(preserveSelection.end, textLen));
|
|
64
|
+
setSelectionOffsets(primaryEl, start, end);
|
|
65
|
+
} else {
|
|
66
|
+
setCursorPosition(primaryEl, Math.max(0, textLen));
|
|
67
|
+
}
|
|
68
|
+
requestAnimationFrame(function () {
|
|
69
|
+
requestAnimationFrame(function () {
|
|
70
|
+
setTimeout(function () {
|
|
71
|
+
isApplyingHistoryRef.current = false;
|
|
72
|
+
}, 120);
|
|
73
|
+
});
|
|
62
74
|
});
|
|
63
|
-
}, [cellInputRef, fxInputRef, primary, primaryRef
|
|
75
|
+
}, [cellInputRef, fxInputRef, primary, primaryRef]);
|
|
64
76
|
var handleFormulaHistoryUndoRedo = useCallback(function (isRedo) {
|
|
77
|
+
var _a, _b;
|
|
65
78
|
var history = formulaHistoryRef.current;
|
|
66
79
|
if (!history.active || history.entries.length === 0) return false;
|
|
67
80
|
var nextIndex = isRedo ? history.index + 1 : history.index - 1;
|
|
68
|
-
if (nextIndex < 0 || nextIndex >= history.entries.length)
|
|
81
|
+
if (nextIndex < 0 || nextIndex >= history.entries.length) {
|
|
82
|
+
if (!isRedo && nextIndex < 0 && startedFromEmptyRef.current) {
|
|
83
|
+
var liveHtml = normalizeEditorHtmlSnapshot((_b = (_a = primaryRef.current) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : "");
|
|
84
|
+
if (liveHtml !== "") {
|
|
85
|
+
history.entries[0] = {
|
|
86
|
+
html: "",
|
|
87
|
+
caret: 0
|
|
88
|
+
};
|
|
89
|
+
history.index = 0;
|
|
90
|
+
var currentSelection_1 = primaryRef.current ? getSelectionOffsets(primaryRef.current) : undefined;
|
|
91
|
+
applyFormulaHistoryEntry(history.entries[0], currentSelection_1);
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
69
97
|
history.index = nextIndex;
|
|
70
|
-
|
|
98
|
+
var entry = history.entries[nextIndex];
|
|
99
|
+
var currentSelection = primaryRef.current ? getSelectionOffsets(primaryRef.current) : undefined;
|
|
100
|
+
applyFormulaHistoryEntry(entry, currentSelection);
|
|
71
101
|
return true;
|
|
72
|
-
}, [applyFormulaHistoryEntry]);
|
|
73
|
-
var
|
|
102
|
+
}, [applyFormulaHistoryEntry, primaryRef]);
|
|
103
|
+
var capturePreEditorHistoryState = useCallback(function () {
|
|
104
|
+
var _a;
|
|
74
105
|
var el = primaryRef.current;
|
|
75
106
|
if (!el) return;
|
|
76
107
|
preTextRef.current = el.innerText;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
108
|
+
preHtmlRef.current = el.innerHTML;
|
|
109
|
+
preCaretRef.current = getCursorPosition(el);
|
|
110
|
+
if (!formulaHistoryRef.current.active) {
|
|
111
|
+
startedFromEmptyRef.current = normalizeEditorHtmlSnapshot((_a = preHtmlRef.current) !== null && _a !== void 0 ? _a : "") === "";
|
|
112
|
+
}
|
|
81
113
|
}, [primaryRef]);
|
|
82
|
-
var
|
|
114
|
+
var appendEditorHistoryFromPrimaryEditor = useCallback(function (getCaret) {
|
|
83
115
|
var _a, _b;
|
|
116
|
+
if (isApplyingHistoryRef.current) return;
|
|
84
117
|
var el = primaryRef.current;
|
|
85
118
|
if (!el) return;
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
var seedText = preTextRef.current || "";
|
|
95
|
-
pushFormulaHistoryEntry({
|
|
96
|
-
text: seedText,
|
|
97
|
-
caret: Math.min(caret, seedText.length),
|
|
98
|
-
spanValues: (_b = (_a = preFormulaSpanValuesRef.current) !== null && _a !== void 0 ? _a : spanValues) !== null && _b !== void 0 ? _b : []
|
|
99
|
-
});
|
|
100
|
-
}
|
|
119
|
+
var preHtmlSnapshot = normalizeEditorHtmlSnapshot((_a = preHtmlRef.current) !== null && _a !== void 0 ? _a : "");
|
|
120
|
+
var snapshotHtml = normalizeEditorHtmlSnapshot((_b = el.innerHTML) !== null && _b !== void 0 ? _b : "");
|
|
121
|
+
var caret = getCaret();
|
|
122
|
+
var history = formulaHistoryRef.current;
|
|
123
|
+
var wasInactive = !history.active || history.entries.length === 0;
|
|
124
|
+
if (wasInactive) {
|
|
125
|
+
startedFromEmptyRef.current = preHtmlSnapshot === "";
|
|
126
|
+
var seedHtml = preHtmlSnapshot === snapshotHtml ? "" : preHtmlSnapshot !== null && preHtmlSnapshot !== void 0 ? preHtmlSnapshot : "";
|
|
101
127
|
pushFormulaHistoryEntry({
|
|
102
|
-
|
|
103
|
-
caret:
|
|
104
|
-
spanValues: spanValues
|
|
128
|
+
html: seedHtml,
|
|
129
|
+
caret: preCaretRef.current
|
|
105
130
|
});
|
|
106
|
-
} else if (formulaHistoryRef.current.active) {
|
|
107
|
-
resetFormulaHistory();
|
|
108
131
|
}
|
|
109
|
-
|
|
132
|
+
pushFormulaHistoryEntry({
|
|
133
|
+
html: snapshotHtml,
|
|
134
|
+
caret: caret
|
|
135
|
+
});
|
|
136
|
+
}, [primaryRef, pushFormulaHistoryEntry]);
|
|
110
137
|
return {
|
|
111
138
|
formulaHistoryRef: formulaHistoryRef,
|
|
112
139
|
preTextRef: preTextRef,
|
|
113
|
-
preFormulaSpanValuesRef: preFormulaSpanValuesRef,
|
|
114
140
|
resetFormulaHistory: resetFormulaHistory,
|
|
115
141
|
handleFormulaHistoryUndoRedo: handleFormulaHistoryUndoRedo,
|
|
116
|
-
|
|
117
|
-
|
|
142
|
+
capturePreEditorHistoryState: capturePreEditorHistoryState,
|
|
143
|
+
appendEditorHistoryFromPrimaryEditor: appendEditorHistoryFromPrimaryEditor,
|
|
144
|
+
capturePreFormulaState: capturePreEditorHistoryState,
|
|
145
|
+
appendFormulaHistoryFromPrimaryEditor: appendEditorHistoryFromPrimaryEditor
|
|
118
146
|
};
|
|
119
147
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type RefObject } from "react";
|
|
2
|
-
export declare function useRerenderOnFormulaCaret(editorRef: RefObject<HTMLDivElement | null>, editSessionActive: boolean): void;
|
|
2
|
+
export declare function useRerenderOnFormulaCaret(editorRef: RefObject<HTMLDivElement | null>, editSessionActive: boolean, onAfterCaretMove?: () => void): void;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
export function useRerenderOnFormulaCaret(editorRef, editSessionActive) {
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
export function useRerenderOnFormulaCaret(editorRef, editSessionActive, onAfterCaretMove) {
|
|
3
3
|
var _a = useState(0),
|
|
4
4
|
bump = _a[1];
|
|
5
|
+
var onAfterCaretMoveRef = useRef(onAfterCaretMove);
|
|
6
|
+
onAfterCaretMoveRef.current = onAfterCaretMove;
|
|
5
7
|
useEffect(function () {
|
|
6
8
|
if (!editSessionActive) {
|
|
7
9
|
return function () {};
|
|
8
10
|
}
|
|
9
11
|
var onSelectionChange = function onSelectionChange() {
|
|
10
|
-
var _a, _b;
|
|
12
|
+
var _a, _b, _c;
|
|
11
13
|
var el = editorRef.current;
|
|
12
14
|
if (!el) return;
|
|
13
15
|
var text = (_b = (_a = el.innerText) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
|
|
@@ -19,6 +21,7 @@ export function useRerenderOnFormulaCaret(editorRef, editSessionActive) {
|
|
|
19
21
|
bump(function (n) {
|
|
20
22
|
return n + 1;
|
|
21
23
|
});
|
|
24
|
+
(_c = onAfterCaretMoveRef.current) === null || _c === void 0 ? void 0 : _c.call(onAfterCaretMoveRef);
|
|
22
25
|
};
|
|
23
26
|
document.addEventListener("selectionchange", onSelectionChange);
|
|
24
27
|
return function () {
|