diff --git a/packages/core/src/services/instance/__tests__/instance.service.spec.ts b/packages/core/src/services/instance/__tests__/instance.service.spec.ts index 3c34345119..d2d0dc5801 100644 --- a/packages/core/src/services/instance/__tests__/instance.service.spec.ts +++ b/packages/core/src/services/instance/__tests__/instance.service.spec.ts @@ -183,7 +183,7 @@ describe('UniverInstanceService', () => { expect(contextService.getContextValue(FOCUSING_BOARD)).toBe(false); }); - it('should replace docs and dispose units while resetting focus and current', () => { + it('should dispose units while resetting focus and current', () => { const disposed: string[] = []; service.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_DOC).subscribe((unit) => { disposed.push(unit.getUnitId()); @@ -192,10 +192,6 @@ describe('UniverInstanceService', () => { const doc = service.createUnit, DocumentDataModel>(UniverInstanceType.UNIVER_DOC, createDocData()); service.focusUnit(doc.getUnitId()); - const replacement = new DocumentDataModel(createDocData('doc-unit')); - service.changeDoc(doc.getUnitId(), replacement); - expect(service.getUnit('doc-unit')).toBe(replacement); - expect(service.disposeUnit('doc-unit')).toBe(true); expect(disposed).toEqual(['doc-unit']); expect(service.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC)).toBeNull(); diff --git a/packages/core/src/services/instance/instance.service.ts b/packages/core/src/services/instance/instance.service.ts index 908e26c31e..30670fb23a 100644 --- a/packages/core/src/services/instance/instance.service.ts +++ b/packages/core/src/services/instance/instance.service.ts @@ -113,9 +113,6 @@ export interface IUniverInstanceService { registerCtorForType(type: UniverInstanceType, ctor: new (...args: any[]) => T): IDisposable; - /** @deprecated */ - changeDoc(unitId: string, doc: DocumentDataModel): void; - getUnit(id: string, type?: UniverInstanceType): Nullable; getAllUnitsForType(type: UniverInstanceType): T[]; getUnitType(unitId: string): UniverInstanceType; @@ -258,18 +255,6 @@ export class UniverInstanceService extends Disposable implements IUniverInstance return (this._unitsByType.get(type) ?? []) as T[]; } - changeDoc(unitId: string, doc: DocumentDataModel): void { - const allDocs = this.getAllUnitsForType(UniverInstanceType.UNIVER_DOC); - const oldDoc = allDocs.find((doc) => doc.getUnitId() === unitId); - - if (oldDoc != null) { - const index = allDocs.indexOf(oldDoc); - allDocs.splice(index, 1); - } - - this.__addUnit(doc); - } - private readonly _focused$ = new BehaviorSubject>(null); readonly focused$ = this._focused$.asObservable(); get focused(): Nullable { diff --git a/packages/sheets-formula-ui/src/views/more-functions/__tests__/MoreFunctions.spec.tsx b/packages/sheets-formula-ui/src/views/more-functions/__tests__/MoreFunctions.spec.tsx index 142d555028..c410fab8ce 100644 --- a/packages/sheets-formula-ui/src/views/more-functions/__tests__/MoreFunctions.spec.tsx +++ b/packages/sheets-formula-ui/src/views/more-functions/__tests__/MoreFunctions.spec.tsx @@ -278,8 +278,6 @@ class TestUniverInstanceService { return { dispose: () => {} }; } - changeDoc(): void {} - getUnitType() { return UniverInstanceType.UNIVER_SHEET; } diff --git a/packages/slides-ui/src/controllers/__tests__/slide-editing-render-business.spec.ts b/packages/slides-ui/src/controllers/__tests__/slide-editing-render-business.spec.ts new file mode 100644 index 0000000000..5d177e6d29 --- /dev/null +++ b/packages/slides-ui/src/controllers/__tests__/slide-editing-render-business.spec.ts @@ -0,0 +1,139 @@ +/** + * Copyright 2023-present DreamNum Co., Ltd. + * + * 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 { DocumentDataModel, Injector } from '@univerjs/core'; +import type { IRenderContext, IRichTextProps } from '@univerjs/engine-render'; +import type { ISlideData } from '@univerjs/slides'; +import { + ICommandService, + IUniverInstanceService, + LocaleService, + Univer, + UniverInstanceType, +} from '@univerjs/core'; +import { + DocSelectionManagerService, + DocStateEmitService, + RichTextEditingMutation, +} from '@univerjs/docs'; +import { EditorService, IEditorService, ReplaceSnapshotCommand } from '@univerjs/docs-ui'; +import { IRenderManagerService, RichText } from '@univerjs/engine-render'; +import { SlideDataModel } from '@univerjs/slides'; +import { DesktopLayoutService, ILayoutService } from '@univerjs/ui'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { SLIDE_EDITOR_ID } from '../../const'; +import { ISlideEditorBridgeService, SlideEditorBridgeService } from '../../services/slide-editor-bridge.service'; +import { ISlideEditorManagerService, SlideEditorManagerService } from '../../services/slide-editor-manager.service'; +import { SlideEditingRenderController } from '../slide-editing.render-controller'; + +const unitId = 'slide-unit'; + +function createSlideSnapshot(): Partial { + return { + id: unitId, + title: 'Editor test deck', + pageSize: { width: 960, height: 540 }, + body: { + pageOrder: [], + pages: {}, + }, + }; +} + +function createRichText(injector: Injector, id: string, text: string, top: number): RichText { + const props: IRichTextProps = { + text, + zIndex: 1, + left: 10, + top, + width: 200, + height: 40, + }; + + return injector.createInstance(RichText, injector.get(LocaleService), id, props); +} + +describe('SlideEditingRenderController', () => { + let univer: Univer; + let controller: SlideEditingRenderController; + + beforeEach(() => { + univer = new Univer(); + const injector = univer.__getInjector(); + const renderManagerService = { + getRenderUnitById: () => null, + } as unknown as IRenderManagerService; + + injector.add([IRenderManagerService, { useValue: renderManagerService }]); + injector.add([DocSelectionManagerService]); + injector.add([DocStateEmitService]); + injector.add([IEditorService, { useClass: EditorService }]); + injector.add([ILayoutService, { useClass: DesktopLayoutService }]); + injector.add([ISlideEditorBridgeService, { useClass: SlideEditorBridgeService }]); + injector.add([ISlideEditorManagerService, { useClass: SlideEditorManagerService }]); + + const instanceService = injector.get(IUniverInstanceService); + instanceService.registerCtorForType(UniverInstanceType.UNIVER_SLIDE, SlideDataModel); + const commandService = injector.get(ICommandService); + commandService.registerCommand(RichTextEditingMutation); + commandService.registerCommand(ReplaceSnapshotCommand); + + const slide = univer.createUnit(UniverInstanceType.UNIVER_SLIDE, createSlideSnapshot()); + controller = injector.createInstance(SlideEditingRenderController, { + unitId, + unit: slide, + } as IRenderContext); + }); + + afterEach(() => { + controller?.dispose(); + univer.dispose(); + }); + + it('keeps the registered editor unit while replacing its snapshot', () => { + const injector = univer.__getInjector(); + const instanceService = injector.get(IUniverInstanceService); + const editorBridgeService = injector.get(ISlideEditorBridgeService); + const firstText = createRichText(injector, 'first', 'First text', 20); + const secondText = createRichText(injector, 'second', 'Second text', 80); + + editorBridgeService.setEditorRect({ + scene: null as never, + engine: null as never, + unitId, + pageId: 'page-1', + richTextObj: firstText, + }); + + const editorDocument = instanceService.getUnit(SLIDE_EDITOR_ID, UniverInstanceType.UNIVER_DOC); + expect(editorDocument?.getBody()?.dataStream).toBe('First text\r\n'); + + editorBridgeService.setEditorRect({ + scene: null as never, + engine: null as never, + unitId, + pageId: 'page-1', + richTextObj: secondText, + }); + + expect(instanceService.getUnit(SLIDE_EDITOR_ID, UniverInstanceType.UNIVER_DOC)).toBe(editorDocument); + expect(editorDocument?.getBody()?.dataStream).toBe('Second text\r\n'); + expect(instanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC)).toBe(editorDocument); + + firstText.dispose(); + secondText.dispose(); + }); +}); diff --git a/packages/slides-ui/src/controllers/slide-editing.render-controller.ts b/packages/slides-ui/src/controllers/slide-editing.render-controller.ts index ca7833bf9d..6e7db04262 100644 --- a/packages/slides-ui/src/controllers/slide-editing.render-controller.ts +++ b/packages/slides-ui/src/controllers/slide-editing.render-controller.ts @@ -68,6 +68,7 @@ import { IEditorService, MoveCursorOperation, MoveSelectionOperation, + ReplaceSnapshotCommand, VIEWPORT_KEY, } from '@univerjs/docs-ui'; import { @@ -249,7 +250,17 @@ export class SlideEditingRenderController extends Disposable implements IRenderM documentModel!.updateDocumentDataPageSize((endX - startX) / scaleX); } - this._instanceSrv.changeDoc(editorUnitId, documentModel!); + const snapshot = documentModel!.getSnapshot(); + const editorDocument = this._instanceSrv.getUnit(editorUnitId, UniverInstanceType.UNIVER_DOC); + if (editorDocument == null) { + this._instanceSrv.createUnit(UniverInstanceType.UNIVER_DOC, snapshot); + } else { + this._commandService.syncExecuteCommand(ReplaceSnapshotCommand.id, { + unitId: editorUnitId, + snapshot, + }); + } + this._instanceSrv.setCurrentUnitForType(editorUnitId); this._contextService.setContextValue(FOCUSING_EDITOR_BUT_HIDDEN, true); this._textSelectionManagerService.replaceTextRanges([{ startOffset: 0,