@univerjs/sheets-formula-ui 1.0.0-alpha.2 → 1.0.0-alpha.3

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/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { AbsoluteRefType, BuildTextUtils, CellValueType, ColorKit, CommandType, DEFAULT_EMPTY_DOCUMENT_VALUE, DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DependentOn, Direction, Disposable, DisposableCollection, DocumentFlavor, EDITOR_ACTIVATED, HorizontalAlign, ICommandService, IConfigService, IContextService, ILogService, IUniverInstanceService, Inject, Injector, InterceptorEffectEnum, LocaleService, ObjectMatrix, Plugin, RANGE_TYPE, Range, Rectangle, RichTextBuilder, RxDisposable, ThemeService, Tools, UniverInstanceType, VerticalAlign, createIdentifier, createInternalEditorID, generateRandomId, getBodySlice, getCellValueType, getEmptyCell, isFormulaId, isFormulaString, isICellData, isRealNum, merge, noop, registerDependencies, toDisposable, touchDependencies } from "@univerjs/core";
2
- import { BaseSelectionRenderService, COPY_SPECIAL_MENU_ID, COPY_TYPE, CellAlertManagerService, CellAlertType, EMBEDDING_FORMULA_EDITOR, EMBEDDING_FORMULA_EDITOR_COMPONENT_KEY, ExpandSelectionCommand, HoverManagerService, IEditorBridgeService, IMarkSelectionService, ISheetClipboardService, JumpOver, MoveSelectionCommand, PASTE_SPECIAL_MENU_ID, PREDEFINED_HOOK_NAME_COPY, PREDEFINED_HOOK_NAME_PASTE, RANGE_SELECTOR_COMPONENT_KEY, SELECTION_SHAPE_DEPTH, SelectionControl, SetCellEditVisibleOperation, SheetPasteCommand, SheetSkeletonManagerService, SheetsUIPart, checkInHeaderRanges, genNormalSelectionStyle, getAllSelection, getCoordByOffset, getCurrentRangeDisable$, getSheetObject, menuClipboardDisabledObservable, useActiveWorkbook, whenSheetEditorActivated, whenSheetEditorFocused } from "@univerjs/sheets-ui";
1
+ import { AbsoluteRefType, BuildTextUtils, CellValueType, ColorKit, CommandType, DEFAULT_EMPTY_DOCUMENT_VALUE, DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DependentOn, Direction, Disposable, DisposableCollection, DocumentFlavor, EDITOR_ACTIVATED, FOCUSING_FX_BAR_EDITOR, HorizontalAlign, ICommandService, IConfigService, IContextService, ILogService, IUniverInstanceService, Inject, Injector, InterceptorEffectEnum, LocaleService, ObjectMatrix, Plugin, RANGE_TYPE, Range, Rectangle, RichTextBuilder, RxDisposable, ThemeService, Tools, UniverInstanceType, VerticalAlign, createIdentifier, createInternalEditorID, generateRandomId, getCellValueType, getEmptyCell, isFormulaId, isFormulaString, isICellData, isRealNum, merge, noop, registerDependencies, toDisposable, touchDependencies } from "@univerjs/core";
2
+ import { BaseSelectionRenderService, COPY_SPECIAL_MENU_ID, COPY_TYPE, CellAlertManagerService, CellAlertType, EMBEDDING_FORMULA_EDITOR, EMBEDDING_FORMULA_EDITOR_COMPONENT_KEY, ExpandSelectionCommand, HoverManagerService, IEditorBridgeService, IMarkSelectionService, ISheetClipboardService, ISheetSelectionRenderService, JumpOver, MoveSelectionCommand, PASTE_SPECIAL_MENU_ID, PREDEFINED_HOOK_NAME_COPY, PREDEFINED_HOOK_NAME_PASTE, RANGE_SELECTOR_COMPONENT_KEY, SELECTION_SHAPE_DEPTH, SelectionControl, SetCellEditVisibleOperation, SheetPasteCommand, SheetSkeletonManagerService, SheetsUIPart, checkInHeaderRanges, genNormalSelectionStyle, getAllSelection, getCoordByOffset, getCurrentRangeDisable$, getSheetObject, menuClipboardDisabledObservable, useActiveWorkbook, whenSheetEditorActivated, whenSheetEditorFocused } from "@univerjs/sheets-ui";
3
3
  import { ErrorType, FormulaDataModel, FunctionType, LexerTreeBuilder, SetArrayFormulaDataMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStopMutation, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, generateStringWithSequence, getAbsoluteRefTypeWithSingleString, handleRefStringInfo, isFormulaLexerToken, matchRefDrawToken, matchToken, operatorToken, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet } from "@univerjs/engine-formula";
4
4
  import { BehaviorSubject, Subject, combineLatestWith, debounceTime, distinctUntilChanged, filter, map, merge as merge$1, throttleTime } from "rxjs";
5
5
  import { DocBackScrollRenderController, DocSelectionRenderService, IEditorService, MoveCursorOperation, MoveSelectionOperation, ReplaceTextRunsCommand, RichTextEditor, createEditorUndoRedoKeyboardConfig, useKeyboardEvent, useResize } from "@univerjs/docs-ui";
@@ -777,10 +777,231 @@ FormulaReorderController = __decorate([
777
777
  __decorateParam(3, Inject(LexerTreeBuilder))
778
778
  ], FormulaReorderController);
779
779
 
780
+ //#endregion
781
+ //#region src/menu/menu.ts
782
+ function InsertCommonFunctionMenuItemFactory(accessor) {
783
+ const commonFunctions = [
784
+ "SUMIF",
785
+ "SUM",
786
+ "AVERAGE",
787
+ "IF",
788
+ "COUNT",
789
+ "SIN",
790
+ "MAX"
791
+ ];
792
+ let selections = commonFunctions.map((name) => ({
793
+ label: {
794
+ name,
795
+ selectable: false
796
+ },
797
+ value: name
798
+ }));
799
+ try {
800
+ const descriptionService = accessor.get(IDescriptionService);
801
+ const filtered = commonFunctions.filter((name) => Boolean(descriptionService.getFunctionInfo(name)));
802
+ if (filtered.length > 0) selections = filtered.map((name) => ({
803
+ label: {
804
+ name,
805
+ selectable: false
806
+ },
807
+ value: name
808
+ }));
809
+ } catch {}
810
+ return {
811
+ id: `${InsertFunctionOperation.id}.common`,
812
+ commandId: InsertFunctionOperation.id,
813
+ title: "sheets-formula-ui.insert.common",
814
+ tooltip: "sheets-formula-ui.insert.tooltip",
815
+ icon: "FunctionIcon",
816
+ type: MenuItemType.SELECTOR,
817
+ selections,
818
+ hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
819
+ };
820
+ }
821
+ function createInsertFunctionCategoryMenuItemFactory(functionType, categoryKey, icon) {
822
+ return function insertFunctionCategoryMenuItemFactory(accessor) {
823
+ let selections = [];
824
+ try {
825
+ selections = accessor.get(IDescriptionService).getSearchListByType(functionType).map(({ name }) => ({
826
+ label: {
827
+ name,
828
+ selectable: false
829
+ },
830
+ value: name
831
+ }));
832
+ } catch {
833
+ selections = [];
834
+ }
835
+ return {
836
+ id: `${InsertFunctionOperation.id}.${categoryKey}`,
837
+ commandId: InsertFunctionOperation.id,
838
+ title: `sheets-formula-ui.functionType.${categoryKey}`,
839
+ tooltip: "sheets-formula-ui.insert.tooltip",
840
+ icon,
841
+ type: MenuItemType.SELECTOR,
842
+ selections,
843
+ hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
844
+ };
845
+ };
846
+ }
847
+ const InsertFinancialFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Financial, "financial");
848
+ const InsertLogicalFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Logical, "logical");
849
+ const InsertTextFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Text, "text");
850
+ const InsertDateFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Date, "date");
851
+ const InsertLookupFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Lookup, "lookup");
852
+ const InsertMathFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Math, "math");
853
+ const InsertStatisticalFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Statistical, "statistical");
854
+ const InsertEngineeringFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Engineering, "engineering");
855
+ const InsertInformationFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Information, "information");
856
+ const InsertDatabaseFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Database, "database");
857
+ function AllFunctionsMenuItemFactory(accessor) {
858
+ return {
859
+ id: MoreFunctionsOperation.id,
860
+ title: "sheets-formula-ui.moreFunctions.allFunctions",
861
+ tooltip: "sheets-formula-ui.insert.tooltip",
862
+ type: MenuItemType.BUTTON,
863
+ hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET),
864
+ disabled$: getCurrentRangeDisable$(accessor, {
865
+ workbookTypes: [WorkbookEditablePermission],
866
+ worksheetTypes: [WorksheetEditPermission, WorksheetSetCellValuePermission],
867
+ rangeTypes: [RangeProtectionPermissionEditPoint]
868
+ })
869
+ };
870
+ }
871
+ function CopyFormulaOnlyMenuItemFactory(accessor) {
872
+ return {
873
+ id: SheetCopyFormulaOnlyCommand.id,
874
+ type: MenuItemType.BUTTON,
875
+ title: "sheets-formula-ui.operation.copyFormulaOnly",
876
+ disabled$: getCurrentRangeDisable$(accessor, {
877
+ workbookTypes: [WorkbookCopyPermission],
878
+ worksheetTypes: [WorksheetCopyPermission],
879
+ rangeTypes: [RangeProtectionPermissionViewPoint]
880
+ }),
881
+ hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
882
+ };
883
+ }
884
+ function PasteFormulaMenuItemFactory(accessor) {
885
+ return {
886
+ id: SheetOnlyPasteFormulaCommand.id,
887
+ type: MenuItemType.BUTTON,
888
+ title: "sheets-formula-ui.operation.pasteFormula",
889
+ disabled$: menuClipboardDisabledObservable(accessor).pipe(combineLatestWith(getCurrentRangeDisable$(accessor, {
890
+ workbookTypes: [WorkbookEditablePermission],
891
+ rangeTypes: [RangeProtectionPermissionEditPoint],
892
+ worksheetTypes: [WorksheetSetCellValuePermission, WorksheetEditPermission]
893
+ })), map(([d1, d2]) => d1 || d2)),
894
+ hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
895
+ };
896
+ }
897
+
898
+ //#endregion
899
+ //#region src/menu/schema.ts
900
+ const menuSchema = {
901
+ [RibbonFormulasGroup.BASIC]: {
902
+ [`${InsertFunctionOperation.id}.common`]: {
903
+ order: 0,
904
+ menuItemFactory: InsertCommonFunctionMenuItemFactory,
905
+ [MoreFunctionsOperation.id]: {
906
+ order: 0,
907
+ menuItemFactory: AllFunctionsMenuItemFactory
908
+ }
909
+ },
910
+ [`${InsertFunctionOperation.id}.financial`]: {
911
+ order: 1,
912
+ menuItemFactory: InsertFinancialFunctionMenuItemFactory,
913
+ [MoreFunctionsOperation.id]: {
914
+ order: 0,
915
+ menuItemFactory: AllFunctionsMenuItemFactory
916
+ }
917
+ },
918
+ [`${InsertFunctionOperation.id}.logical`]: {
919
+ order: 2,
920
+ menuItemFactory: InsertLogicalFunctionMenuItemFactory,
921
+ [MoreFunctionsOperation.id]: {
922
+ order: 0,
923
+ menuItemFactory: AllFunctionsMenuItemFactory
924
+ }
925
+ },
926
+ [`${InsertFunctionOperation.id}.text`]: {
927
+ order: 3,
928
+ menuItemFactory: InsertTextFunctionMenuItemFactory,
929
+ [MoreFunctionsOperation.id]: {
930
+ order: 0,
931
+ menuItemFactory: AllFunctionsMenuItemFactory
932
+ }
933
+ },
934
+ [`${InsertFunctionOperation.id}.date`]: {
935
+ order: 4,
936
+ menuItemFactory: InsertDateFunctionMenuItemFactory,
937
+ [MoreFunctionsOperation.id]: {
938
+ order: 0,
939
+ menuItemFactory: AllFunctionsMenuItemFactory
940
+ }
941
+ },
942
+ [`${InsertFunctionOperation.id}.lookup`]: {
943
+ order: 5,
944
+ menuItemFactory: InsertLookupFunctionMenuItemFactory,
945
+ [MoreFunctionsOperation.id]: {
946
+ order: 0,
947
+ menuItemFactory: AllFunctionsMenuItemFactory
948
+ }
949
+ },
950
+ [`${InsertFunctionOperation.id}.math`]: {
951
+ order: 6,
952
+ menuItemFactory: InsertMathFunctionMenuItemFactory,
953
+ [MoreFunctionsOperation.id]: {
954
+ order: 0,
955
+ menuItemFactory: AllFunctionsMenuItemFactory
956
+ }
957
+ },
958
+ [`${InsertFunctionOperation.id}.statistical`]: {
959
+ order: 7,
960
+ menuItemFactory: InsertStatisticalFunctionMenuItemFactory,
961
+ [MoreFunctionsOperation.id]: {
962
+ order: 0,
963
+ menuItemFactory: AllFunctionsMenuItemFactory
964
+ }
965
+ },
966
+ [`${InsertFunctionOperation.id}.engineering`]: {
967
+ order: 8,
968
+ menuItemFactory: InsertEngineeringFunctionMenuItemFactory,
969
+ [MoreFunctionsOperation.id]: {
970
+ order: 0,
971
+ menuItemFactory: AllFunctionsMenuItemFactory
972
+ }
973
+ },
974
+ [`${InsertFunctionOperation.id}.information`]: {
975
+ order: 9,
976
+ menuItemFactory: InsertInformationFunctionMenuItemFactory,
977
+ [MoreFunctionsOperation.id]: {
978
+ order: 0,
979
+ menuItemFactory: AllFunctionsMenuItemFactory
980
+ }
981
+ },
982
+ [`${InsertFunctionOperation.id}.database`]: {
983
+ order: 10,
984
+ menuItemFactory: InsertDatabaseFunctionMenuItemFactory,
985
+ [MoreFunctionsOperation.id]: {
986
+ order: 0,
987
+ menuItemFactory: AllFunctionsMenuItemFactory
988
+ }
989
+ }
990
+ },
991
+ [COPY_SPECIAL_MENU_ID]: { [SheetCopyFormulaOnlyCommand.id]: {
992
+ order: 0,
993
+ menuItemFactory: CopyFormulaOnlyMenuItemFactory
994
+ } },
995
+ [PASTE_SPECIAL_MENU_ID]: { [SheetOnlyPasteFormulaCommand.id]: {
996
+ order: 4,
997
+ menuItemFactory: PasteFormulaMenuItemFactory
998
+ } }
999
+ };
1000
+
780
1001
  //#endregion
