From be77b78c9183e2df03d74a3bb10b2ca271a6b206 Mon Sep 17 00:00:00 2001 From: Ran Luo Date: Fri, 1 Nov 2024 10:54:37 +0800 Subject: [PATCH] fix: change mode set cursor (#3915) --- packages/docs-ui/src/basics/selection.ts | 46 +++++++++++++++++++ .../commands/doc-header-footer.command.ts | 19 +++++++- .../doc-selection-render.controller.ts | 33 ++----------- 3 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 packages/docs-ui/src/basics/selection.ts diff --git a/packages/docs-ui/src/basics/selection.ts b/packages/docs-ui/src/basics/selection.ts new file mode 100644 index 00000000000..b69dc69340b --- /dev/null +++ b/packages/docs-ui/src/basics/selection.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2023-present DreamNum Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { IDocumentData } from '@univerjs/core'; +import { DataStreamTreeTokenType } from '@univerjs/core'; + +export function findFirstCursorOffset(snapshot: IDocumentData) { + const { dataStream } = snapshot.body ?? {}; + const EXCLUDE_TOKENS: string[] = [ + DataStreamTreeTokenType.TABLE_START, + DataStreamTreeTokenType.TABLE_CELL_END, + DataStreamTreeTokenType.TABLE_CELL_START, + DataStreamTreeTokenType.TABLE_END, + DataStreamTreeTokenType.TABLE_ROW_END, + DataStreamTreeTokenType.TABLE_ROW_START, + DataStreamTreeTokenType.COLUMN_BREAK, + DataStreamTreeTokenType.PAGE_BREAK, + DataStreamTreeTokenType.TAB, + DataStreamTreeTokenType.DOCS_END, + DataStreamTreeTokenType.CUSTOM_BLOCK, + ]; + + if (typeof dataStream === 'string') { + for (let i = 0; i < dataStream.length; i++) { + const char = dataStream[i]; + if (!EXCLUDE_TOKENS.includes(char)) { + return i; + } + } + } + + return 0; +} diff --git a/packages/docs-ui/src/commands/commands/doc-header-footer.command.ts b/packages/docs-ui/src/commands/commands/doc-header-footer.command.ts index 76785381898..55762f18326 100644 --- a/packages/docs-ui/src/commands/commands/doc-header-footer.command.ts +++ b/packages/docs-ui/src/commands/commands/doc-header-footer.command.ts @@ -14,11 +14,12 @@ * limitations under the License. */ -import type { ICommand, IDocumentBody, IMutationInfo, JSONXActions } from '@univerjs/core'; +import type { DocumentDataModel, ICommand, IDocumentBody, IMutationInfo, JSONXActions } from '@univerjs/core'; import type { IRichTextEditingMutationParams } from '@univerjs/docs'; import { BooleanNumber, CommandType, ICommandService, IUniverInstanceService, JSONX, Tools } from '@univerjs/core'; import { DocSelectionManagerService, DocSkeletonManagerService, RichTextEditingMutation } from '@univerjs/docs'; import { DocumentEditArea, IRenderManagerService, type ITextRangeWithStyle } from '@univerjs/engine-render'; +import { findFirstCursorOffset } from '../../basics/selection'; import { HeaderFooterType } from '../../controllers/doc-header-footer.controller'; import { DocSelectionRenderService } from '../../services/selection/doc-selection-render.service'; import { SidebarDocHeaderFooterPanelOperation } from '../operations/doc-header-footer-panel.operation'; @@ -256,6 +257,7 @@ export const CloseHeaderFooterCommand: ICommand = { const commandService = accessor.get(ICommandService); const renderManagerService = accessor.get(IRenderManagerService); const docSelectionManagerService = accessor.get(DocSelectionManagerService); + const instanceService = accessor.get(IUniverInstanceService); const { unitId } = params; @@ -284,6 +286,21 @@ export const CloseHeaderFooterCommand: ICommand = { skeleton.calculate(); renderObject.mainComponent?.makeDirty(true); + queueMicrotask(() => { + const docDataModel = instanceService.getUnit(unitId); + const snapshot = docDataModel?.getSnapshot(); + if (snapshot == null) { + return; + } + const offset = findFirstCursorOffset(snapshot); + docSelectionManagerService.replaceDocRanges([ + { + startOffset: offset, + endOffset: offset, + }, + ]); + }); + commandService.executeCommand(SidebarDocHeaderFooterPanelOperation.id, { value: 'close' }); return true; diff --git a/packages/docs-ui/src/controllers/render-controllers/doc-selection-render.controller.ts b/packages/docs-ui/src/controllers/render-controllers/doc-selection-render.controller.ts index 5f525981550..0b288dc897c 100644 --- a/packages/docs-ui/src/controllers/render-controllers/doc-selection-render.controller.ts +++ b/packages/docs-ui/src/controllers/render-controllers/doc-selection-render.controller.ts @@ -14,46 +14,19 @@ * limitations under the License. */ -import type { DocumentDataModel, ICommandInfo, IDocumentData } from '@univerjs/core'; +import type { DocumentDataModel, ICommandInfo } from '@univerjs/core'; import type { IMouseEvent, IPointerEvent, IRenderContext, IRenderModule, RenderComponentType } from '@univerjs/engine-render'; import type { ISetDocZoomRatioOperationParams } from '../../commands/operations/set-doc-zoom-ratio.operation'; -import { DataStreamTreeTokenType, Disposable, ICommandService, Inject, isInternalEditorID, IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; +import { Disposable, ICommandService, Inject, isInternalEditorID, IUniverInstanceService, UniverInstanceType } from '@univerjs/core'; import { DocSelectionManagerService, DocSkeletonManagerService } from '@univerjs/docs'; import { CURSOR_TYPE, DocumentEditArea, PageLayoutType, Vector2 } from '@univerjs/engine-render'; import { neoGetDocObject } from '../../basics/component-tools'; +import { findFirstCursorOffset } from '../../basics/selection'; import { SetDocZoomRatioOperation } from '../../commands/operations/set-doc-zoom-ratio.operation'; import { IEditorService } from '../../services/editor/editor-manager.service'; import { DocSelectionRenderService } from '../../services/selection/doc-selection-render.service'; -function findFirstCursorOffset(snapshot: IDocumentData) { - const { dataStream } = snapshot.body ?? {}; - const EXCLUDE_TOKENS: string[] = [ - DataStreamTreeTokenType.TABLE_START, - DataStreamTreeTokenType.TABLE_CELL_END, - DataStreamTreeTokenType.TABLE_CELL_START, - DataStreamTreeTokenType.TABLE_END, - DataStreamTreeTokenType.TABLE_ROW_END, - DataStreamTreeTokenType.TABLE_ROW_START, - DataStreamTreeTokenType.COLUMN_BREAK, - DataStreamTreeTokenType.PAGE_BREAK, - DataStreamTreeTokenType.TAB, - DataStreamTreeTokenType.DOCS_END, - DataStreamTreeTokenType.CUSTOM_BLOCK, - ]; - - if (typeof dataStream === 'string') { - for (let i = 0; i < dataStream.length; i++) { - const char = dataStream[i]; - if (!EXCLUDE_TOKENS.includes(char)) { - return i; - } - } - } - - return 0; -} - export class DocSelectionRenderController extends Disposable implements IRenderModule { private _loadedMap = new WeakSet();