Skip to content

Commit 5da6949

Browse files
committed
feat(docs-drawing): preserve image history semantics
1 parent 603102b commit 5da6949

5 files changed

Lines changed: 108 additions & 3 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Copyright 2023-present DreamNum Co., Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import type { IUpdateDrawingDocTransformCommandParams } from '@univerjs/docs-drawing';
18+
import { ICommandService, ImageSourceType } from '@univerjs/core';
19+
import { DocHistoryAction, RichTextEditingMutation } from '@univerjs/docs';
20+
import { UpdateDrawingDocTransformCommand } from '@univerjs/docs-drawing';
21+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
22+
import { createFacadeTestBed } from '../../../facade/__tests__/create-test-bed';
23+
24+
class MockImage {
25+
width = 800;
26+
height = 400;
27+
onload: (() => void) | null = null;
28+
onerror: (() => void) | null = null;
29+
30+
get src(): string {
31+
return '';
32+
}
33+
34+
set src(_value: string) {
35+
queueMicrotask(() => this.onload?.());
36+
}
37+
}
38+
39+
describe('UpdateDrawingDocTransformCommand', () => {
40+
let testBed: ReturnType<typeof createFacadeTestBed>;
41+
42+
beforeEach(() => {
43+
vi.stubGlobal('Image', MockImage);
44+
testBed = createFacadeTestBed();
45+
});
46+
47+
afterEach(() => {
48+
testBed.univer.dispose();
49+
vi.unstubAllGlobals();
50+
});
51+
52+
it('marks image transforms for history action summaries', async () => {
53+
const image = await testBed.document.insertImage({
54+
source: 'data:image/png;base64,image',
55+
imageSourceType: ImageSourceType.BASE64,
56+
width: 160,
57+
height: 90,
58+
textRange: {
59+
startOffset: 3,
60+
endOffset: 3,
61+
collapsed: true,
62+
segmentId: '',
63+
},
64+
});
65+
const commandService = testBed.injector.get(ICommandService);
66+
const mutationSpy = vi.spyOn(commandService, 'syncExecuteCommand');
67+
68+
const result = commandService.syncExecuteCommand<IUpdateDrawingDocTransformCommandParams>(
69+
UpdateDrawingDocTransformCommand.id,
70+
{
71+
unitId: 'test-doc',
72+
subUnitId: 'test-doc',
73+
drawings: [{ drawingId: image!.getId(), key: 'angle', value: 15 }],
74+
}
75+
);
76+
77+
expect(result).toBe(true);
78+
expect(mutationSpy).toHaveBeenCalledWith(
79+
RichTextEditingMutation.id,
80+
expect.objectContaining({ historyAction: DocHistoryAction.UpdateImage })
81+
);
82+
});
83+
});