781
1002
  //#region package.json
782
1003
  var name = "@univerjs/sheets-formula-ui";
783
- var version = "1.0.0-alpha.2";
1004
+ var version = "1.0.0-alpha.3";
784
1005
 
785
1006
  //#endregion
786
1007
  //#region src/config/config.ts
@@ -825,6 +1046,112 @@ const findRefSequenceIndex = (sequenceNode, targetIndex) => {
825
1046
  return result;
826
1047
  };
827
1048
 
1049
+ //#endregion
1050
+ //#region src/views/formula-editor/formula-embed-integration.service.ts
1051
+ const FORMULA_EMBED_INTERACTION_BOUNDARY_OWNER_ATTRIBUTE = "data-embed-interaction-boundary-owner";
1052
+ const FORMULA_EMBED_ID_ATTRIBUTE = "data-embed-id";
1053
+ const FORMULA_EMBED_HOST_UNIT_ID_ATTRIBUTE = "data-embed-host-unit-id";
1054
+ const FORMULA_EMBED_CHILD_UNIT_ID_ATTRIBUTE = "data-embed-child-unit-id";
1055
+ const IFormulaEmbedRuntimeFocusCoordinator = createIdentifier("sheets-formula-ui.embed-runtime-focus-coordinator");
1056
+ const IFormulaEmbedInteractionBoundaryService = createIdentifier("sheets-formula-ui.embed-interaction-boundary.service");
1057
+ function registerFormulaEditorRuntimePortal(options) {
1058
+ var _options$ownerDocumen;
1059
+ const ownerDocument = (_options$ownerDocumen = options.ownerDocument) !== null && _options$ownerDocumen !== void 0 ? _options$ownerDocumen : typeof document === "undefined" ? void 0 : document;
1060
+ if (!ownerDocument) return toDisposable(() => {});
1061
+ const collection = new DisposableCollection();
1062
+ const view = ownerDocument.defaultView;
1063
+ const frameHandles = [];
1064
+ let observer;
1065
+ let portalRegistration;
1066
+ let registeredPortalRoot = null;
1067
+ let disposed = false;
1068
+ const tryRegister = () => {
1069
+ if (disposed) return;
1070
+ const portalRoot = resolveFormulaEditorPortalRoot(options.editorId, ownerDocument);
1071
+ if (portalRoot === registeredPortalRoot) return;
1072
+ portalRegistration === null || portalRegistration === void 0 || portalRegistration.dispose();
1073
+ portalRegistration = void 0;
1074
+ registeredPortalRoot = null;
1075
+ if (!portalRoot) return;
1076
+ registeredPortalRoot = portalRoot;
1077
+ portalRegistration = registerFormulaEditorPortalRoot(options, ownerDocument, portalRoot);
1078
+ };
1079
+ const scheduleRetry = (remaining) => {
1080
+ if (remaining <= 0 || !(view === null || view === void 0 ? void 0 : view.requestAnimationFrame)) return;
1081
+ const handle = view.requestAnimationFrame(() => {
1082
+ const index = frameHandles.indexOf(handle);
1083
+ if (index >= 0) frameHandles.splice(index, 1);
1084
+ tryRegister();
1085
+ if (!registeredPortalRoot) scheduleRetry(remaining - 1);
1086
+ });
1087
+ frameHandles.push(handle);
1088
+ };
1089
+ tryRegister();
1090
+ if (!registeredPortalRoot) scheduleRetry(2);
1091
+ if ((view === null || view === void 0 ? void 0 : view.MutationObserver) && ownerDocument.body) {
1092
+ observer = new view.MutationObserver(() => tryRegister());
1093
+ observer.observe(ownerDocument.body, {
1094
+ childList: true,
1095
+ subtree: true
1096
+ });
1097
+ }
1098
+ collection.add(toDisposable(() => {
1099
+ disposed = true;
1100
+ frameHandles.forEach((handle) => {
1101
+ var _view$cancelAnimation;
1102
+ return view === null || view === void 0 || (_view$cancelAnimation = view.cancelAnimationFrame) === null || _view$cancelAnimation === void 0 ? void 0 : _view$cancelAnimation.call(view, handle);
1103
+ });
1104
+ frameHandles.length = 0;
1105
+ observer === null || observer === void 0 || observer.disconnect();
1106
+ observer = void 0;
1107
+ portalRegistration === null || portalRegistration === void 0 || portalRegistration.dispose();
1108
+ portalRegistration = void 0;
1109
+ registeredPortalRoot = null;
1110
+ }));
1111
+ return collection;
1112
+ }
1113
+ function resolveFormulaEditorPortalRoot(editorId, ownerDocument) {
1114
+ var _ref;
1115
+ return (_ref = ownerDocument.getElementById(`univer-doc-selection-container-${editorId}`)) !== null && _ref !== void 0 ? _ref : ownerDocument.getElementById(`__editor_${editorId}`);
1116
+ }
1117
+ function registerFormulaEditorPortalRoot(options, ownerDocument, portalRoot) {
1118
+ const collection = new DisposableCollection();
1119
+ const editorElement = ownerDocument.getElementById(`__editor_${options.editorId}`);
1120
+ (editorElement && editorElement !== portalRoot ? [portalRoot, editorElement] : [portalRoot]).forEach((element) => {
1121
+ if (options.interactionBoundaryService) collection.add(options.interactionBoundaryService.registerOwnedElement(options.embedId, element));
1122
+ if (options.focusCoordinator) collection.add(options.focusCoordinator.registerElement({
1123
+ embedId: options.embedId,
1124
+ role: "child-editor",
1125
+ element
1126
+ }));
1127
+ });
1128
+ return collection;
1129
+ }
1130
+ function resolveFormulaEmbedRuntimeDomScope(root) {
1131
+ var _scopeElement$getAttr, _scopeElement$getAttr2;
1132
+ const scopeElement = root === null || root === void 0 ? void 0 : root.closest(`[${FORMULA_EMBED_ID_ATTRIBUTE}]`);
1133
+ const embedId = scopeElement === null || scopeElement === void 0 ? void 0 : scopeElement.getAttribute(FORMULA_EMBED_ID_ATTRIBUTE);
1134
+ if (!scopeElement || !embedId) return;
1135
+ return {
1136
+ embedId,
1137
+ hostUnitId: (_scopeElement$getAttr = scopeElement.getAttribute("data-embed-host-unit-id")) !== null && _scopeElement$getAttr !== void 0 ? _scopeElement$getAttr : void 0,
1138
+ childUnitId: (_scopeElement$getAttr2 = scopeElement.getAttribute("data-embed-child-unit-id")) !== null && _scopeElement$getAttr2 !== void 0 ? _scopeElement$getAttr2 : void 0
1139
+ };
1140
+ }
1141
+ function resolveActiveFormulaEmbedRuntimeDomScope(ownerDocument) {
1142
+ const activeElement = ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.activeElement;
1143
+ return activeElement instanceof HTMLElement ? resolveFormulaEmbedRuntimeDomScope(activeElement) : void 0;
1144
+ }
1145
+ function isEventTargetInSameFormulaEmbedInteractionBoundary(left, right) {
1146
+ const leftOwner = resolveFormulaEmbedInteractionOwnerId(left);
1147
+ return Boolean(leftOwner && leftOwner === resolveFormulaEmbedInteractionOwnerId(right));
1148
+ }
1149
+ function resolveFormulaEmbedInteractionOwnerId(target) {
1150
+ var _target$closest$getAt, _target$closest;
1151
+ if (!(target instanceof Element)) return;
1152
+ return (_target$closest$getAt = (_target$closest = target.closest(`[${"data-embed-interaction-boundary-owner"}]`)) === null || _target$closest === void 0 ? void 0 : _target$closest.getAttribute("data-embed-interaction-boundary-owner")) !== null && _target$closest$getAt !== void 0 ? _target$closest$getAt : void 0;
1153
+ }
1154
+
828
1155
  //#endregion
829
1156
  //#region src/services/utils.ts
