snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-16 05:09:45 +05:00
commit bcf6ef63ad
7118 changed files with 1236854 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
/**
* 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 { awaitTime } from '@univerjs/core';
import { IWatermarkTypeEnum, UNIVER_WATERMARK_STORAGE_KEY } from '@univerjs/engine-render';
import { Subject } from 'rxjs';
import { describe, expect, it, vi } from 'vitest';
import { WatermarkRenderController } from '../watermark.render.controller';
const layerInstances: Array<{ updateConfig: ReturnType<typeof vi.fn> }> = [];
vi.mock('@univerjs/engine-render', async () => {
const actual = await vi.importActual<typeof import('@univerjs/engine-render')>('@univerjs/engine-render');
class WatermarkLayer {
readonly updateConfig = vi.fn();
constructor() {
layerInstances.push(this);
}
}
return {
...actual,
IWatermarkTypeEnum: {
UserInfo: 'userInfo',
Text: 'text',
Image: 'image',
},
UNIVER_WATERMARK_LAYER_INDEX: 1000,
UNIVER_WATERMARK_STORAGE_KEY: 'UNIVER_WATERMARK_STORAGE_KEY',
WatermarkLayer,
};
});
describe('WatermarkRenderController', () => {
it('should init layer, load config and react to updates', async () => {
layerInstances.length = 0;
const updateConfig$ = new Subject<unknown>();
const updateWatermarkConfig = vi.fn();
const scene = {
addLayer: vi.fn(),
};
const makeDirty = vi.fn();
const localStorageService = {
getItem: vi.fn(async () => ({
type: IWatermarkTypeEnum.Text,
config: { text: { content: 'init' } },
})),
};
const userManagerService = {
getCurrentUser: vi.fn(() => ({ id: 'u1' })),
};
const controller = new WatermarkRenderController(
{
scene,
mainComponent: { makeDirty },
} as never,
{
updateConfig$: updateConfig$.asObservable(),
updateWatermarkConfig,
} as never,
localStorageService as never,
userManagerService as never
);
expect(scene.addLayer).toHaveBeenCalledTimes(1);
expect(localStorageService.getItem).toHaveBeenCalledWith(UNIVER_WATERMARK_STORAGE_KEY);
await awaitTime(0);
expect(updateWatermarkConfig).toHaveBeenCalledWith({
type: IWatermarkTypeEnum.Text,
config: { text: { content: 'init' } },
});
expect(makeDirty).toHaveBeenCalled();
const layer = layerInstances[0];
expect(layer).toBeDefined();
updateConfig$.next(null);
expect(layer.updateConfig).toHaveBeenCalledWith();
updateConfig$.next({
type: IWatermarkTypeEnum.UserInfo,
config: { userInfo: { name: true } },
});
expect(layer.updateConfig).toHaveBeenCalledWith(
{ type: IWatermarkTypeEnum.UserInfo, config: { userInfo: { name: true } } },
{ id: 'u1' }
);
updateConfig$.next({
type: IWatermarkTypeEnum.Image,
config: { image: { url: 'img' } },
});
expect(layer.updateConfig).toHaveBeenCalledWith({
type: IWatermarkTypeEnum.Image,
config: { image: { url: 'img' } },
});
await controller.dispose();
});
it('should skip init config update when storage is empty', async () => {
layerInstances.length = 0;
const updateConfig$ = new Subject<unknown>();
const updateWatermarkConfig = vi.fn();
const makeDirty = vi.fn();
const _controller = new WatermarkRenderController(
{
scene: { addLayer: vi.fn() },
mainComponent: { makeDirty },
} as never,
{
updateConfig$: updateConfig$.asObservable(),
updateWatermarkConfig,
} as never,
{ getItem: vi.fn(async () => undefined) } as never,
{ getCurrentUser: vi.fn(() => ({ id: 'u1' })) } as never
);
expect(_controller).toBeDefined();
await awaitTime(0);
expect(updateWatermarkConfig).not.toHaveBeenCalled();
expect(makeDirty).not.toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,74 @@
/**
* 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 { UnitModel } from '@univerjs/core';
import type { IRenderContext, IRenderModule, IWatermarkConfigWithType } from '@univerjs/engine-render';
import { ILocalStorageService, Inject, RxDisposable, UserManagerService } from '@univerjs/core';
import {
IWatermarkTypeEnum,
UNIVER_WATERMARK_LAYER_INDEX,
UNIVER_WATERMARK_STORAGE_KEY,
WatermarkLayer,
} from '@univerjs/engine-render';
import { WatermarkService } from '../services/watermark.service';
export class WatermarkRenderController extends RxDisposable implements IRenderModule {
private readonly _watermarkLayer: WatermarkLayer;
constructor(
private readonly _context: IRenderContext<UnitModel>,
@Inject(WatermarkService) private _watermarkService: WatermarkService,
@Inject(ILocalStorageService) private _localStorageService: ILocalStorageService,
@Inject(UserManagerService) private _userManagerService: UserManagerService
) {
super();
this._watermarkLayer = new WatermarkLayer(_context.scene, [], UNIVER_WATERMARK_LAYER_INDEX);
this._initAddRender();
this._initWatermarkUpdate();
this._initWatermarkConfig();
}
private _initAddRender() {
const { scene } = this._context;
scene.addLayer(this._watermarkLayer);
}
private async _initWatermarkConfig() {
const config = await this._localStorageService.getItem<IWatermarkConfigWithType>(UNIVER_WATERMARK_STORAGE_KEY);
if (config) {
this._watermarkService.updateWatermarkConfig(config);
this._context.mainComponent?.makeDirty();
}
}
private _initWatermarkUpdate() {
this.disposeWithMe(
this._watermarkService.updateConfig$.subscribe((_config) => {
if (!_config) {
this._watermarkLayer.updateConfig();
this._context.mainComponent?.makeDirty();
return;
}
if (_config.type === IWatermarkTypeEnum.UserInfo) {
this._watermarkLayer.updateConfig(_config, this._userManagerService.getCurrentUser());
} else {
this._watermarkLayer.updateConfig(_config);
}
this._context.mainComponent?.makeDirty();
})
);
}
}