packages/docs-drawing/src/commands/commands/__tests__/update-doc-drawing-wrapping-style.command.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PositionedObjectLayoutType,
2727
UniverInstanceType,
2828
} from '@univerjs/core';
29+
import { DocHistoryAction, RichTextEditingMutation } from '@univerjs/docs';
2930
import { TextWrappingStyle, UpdateDocDrawingWrappingStyleCommand } from '@univerjs/docs-drawing';
3031
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3132
import { createFacadeTestBed } from '../../../facade/__tests__/create-test-bed';
@@ -86,7 +87,9 @@ describe('UpdateDocDrawingWrappingStyleCommand', () => {
8687
);
8788
testBed.injector.get(IUniverInstanceService).focusUnit(otherDocument.getUnitId());
8889

89-
const result = testBed.injector.get(ICommandService).syncExecuteCommand<IUpdateDocDrawingWrappingStyleParams>(
90+
const commandService = testBed.injector.get(ICommandService);
91+
const mutationSpy = vi.spyOn(commandService, 'syncExecuteCommand');
92+
const result = commandService.syncExecuteCommand<IUpdateDocDrawingWrappingStyleParams>(
9093
UpdateDocDrawingWrappingStyleCommand.id,
9194
{
9295
unitId: 'test-doc',
@@ -100,6 +103,10 @@ describe('UpdateDocDrawingWrappingStyleCommand', () => {
100103
);
101104

102105
expect(result).toBe(true);
106+
expect(mutationSpy).toHaveBeenCalledWith(
107+
RichTextEditingMutation.id,
108+
expect.objectContaining({ historyAction: DocHistoryAction.UpdateImage })
109+
);
103110
expect(testBed.document.getImage(image!.getId())?.getImageData()).toMatchObject({
104111
layoutType: PositionedObjectLayoutType.WRAP_NONE,
105112
behindDoc: BooleanNumber.TRUE,

packages/docs-drawing/src/commands/commands/update-doc-drawing-transform.command.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ import type { IRichTextEditingMutationParams } from '@univerjs/docs';
1919
import type { IDocImage } from '../../services/doc-drawing.service';
2020
import {
2121
CommandType,
22+
DrawingTypeEnum,
2223
ICommandService,
2324
IUniverInstanceService,
2425
JSONX,
2526
Tools,
2627
UniverInstanceType,
2728
} from '@univerjs/core';
28-
import { RichTextEditingMutation } from '@univerjs/docs';
29+
import { DocHistoryAction, RichTextEditingMutation } from '@univerjs/docs';
2930

3031
export interface IDrawingDocTransform {
3132
drawingId: string;
@@ -57,6 +58,11 @@ export const UpdateDrawingDocTransformCommand: ICommand = {
5758
}
5859

5960
const oldDrawings = documentDataModel.getSnapshot().drawings ?? {};
61+
const historyAction = drawings.length > 0 && drawings.every(({ drawingId }) =>
62+
oldDrawings[drawingId]?.drawingType === DrawingTypeEnum.DRAWING_IMAGE
63+
)
64+
? DocHistoryAction.UpdateImage
65+
: undefined;
6066
const jsonX = JSONX.getInstance();
6167
const actions: JSONXActions = [];
6268

@@ -78,6 +84,7 @@ export const UpdateDrawingDocTransformCommand: ICommand = {
7884

7985
return Boolean(commandService.syncExecuteCommand<IRichTextEditingMutationParams, IRichTextEditingMutationParams>(RichTextEditingMutation.id, {
8086
unitId,
87+
historyAction,
8188
actions: actions.reduce((acc, action) => JSONX.compose(acc, action as JSONXActions), null as JSONXActions),
8289
textRanges: null,
8390
debounce: true,

packages/docs-drawing/src/commands/commands/update-doc-drawing-wrapping-style.command.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ import type { IDocDrawing } from '../../services/doc-drawing.service';
2020
import {
2121
BooleanNumber,
2222
CommandType,
23+
DrawingTypeEnum,
2324
ICommandService,
2425
IUniverInstanceService,
2526
JSONX,
2627
PositionedObjectLayoutType,
2728
Tools,
2829
UniverInstanceType,
2930
} from '@univerjs/core';
30-
import { RichTextEditingMutation } from '@univerjs/docs';
31+
import { DocHistoryAction, RichTextEditingMutation } from '@univerjs/docs';
3132

3233
/**
3334
* Controls how a document drawing participates in text layout.
@@ -106,6 +107,11 @@ export const UpdateDocDrawingWrappingStyleCommand: ICommand = {
106107
}
107108

108109
const oldDrawings = documentDataModel.getDrawings() ?? {};
110+
const historyAction = drawings.length > 0 && drawings.every(({ drawingId }) =>
111+
oldDrawings[drawingId]?.drawingType === DrawingTypeEnum.DRAWING_IMAGE
112+
)
113+
? DocHistoryAction.UpdateImage
114+
: undefined;
109115
const jsonX = JSONX.getInstance();
110116
const rawActions: JSONXActions = [];
111117

@@ -142,6 +148,7 @@ export const UpdateDocDrawingWrappingStyleCommand: ICommand = {
142148
id: RichTextEditingMutation.id,
143149
params: {
144150
unitId,
151+
historyAction,
145152
actions: rawActions.reduce(
146153
(actions, action) => JSONX.compose(actions, action as JSONXActions),
147154
null as JSONXActions

packages/docs/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export enum DocHistoryAction {
1919
EditTableCell = 'edit-table-cell',
2020
FormatParagraph = 'format-paragraph',
2121
InsertCustomRange = 'insert-custom-range',
22+
UpdateImage = 'update-image',
2223
UpdatePageLayout = 'update-page-layout',
2324
}
2425

0 commit comments

Comments
 (0)