830
1157
  function getFunctionTypeValues(localeService, customFormula) {
@@ -1064,16 +1391,19 @@ const HelpHiddenTip = ({ onClick }) => {
1064
1391
 
1065
1392
  //#endregion
1066
1393
  //#region src/views/formula-editor/help-function/HelpFunction.tsx
1067
- const Params = ({ className, title, value }) => /* @__PURE__ */ jsxs("div", {
1068
- className: "univer-my-2",
1069
- children: [/* @__PURE__ */ jsx("div", {
1070
- className: clsx("univer-mb-2 univer-text-sm univer-font-medium univer-text-gray-900 dark:!univer-text-white", className),
1071
- children: title
1072
- }), /* @__PURE__ */ jsx("div", {
1073
- className: "univer-whitespace-pre-wrap univer-break-words univer-text-xs univer-text-gray-500",
1074
- children: value
1075
- })]
1076
- });
1394
+ const Params = ({ className, title, titleKey, value }) => {
1395
+ const localeService = useDependency(LocaleService);
1396
+ return /* @__PURE__ */ jsxs("div", {
1397
+ className: "univer-my-2",
1398
+ children: [/* @__PURE__ */ jsx("div", {
1399
+ className: clsx("univer-mb-2 univer-text-sm univer-font-medium univer-text-gray-900 dark:!univer-text-white", className),
1400
+ children: titleKey ? localeService.t(titleKey) : title
1401
+ }), /* @__PURE__ */ jsx("div", {
1402
+ className: "univer-whitespace-pre-wrap univer-break-words univer-text-xs univer-text-gray-500",
1403
+ children: value
1404
+ })]
1405
+ });
1406
+ };
1077
1407
  const Help = (props) => {
1078
1408
  const { prefix, value, active, onClick } = props;
1079
1409
  return /* @__PURE__ */ jsxs("div", { children: [
@@ -1149,11 +1479,11 @@ function HelpFunction(props) {
1149
1479
  className: "univer-mt-3",
1150
1480
  children: [
1151
1481
  /* @__PURE__ */ jsx(Params, {
1152
- title: localeService.t("sheets-formula-ui.prompt.helpExample"),
1482
+ titleKey: "sheets-formula-ui.prompt.helpExample",
1153
1483
  value: `${functionInfo.functionName}(${functionInfo.functionParameter.map((item) => item.example).join(",")})`
1154
1484
  }),
1155
1485
  /* @__PURE__ */ jsx(Params, {
1156
- title: localeService.t("sheets-formula-ui.prompt.helpAbstract"),
1486
+ titleKey: "sheets-formula-ui.prompt.helpAbstract",
1157
1487
  value: functionInfo.description
1158
1488
  }),
1159
1489
  functionInfo && functionInfo.functionParameter && functionInfo.functionParameter.map((item, i) => /* @__PURE__ */ jsx(Params, {
@@ -1170,26 +1500,47 @@ function HelpFunction(props) {
1170
1500
 
1171
1501
  //#endregion
1172
1502
  //#region src/views/formula-editor/hooks/use-focus.ts
1503
+ function focusFormulaEditor(editorService, editor, offset) {
1504
+ if (!editor) return;
1505
+ editorService.focus(editor.getEditorId());
1506
+ focusFormulaEditorElement(editor);
1507
+ if (editor.docSelectionRenderService.isOnPointerEvent) return;
1508
+ const selections = [...editor.getSelectionRanges()];
1509
+ if (Tools.isDefine(offset)) editor.setSelectionRanges([{
1510
+ startOffset: offset,
1511
+ endOffset: offset
1512
+ }]);
1513
+ else if (!selections.length) {
1514
+ var _editor$getDocumentDa, _editor$getDocumentDa2;
1515
+ const body = (_editor$getDocumentDa = (_editor$getDocumentDa2 = editor.getDocumentData().body) === null || _editor$getDocumentDa2 === void 0 ? void 0 : _editor$getDocumentDa2.dataStream) !== null && _editor$getDocumentDa !== void 0 ? _editor$getDocumentDa : "\r\n";
1516
+ const offset = Math.max(body.length - 2, 0);
1517
+ editor.setSelectionRanges([{
1518
+ startOffset: offset,
1519
+ endOffset: offset
1520
+ }]);
1521
+ } else editor.setSelectionRanges(selections);
1522
+ }
1523
+ function focusFormulaEditorElement(editor) {
1524
+ var _editor$editorDOM$own, _editor$editorDOM;
1525
+ const editorElement = ((_editor$editorDOM$own = (_editor$editorDOM = editor.editorDOM) === null || _editor$editorDOM === void 0 ? void 0 : _editor$editorDOM.ownerDocument) !== null && _editor$editorDOM$own !== void 0 ? _editor$editorDOM$own : document).getElementById(`__editor_${editor.getEditorId()}`);
1526
+ editorElement === null || editorElement === void 0 || editorElement.focus({ preventScroll: true });
1527
+ }
1528
+ function shouldSkipFormulaEditorMouseUpFocus(_target) {
1529
+ return false;
1530
+ }
1531
+ function shouldRefocusFormulaEditorOnMouseUp(options) {
1532
+ if (shouldSkipFormulaEditorMouseUpFocus(options.target)) return false;
1533
+ if (options.isPointerSelecting || options.isFocusing) return false;
1534
+ return true;
1535
+ }
1536
+ function hasActiveFormulaEmbedInteraction(scopeElement) {
1537
+ const ownerDocument = scopeElement === null || scopeElement === void 0 ? void 0 : scopeElement.ownerDocument;
1538
+ return isEventTargetInSameFormulaEmbedInteractionBoundary(scopeElement, ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.activeElement);
1539
+ }
1173
1540
  const useFocus = (editor) => {
1174
1541
  const editorService = useDependency(IEditorService);
1175
1542
  return useEvent((offset) => {
1176
- if (editor) {
1177
- editorService.focus(editor.getEditorId());
1178
- const selections = [...editor.getSelectionRanges()];
1179
- if (Tools.isDefine(offset)) editor.setSelectionRanges([{
1180
- startOffset: offset,
1181
- endOffset: offset
1182
- }]);
1183
- else if (!selections.length && !editor.docSelectionRenderService.isOnPointerEvent) {
1184
- var _editor$getDocumentDa, _editor$getDocumentDa2;
1185
- const body = (_editor$getDocumentDa = (_editor$getDocumentDa2 = editor.getDocumentData().body) === null || _editor$getDocumentDa2 === void 0 ? void 0 : _editor$getDocumentDa2.dataStream) !== null && _editor$getDocumentDa !== void 0 ? _editor$getDocumentDa : "\r\n";
1186
- const offset = Math.max(body.length - 2, 0);
1187
- editor.setSelectionRanges([{
1188
- startOffset: offset,
1189
- endOffset: offset
1190
- }]);
1191
- } else editor.setSelectionRanges(selections);
1192
- }
1543
+ focusFormulaEditor(editorService, editor, offset);
1193
1544
  });
1194
1545
  };
1195
1546
 
@@ -1538,9 +1889,16 @@ function getDefaultRefSelectionStyle(themeService) {
1538
1889
 
1539
1890
  //#endregion
1540
1891
  //#region src/views/formula-editor/hooks/use-formula-selection.ts
1541
- function getCurrentBodyDataStreamAndOffset(accssor) {
1542
- var _documentModel$getBod, _documentModel$getBod2;
1543
- const documentModel = accssor.get(IUniverInstanceService).getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
1892
+ function resolveFormulaSelectionDataStream(accssor, editor, editorId) {
1893
+ var _editor$getDocumentDa, _documentModel$getBod, _documentModel$getBod2;
1894
+ const editorDataStream = editor === null || editor === void 0 || (_editor$getDocumentDa = editor.getDocumentData().body) === null || _editor$getDocumentDa === void 0 ? void 0 : _editor$getDocumentDa.dataStream;
1895
+ if (editorDataStream != null) return {
1896
+ dataStream: editorDataStream,
1897
+ offset: 0
1898
+ };
1899
+ const univerInstanceService = accssor.get(IUniverInstanceService);
1900
+ const editorDocumentModel = editorId ? univerInstanceService.getUnit(editorId, UniverInstanceType.UNIVER_DOC) : void 0;
1901
+ const documentModel = editorDocumentModel !== null && editorDocumentModel !== void 0 ? editorDocumentModel : univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
1544
1902
  if (!(documentModel === null || documentModel === void 0 ? void 0 : documentModel.getBody())) return;
1545
1903
  return {
1546
1904
  dataStream: (_documentModel$getBod = (_documentModel$getBod2 = documentModel.getBody()) === null || _documentModel$getBod2 === void 0 ? void 0 : _documentModel$getBod2.dataStream) !== null && _documentModel$getBod !== void 0 ? _documentModel$getBod : "",
@@ -1550,9 +1908,36 @@ function getCurrentBodyDataStreamAndOffset(accssor) {
1550
1908
  function shouldSkipReferenceEditingByPointer(isDisabledByPointer, disableOnClick) {
1551
1909
  return isDisabledByPointer && !disableOnClick;
1552
1910
  }
1911
+ function resolveFormulaSelectionWorkbook(currentWorkbook, fallbackWorkbook) {
1912
+ var _ref;
1913
+ return (_ref = currentWorkbook !== null && currentWorkbook !== void 0 ? currentWorkbook : fallbackWorkbook) !== null && _ref !== void 0 ? _ref : void 0;
1914
+ }
1915
+ function resolveFormulaSelectionCursorIndex(activeRange, dataStream) {
1916
+ const index = (activeRange === null || activeRange === void 0 ? void 0 : activeRange.collapsed) ? activeRange.startOffset : -1;
1917
+ if (index <= 0 && dataStream.startsWith("=") && dataStream.length > 0) return dataStream.length;
1918
+ return index;
1919
+ }
1920
+ function getSelectionAfterLaggingFormulaInput(dataStream, selection, content) {
1921
+ if (!content || content.includes("\r") || content.includes("\n") || !dataStream.startsWith("=") || !(selection === null || selection === void 0 ? void 0 : selection.collapsed)) return;
1922
+ const startOffset = selection.startOffset;
1923
+ if (startOffset == null) return;
1924
+ if (selection.endOffset !== startOffset) return;
1925
+ if (dataStream.slice(startOffset, startOffset + content.length) !== content) return;
1926
+ const nextOffset = startOffset + content.length;
1927
+ return {
1928
+ startOffset: nextOffset,
1929
+ endOffset: nextOffset,
1930
+ collapsed: true
1931
+ };
1932
+ }
1933
+ function resolveFormulaSelectingIntent(adding, editing) {
1934
+ if (adding) return 1;
1935
+ if (editing) return 2;
1936
+ return 0;
1937
+ }
1553
1938
  function useFormulaSelecting(opts) {
1554
1939
  var _renderer$mainCompone2;
1555
- const { editorId, isFocus, disableOnClick, unitId, subUnitId } = opts;
1940
+ const { editor, editorId, isFocus, disableOnClick, unitId, subUnitId } = opts;
1556
1941
  const renderManagerService = useDependency(IRenderManagerService);
1557
1942
  const univerInstanceService = useDependency(IUniverInstanceService);
1558
1943
  const sheetRenderer = renderManagerService.getRenderById(unitId);
@@ -1563,6 +1948,7 @@ function useFormulaSelecting(opts) {
1563
1948
  const [isSelecting, innerSetIsSelecting] = useState(0);
1564
1949
  const lexerTreeBuilder = useDependency(LexerTreeBuilder);
1565
1950
  const isDisabledByPointer = useRef(true);
1951
+ const lastInputContentRef = useRef("");
1566
1952
  const refSelectionsRenderService = sheetRenderer === null || sheetRenderer === void 0 ? void 0 : sheetRenderer.with(RefSelectionsRenderService);
1567
1953
  const isSelectingRef = useStateRef(isSelecting);
1568
1954
  const workbook = univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_SHEET);
@@ -1573,15 +1959,15 @@ function useFormulaSelecting(opts) {
1573
1959
  innerSetIsSelecting(v);
1574
1960
  });
1575
1961
  const calculateSelectingType = useEvent(() => {
1576
- var _config$dataStream, _lexerTreeBuilder$seq;
1577
- const currentWorkbook = univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET);
1962
+ var _editor$getSelectionR, _editor$getSelectionR2, _config$dataStream, _getSelectionAfterLag, _lexerTreeBuilder$seq;
1963
+ const currentWorkbook = resolveFormulaSelectionWorkbook(univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET), workbook);
1578
1964
  if (!currentWorkbook) return;
1579
1965
  const currentSheet = currentWorkbook.getActiveSheet();
1580
- const activeRange = docSelectionRenderService === null || docSelectionRenderService === void 0 ? void 0 : docSelectionRenderService.getActiveTextRange();
1581
- const index = (activeRange === null || activeRange === void 0 ? void 0 : activeRange.collapsed) ? activeRange.startOffset : -1;
1582
- const config = getCurrentBodyDataStreamAndOffset(injector);
1966
+ const activeRange = (_editor$getSelectionR = editor === null || editor === void 0 || (_editor$getSelectionR2 = editor.getSelectionRanges()) === null || _editor$getSelectionR2 === void 0 ? void 0 : _editor$getSelectionR2[0]) !== null && _editor$getSelectionR !== void 0 ? _editor$getSelectionR : docSelectionRenderService === null || docSelectionRenderService === void 0 ? void 0 : docSelectionRenderService.getActiveTextRange();
1967
+ const config = resolveFormulaSelectionDataStream(injector, editor, editorId);
1583
1968
  if (!config) return;
1584
1969
  const dataStream = config === null || config === void 0 || (_config$dataStream = config.dataStream) === null || _config$dataStream === void 0 ? void 0 : _config$dataStream.slice(0, -2);
1970
+ const index = resolveFormulaSelectionCursorIndex((_getSelectionAfterLag = getSelectionAfterLaggingFormulaInput(dataStream, activeRange, lastInputContentRef.current)) !== null && _getSelectionAfterLag !== void 0 ? _getSelectionAfterLag : activeRange, dataStream);
1585
1971
  const nodes = ((_lexerTreeBuilder$seq = lexerTreeBuilder.sequenceNodesBuilder(dataStream)) !== null && _lexerTreeBuilder$seq !== void 0 ? _lexerTreeBuilder$seq : []).map((node) => {
1586
1972
  if (typeof node === "object") {
1587
1973
  if (node.nodeType === sequenceNodeType.REFERENCE) return {
@@ -1599,21 +1985,22 @@ function useFormulaSelecting(opts) {
1599
1985
  const nextChar = dataStream[index];
1600
1986
  const focusingNode = nodes.find((node) => typeof node === "object" && node.nodeType === sequenceNodeType.REFERENCE && index === node.endIndex + 2);
1601
1987
  const adding = char && matchRefDrawToken(char) && (!nextChar || isFormulaLexerToken(nextChar) && nextChar !== matchToken.OPEN_BRACKET);
1602
- const editing = Boolean(focusingNode);
1603
- if ((dataStream === null || dataStream === void 0 ? void 0 : dataStream.substring(0, 1)) === "=" && (adding || editing)) if (editing) {
1604
- var _univerInstanceServic;
1605
- if (shouldSkipReferenceEditingByPointer(isDisabledByPointer.current, disableOnClick)) return;
1606
- isDisabledByPointer.current = false;
1607
- const { sheetName, unitId } = focusingNode.range;
1608
- const currentUnitId = (_univerInstanceServic = univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET)) === null || _univerInstanceServic === void 0 ? void 0 : _univerInstanceServic.getUnitId();
1609
- if (unitId && unitId !== currentUnitId) setIsSelecting(4);
1610
- else if (!sheetName && currentSheet.getSheetId() === (sourceSheet === null || sourceSheet === void 0 ? void 0 : sourceSheet.getSheetId()) || sheetName === currentSheet.getName()) setIsSelecting(2);
1611
- else setIsSelecting(3);
1612
- } else {
1613
- isDisabledByPointer.current = false;
1614
- setIsSelecting(1);
1615
- }
1616
- else setIsSelecting(0);
1988
+ const selectingIntent = resolveFormulaSelectingIntent(Boolean(adding), Boolean(focusingNode));
1989
+ if ((dataStream === null || dataStream === void 0 ? void 0 : dataStream.substring(0, 1)) === "=" && selectingIntent !== 0) {
1990
+ if (selectingIntent === 1) {
1991
+ isDisabledByPointer.current = false;
1992
+ setIsSelecting(1);
1993
+ } else if (focusingNode) {
1994
+ var _resolveFormulaSelect;
1995
+ if (shouldSkipReferenceEditingByPointer(isDisabledByPointer.current, disableOnClick)) return;
1996
+ isDisabledByPointer.current = false;
1997
+ const { sheetName, unitId } = focusingNode.range;
1998
+ const currentUnitId = (_resolveFormulaSelect = resolveFormulaSelectionWorkbook(univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET), workbook)) === null || _resolveFormulaSelect === void 0 ? void 0 : _resolveFormulaSelect.getUnitId();
1999
+ if (unitId && unitId !== currentUnitId) setIsSelecting(4);
2000
+ else if (!sheetName && currentSheet.getSheetId() === (sourceSheet === null || sourceSheet === void 0 ? void 0 : sourceSheet.getSheetId()) || sheetName === currentSheet.getName()) setIsSelecting(2);
2001
+ else setIsSelecting(3);
2002
+ }
2003
+ } else setIsSelecting(0);
1617
2004
  });
1618
2005
  useEffect(() => {
1619
2006
  const sub = docSelectionManagerService.textSelection$.pipe(filter((param) => param.unitId === editorId)).subscribe(() => {
@@ -1625,6 +2012,43 @@ function useFormulaSelecting(opts) {
1625
2012
  docSelectionManagerService.textSelection$,
1626
2013
  editorId
1627
2014
  ]);
2015
+ useEffect(() => {
2016
+ if (!isFocus || !editor) return;
2017
+ let timeout;
2018
+ const sub = editor.input$.subscribe(({ content, isComposing }) => {
2019
+ if (!isComposing) lastInputContentRef.current = content;
2020
+ queueMicrotask(() => {
2021
+ calculateSelectingType();
2022
+ });
2023
+ if (timeout) clearTimeout(timeout);
2024
+ timeout = setTimeout(() => {
2025
+ calculateSelectingType();
2026
+ lastInputContentRef.current = "";
2027
+ }, 0);
2028
+ });
2029
+ return () => {
2030
+ if (timeout) clearTimeout(timeout);
2031
+ sub.unsubscribe();
2032
+ };
2033
+ }, [
2034
+ calculateSelectingType,
2035
+ editor,
2036
+ isFocus
2037
+ ]);
2038
+ useEffect(() => {
2039
+ var _editorDocumentModel$;
2040
+ if (!isFocus) return;
2041
+ const editorDocumentModel = univerInstanceService.getUnit(editorId, UniverInstanceType.UNIVER_DOC);
2042
+ const sub = editorDocumentModel === null || editorDocumentModel === void 0 || (_editorDocumentModel$ = editorDocumentModel.change$) === null || _editorDocumentModel$ === void 0 ? void 0 : _editorDocumentModel$.subscribe(() => {
2043
+ queueMicrotask(calculateSelectingType);
2044
+ });
2045
+ return () => sub === null || sub === void 0 ? void 0 : sub.unsubscribe();
2046
+ }, [
2047
+ calculateSelectingType,
2048
+ editorId,
2049
+ isFocus,
2050
+ univerInstanceService
2051
+ ]);
1628
2052
  useEffect(() => {
1629
2053
  if (!isFocus) {
1630
2054
  setIsSelecting(0);
@@ -1710,10 +2134,7 @@ function calcHighlightRanges(opts) {
1710
2134
  const workbook = univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_SHEET);
1711
2135
  const worksheet = workbook === null || workbook === void 0 ? void 0 : workbook.getActiveSheet();
1712
2136
  const selectionWithStyle = [];
1713
- if (!workbook || !worksheet) {
1714
- refSelectionsService.setSelections(selectionWithStyle);
1715
- return;
1716
- }
2137
+ if (!workbook || !worksheet) return selectionWithStyle;
1717
2138
  const currentSheetId = worksheet.getSheetId();
1718
2139
  const getSheetIdByName = (name) => {
1719
2140
  var _workbook$getSheetByS;
@@ -1758,6 +2179,7 @@ function calcHighlightRanges(opts) {
1758
2179
  const cursor = (_editor$getSelectionR = editor.getSelectionRanges()) === null || _editor$getSelectionR === void 0 || (_editor$getSelectionR = _editor$getSelectionR[0]) === null || _editor$getSelectionR === void 0 ? void 0 : _editor$getSelectionR.startOffset;
1759
2180
  const activeIndex = endIndexes.findIndex((end) => end + 2 === cursor);
1760
2181
  if (activeIndex !== -1) refSelectionsRenderService === null || refSelectionsRenderService === void 0 || refSelectionsRenderService.setActiveSelectionIndex(activeIndex);
2182
+ else if (selectionWithStyle.length) refSelectionsRenderService === null || refSelectionsRenderService === void 0 || refSelectionsRenderService.setActiveSelectionIndex(selectionWithStyle.length - 1);
1761
2183
  else refSelectionsRenderService === null || refSelectionsRenderService === void 0 || refSelectionsRenderService.resetActiveSelectionIndex();
1762
2184
  }
1763
2185
  return selectionWithStyle;
@@ -1772,14 +2194,25 @@ function useSheetHighlight(unitId, subUnitId) {
1772
2194
  const themeService = useDependency(ThemeService);
1773
2195
  const refSelectionsService = useDependency(IRefSelectionsService);
1774
2196
  const renderManagerService = useDependency(IRenderManagerService);
1775
- const currentWorkbook = useObservable(useMemo(() => univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET), [univerInstanceService]));
1776
- const currentRender = currentWorkbook ? renderManagerService.getRenderById(currentWorkbook.getUnitId()) : null;
1777
- const refSelectionsRenderService = currentRender === null || currentRender === void 0 ? void 0 : currentRender.with(RefSelectionsRenderService);
1778
- const sheetSkeletonManagerService = currentRender === null || currentRender === void 0 ? void 0 : currentRender.with(SheetSkeletonManagerService);
1779
- const highlightSheet = useEvent((refSelections, editor) => {
2197
+ const ownerRender = renderManagerService.getRenderById(unitId);
2198
+ const ownerRefSelectionsRenderService = ownerRender === null || ownerRender === void 0 ? void 0 : ownerRender.with(RefSelectionsRenderService);
2199
+ const getHighlightWorkbook = useEvent((refSelections) => {
2200
+ const ownerWorkbook = univerInstanceService.getUnit(unitId, UniverInstanceType.UNIVER_SHEET);
1780
2201
  const currentWorkbook = univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_SHEET);
2202
+ const currentUnitId = currentWorkbook === null || currentWorkbook === void 0 ? void 0 : currentWorkbook.getUnitId();
2203
+ return Boolean(currentUnitId) && refSelections.some((refSelection) => deserializeRangeWithSheet(refSelection.token).unitId === currentUnitId) ? currentWorkbook : ownerWorkbook !== null && ownerWorkbook !== void 0 ? ownerWorkbook : currentWorkbook;
2204
+ });
2205
+ const highlightSheet = useEvent((refSelections, editor, isEnd = false) => {
2206
+ var _currentWorkbook$getA;
2207
+ const currentWorkbook = getHighlightWorkbook(refSelections);
1781
2208
  if (!currentWorkbook) return;
1782
- if (refSelectionsRenderService === null || refSelectionsRenderService === void 0 ? void 0 : refSelectionsRenderService.selectionMoving) return;
2209
+ const currentRender = renderManagerService.getRenderById(currentWorkbook.getUnitId());
2210
+ const refSelectionsRenderService = currentRender === null || currentRender === void 0 ? void 0 : currentRender.with(RefSelectionsRenderService);
2211
+ const sheetSelectionRenderService = currentRender === null || currentRender === void 0 ? void 0 : currentRender.with(ISheetSelectionRenderService);
2212
+ const sheetSkeletonManagerService = currentRender === null || currentRender === void 0 ? void 0 : currentRender.with(SheetSkeletonManagerService);
2213
+ if (!isEnd && (refSelectionsRenderService === null || refSelectionsRenderService === void 0 ? void 0 : refSelectionsRenderService.selectionMoving)) return;
2214
+ const currentSheetId = (_currentWorkbook$getA = currentWorkbook.getActiveSheet()) === null || _currentWorkbook$getA === void 0 ? void 0 : _currentWorkbook$getA.getSheetId();
2215
+ if (!currentSheetId) return;
1783
2216
  const selectionWithStyle = calcHighlightRanges({
1784
2217
  unitId,
1785
2218
  subUnitId,
@@ -1794,13 +2227,14 @@ function useSheetHighlight(unitId, subUnitId) {
1794
2227
  });
1795
2228
  if (!selectionWithStyle) return;
1796
2229
  if (((refSelectionsRenderService === null || refSelectionsRenderService === void 0 ? void 0 : refSelectionsRenderService.getSelectionControls()) || []).length === selectionWithStyle.length) refSelectionsRenderService === null || refSelectionsRenderService === void 0 || refSelectionsRenderService.resetSelectionsByModelData(selectionWithStyle);
1797
- else refSelectionsService.setSelections(selectionWithStyle);
2230
+ else refSelectionsService.setSelections(currentWorkbook.getUnitId(), currentSheetId, selectionWithStyle);
2231
+ if (isEnd && selectionWithStyle.length) sheetSelectionRenderService === null || sheetSelectionRenderService === void 0 || sheetSelectionRenderService.resetSelectionsByModelData([]);
1798
2232
  });
1799
2233
  useEffect(() => {
1800
2234
  return () => {
1801
- refSelectionsRenderService === null || refSelectionsRenderService === void 0 || refSelectionsRenderService.resetActiveSelectionIndex();
2235
+ ownerRefSelectionsRenderService === null || ownerRefSelectionsRenderService === void 0 || ownerRefSelectionsRenderService.resetActiveSelectionIndex();
1802
2236
  };
1803
- }, [refSelectionsRenderService]);
2237
+ }, [ownerRefSelectionsRenderService]);
1804
2238
  return highlightSheet;
1805
2239
  }
1806
2240
  function useDocHight(_leadingCharacter = "") {
@@ -1808,23 +2242,18 @@ function useDocHight(_leadingCharacter = "") {
1808
2242
  const colorMap = useColor();
1809
2243
  const commandService = useDependency(ICommandService);
1810
2244
  const leadingCharacterLength = useMemo(() => _leadingCharacter.length, [_leadingCharacter]);
1811
- return useEvent((editor, sequenceNodes, isNeedResetSelection = true, newSelections) => {
2245
+ return useEvent((editor, sequenceNodes, isNeedResetSelection = true, newSelections, sourceText) => {
1812
2246
  const data = editor.getDocumentData();
1813
2247
  const editorId = editor.getEditorId();
1814
2248
  if (!data) return [];
1815
2249
  const body = data.body;
1816
2250
  if (!body) return [];
1817
2251
  const str = body.dataStream.slice(0, body.dataStream.length - 2);
1818
- const cloneBody = {
1819
- dataStream: "",
1820
- ...data.body
1821
- };
1822
2252
  if (!str.startsWith(_leadingCharacter)) return [];
1823
2253
  if (sequenceNodes == null || sequenceNodes.length === 0) {
1824
- cloneBody.textRuns = [];
1825
2254
  commandService.syncExecuteCommand(ReplaceTextRunsCommand.id, {
1826
2255
  unitId: editorId,
1827
- body: getBodySlice(cloneBody, 0, cloneBody.dataStream.length - 2)
2256
+ body: createFormulaHighlightBody(str, [])
1828
2257
  });
1829
2258
  return [];
1830
2259
  } else {
@@ -1833,19 +2262,16 @@ function useDocHight(_leadingCharacter = "") {
1833
2262
  e.ed = e.ed + leadingCharacterLength;
1834
2263
  e.st = e.st + leadingCharacterLength;
1835
2264
  });
1836
- cloneBody.textRuns = [{
2265
+ const highlightDataStream = getFormulaHighlightDataStream(_leadingCharacter, sequenceNodes, sourceText);
2266
+ const highlightTextRuns = [{
1837
2267
  st: 0,
1838
2268
  ed: 1,
1839
2269
  ts: { fs: 11 }
1840
2270
  }, ...textRuns];
1841
- cloneBody.dataStream = `${_leadingCharacter}${sequenceNodes.reduce((pre, cur) => {
1842
- if (typeof cur === "string") return `${pre}${cur}`;
1843
- return `${pre}${cur.token}`;
1844
- }, "")}\r\n`;
1845
2271
  let selections;
1846
2272
  if (isNeedResetSelection) {
1847
2273
  selections = editor.getSelectionRanges();
1848
- const maxOffset = cloneBody.dataStream.length - 2 + leadingCharacterLength;
2274
+ const maxOffset = highlightDataStream.length - 2 + leadingCharacterLength;
1849
2275
  selections.forEach((selection) => {
1850
2276
  selection.startOffset = Math.max(0, Math.min(selection.startOffset, maxOffset));
1851
2277
  selection.endOffset = Math.max(0, Math.min(selection.endOffset, maxOffset));
@@ -1853,13 +2279,30 @@ function useDocHight(_leadingCharacter = "") {
1853
2279
  }
1854
2280
  commandService.syncExecuteCommand(ReplaceTextRunsCommand.id, {
1855
2281
  unitId: editorId,
1856
- body: getBodySlice(cloneBody, 0, cloneBody.dataStream.length - 2),
2282
+ body: createFormulaHighlightBody(highlightDataStream.slice(0, -2), highlightTextRuns),
1857
2283
  textRanges: newSelections !== null && newSelections !== void 0 ? newSelections : selections
1858
2284
  });
1859
2285
  return refSelections;
1860
2286
  }
1861
2287
  });
1862
2288
  }
2289
+ /**
2290
+ * ReplaceTextRunsCommand shifts the editor's existing structural metadata when text changes.
2291
+ * Its replacement body must therefore contain only inline formula data; carrying paragraphs
2292
+ * or section breaks copied from the old snapshot would leave their indexes stale.
2293
+ */
2294
+ function createFormulaHighlightBody(dataStream, textRuns) {
2295
+ return {
2296
+ dataStream,
2297
+ textRuns
2298
+ };
2299
+ }
2300
+ function getFormulaHighlightDataStream(leadingCharacter, sequenceNodes, sourceText) {
2301
+ return `${leadingCharacter}${sourceText !== null && sourceText !== void 0 ? sourceText : sequenceNodes.reduce((pre, cur) => {
2302
+ if (typeof cur === "string") return `${pre}${cur}`;
2303
+ return `${pre}${cur.token}`;
2304
+ }, "")}\r\n`;
2305
+ }
1863
2306
  function useColor() {
1864
2307
  const themeService = useDependency(ThemeService);
1865
2308
  return useMemo(() => {
@@ -1962,17 +2405,41 @@ function buildTextRuns(descriptionService, colorMap, sequenceNodes) {
1962
2405
 
1963
2406
  //#endregion
1964
2407
  //#region src/views/formula-editor/hooks/use-left-and-right-arrow.ts
1965
- const useLeftAndRightArrow = (isNeed, shouldMoveSelection, editor, onMoveInEditor) => {
2408
+ function shouldMoveFormulaSelectionFromCurrentSelection(selectingType, refSelectionCount) {
2409
+ if (selectingType === 1) return refSelectionCount === 0;
2410
+ return selectingType === 3;
2411
+ }
2412
+ function isFormulaEditorInteractionOwner(focusEditorId, editorId, options) {
2413
+ var _options$formulaBarEd, _options$normalEditor;
2414
+ if (focusEditorId === editorId) return true;
2415
+ if (!(options === null || options === void 0 ? void 0 : options.fxBarFocused)) return false;
2416
+ return editorId === ((_options$formulaBarEd = options.formulaBarEditorId) !== null && _options$formulaBarEd !== void 0 ? _options$formulaBarEd : DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY) && focusEditorId === ((_options$normalEditor = options.normalEditorId) !== null && _options$normalEditor !== void 0 ? _options$normalEditor : DOCS_NORMAL_EDITOR_UNIT_ID_KEY);
2417
+ }
2418
+ const useLeftAndRightArrow = (isNeed, shouldMoveSelection, editor, onMoveInEditor, getRefSelectionCount) => {
1966
2419
  const commandService = useDependency(ICommandService);
1967
2420
  const shortcutService = useDependency(IShortcutService);
2421
+ const editorService = useDependency(IEditorService);
2422
+ const contextService = useDependency(IContextService);
2423
+ const operationNamespace = useMemo(() => generateRandomId(4), []);
1968
2424
  const shouldMoveSelectionRef = useRef(shouldMoveSelection);
1969
2425
  shouldMoveSelectionRef.current = shouldMoveSelection;
1970
2426
  const onMoveInEditorRef = useRef(onMoveInEditor);
1971
2427
  onMoveInEditorRef.current = onMoveInEditor;
2428
+ const getRefSelectionCountRef = useRef(getRefSelectionCount);
2429
+ getRefSelectionCountRef.current = getRefSelectionCount;
1972
2430
  useEffect(() => {
1973
2431
  if (!editor || !isNeed) return;
1974
- const operationId = `sheet.formula-embedding-editor.${editor.getEditorId()}`;
2432
+ const editorId = editor.getEditorId();
2433
+ const operationId = `sheet.formula-embedding-editor.${editorId}.${operationNamespace}`;
1975
2434
  const d = new DisposableCollection();
2435
+ const shouldHandleShortcut = () => {
2436
+ try {
2437
+ const fxBarFocused = contextService.getContextValue(FOCUSING_FX_BAR_EDITOR);
2438
+ return isFormulaEditorInteractionOwner(editorService.getFocusId(), editorId, { fxBarFocused }) && (editor.docSelectionRenderService.isFocusing || fxBarFocused);
2439
+ } catch {
2440
+ return false;
2441
+ }
2442
+ };
1976
2443
  const handleMoveInEditor = (keycode, metaKey) => {
1977
2444
  if (onMoveInEditorRef.current) {
1978
2445
  onMoveInEditorRef.current(keycode, metaKey);
@@ -1991,27 +2458,30 @@ const useLeftAndRightArrow = (isNeed, shouldMoveSelection, editor, onMoveInEdito
1991
2458
  else if (keycode === KeyCode.ARROW_UP) direction = Direction.UP;
1992
2459
  else if (keycode === KeyCode.ARROW_LEFT) direction = Direction.LEFT;
1993
2460
  else if (keycode === KeyCode.ARROW_RIGHT) direction = Direction.RIGHT;
1994
- if (shouldMoveSelectionRef.current) if (metaKey === MetaKeys.CTRL_COMMAND) commandService.executeCommand(MoveSelectionCommand.id, {
1995
- direction,
1996
- jumpOver: JumpOver.moveGap,
1997
- extra: "formula-editor",
1998
- fromCurrentSelection: shouldMoveSelectionRef.current === 1 || shouldMoveSelectionRef.current === 3
1999
- });
2000
- else if (metaKey === MetaKeys.SHIFT) commandService.executeCommand(ExpandSelectionCommand.id, {
2001
- direction,
2002
- extra: "formula-editor"
2003
- });
2004
- else if (metaKey === (MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT)) commandService.executeCommand(ExpandSelectionCommand.id, {
2005
- direction,
2006
- jumpOver: JumpOver.moveGap,
2007
- extra: "formula-editor"
2008
- });
2009
- else commandService.executeCommand(MoveSelectionCommand.id, {
2010
- direction,
2011
- extra: "formula-editor",
2012
- fromCurrentSelection: shouldMoveSelectionRef.current === 1 || shouldMoveSelectionRef.current === 3
2013
- });
2014
- else handleMoveInEditor(keycode, metaKey);
2461
+ if (shouldMoveSelectionRef.current) {
2462
+ var _getRefSelectionCount, _getRefSelectionCount2;
2463
+ const fromCurrentSelection = shouldMoveFormulaSelectionFromCurrentSelection(shouldMoveSelectionRef.current, (_getRefSelectionCount = (_getRefSelectionCount2 = getRefSelectionCountRef.current) === null || _getRefSelectionCount2 === void 0 ? void 0 : _getRefSelectionCount2.call(getRefSelectionCountRef)) !== null && _getRefSelectionCount !== void 0 ? _getRefSelectionCount : 0);
2464
+ if (metaKey === MetaKeys.CTRL_COMMAND) commandService.executeCommand(MoveSelectionCommand.id, {
2465
+ direction,
2466
+ jumpOver: JumpOver.moveGap,
2467
+ extra: "formula-editor",
2468
+ fromCurrentSelection
2469
+ });
2470
+ else if (metaKey === MetaKeys.SHIFT) commandService.executeCommand(ExpandSelectionCommand.id, {
2471
+ direction,
2472
+ extra: "formula-editor"
2473
+ });
2474
+ else if (metaKey === (MetaKeys.CTRL_COMMAND | MetaKeys.SHIFT)) commandService.executeCommand(ExpandSelectionCommand.id, {
2475
+ direction,
2476
+ jumpOver: JumpOver.moveGap,
2477
+ extra: "formula-editor"
2478
+ });
2479
+ else commandService.executeCommand(MoveSelectionCommand.id, {
2480
+ direction,
2481
+ extra: "formula-editor",
2482
+ fromCurrentSelection
2483
+ });
2484
+ } else handleMoveInEditor(keycode, metaKey);
2015
2485
  };
2016
2486
  d.add(commandService.registerCommand({
2017
2487
  id: operationId,
@@ -2078,7 +2548,7 @@ const useLeftAndRightArrow = (isNeed, shouldMoveSelection, editor, onMoveInEdito
2078
2548
  return {
2079
2549
  id: operationId,
2080
2550
  binding: metaKey ? keyCode | metaKey : keyCode,
2081
- preconditions: () => true,
2551
+ preconditions: shouldHandleShortcut,
2082
2552
  priority: 900,
2083
2553
  staticParameters: {
2084
2554
  eventType: DeviceInputEventType.Keyboard,
@@ -2094,8 +2564,11 @@ const useLeftAndRightArrow = (isNeed, shouldMoveSelection, editor, onMoveInEdito
2094
2564
  };
2095
2565
  }, [
2096
2566
  commandService,
2567
+ contextService,
2097
2568
  editor,
2569
+ editorService,
2098
2570
  isNeed,
2571
+ operationNamespace,
2099
2572
  shortcutService
2100
2573
  ]);
2101
2574
  };
@@ -2131,7 +2604,7 @@ const useRefactorEffect = (isNeed, selecting, unitId, editorId, disableContextMe
2131
2604
  editorId
2132
2605
  ]);
2133
2606
  useLayoutEffect(() => {
2134
- if (isNeed && selecting) {
2607
+ if (isNeed && Boolean(selecting)) {
2135
2608
  const d1 = refSelectionsRenderService === null || refSelectionsRenderService === void 0 ? void 0 : refSelectionsRenderService.enableSelectionChanging();
2136
2609
  contextService.setContextValue(REF_SELECTIONS_ENABLED, true);
2137
2610
  return () => {
@@ -2202,18 +2675,45 @@ const prepareSelectionChangeContext = (opts) => {
2202
2675
  var _editor$getDocumentDa, _editor$getDocumentDa2, _lexerTreeBuilder$seq;
2203
2676
  const { editor, lexerTreeBuilder } = opts;
2204
2677
  const currentDocSelections = editor === null || editor === void 0 ? void 0 : editor.getSelectionRanges();
2205
- if ((currentDocSelections === null || currentDocSelections === void 0 ? void 0 : currentDocSelections.length) !== 1) return;
2206
- const offset = currentDocSelections[0].startOffset - 1;
2207
2678
  const dataStream = ((_editor$getDocumentDa = editor === null || editor === void 0 || (_editor$getDocumentDa2 = editor.getDocumentData().body) === null || _editor$getDocumentDa2 === void 0 ? void 0 : _editor$getDocumentDa2.dataStream) !== null && _editor$getDocumentDa !== void 0 ? _editor$getDocumentDa : "\r\n").slice(0, -2);
2208
2679
  const sequenceNodes = (_lexerTreeBuilder$seq = lexerTreeBuilder.sequenceNodesBuilder(dataStream.slice(1))) !== null && _lexerTreeBuilder$seq !== void 0 ? _lexerTreeBuilder$seq : [];
2680
+ let offset;
2681
+ if ((currentDocSelections === null || currentDocSelections === void 0 ? void 0 : currentDocSelections.length) === 1) offset = currentDocSelections[0].startOffset - 1;
2682
+ else if (dataStream.startsWith("=")) offset = Math.max(dataStream.length - 1, 0);
2683
+ else return;
2209
2684
  const nodeIndex = findIndexFromSequenceNodes(sequenceNodes, offset, false);
2210
2685
  return {
2211
2686
  nodeIndex,
2212
2687
  updatingRefIndex: findRefSequenceIndex(sequenceNodes, nodeIndex),
2688
+ formulaText: dataStream.slice(1),
2213
2689
  sequenceNodes,
2214
2690
  offset
2215
2691
  };
2216
2692
  };
2693
+ function getSequenceNodeCharAtOffset(sequenceNodes, offset) {
2694
+ let currentOffset = 0;
2695
+ for (const node of sequenceNodes) {
2696
+ const text = typeof node === "string" ? node : node.token;
2697
+ const nextOffset = currentOffset + text.length;
2698
+ if (offset > currentOffset && offset <= nextOffset) return text[offset - currentOffset - 1];
2699
+ currentOffset = nextOffset;
2700
+ }
2701
+ }
2702
+ function isFormulaReferenceAddingContext(sequenceNodes, offset) {
2703
+ const char = getSequenceNodeCharAtOffset(sequenceNodes, offset);
2704
+ return Boolean(char && matchRefDrawToken(char));
2705
+ }
2706
+ function isFormulaReferenceAddingTextContext(formulaText, offset) {
2707
+ const char = formulaText[offset - 1];
2708
+ const nextChar = formulaText[offset];
2709
+ return Boolean(char && matchRefDrawToken(char) && (!nextChar || isFormulaLexerToken(nextChar) && nextChar !== matchToken.OPEN_BRACKET));
2710
+ }
2711
+ function insertFormulaReferenceText(formulaText, refText, offset) {
2712
+ return `${formulaText.slice(0, offset)}${refText}${formulaText.slice(offset)}`;
2713
+ }
2714
+ function shouldSkipFormulaReferenceUpdate(isAdd, selectionCount) {
2715
+ return !isAdd && selectionCount === 0;
2716
+ }
2217
2717
  function getSelectionsForFormulaRefUpdate(selections, updatingRefIndex, isCtrlAddMode) {
2218
2718
  const orderedSelections = [...selections];
2219
2719
  if (updatingRefIndex === -1) return { orderedSelections };
@@ -2225,17 +2725,78 @@ function getSelectionsForFormulaRefUpdate(selections, updatingRefIndex, isCtrlAd
2225
2725
  insertedSelection
2226
2726
  };
2227
2727
  }
2728
+ function getLastFormulaSelection(selections) {
2729
+ return selections[selections.length - 1];
2730
+ }
2731
+ function getFormulaSelectionIdentityKey(selection) {
2732
+ var _ref, _item$rangeWithCoord, _range$startRow, _range$endRow, _range$startColumn, _range$endColumn;
2733
+ const item = selection;
2734
+ const range = (_ref = (_item$rangeWithCoord = item.rangeWithCoord) !== null && _item$rangeWithCoord !== void 0 ? _item$rangeWithCoord : item.range) !== null && _ref !== void 0 ? _ref : item;
2735
+ return [
2736
+ (_range$startRow = range.startRow) !== null && _range$startRow !== void 0 ? _range$startRow : "",
2737
+ (_range$endRow = range.endRow) !== null && _range$endRow !== void 0 ? _range$endRow : "",
2738
+ (_range$startColumn = range.startColumn) !== null && _range$startColumn !== void 0 ? _range$startColumn : "",
2739
+ (_range$endColumn = range.endColumn) !== null && _range$endColumn !== void 0 ? _range$endColumn : ""
2740
+ ].join(":");
2741
+ }
2742
+ function isSameFormulaSelection(first, second) {
2743
+ return getFormulaSelectionIdentityKey(first) === getFormulaSelectionIdentityKey(second);
2744
+ }
2745
+ const SHARED_SELECTION_CHANGE_DUPLICATE_END_GUARDS = /* @__PURE__ */ new Map();
2746
+ function getSharedSelectionChangeDuplicateEndGuard(key) {
2747
+ let guard = SHARED_SELECTION_CHANGE_DUPLICATE_END_GUARDS.get(key);
2748
+ if (!guard) {
2749
+ guard = createSelectionChangeDuplicateEndGuard();
2750
+ SHARED_SELECTION_CHANGE_DUPLICATE_END_GUARDS.set(key, guard);
2751
+ }
2752
+ return guard;
2753
+ }
2754
+ function createSelectionChangeDuplicateEndGuard() {
2755
+ let lastTransientSelectionsKey;
2756
+ const getSelectionsKey = (selections) => selections.map(getFormulaSelectionIdentityKey).join("|");
2757
+ return {
2758
+ shouldSkip(selections, isEnd) {
2759
+ const selectionsKey = getSelectionsKey(selections);
2760
+ if (selectionsKey === lastTransientSelectionsKey) return true;
2761
+ if (isEnd) {
2762
+ lastTransientSelectionsKey = void 0;
2763
+ return false;
2764
+ }
2765
+ lastTransientSelectionsKey = selectionsKey;
2766
+ return false;
2767
+ },
2768
+ reset() {
2769
+ lastTransientSelectionsKey = void 0;
2770
+ }
2771
+ };
2772
+ }
2228
2773
  function createSelectionChangeHandler(opts) {
2774
+ var _opts$duplicateEndGua;
2229
2775
  let prevSelectionsCount = opts.initialSelectionsCount;
2230
2776
  let pendingCtrlAddCount = 0;
2777
+ const duplicateEndGuard = (_opts$duplicateEndGua = opts.duplicateEndGuard) !== null && _opts$duplicateEndGua !== void 0 ? _opts$duplicateEndGua : createSelectionChangeDuplicateEndGuard();
2231
2778
  return (selections, isEnd, options) => {
2232
2779
  if (options === null || options === void 0 ? void 0 : options.initial) return;
2233
- const isCtrlAddMode = selections.length > prevSelectionsCount;
2780
+ if (selections.length === 0) return;
2781
+ const isCtrlAddMode = !(options === null || options === void 0 ? void 0 : options.initial) && prevSelectionsCount > 0 && selections.length > prevSelectionsCount;
2234
2782
  if (isCtrlAddMode && !isEnd) {
2235
2783
  pendingCtrlAddCount = selections.length;
2784
+ if (duplicateEndGuard.shouldSkip(selections, false)) return;
2785
+ opts.onSelectionsChange(selections, false, true);
2786
+ prevSelectionsCount = selections.length;
2787
+ pendingCtrlAddCount = 0;
2236
2788
  return;
2237
2789
  }
2238
2790
  const shouldApplyPendingCtrlAdd = isEnd && selections.length === pendingCtrlAddCount;
2791
+ if (duplicateEndGuard.shouldSkip(selections, isEnd)) {
2792
+ if (isEnd) {
2793
+ var _opts$onDuplicateEnd;
2794
+ (_opts$onDuplicateEnd = opts.onDuplicateEnd) === null || _opts$onDuplicateEnd === void 0 || _opts$onDuplicateEnd.call(opts, selections);
2795
+ }
2796
+ prevSelectionsCount = selections.length;
2797
+ pendingCtrlAddCount = 0;
2798
+ return;
2799
+ }
2239
2800
  if (isEnd) {
2240
2801
  prevSelectionsCount = selections.length;
2241
2802
  pendingCtrlAddCount = 0;
@@ -2243,12 +2804,29 @@ function createSelectionChangeHandler(opts) {
2243
2804
  opts.onSelectionsChange(selections, isEnd, isCtrlAddMode || shouldApplyPendingCtrlAdd);
2244
2805
  };
2245
2806
  }
2807
+ function replaceFormulaControlSelection(selections, index, newRange) {
2808
+ const current = selections[index];
2809
+ if (!current) return;
2810
+ const nextRange = {
2811
+ ...newRange,
2812
+ sheetId: current.sheetId,
2813
+ unitId: current.unitId
2814
+ };
2815
+ const nextSelections = [...selections];
2816
+ nextSelections[index] = nextRange;
2817
+ return nextSelections;
2818
+ }
2819
+ function getInitialFormulaReferenceSelectionCount(renderSelectionCount, formulaReferenceCount, selectingType) {
2820
+ return Math.max(renderSelectionCount, formulaReferenceCount);
2821
+ }
2246
2822
  const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUnitId, getRefSelections, isSupportAcrossSheet, listenSelectionSet, editor, handleRangeChange = noop) => {
2247
- var _currentUnit$getUnitI;
2823
+ var _activeWorkbook$getUn;
2248
2824
  const renderManagerService = useDependency(IRenderManagerService);
2249
2825
  const univerInstanceService = useDependency(IUniverInstanceService);
2250
2826
  const commandService = useDependency(ICommandService);
2827
+ const contextService = useDependency(IContextService);
2251
2828
  const docSelectionManagerService = useDependency(DocSelectionManagerService);
2829
+ const editorService = useDependency(IEditorService);
2252
2830
  const themeService = useDependency(ThemeService);
2253
2831
  const lexerTreeBuilder = useDependency(LexerTreeBuilder);
2254
2832
  const workbook = univerInstanceService.getUnit(unitId);
@@ -2266,32 +2844,39 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2266
2844
  activeSheet,
2267
2845
  sheetName
2268
2846
  });
2269
- const currentUnit = useObservable(useMemo(() => univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET), [univerInstanceService]));
2270
- const render = renderManagerService.getRenderById((_currentUnit$getUnitI = currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== null && _currentUnit$getUnitI !== void 0 ? _currentUnit$getUnitI : "");
2847
+ const activeWorkbook = resolveFormulaSelectionWorkbook(useObservable(useMemo(() => univerInstanceService.getCurrentTypeOfUnit$(UniverInstanceType.UNIVER_SHEET), [univerInstanceService])), workbook);
2848
+ const render = renderManagerService.getRenderById((_activeWorkbook$getUn = activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== null && _activeWorkbook$getUn !== void 0 ? _activeWorkbook$getUn : unitId);
2271
2849
  const refSelectionsRenderService = render === null || render === void 0 ? void 0 : render.with(RefSelectionsRenderService);
2272
2850
  const sheetSkeletonManagerService = render === null || render === void 0 ? void 0 : render.with(SheetSkeletonManagerService);
2273
2851
  const refSelectionsService = useDependency(IRefSelectionsService);
2852
+ const duplicateEndGuard = useMemo(() => getSharedSelectionChangeDuplicateEndGuard(`${unitId}:${subUnitId}`), [subUnitId, unitId]);
2274
2853
  const onSelectionsChange = useEvent((selections, isEnd, isCtrlAddMode) => {
2854
+ if (!editor || !isFormulaEditorInteractionOwner(editorService.getFocusId(), editor.getEditorId(), { fxBarFocused: contextService.getContextValue(FOCUSING_FX_BAR_EDITOR) })) return;
2275
2855
  const ctx = prepareSelectionChangeContext({
2276
2856
  editor,
2277
2857
  lexerTreeBuilder
2278
2858
  });
2279
2859
  if (!ctx) return;
2280
- const { nodeIndex, updatingRefIndex, sequenceNodes, offset } = ctx;
2281
- if (isSelectingRef.current === 1) if (offset !== 0) {
2860
+ const { nodeIndex, updatingRefIndex, formulaText, sequenceNodes, offset } = ctx;
2861
+ if (isSelectingRef.current === 1 || isFormulaReferenceAddingContext(sequenceNodes, offset) || isFormulaReferenceAddingTextContext(formulaText, offset)) if (offset !== 0) {
2282
2862
  var _range$sheetId, _range$unitId, _range$unitId2;
2283
2863
  if (nodeIndex === -1 && sequenceNodes.length) return;
2284
- const range = selections[selections.length - 1];
2864
+ const range = getLastFormulaSelection(selections);
2865
+ if (!range) return;
2285
2866
  const lastNodes = sequenceNodes.splice(nodeIndex + 1);
2286
2867
  const rangeSheetId = (_range$sheetId = range.sheetId) !== null && _range$sheetId !== void 0 ? _range$sheetId : subUnitId;
2287
2868
  const unitRangeName = {
2288
2869
  range,
2289
- unitId: (_range$unitId = range.unitId) !== null && _range$unitId !== void 0 ? _range$unitId : currentUnit.getUnitId(),
2290
- sheetName: getSheetNameById((_range$unitId2 = range.unitId) !== null && _range$unitId2 !== void 0 ? _range$unitId2 : currentUnit.getUnitId(), rangeSheetId)
2870
+ unitId: (_range$unitId = range.unitId) !== null && _range$unitId !== void 0 ? _range$unitId : activeWorkbook.getUnitId(),
2871
+ sheetName: getSheetNameById((_range$unitId2 = range.unitId) !== null && _range$unitId2 !== void 0 ? _range$unitId2 : activeWorkbook.getUnitId(), rangeSheetId)
2291
2872
  };
2292
2873
  const isAcrossSheet = rangeSheetId !== subUnitId;
2293
- const isAcrossWorkbook = (currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== unitId;
2874
+ const isAcrossWorkbook = (activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== unitId;
2294
2875
  const refRanges = unitRangesToText([unitRangeName], isSupportAcrossSheet && (isAcrossSheet || isAcrossWorkbook), sheetName, isAcrossWorkbook);
2876
+ if (isFormulaReferenceAddingTextContext(formulaText, offset)) {
2877
+ handleRangeChange(insertFormulaReferenceText(formulaText, refRanges[0], offset), offset + refRanges[0].length, isEnd);
2878
+ return;
2879
+ }
2295
2880
  sequenceNodes.push({
2296
2881
  token: refRanges[0],
2297
2882
  nodeType: sequenceNodeType.REFERENCE
@@ -2299,15 +2884,16 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2299
2884
  handleRangeChange(sequenceNodeToText([...sequenceNodes, ...lastNodes]), getOffsetFromSequenceNodes(sequenceNodes), isEnd);
2300
2885
  } else {
2301
2886
  var _range$sheetId2, _range$unitId3, _range$unitId4;
2302
- const range = selections[selections.length - 1];
2887
+ const range = getLastFormulaSelection(selections);
2888
+ if (!range) return;
2303
2889
  const rangeSheetId = (_range$sheetId2 = range.sheetId) !== null && _range$sheetId2 !== void 0 ? _range$sheetId2 : subUnitId;
2304
2890
  const unitRangeName = {
2305
2891
  range,
2306
- unitId: (_range$unitId3 = range.unitId) !== null && _range$unitId3 !== void 0 ? _range$unitId3 : currentUnit.getUnitId(),
2307
- sheetName: getSheetNameById((_range$unitId4 = range.unitId) !== null && _range$unitId4 !== void 0 ? _range$unitId4 : currentUnit.getUnitId(), rangeSheetId)
2892
+ unitId: (_range$unitId3 = range.unitId) !== null && _range$unitId3 !== void 0 ? _range$unitId3 : activeWorkbook.getUnitId(),
2893
+ sheetName: getSheetNameById((_range$unitId4 = range.unitId) !== null && _range$unitId4 !== void 0 ? _range$unitId4 : activeWorkbook.getUnitId(), rangeSheetId)
2308
2894
  };
2309
2895
  const isAcrossSheet = rangeSheetId !== subUnitId;
2310
- const isAcrossWorkbook = (currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== unitId;
2896
+ const isAcrossWorkbook = (activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== unitId;
2311
2897
  const refRanges = unitRangesToText([unitRangeName], isSupportAcrossSheet && (isAcrossSheet || isAcrossWorkbook), sheetName, isAcrossWorkbook);
2312
2898
  sequenceNodes.unshift({
2313
2899
  token: refRanges[0],
@@ -2321,9 +2907,9 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2321
2907
  const node = sequenceNodes[nodeIndex];
2322
2908
  if (typeof node === "object" && node.nodeType === sequenceNodeType.REFERENCE) {
2323
2909
  const oldToken = node.token;
2324
- if ((currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== unitId) {
2325
- var _currentUnit$getUnitI2;
2326
- node.token = serializeRangeWithSpreadsheet((_currentUnit$getUnitI2 = currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== null && _currentUnit$getUnitI2 !== void 0 ? _currentUnit$getUnitI2 : "", sheetName, last);
2910
+ if ((activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== unitId) {
2911
+ var _activeWorkbook$getUn2;
2912
+ node.token = serializeRangeWithSpreadsheet((_activeWorkbook$getUn2 = activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== null && _activeWorkbook$getUn2 !== void 0 ? _activeWorkbook$getUn2 : "", sheetName, last);
2327
2913
  } else node.token = sheetName === (activeSheet === null || activeSheet === void 0 ? void 0 : activeSheet.getName()) ? serializeRange(last) : serializeRangeWithSheet(activeSheet.getName(), last);
2328
2914
  const newOffset = offset + (node.token.length - oldToken.length);
2329
2915
  handleRangeChange(generateStringWithSequence(sequenceNodes), newOffset, isEnd);
@@ -2335,10 +2921,10 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2335
2921
  const rangeSheetId = (_range$sheetId3 = range.sheetId) !== null && _range$sheetId3 !== void 0 ? _range$sheetId3 : subUnitId;
2336
2922
  const unitRangeName = {
2337
2923
  range,
2338
- unitId: (_range$unitId5 = range.unitId) !== null && _range$unitId5 !== void 0 ? _range$unitId5 : currentUnit.getUnitId(),
2339
- sheetName: getSheetNameById((_range$unitId6 = range.unitId) !== null && _range$unitId6 !== void 0 ? _range$unitId6 : currentUnit.getUnitId(), rangeSheetId)
2924
+ unitId: (_range$unitId5 = range.unitId) !== null && _range$unitId5 !== void 0 ? _range$unitId5 : activeWorkbook.getUnitId(),
2925
+ sheetName: getSheetNameById((_range$unitId6 = range.unitId) !== null && _range$unitId6 !== void 0 ? _range$unitId6 : activeWorkbook.getUnitId(), rangeSheetId)
2340
2926
  };
2341
- const isAcrossWorkbook = (currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId()) !== unitId;
2927
+ const isAcrossWorkbook = (activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId()) !== unitId;
2342
2928
  return unitRangesToText([unitRangeName], isSupportAcrossSheet && (rangeSheetId !== subUnitId || isAcrossWorkbook), sheetName, isAcrossWorkbook)[0];
2343
2929
  };
2344
2930
  let currentRefIndex = 0;
@@ -2347,7 +2933,7 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2347
2933
  if (item.nodeType === sequenceNodeType.REFERENCE) {
2348
2934
  const nodeRange = deserializeRangeWithSheet(item.token);
2349
2935
  if (!nodeRange.sheetName) nodeRange.sheetName = sheetName;
2350
- if ((nodeRange.unitId || unitId) !== (currentUnit === null || currentUnit === void 0 ? void 0 : currentUnit.getUnitId())) return item.token;
2936
+ if ((nodeRange.unitId || unitId) !== (activeWorkbook === null || activeWorkbook === void 0 ? void 0 : activeWorkbook.getUnitId())) return item.token;
2351
2937
  if (isSupportAcrossSheet) {
2352
2938
  var _contextRef$current$a;
2353
2939
  if (((_contextRef$current$a = contextRef.current.activeSheet) === null || _contextRef$current$a === void 0 ? void 0 : _contextRef$current$a.getName()) !== nodeRange.sheetName) return item.token;
@@ -2382,13 +2968,28 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2382
2968
  useEffect(() => {
2383
2969
  if (refSelectionsRenderService && isNeed) {
2384
2970
  const handleSelectionsChange = createSelectionChangeHandler({
2385
- initialSelectionsCount: Math.max(refSelectionsRenderService.getSelectionDataWithStyle().length, refSelectionsService.getCurrentSelections().length, getRefSelections().length),
2971
+ initialSelectionsCount: getInitialFormulaReferenceSelectionCount(refSelectionsRenderService.getSelectionDataWithStyle().length, getRefSelections().length, isSelectingRef.current),
2972
+ duplicateEndGuard: {
2973
+ shouldSkip: (selections, isEnd) => duplicateEndGuard.shouldSkip(selections.map((i) => i.rangeWithCoord), isEnd),
2974
+ reset: duplicateEndGuard.reset
2975
+ },
2386
2976
  onSelectionsChange: (selections, isEnd, isCtrlAddMode) => {
2387
2977
  onSelectionsChange(selections.map((i) => i.rangeWithCoord), isEnd, isCtrlAddMode);
2978
+ },
2979
+ onDuplicateEnd: () => {
2980
+ const ctx = prepareSelectionChangeContext({
2981
+ editor,
2982
+ lexerTreeBuilder
2983
+ });
2984
+ if (!ctx) return;
2985
+ handleRangeChange(ctx.formulaText, ctx.offset, true);
2388
2986
  }
2389
2987
  });
2390
2988
  let isInitialMoveEnd = true;
2391
2989
  const disposableCollection = new DisposableCollection();
2990
+ disposableCollection.add(refSelectionsRenderService.selectionMoveStart$.subscribe((selections) => {
2991
+ handleSelectionsChange(selections, false);
2992
+ }));
2392
2993
  disposableCollection.add(refSelectionsRenderService.selectionMoving$.subscribe((selections) => {
2393
2994
  handleSelectionsChange(selections, false);
2394
2995
  }));
@@ -2414,20 +3015,12 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2414
3015
  disposableCollection.dispose();
2415
3016
  refSelectionsRenderService.getSelectionControls().forEach((control, index) => {
2416
3017
  disposableCollection.add(control.selectionScaling$.subscribe((newRange) => {
2417
- const selections = refSelectionsRenderService.getSelectionDataWithStyle().map((i) => i.rangeWithCoord);
2418
- const current = selections[index];
2419
- newRange.sheetId = current.sheetId;
2420
- newRange.unitId = current.unitId;
2421
- selections[index] = newRange;
2422
- onSelectionsChange(selections, false);
3018
+ const nextSelections = replaceFormulaControlSelection(refSelectionsRenderService.getSelectionDataWithStyle().map((i) => i.rangeWithCoord), index, newRange);
3019
+ if (nextSelections) onSelectionsChange(nextSelections, false);
2423
3020
  }));
2424
3021
  disposableCollection.add(control.selectionMoving$.subscribe((newRange) => {
2425
- const selections = refSelectionsRenderService.getSelectionDataWithStyle().map((i) => i.rangeWithCoord);
2426
- const current = selections[index];
2427
- newRange.sheetId = current.sheetId;
2428
- newRange.unitId = current.unitId;
2429
- selections[index] = newRange;
2430
- onSelectionsChange(selections, true);
3022
+ const nextSelections = replaceFormulaControlSelection(refSelectionsRenderService.getSelectionDataWithStyle().map((i) => i.rangeWithCoord), index, newRange);
3023
+ if (nextSelections) onSelectionsChange(nextSelections, true);
2431
3024
  }));
2432
3025
  });
2433
3026
  };
@@ -2451,6 +3044,7 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2451
3044
  if (listenSelectionSet) {
2452
3045
  const d = commandService.onCommandExecuted((commandInfo) => {
2453
3046
  if (commandInfo.id !== SetSelectionsOperation.id) return;
3047
+ if (!editor || !isFormulaEditorInteractionOwner(editorService.getFocusId(), editor.getEditorId(), { fxBarFocused: contextService.getContextValue(FOCUSING_FX_BAR_EDITOR) })) return;
2454
3048
  const params = commandInfo.params;
2455
3049
  if (params.extra !== "formula-editor") return;
2456
3050
  if (params.selections.length) {
@@ -2466,10 +3060,20 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2466
3060
  }
2467
3061
  range.unitId = params.unitId;
2468
3062
  range.sheetId = params.subUnitId;
2469
- const isAdd = isSelectingRef.current === 1;
3063
+ const ctx = prepareSelectionChangeContext({
3064
+ editor,
3065
+ lexerTreeBuilder
3066
+ });
3067
+ const isAdd = isSelectingRef.current === 1 || Boolean(ctx && (isFormulaReferenceAddingContext(ctx.sequenceNodes, ctx.offset) || isFormulaReferenceAddingTextContext(ctx.formulaText, ctx.offset)));
2470
3068
  const selections = ((_refSelectionsRenderS = refSelectionsRenderService === null || refSelectionsRenderService === void 0 ? void 0 : refSelectionsRenderService.getSelectionDataWithStyle()) !== null && _refSelectionsRenderS !== void 0 ? _refSelectionsRenderS : []).map((i) => i.rangeWithCoord);
2471
- if (isAdd) selections.push(range);
2472
- else selections[selections.length - 1] = range;
3069
+ if (isAdd) {
3070
+ if (selections.length > 0 && isSameFormulaSelection(selections[selections.length - 1], range)) return;
3071
+ selections.push(range);
3072
+ } else {
3073
+ if (shouldSkipFormulaReferenceUpdate(isAdd, selections.length)) return;
3074
+ selections[selections.length - 1] = range;
3075
+ }
3076
+ if (duplicateEndGuard.shouldSkip(selections, true)) return;
2473
3077
  onSelectionsChange(selections, true);
2474
3078
  }
2475
3079
  }
@@ -2480,7 +3084,10 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2480
3084
  }
2481
3085
  }, [
2482
3086
  commandService,
3087
+ contextService,
3088
+ duplicateEndGuard,
2483
3089
  editor,
3090
+ editorService,
2484
3091
  isSelectingRef,
2485
3092
  lexerTreeBuilder,
2486
3093
  listenSelectionSet,
@@ -2501,7 +3108,7 @@ const useSheetSelectionChange = (isNeed, isFocus, isSelectingRef, unitId, subUni
2501
3108
  sheetSkeletonManagerService,
2502
3109
  themeService,
2503
3110
  univerInstanceService,
2504
- currentWorkbook: currentUnit
3111
+ currentWorkbook: activeWorkbook
2505
3112
  });
2506
3113
  });
2507
3114
  return () => sub.unsubscribe();
@@ -2863,18 +3470,22 @@ const getFormulaText = (formula) => {
2863
3470
 
2864
3471
  //#endregion
2865
3472
  //#region src/views/formula-editor/index.tsx
3473
+ function shouldApplyFormulaSelectionChange(selectingMode, isFocusing, hasActiveInteraction) {
3474
+ return Boolean(selectingMode) || Boolean(isFocusing) || hasActiveInteraction;
3475
+ }
2866
3476
  function syncCounterpartFormulaEditorSelection(editorService, editorId, selections) {
2867
3477
  var _editorService$getEdi;
2868
3478
  if (!(selections === null || selections === void 0 ? void 0 : selections.length)) return;
2869
3479
  const syncEditorId = editorId === DOCS_NORMAL_EDITOR_UNIT_ID_KEY ? DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY : editorId === DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY ? DOCS_NORMAL_EDITOR_UNIT_ID_KEY : null;
2870
3480
  if (!syncEditorId) return;
2871
- (_editorService$getEdi = editorService.getEditor(syncEditorId)) === null || _editorService$getEdi === void 0 || _editorService$getEdi.setSelectionRanges(selections);
3481
+ (_editorService$getEdi = editorService.getEditor(syncEditorId)) === null || _editorService$getEdi === void 0 || _editorService$getEdi.setSelectionRanges(selections, false);
2872
3482
  }
2873
3483
  const FormulaEditor = forwardRef((props, ref) => {
2874
3484
  var _document$getBody$dat, _document$getBody, _configService$getCon, _configService$getCon2;
2875
3485
  const { errorText, initValue, unitId, subUnitId, isFocus: _isFocus = true, isSupportAcrossSheet = false, onFocus = noop, onBlur = noop, onChange: propOnChange, onVerify, className, editorId: propEditorId, moveCursor = true, onFormulaSelectingChange: propOnFormulaSelectingChange, keyboardEventConfig, onMoveInEditor, resetSelectionOnBlur = true, autoScrollbar = true, isSingle = true, disableSelectionOnClick = false, autofocus = true, disableContextMenu, style, borderless = false, canvasStyle } = props;
2876
3486
  const editorService = useDependency(IEditorService);
2877
3487
  const commandService = useDependency(ICommandService);
3488
+ const injector = useDependency(Injector);
2878
3489
  const sheetEmbeddingRef = useRef(null);
2879
3490
  const onChange = useEvent(propOnChange);
2880
3491
  useImperativeHandle(ref, () => ({ isClickOutSide: (e) => {
@@ -2884,7 +3495,7 @@ const FormulaEditor = forwardRef((props, ref) => {
2884
3495
  const onFormulaSelectingChange = useEvent(propOnFormulaSelectingChange);
2885
3496
  const searchFunctionRef = useRef(null);
2886
3497
  const editorRef = useRef(void 0);
2887
- const editor = editorRef.current;
3498
+ const [editor, setEditor] = useState();
2888
3499
  const [isFocus, setIsFocus] = useState(_isFocus);
2889
3500
  const formulaEditorContainerRef = useRef(null);
2890
3501
  const editorId = useMemo(() => propEditorId !== null && propEditorId !== void 0 ? propEditorId : createInternalEditorID(`${EMBEDDING_FORMULA_EDITOR}-${generateRandomId(4)}`), []);
@@ -2900,6 +3511,7 @@ const FormulaEditor = forwardRef((props, ref) => {
2900
3511
  const { isSelecting, isSelectingRef } = useFormulaSelecting({
2901
3512
  unitId,
2902
3513
  subUnitId,
3514
+ editor,
2903
3515
  editorId,
2904
3516
  isFocus,
2905
3517
  disableOnClick: disableSelectionOnClick
@@ -2912,11 +3524,33 @@ const FormulaEditor = forwardRef((props, ref) => {
2912
3524
  const docFocusing = (currentDoc === null || currentDoc === void 0 ? void 0 : currentDoc.getUnitId()) === editorId;
2913
3525
  const refSelections = useRef([]);
2914
3526
  const getRefSelections = useEvent(() => refSelections.current);
3527
+ const getRefSelectionCount = useEvent(() => getRefSelections().length);
2915
3528
  const selectingMode = isSelecting;
2916
3529
  const functionScreenTips = (_configService$getCon = (_configService$getCon2 = useDependency(IConfigService).getConfig("sheets-formula-ui.base.config")) === null || _configService$getCon2 === void 0 ? void 0 : _configService$getCon2.functionScreenTips) !== null && _configService$getCon !== void 0 ? _configService$getCon : true;
2917
3530
  useUpdateEffect(() => {
2918
3531
  onChange(formulaText);
2919
3532
  }, [formulaText, onChange]);
3533
+ useEffect(() => {
3534
+ if (!isFocus || !editor) return;
3535
+ const subscription = editor.input$.subscribe(({ content, isComposing }) => {
3536
+ if (isComposing) return;
3537
+ queueMicrotask(() => {
3538
+ var _editor$getSelectionR, _editor$getDocumentDa, _editor$getDocumentDa2;
3539
+ const selection = (_editor$getSelectionR = editor.getSelectionRanges()) === null || _editor$getSelectionR === void 0 ? void 0 : _editor$getSelectionR[0];
3540
+ const normalizedSelection = getSelectionAfterLaggingFormulaInput((_editor$getDocumentDa = (_editor$getDocumentDa2 = editor.getDocumentData().body) === null || _editor$getDocumentDa2 === void 0 ? void 0 : _editor$getDocumentDa2.dataStream) !== null && _editor$getDocumentDa !== void 0 ? _editor$getDocumentDa : "", selection, content);
3541
+ if (!normalizedSelection) return;
3542
+ const selections = [normalizedSelection];
3543
+ editor.setSelectionRanges(selections, false);
3544
+ syncCounterpartFormulaEditorSelection(editorService, editorId, selections);
3545
+ });
3546
+ });
3547
+ return () => subscription.unsubscribe();
3548
+ }, [
3549
+ editor,
3550
+ editorId,
3551
+ editorService,
3552
+ isFocus
3553
+ ]);
2920
3554
  const highlightDoc = useDocHight("=");
2921
3555
  const highlightSheet = useSheetHighlight(unitId, subUnitId);
2922
3556
  const highlight = useEvent((text, isNeedResetSelection = true, isEnd, newSelections) => {
@@ -2924,18 +3558,18 @@ const FormulaEditor = forwardRef((props, ref) => {
2924
3558
  highTextRef.current = text;
2925
3559
  const formulaStr = text[0] === "=" ? text.slice(1) : "";
2926
3560
  const sequenceNodes = getFormulaToken(formulaStr);
2927
- const parsedFormula = sequenceNodes.reduce((pre, cur) => typeof cur === "object" ? `${pre}${cur.token}` : `${pre}${cur}`, "");
2928
- const ranges = highlightDoc(editorRef.current, parsedFormula === formulaStr ? sequenceNodes : [], isNeedResetSelection, newSelections);
3561
+ const ranges = highlightDoc(editorRef.current, sequenceNodes, isNeedResetSelection, newSelections, formulaStr);
2929
3562
  refSelections.current = ranges;
2930
3563
  if (isEnd) {
2931
3564
  const currentDocSelections = newSelections !== null && newSelections !== void 0 ? newSelections : editor === null || editor === void 0 ? void 0 : editor.getSelectionRanges();
2932
- if ((currentDocSelections === null || currentDocSelections === void 0 ? void 0 : currentDocSelections.length) !== 1) return;
2933
- const refIndex = findRefSequenceIndex(sequenceNodes, findIndexFromSequenceNodes(sequenceNodes, currentDocSelections[0].startOffset - 1, false));
2934
- if (refIndex >= 0) {
2935
- const target = ranges.splice(refIndex, 1)[0];
2936
- target && ranges.push(target);
3565
+ if ((currentDocSelections === null || currentDocSelections === void 0 ? void 0 : currentDocSelections.length) === 1) {
3566
+ const refIndex = findRefSequenceIndex(sequenceNodes, findIndexFromSequenceNodes(sequenceNodes, currentDocSelections[0].startOffset - 1, false));
3567
+ if (refIndex >= 0) {
3568
+ const target = ranges.splice(refIndex, 1)[0];
3569
+ target && ranges.push(target);
3570
+ }
2937
3571
  }
2938
- highlightSheet(isFocus ? ranges : [], editorRef.current);
3572
+ highlightSheet(isFocus ? ranges : [], editorRef.current, isEnd);
2939
3573
  }
2940
3574
  });
2941
3575
  useEffect(() => {
@@ -3000,13 +3634,52 @@ const FormulaEditor = forwardRef((props, ref) => {
3000
3634
  },
3001
3635
  canvasStyle
3002
3636
  }, formulaEditorContainerRef.current);
3003
- editorRef.current = editorService.getEditor(editorId);
3637
+ const registeredEditor = editorService.getEditor(editorId);
3638
+ editorRef.current = registeredEditor;
3639
+ setEditor(registeredEditor);
3004
3640
  highlight(initValue, false, true);
3005
3641
  }
3006
3642
  return () => {
3643
+ editorRef.current = void 0;
3007
3644
  dispose === null || dispose === void 0 || dispose.dispose();
3008
3645
  };
3009
3646
  }, []);
3647
+ useEffect(() => {
3648
+ var _ref, _resolveFormulaEmbedR;
3649
+ const formulaEditorContainer = formulaEditorContainerRef.current;
3650
+ if (!isFocus || !formulaEditorContainer || !injector.has(IFormulaEmbedRuntimeFocusCoordinator)) return;
3651
+ const focusCoordinator = injector.get(IFormulaEmbedRuntimeFocusCoordinator);
3652
+ const scope = (_ref = (_resolveFormulaEmbedR = resolveFormulaEmbedRuntimeDomScope(formulaEditorContainer)) !== null && _resolveFormulaEmbedR !== void 0 ? _resolveFormulaEmbedR : focusCoordinator.resolveRuntimeScopeByChildUnitId(editorId)) !== null && _ref !== void 0 ? _ref : resolveActiveFormulaEmbedRuntimeDomScope(formulaEditorContainer.ownerDocument);
3653
+ if (!scope) return;
3654
+ const collection = new DisposableCollection();
3655
+ const interactionBoundaryService = injector.has(IFormulaEmbedInteractionBoundaryService) ? injector.get(IFormulaEmbedInteractionBoundaryService) : void 0;
3656
+ collection.add(focusCoordinator.acquireLease({
3657
+ embedId: scope.embedId,
3658
+ role: "child-editor",
3659
+ owner: "sheet-formula-editor",
3660
+ hostUnitId: scope.hostUnitId,
3661
+ childUnitId: scope.childUnitId,
3662
+ associatedChildUnitIds: [editorId]
3663
+ }));
3664
+ if (interactionBoundaryService) collection.add(interactionBoundaryService.registerOwnedElement(scope.embedId, formulaEditorContainer));
3665
+ collection.add(focusCoordinator.registerElement({
3666
+ embedId: scope.embedId,
3667
+ role: "child-editor",
3668
+ element: formulaEditorContainer
3669
+ }));
3670
+ collection.add(registerFormulaEditorRuntimePortal({
3671
+ embedId: scope.embedId,
3672
+ editorId,
3673
+ ownerDocument: formulaEditorContainer.ownerDocument,
3674
+ interactionBoundaryService,
3675
+ focusCoordinator
3676
+ }));
3677
+ return () => collection.dispose();
3678
+ }, [
3679
+ editorId,
3680
+ injector,
3681
+ isFocus
3682
+ ]);
3010
3683
  useLayoutEffect(() => {
3011
3684
  let focusRetryFrame = 0;
3012
3685
  let finalFocusRetryFrame = 0;
@@ -3040,10 +3713,10 @@ const FormulaEditor = forwardRef((props, ref) => {
3040
3713
  resetSelectionOnBlur
3041
3714
  ]);
3042
3715
  const { checkScrollBar } = useResize(editor, isSingle, autoScrollbar);
3043
- useRefactorEffect(isFocus, Boolean(isSelecting && docFocusing), unitId, editorId, disableContextMenu);
3044
- useLeftAndRightArrow(Boolean(isFocus && isFocusing && moveCursor), selectingMode, editor, onMoveInEditor);
3716
+ useRefactorEffect(isFocus, isSelecting, unitId, editorId, disableContextMenu);
3717
+ useLeftAndRightArrow(Boolean(isFocus && isFocusing && moveCursor), selectingMode, editor, onMoveInEditor, getRefSelectionCount);
3045
3718
  const handleSelectionChange = useEvent((refString, offset, isEnd) => {
3046
- if (!isFocusing) return;
3719
+ if (!shouldApplyFormulaSelectionChange(selectingMode, isFocusing, hasActiveFormulaEmbedInteraction(formulaEditorContainerRef.current))) return;
3047
3720
  const newSelections = offset !== -1 ? [{
3048
3721
  startOffset: offset + 1,
3049
3722
  endOffset: offset + 1,
@@ -3067,7 +3740,7 @@ const FormulaEditor = forwardRef((props, ref) => {
3067
3740
  checkScrollBar();
3068
3741
  }
3069
3742
  });
3070
- useSheetSelectionChange(isFocus && Boolean(isSelecting && docFocusing), isFocus, isSelectingRef, unitId, subUnitId, getRefSelections, isSupportAcrossSheet, Boolean(selectingMode), editor, handleSelectionChange);
3743
+ useSheetSelectionChange(isFocus && Boolean(isSelecting), isFocus, isSelectingRef, unitId, subUnitId, getRefSelections, isSupportAcrossSheet, Boolean(selectingMode), editor, handleSelectionChange);
3071
3744
  useSwitchSheet(isFocus && Boolean(isSelecting && docFocusing), unitId, isSupportAcrossSheet, setIsFocus, onBlur, () => {
3072
3745
  highlight(formulaTextRef.current, false, true);
3073
3746
  });
@@ -3090,7 +3763,13 @@ const FormulaEditor = forwardRef((props, ref) => {
3090
3763
  highlight(`=${res.text}`);
3091
3764
  }
3092
3765
  };
3093
- const handleMouseUp = () => {
3766
+ const handleMouseUp = (event) => {
3767
+ if (hasActiveFormulaEmbedInteraction(formulaEditorContainerRef.current)) return;
3768
+ if (!shouldRefocusFormulaEditorOnMouseUp({
3769
+ target: event.target,
3770
+ isFocusing,
3771
+ isPointerSelecting: docSelectionRenderService === null || docSelectionRenderService === void 0 ? void 0 : docSelectionRenderService.isOnPointerEvent
3772
+ })) return;
3094
3773
  setIsFocus(true);
3095
3774
  onFocus();
3096
3775
  focus();
@@ -3107,6 +3786,7 @@ const FormulaEditor = forwardRef((props, ref) => {
3107
3786
  }),
3108
3787
  children: /* @__PURE__ */ jsx("div", {
3109
3788
  ref: formulaEditorContainerRef,
3789
+ "data-u-comp": "formula-editor",
3110
3790
  className: "univer-relative univer-size-full",
3111
3791
  onMouseUp: handleMouseUp
3112
3792
  })
@@ -4549,227 +5229,6 @@ ImageFormulaRenderController = __decorate([
4549
5229
  __decorateParam(2, IUniverInstanceService)
4550
5230
  ], ImageFormulaRenderController);
4551
5231
 
4552
- //#endregion
4553
- //#region src/menu/menu.ts
4554
- function InsertCommonFunctionMenuItemFactory(accessor) {
4555
- const commonFunctions = [
4556
- "SUMIF",
4557
- "SUM",
4558
- "AVERAGE",
4559
- "IF",
4560
- "COUNT",
4561
- "SIN",
4562
- "MAX"
4563
- ];
4564
- let selections = commonFunctions.map((name) => ({
4565
- label: {
4566
- name,
4567
- selectable: false
4568
- },
4569
- value: name
4570
- }));
4571
- try {
4572
- const descriptionService = accessor.get(IDescriptionService);
4573
- const filtered = commonFunctions.filter((name) => Boolean(descriptionService.getFunctionInfo(name)));
4574
- if (filtered.length > 0) selections = filtered.map((name) => ({
4575
- label: {
4576
- name,
4577
- selectable: false
4578
- },
4579
- value: name
4580
- }));
4581
- } catch {}
4582
- return {
4583
- id: `${InsertFunctionOperation.id}.common`,
4584
- commandId: InsertFunctionOperation.id,
4585
- title: "sheets-formula-ui.insert.common",
4586
- tooltip: "sheets-formula-ui.insert.tooltip",
4587
- icon: "FunctionIcon",
4588
- type: MenuItemType.SELECTOR,
4589
- selections,
4590
- hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
4591
- };
4592
- }
4593
- function createInsertFunctionCategoryMenuItemFactory(functionType, categoryKey, icon) {
4594
- return function insertFunctionCategoryMenuItemFactory(accessor) {
4595
- let selections = [];
4596
- try {
4597
- selections = accessor.get(IDescriptionService).getSearchListByType(functionType).map(({ name }) => ({
4598
- label: {
4599
- name,
4600
- selectable: false
4601
- },
4602
- value: name
4603
- }));
4604
- } catch {
4605
- selections = [];
4606
- }
4607
- return {
4608
- id: `${InsertFunctionOperation.id}.${categoryKey}`,
4609
- commandId: InsertFunctionOperation.id,
4610
- title: `sheets-formula-ui.functionType.${categoryKey}`,
4611
- tooltip: "sheets-formula-ui.insert.tooltip",
4612
- icon,
4613
- type: MenuItemType.SELECTOR,
4614
- selections,
4615
- hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
4616
- };
4617
- };
4618
- }
4619
- const InsertFinancialFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Financial, "financial");
4620
- const InsertLogicalFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Logical, "logical");
4621
- const InsertTextFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Text, "text");
4622
- const InsertDateFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Date, "date");
4623
- const InsertLookupFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Lookup, "lookup");
4624
- const InsertMathFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Math, "math");
4625
- const InsertStatisticalFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Statistical, "statistical");
4626
- const InsertEngineeringFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Engineering, "engineering");
4627
- const InsertInformationFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Information, "information");
4628
- const InsertDatabaseFunctionMenuItemFactory = createInsertFunctionCategoryMenuItemFactory(FunctionType.Database, "database");
4629
- function AllFunctionsMenuItemFactory(accessor) {
4630
- return {
4631
- id: MoreFunctionsOperation.id,
4632
- title: "sheets-formula-ui.moreFunctions.allFunctions",
4633
- tooltip: "sheets-formula-ui.insert.tooltip",
4634
- type: MenuItemType.BUTTON,
4635
- hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET),
4636
- disabled$: getCurrentRangeDisable$(accessor, {
4637
- workbookTypes: [WorkbookEditablePermission],
4638
- worksheetTypes: [WorksheetEditPermission, WorksheetSetCellValuePermission],
4639
- rangeTypes: [RangeProtectionPermissionEditPoint]
4640
- })
4641
- };
4642
- }
4643
- function CopyFormulaOnlyMenuItemFactory(accessor) {
4644
- return {
4645
- id: SheetCopyFormulaOnlyCommand.id,
4646
- type: MenuItemType.BUTTON,
4647
- title: "sheets-formula-ui.operation.copyFormulaOnly",
4648
- disabled$: getCurrentRangeDisable$(accessor, {
4649
- workbookTypes: [WorkbookCopyPermission],
4650
- worksheetTypes: [WorksheetCopyPermission],
4651
- rangeTypes: [RangeProtectionPermissionViewPoint]
4652
- }),
4653
- hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
4654
- };
4655
- }
4656
- function PasteFormulaMenuItemFactory(accessor) {
4657
- return {
4658
- id: SheetOnlyPasteFormulaCommand.id,
4659
- type: MenuItemType.BUTTON,
4660
- title: "sheets-formula-ui.operation.pasteFormula",
4661
- disabled$: menuClipboardDisabledObservable(accessor).pipe(combineLatestWith(getCurrentRangeDisable$(accessor, {
4662
- workbookTypes: [WorkbookEditablePermission],
4663
- rangeTypes: [RangeProtectionPermissionEditPoint],
4664
- worksheetTypes: [WorksheetSetCellValuePermission, WorksheetEditPermission]
4665
- })), map(([d1, d2]) => d1 || d2)),
4666
- hidden$: getMenuHiddenObservable(accessor, UniverInstanceType.UNIVER_SHEET)
4667
- };
4668
- }
4669
-
4670
- //#endregion
4671
- //#region src/menu/schema.ts
4672
- const menuSchema = {
4673
- [RibbonFormulasGroup.BASIC]: {
4674
- [`${InsertFunctionOperation.id}.common`]: {
4675
- order: 0,
4676
- menuItemFactory: InsertCommonFunctionMenuItemFactory,
4677
- [MoreFunctionsOperation.id]: {
4678
- order: 0,
4679
- menuItemFactory: AllFunctionsMenuItemFactory
4680
- }
4681
- },
4682
- [`${InsertFunctionOperation.id}.financial`]: {
4683
- order: 1,
4684
- menuItemFactory: InsertFinancialFunctionMenuItemFactory,
4685
- [MoreFunctionsOperation.id]: {
4686
- order: 0,
4687
- menuItemFactory: AllFunctionsMenuItemFactory
4688
- }
4689
- },
4690
- [`${InsertFunctionOperation.id}.logical`]: {
4691
- order: 2,
4692
- menuItemFactory: InsertLogicalFunctionMenuItemFactory,
4693
- [MoreFunctionsOperation.id]: {
4694
- order: 0,
4695
- menuItemFactory: AllFunctionsMenuItemFactory
4696
- }
4697
- },
4698
- [`${InsertFunctionOperation.id}.text`]: {
4699
- order: 3,
4700
- menuItemFactory: InsertTextFunctionMenuItemFactory,
4701
- [MoreFunctionsOperation.id]: {
4702
- order: 0,
4703
- menuItemFactory: AllFunctionsMenuItemFactory
4704
- }
4705
- },
4706
- [`${InsertFunctionOperation.id}.date`]: {
4707
- order: 4,
4708
- menuItemFactory: InsertDateFunctionMenuItemFactory,
4709
- [MoreFunctionsOperation.id]: {
4710
- order: 0,
4711
- menuItemFactory: AllFunctionsMenuItemFactory
4712
- }
4713
- },
4714
- [`${InsertFunctionOperation.id}.lookup`]: {
4715
- order: 5,
4716
- menuItemFactory: InsertLookupFunctionMenuItemFactory,
4717
- [MoreFunctionsOperation.id]: {
4718
- order: 0,
4719
- menuItemFactory: AllFunctionsMenuItemFactory
4720
- }
4721
- },
4722
- [`${InsertFunctionOperation.id}.math`]: {
4723
- order: 6,
4724
- menuItemFactory: InsertMathFunctionMenuItemFactory,
4725
- [MoreFunctionsOperation.id]: {
4726
- order: 0,
4727
- menuItemFactory: AllFunctionsMenuItemFactory
4728
- }
4729
- },
4730
- [`${InsertFunctionOperation.id}.statistical`]: {
4731
- order: 7,
4732
- menuItemFactory: InsertStatisticalFunctionMenuItemFactory,
4733
- [MoreFunctionsOperation.id]: {
4734
- order: 0,
4735
- menuItemFactory: AllFunctionsMenuItemFactory
4736
- }
4737
- },
4738
- [`${InsertFunctionOperation.id}.engineering`]: {
4739
- order: 8,
4740
- menuItemFactory: InsertEngineeringFunctionMenuItemFactory,
4741
- [MoreFunctionsOperation.id]: {
4742
- order: 0,
4743
- menuItemFactory: AllFunctionsMenuItemFactory
4744
- }
4745
- },
4746
- [`${InsertFunctionOperation.id}.information`]: {
4747
- order: 9,
4748
- menuItemFactory: InsertInformationFunctionMenuItemFactory,
4749
- [MoreFunctionsOperation.id]: {
4750
- order: 0,
4751
- menuItemFactory: AllFunctionsMenuItemFactory
4752
- }
4753
- },
4754
- [`${InsertFunctionOperation.id}.database`]: {
4755
- order: 10,
4756
- menuItemFactory: InsertDatabaseFunctionMenuItemFactory,
4757
- [MoreFunctionsOperation.id]: {
4758
- order: 0,
4759
- menuItemFactory: AllFunctionsMenuItemFactory
4760
- }
4761
- }
4762
- },
4763
- [COPY_SPECIAL_MENU_ID]: { [SheetCopyFormulaOnlyCommand.id]: {
4764
- order: 0,
4765
- menuItemFactory: CopyFormulaOnlyMenuItemFactory
4766
- } },
4767
- [PASTE_SPECIAL_MENU_ID]: { [SheetOnlyPasteFormulaCommand.id]: {
4768
- order: 4,
4769
- menuItemFactory: PasteFormulaMenuItemFactory
4770
- } }
4771
- };
4772
-
4773
5232
  //#endregion
4774
5233
  //#region src/views/formula-progress/FormulaProgress.tsx
4775
5234
  /**
@@ -4989,4 +5448,4 @@ UniverSheetsFormulaUIPlugin = __decorate([
4989
5448
  ], UniverSheetsFormulaUIPlugin);
4990
5449
 
4991
5450
  //#endregion
4992
- export { FORMULA_PROMPT_ACTIVATED, FormulaEditor, FormulaReorderController, GlobalRangeSelectorService, HelpFunctionOperation, InsertFunctionOperation, MoreFunctionsOperation, RangeSelector, RefSelectionsRenderService, ReferenceAbsoluteOperation, SearchFunctionOperation, SheetCopyFormulaOnlyCommand, SheetOnlyPasteFormulaCommand, UniverSheetsFormulaUIPlugin };
5451
+ export { FORMULA_PROMPT_ACTIVATED, FormulaEditor, FormulaReorderController, GlobalRangeSelectorService, HelpFunctionOperation, InsertFunctionOperation, MoreFunctionsOperation, RangeSelector, RefSelectionsRenderService, ReferenceAbsoluteOperation, SearchFunctionOperation, SheetCopyFormulaOnlyCommand, SheetOnlyPasteFormulaCommand, menuSchema as SheetsFormulaUIMenuSchema, UniverSheetsFormulaUIPlugin };