refactor(core): cleanup unused utilities (#6908)

This commit is contained in:
白熱
2026-05-21 21:16:41 +08:00
committed by GitHub
parent 0839f630b8
commit 0b99692a4d
39 changed files with 214 additions and 223 deletions
+6
View File
@@ -14,6 +14,12 @@
* limitations under the License.
*/
/**
* A no-op (no operation) function that does nothing.
* Use this as a default placeholder for callbacks or optional handlers.
*/
export function noop(): void {}
export function throttle<T extends (...args: any[]) => any>(fn: T, wait: number = 16): T {
let lastTime = 0;
let timer: number | null = null;
@@ -21,8 +21,8 @@ import type { CustomRangeType, IDocumentBody, ITextRun } from '../../../../types
import type { DocumentDataModel } from '../../document-data-model';
import type { TextXAction } from '../action-types';
import type { TextXSelection } from '../text-x';
import fastDiff from 'fast-diff';
import { Tools, UpdateDocsAttributeType } from '../../../../shared';
import { textDiff } from '../../../../shared/text-diff';
import { TextXActionType } from '../action-types';
import { TextX } from '../text-x';
import { getBodySlice, getTextRunSlice } from '../utils';
@@ -284,7 +284,7 @@ export const replaceSelectionTextX = (params: IReplaceSelectionTextXParams) => {
if (!body) return false;
const oldBody = selection.collapsed ? null : getBodySlice(body, selection.startOffset, selection.endOffset);
const diffs = textDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream);
const diffs = fastDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream);
let cursor = 0;
const actions = diffs.map(([type, text]) => {
switch (type) {
@@ -350,7 +350,7 @@ export const replaceSelectionTextRuns = (params: IReplaceSelectionTextRunsParams
if (!body) return false;
const oldBody = selection.collapsed ? null : getBodySlice(body, selection.startOffset, selection.endOffset);
const diffs = textDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream);
const diffs = fastDiff(oldBody ? oldBody.dataStream : '', insertBody.dataStream);
let cursor = 0;
const actions = diffs.map(([type, text]) => {
switch (type) {
+38 -7
View File
@@ -25,9 +25,22 @@ export * from './common/const';
export * from './common/di';
export { shallowEqual } from './common/equal';
export { CanceledError, CustomCommandExecutionError } from './common/error';
export { throttle } from './common/function';
export type { IAsyncInterceptor, ICellInterceptor, IComposeInterceptors, IInterceptor, InterceptorHandler } from './common/interceptor';
export { AsyncInterceptorManager, composeInterceptors, createAsyncInterceptorKey, createInterceptorKey, InterceptorEffectEnum, InterceptorManager } from './common/interceptor';
export { noop, throttle } from './common/function';
export type {
IAsyncInterceptor,
ICellInterceptor,
IComposeInterceptors,
IInterceptor,
InterceptorHandler,
} from './common/interceptor';
export {
AsyncInterceptorManager,
composeInterceptors,
createAsyncInterceptorKey,
createInterceptorKey,
InterceptorEffectEnum,
InterceptorManager,
} from './common/interceptor';
export { invertColorByHSL } from './common/invert-color/invert-hsl';
// invert color utils
export { invertColorByMatrix } from './common/invert-color/invert-rgb';
@@ -47,7 +60,15 @@ export * from './docs/data-model';
export { JSON1, JSONX } from './docs/data-model/json-x/json-x';
export type { JSONXActions, JSONXPath } from './docs/data-model/json-x/json-x';
export { replaceInDocumentBody } from './docs/data-model/replacement';
export { ParagraphStyleBuilder, ParagraphStyleValue, RichTextBuilder, RichTextValue, TextDecorationBuilder, TextStyleBuilder, TextStyleValue } from './docs/data-model/rich-text-builder';
export {
ParagraphStyleBuilder,
ParagraphStyleValue,
RichTextBuilder,
RichTextValue,
TextDecorationBuilder,
TextStyleBuilder,
TextStyleValue,
} from './docs/data-model/rich-text-builder';
export { DEFAULT_DOCUMENT_SUB_COMPONENT_ID } from './docs/data-model/subdocument';
export { ActionIterator } from './docs/data-model/text-x/action-iterator';
export {
@@ -119,7 +140,12 @@ export { PermissionService } from './services/permission/permission.service';
export { IPermissionService, PermissionStatus } from './services/permission/type';
export type { IPermissionParam } from './services/permission/type';
export type { IPermissionPoint } from './services/permission/type';
export type { IPermissionTypes, RangePermissionPointConstructor, WorkbookPermissionPointConstructor, WorkSheetPermissionPointConstructor } from './services/permission/type';
export type {
IPermissionTypes,
RangePermissionPointConstructor,
WorkbookPermissionPointConstructor,
WorkSheetPermissionPointConstructor,
} from './services/permission/type';
export { type DependencyOverride, mergeOverrideWithDependencies } from './services/plugin/plugin-override';
export type { PluginCtor } from './services/plugin/plugin.service';
export { DependentOn, Plugin, PluginService } from './services/plugin/plugin.service';
@@ -150,7 +176,6 @@ export { customNameCharacterCheck, nameCharacterCheck } from './shared/name';
export { type BBox, type IRTreeItem, RBush, RTree } from './shared/r-tree';
export { getIntersectRange } from './shared/range';
export { afterTime, bufferDebounceTime, convertObservableToBehaviorSubject, fromCallback, takeAfter } from './shared/rxjs';
export { textDiff } from './shared/text-diff';
export { awaitTime, delayAnimationFrame } from './shared/timer';
export { isNodeEnv } from './shared/tools';
export * from './sheets/clone';
@@ -194,5 +219,11 @@ export { DataValidationStatus } from './types/enum/data-validation-status';
export { DataValidationType } from './types/enum/data-validation-type';
export * from './types/interfaces';
export type { ICellCustomRender, ICellRenderContext } from './types/interfaces/i-cell-custom-render';
export type { IDataValidationRule, IDataValidationRuleBase, IDataValidationRuleInfo, IDataValidationRuleOptions, ISheetDataValidationRule } from './types/interfaces/i-data-validation';
export type {
IDataValidationRule,
IDataValidationRuleBase,
IDataValidationRuleInfo,
IDataValidationRuleOptions,
ISheetDataValidationRule,
} from './types/interfaces/i-data-validation';
export { type IUniverConfig, Univer } from './univer';
-17
View File
@@ -1,17 +0,0 @@
/**
* 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.
*/
export { default as textDiff } from 'fast-diff';
+14
View File
@@ -14,10 +14,24 @@
* limitations under the License.
*/
/**
* Returns a Promise that resolves after the specified number of milliseconds.
* Use this to pause execution for a given duration.
*
* @param ms The number of milliseconds to wait before resolving.
* @returns A Promise that resolves after `ms` milliseconds.
*/
export function awaitTime(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Returns a Promise that resolves after the specified number of animation frames.
* Use this to wait for the browser to complete one or more rendering cycles.
*
* @param frames The number of animation frames to wait before resolving. Defaults to `1`.
* @returns A Promise that resolves after `frames` animation frames.
*/
export function delayAnimationFrame(frames: number = 1): Promise<void> {
return new Promise((resolve) => {
let count = 0;
-29
View File
@@ -19,35 +19,6 @@ import type { Nullable } from './types';
import { customAlphabet, nanoid } from 'nanoid';
import { isLegalUrl, normalizeUrl, topLevelDomainSet } from '../common/url';
const alphabets = [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
/**
* Deep diff between two object
* @param oneValue The first test value
@@ -16,6 +16,7 @@
import type { DocumentDataModel, ICommand, IDocumentData, Injector } from '@univerjs/core';
import {
awaitTime,
Direction,
ICommandService,
IUniverInstanceService,
@@ -37,10 +38,6 @@ import { MoveDocDrawingsCommand } from '../move-drawings.command';
import { RemoveDocDrawingCommand } from '../remove-doc-drawing.command';
import { UpdateDocDrawingDistanceCommand, UpdateDocDrawingWrapTextCommand, UpdateDrawingDocTransformCommand } from '../update-doc-drawing.command';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function createBaseDocData(): IDocumentData {
return {
id: 'test-doc',
@@ -197,7 +194,7 @@ describe('docs drawing commands integration', () => {
},
}],
})).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -220,7 +217,7 @@ describe('docs drawing commands integration', () => {
testBed.docDrawingService.focusDrawing([{ unitId: 'test-doc', subUnitId: 'test-doc', drawingId: 'shape-1' }]);
expect(await testBed.commandService.executeCommand(DeleteDocDrawingsCommand.id)).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -243,7 +240,7 @@ describe('docs drawing commands integration', () => {
expect(await testBed.commandService.executeCommand(MoveDocDrawingsCommand.id, {
direction: Direction.RIGHT,
})).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -270,7 +267,7 @@ describe('docs drawing commands integration', () => {
distR: 10,
},
})).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -296,7 +293,7 @@ describe('docs drawing commands integration', () => {
}],
wrapText: WrapTextType.RIGHT,
})).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -320,7 +317,7 @@ describe('docs drawing commands integration', () => {
},
}],
})).toBe(true);
await waitNextTick();
await awaitTime(0);
const doc = testBed.get(IUniverInstanceService)
.getUnit<DocumentDataModel>('test-doc', UniverInstanceType.UNIVER_DOC)!;
@@ -16,6 +16,7 @@
import type { DocumentDataModel, ICommand, IDisposable, IDocumentData, Injector } from '@univerjs/core';
import {
awaitTime,
CustomRangeType,
ICommandService,
IUniverInstanceService,
@@ -32,10 +33,6 @@ import { DocHyperLinkSelectionController } from '../controllers/doc-hyper-link-s
import { DocHyperLinkPopupService } from '../services/hyper-link-popup.service';
import { createDocUiTestBed } from './create-doc-ui-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function createDocData(): IDocumentData {
return {
id: 'test-doc',
@@ -134,7 +131,7 @@ describe('docs-hyper-link-ui integration', () => {
unitId: 'test-doc',
payload: 'https://added.invalid',
})).toBeTruthy();
await waitNextTick();
await awaitTime(0);
const addedLink = getBody(get)?.customRanges?.find((range) => range.properties?.url === 'https://added.invalid');
expect(addedLink).toBeDefined();
@@ -160,7 +157,7 @@ describe('docs-hyper-link-ui integration', () => {
label: 'planet',
segmentId: '',
})).toBeTruthy();
await waitNextTick();
await awaitTime(0);
expect(getBody(get)?.dataStream).toBe('Hello planet\r\n');
expect(getBody(get)?.customRanges?.find((range) => range.rangeId === 'link-1')?.properties).toEqual({
@@ -175,7 +172,7 @@ describe('docs-hyper-link-ui integration', () => {
unitId: 'test-doc',
linkId: 'link-1',
})).toBeTruthy();
await waitNextTick();
await awaitTime(0);
expect(getBody(get)?.dataStream).toBe('Hello world\r\n');
expect(getBody(get)?.customRanges?.some((range) => range.rangeId === 'link-1')).toBe(false);
@@ -15,7 +15,7 @@
*/
import type { ICommand, IDisposable, IDocumentData, Univer } from '@univerjs/core';
import { CustomRangeType, Direction, ICommandService, IUniverInstanceService } from '@univerjs/core';
import { awaitTime, CustomRangeType, Direction, ICommandService, IUniverInstanceService } from '@univerjs/core';
import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs';
import { DocCanvasPopManagerService, InsertCommand, MoveCursorOperation } from '@univerjs/docs-ui';
import { afterEach, describe, expect, it, vi } from 'vitest';
@@ -29,10 +29,6 @@ import { DocMentionPopupService } from '../services/doc-mention-popup.service';
import { DocMentionService } from '../services/doc-mention.service';
import { createDocUiTestBed } from './create-doc-ui-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function createTriggerDocData(): IDocumentData {
return {
id: 'test-doc',
@@ -236,7 +232,7 @@ describe('docs-mention-ui integration', () => {
},
},
})).toBeTruthy();
await waitNextTick();
await awaitTime(0);
const documentBody = testBed.get(IUniverInstanceService)
.getCurrentUniverDocInstance()
@@ -288,7 +284,7 @@ describe('docs-mention-ui integration', () => {
unitId: 'test-doc',
mentionId: 'mention-1',
})).toBeTruthy();
await waitNextTick();
await awaitTime(0);
const docBody = testBed.get(IUniverInstanceService)
.getCurrentUniverDocInstance()
@@ -15,16 +15,12 @@
*/
import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core';
import { ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core';
import { awaitTime, ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { BreakLineCommand } from '../break-line.command';
import { createCommandTestBed } from './create-command-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function getDocumentData(): IDocumentData {
return {
id: 'test-doc',
@@ -89,7 +85,7 @@ describe('break line command', () => {
it('splits a heading paragraph and resets heading style for the new paragraph', async () => {
await commandService.executeCommand(BreakLineCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getParagraphs()).toHaveLength(2);
expect(getParagraphs()[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_1);
@@ -16,6 +16,7 @@
import type { DocumentDataModel, ICommand, IDocumentData, Injector, IStyleBase, Univer } from '@univerjs/core';
import {
awaitTime,
BooleanNumber,
CustomRangeType,
ICommandService,
@@ -29,10 +30,6 @@ import { DeleteDirection } from '../../../types/delete-direction';
import { DeleteCommand, InsertCommand, UpdateCommand } from '../core-editing.command';
import { createCommandTestBed } from './create-command-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function getDocumentData(): IDocumentData {
return {
id: 'test-doc',
@@ -124,7 +121,7 @@ describe('core editing commands', () => {
},
});
await waitNextTick();
await awaitTime(0);
expect(getDataStream()).toBe('Hello, brave world\r\n');
});
@@ -137,7 +134,7 @@ describe('core editing commands', () => {
direction: DeleteDirection.RIGHT,
});
await waitNextTick();
await awaitTime(0);
expect(getDataStream()).toBe('Hello \r\n');
expect(getBody()?.customRanges).toEqual([]);
@@ -166,7 +163,7 @@ describe('core editing commands', () => {
}],
});
await waitNextTick();
await awaitTime(0);
expect(getDataStream()).toBe('Hello world\r\n');
expect(getFormatValueAt('bl', 1)).toBe(BooleanNumber.TRUE);
@@ -15,7 +15,7 @@
*/
import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core';
import { ICommandService, IUniverInstanceService, PRESET_LIST_TYPE, PresetListType, UniverInstanceType } from '@univerjs/core';
import { awaitTime, ICommandService, IUniverInstanceService, PRESET_LIST_TYPE, PresetListType, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import {
@@ -31,10 +31,6 @@ import {
} from '../list.command';
import { createCommandTestBed } from './create-command-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function getDocumentData(): IDocumentData {
return {
id: 'test-doc',
@@ -107,7 +103,7 @@ describe('list commands', () => {
]);
await commandService.executeCommand(BulletListCommand.id);
await waitNextTick();
await awaitTime(0);
const paragraphs = getBody()?.paragraphs ?? [];
expect(paragraphs[0].bullet?.listType).toBe(PresetListType.BULLET_LIST);
@@ -128,7 +124,7 @@ describe('list commands', () => {
await commandService.executeCommand(ChangeListNestingLevelCommand.id, {
type: ChangeListNestingLevelType.increase,
});
await waitNextTick();
await awaitTime(0);
const paragraphs = getBody()?.paragraphs ?? [];
expect(paragraphs[0].bullet?.listType).toBe(PresetListType.CHECK_LIST_CHECKED);
@@ -139,7 +135,7 @@ describe('list commands', () => {
setSelections([{ startOffset: 0, endOffset: 4, collapsed: false }]);
await commandService.executeCommand(CheckListCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].bullet?.listType).toBe(PresetListType.CHECK_LIST);
@@ -154,7 +150,7 @@ describe('list commands', () => {
listType: PresetListType.ORDER_LIST,
paragraph,
});
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].bullet?.listType).toBe(PresetListType.ORDER_LIST);
expect(getBody()?.paragraphs?.[0].bullet?.listId).toBeDefined();
@@ -17,6 +17,7 @@
import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core';
import type { IAutoFormat } from '../../../services/doc-auto-format.service';
import {
awaitTime,
CommandType,
CustomRangeType,
HorizontalAlign,
@@ -41,10 +42,6 @@ import { SetDocZoomRatioCommand } from '../set-doc-zoom-ratio.command';
import { genEmptyTable } from '../table/table';
import { createCommandTestBed } from './create-command-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function createBaseDoc(dataStream = 'Hello world\r\n'): IDocumentData {
return {
id: 'test-doc',
@@ -218,7 +215,7 @@ describe('misc document commands', () => {
wholeEntity: true,
});
await waitNextTick();
await awaitTime(0);
expect(getBody()?.dataStream).toBe('Hello@OpenAI\r\n');
expect(getBody()?.customRanges).toEqual([expect.objectContaining({
@@ -248,7 +245,7 @@ describe('misc document commands', () => {
},
});
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].paragraphStyle).toEqual(expect.objectContaining({
namedStyleType: NamedStyleType.HEADING_1,
@@ -277,7 +274,7 @@ describe('misc document commands', () => {
});
const result = await commandService.executeCommand(DocSelectAllCommand.id);
await waitNextTick();
await awaitTime(0);
expect(result).toBe(true);
expect(refreshEvents.at(-1)).toEqual(expect.objectContaining({
@@ -308,7 +305,7 @@ describe('misc document commands', () => {
});
const result = await commandService.executeCommand(DocSelectAllCommand.id);
await waitNextTick();
await awaitTime(0);
expect(result).toBe(true);
expect(refreshEvents.at(-1)).toEqual(expect.objectContaining({
@@ -352,7 +349,7 @@ describe('misc document commands', () => {
},
});
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs).toHaveLength(3);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.borderBottom).toEqual(expect.objectContaining({
width: 1,
@@ -371,7 +368,7 @@ describe('misc document commands', () => {
await commandService.executeCommand(InsertHorizontalLineBellowCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs).toHaveLength(3);
expect(getBody()?.paragraphs?.[1].paragraphStyle?.borderBottom).toEqual(expect.objectContaining({
width: 1,
@@ -389,19 +386,19 @@ describe('misc document commands', () => {
setCollapsedSelection(0, 10);
await commandService.executeCommand(AlignCenterCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.CENTER);
expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.CENTER);
await commandService.executeCommand(AlignCenterCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.UNSPECIFIED);
expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.UNSPECIFIED);
await commandService.executeCommand(AlignJustifyCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.JUSTIFIED);
expect(getBody()?.paragraphs?.[1].paragraphStyle?.horizontalAlign).toBe(HorizontalAlign.JUSTIFIED);
@@ -15,16 +15,12 @@
*/
import type { DocumentDataModel, ICommand, IDocumentData, Injector, Univer } from '@univerjs/core';
import { ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core';
import { awaitTime, ICommandService, IUniverInstanceService, NamedStyleType, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from '@univerjs/docs';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { H1HeadingCommand, QuickHeadingCommand, SetParagraphNamedStyleCommand } from '../set-heading.command';
import { createCommandTestBed } from './create-command-test-bed';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function getHeadingDocumentData(): IDocumentData {
return {
id: 'test-doc',
@@ -106,7 +102,7 @@ describe('set heading commands', () => {
await commandService.executeCommand(H1HeadingCommand.id);
await waitNextTick();
await awaitTime(0);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_1);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.headingId).toBeDefined();
@@ -136,7 +132,7 @@ describe('set heading commands', () => {
value: NamedStyleType.HEADING_2,
});
await waitNextTick();
await awaitTime(0);
expect(getBody()?.dataStream.startsWith('Heading')).toBe(true);
expect(getBody()?.paragraphs?.[0].paragraphStyle?.namedStyleType).toBe(NamedStyleType.HEADING_2);
@@ -14,16 +14,13 @@
* limitations under the License.
*/
import { awaitTime } from '@univerjs/core';
import { RichTextEditingMutation } from '@univerjs/docs';
import { Subject } from 'rxjs';
import { describe, expect, it, vi } from 'vitest';
import { IMEInputCommand } from '../../commands/commands/ime-input.command';
import { DocIMEInputController } from '../render-controllers/doc-ime-input.controller';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function createRange() {
return {
startOffset: 0,
@@ -81,12 +78,12 @@ describe('doc ime input controller', () => {
event: { data: '한' },
activeRange,
});
await waitNextTick();
await awaitTime(0);
onCompositionend$.next({
event: { data: '한' },
activeRange,
});
await waitNextTick();
await awaitTime(0);
expect(commandService.executeCommand).toHaveBeenCalledTimes(1);
expect(commandService.executeCommand).toHaveBeenCalledWith(IMEInputCommand.id, {
@@ -161,12 +158,12 @@ describe('doc ime input controller', () => {
event: { data: 'ㅎ' },
activeRange,
});
await waitNextTick();
await awaitTime(0);
onCompositionend$.next({
event: { data: '한' },
activeRange,
});
await waitNextTick();
await awaitTime(0);
expect(commandService.executeCommand).toHaveBeenCalledTimes(2);
expect(commandService.executeCommand).toHaveBeenNthCalledWith(2, IMEInputCommand.id, {
@@ -53,7 +53,7 @@ import {
} from '@univerjs/ui';
import { CutContentCommand, InnerPasteCommand } from '../../commands/commands/clipboard.inner.command';
import { getCursorWhenDelete } from '../../commands/commands/doc-delete.command';
import { copyContentCache, extractId, genId } from './copy-content-cache';
import { copyContentCache, extractId } from './copy-content-cache';
import { HtmlToUDMService } from './html-to-udm/converter';
import LarkPastePlugin from './html-to-udm/paste-plugins/plugin-lark';
import UniverPastePlugin from './html-to-udm/paste-plugins/plugin-univer';
@@ -327,7 +327,7 @@ export class DocClipboardService extends Disposable implements IDocClipboardServ
}
private async _setClipboardData(documentList: IDocumentData[], needCache = true): Promise<void> {
const copyId = genId();
const copyId = generateRandomId(6);
const text =
(documentList.length > 1
? documentList.map((doc) => doc.body?.dataStream || '').join('\n')
@@ -15,14 +15,9 @@
*/
import type { IDocumentData } from '@univerjs/core';
import { generateRandomId, LRUMap } from '@univerjs/core';
import { LRUMap } from '@univerjs/core';
const COPY_CONTENT_CACHE_LIMIT = 10;
const ID_LENGTH = 6;
export function genId() {
return generateRandomId(ID_LENGTH);
}
export function extractId(html: string) {
const match = html.match(/data-copy-id="([^\s]+)"/);
@@ -16,8 +16,8 @@
import type { DocumentDataModel, ICustomRangeForInterceptor, IDocumentData, IInterceptor } from '@univerjs/core';
import type { IRenderContext } from '@univerjs/engine-render';
import {
awaitTime,
CustomRangeType,
ICommandService,
IUniverInstanceService,
@@ -29,7 +29,6 @@ import {
} from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { DocsRenameMutation } from '../commands/mutations/docs-rename.mutation';
import { SetTextSelectionsOperation } from '../commands/operations/text-selection.operation';
import { UniverDocsPlugin } from '../plugin';
@@ -42,10 +41,6 @@ import { DocViewModelManagerService } from '../services/doc-view-model-manager.s
import { addCustomRangeBySelectionFactory, deleteCustomRangeFactory } from '../utils/custom-range-factory';
import { replaceSelectionFactory } from '../utils/replace-selection-factory';
function waitNextTick() {
return new Promise<void>((resolve) => setTimeout(resolve, 0));
}
function registerRenderManagerForDoc(
injector: ReturnType<Univer['__getInjector']>,
doc: DocumentDataModel
@@ -197,7 +192,7 @@ describe('docs integration', () => {
{ unitId: doc.getUnitId(), subUnitId: doc.getUnitId() }
);
await waitNextTick();
await awaitTime(0);
expect(executed.some((e) => e.id === SetTextSelectionsOperation.id)).toBe(true);
dispose.dispose();
});
@@ -250,7 +245,7 @@ describe('docs integration', () => {
trigger: 'integration-spec' as never,
});
await waitNextTick();
await awaitTime(0);
expect(ok).toBeTruthy();
expect(doc.getBody()?.dataStream).toBe('Hello world\r\n');
+1 -3
View File
@@ -15,13 +15,12 @@
*/
import type { IDisposable, Nullable } from '@univerjs/core';
import type { CURSOR_TYPE } from './basics/const';
import type { IEvent, IKeyboardEvent, IPointerEvent } from './basics/i-events';
import type { ITimeMetric, ITransformChangeState } from './basics/interfaces';
import type { IBasicFrameInfo } from './basics/performance-monitor';
import type { Scene } from './scene';
import { Disposable, EventSubject, toDisposable, Tools } from '@univerjs/core';
import { Disposable, EventSubject, noop, toDisposable, Tools } from '@univerjs/core';
import { Observable, shareReplay, Subject } from 'rxjs';
import { RENDER_CLASS_TYPE } from './basics/const';
import { DeviceType, PointerInput } from './basics/i-events';
@@ -989,7 +988,6 @@ export class Engine extends Disposable {
// IE11 only supports captureEvent:boolean, not options:object, and it defaults to false.
// Feature detection technique copied from: https://github.com/github/eventlistener-polyfill (MIT license)
let passiveSupported = false;
const noop = () => { /* empty */ };
try {
const options: object = {
@@ -15,8 +15,9 @@
*/
import type { FindModel, IFindMatch } from '../find-replace.service';
import { Subject } from 'rxjs';
import { awaitTime } from '@univerjs/core';
import { Subject } from 'rxjs';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { FindBy, FindDirection, FindReplaceModel, FindReplaceService, FindScope } from '../find-replace.service';
@@ -78,7 +79,7 @@ describe('FindReplaceService', () => {
service.find();
// wait for provider find to resolve
await new Promise((r) => setTimeout(r, 0));
await awaitTime(0);
service.moveToNextMatch();
expect(service.getCurrentMatch()).toEqual(match1);
@@ -16,11 +16,11 @@
import type { HTTPHandlerFn } from '../interceptor';
import type { HTTPRequest } from '../request';
import { noop } from '@univerjs/core';
import { Observable } from 'rxjs';
import { HTTPEventType, HTTPResponse } from '../response';
const createDefaultFetchCheck = (time = 300) => {
const noop = () => { };
let cancel = noop;
return (_currentConfig: HTTPRequest) => {
return new Promise<boolean>((res) => {
@@ -15,17 +15,12 @@
*/
import type { IMessageProtocol } from '../rpc.service';
import { awaitTime } from '@univerjs/core';
import { Observable, Subject } from 'rxjs';
import { describe, expect, it } from 'vitest';
import { ChannelService } from '../channel.service';
import { fromModule } from '../rpc.service';
function flushPromises() {
return new Promise<void>((resolve) => {
setTimeout(() => resolve(), 0);
});
}
describe('ChannelService', () => {
it('should register channel, request channel, and dispose', async () => {
const message$ = new Subject<unknown>();
@@ -55,7 +50,7 @@ describe('ChannelService', () => {
const values: number[] = [];
channel.subscribe<number>('values$').subscribe((value) => values.push(value));
await flushPromises();
await awaitTime(0);
expect(values).toEqual([1]);
service.dispose();
@@ -15,6 +15,7 @@
*/
import type { IChannel, IMessageProtocol } from '../rpc.service';
import { awaitTime } from '@univerjs/core';
import { Observable, Subject } from 'rxjs';
import { describe, expect, it, vi } from 'vitest';
import { ChannelClient, ChannelServer, fromModule, toModule } from '../rpc.service';
@@ -31,12 +32,6 @@ const SUBSCRIBE_NEXT = 300;
const SUBSCRIBE_ERROR = 301;
const SUBSCRIBE_COMPLETE = 302;
function flushPromises() {
return new Promise<void>((resolve) => {
setTimeout(() => resolve(), 0);
});
}
function getType(value: unknown): number | undefined {
if (typeof value !== 'object' || value === null) {
return undefined;
@@ -128,7 +123,7 @@ describe('rpc.service edge cases', () => {
lazySubscription.unsubscribe();
protocol.emit({ seq: -1, type: INITIALIZE });
await flushPromises();
await awaitTime(0);
const callRequest = protocol.sent.find((msg) => getType(msg) === CALL);
expect(callRequest).toBeDefined();
@@ -198,7 +193,7 @@ describe('rpc.service edge cases', () => {
protocol.emit({ type: 999, seq: 1, channelName: '', method: '' });
protocol.emit({ type: CALL, seq: 10, channelName: 'missing', method: 'm' });
await flushPromises();
await awaitTime(0);
expect(protocol.sent).toContainEqual({
seq: 10,
type: CALL_FAILURE,
@@ -213,7 +208,7 @@ describe('rpc.service edge cases', () => {
subscribe: () => new Observable(),
} as IChannel);
protocol.emit({ type: CALL, seq: 11, channelName: 'bad-call', method: 'm', args: [] });
await flushPromises();
await awaitTime(0);
expect(protocol.sent).toContainEqual({
seq: 11,
type: CALL_FAILURE,
@@ -225,7 +220,7 @@ describe('rpc.service edge cases', () => {
subscribe: () => new Observable(),
} as IChannel);
protocol.emit({ type: CALL, seq: 12, channelName: 'no-args', method: 'm' });
await flushPromises();
await awaitTime(0);
expect(protocol.sent).toContainEqual({
seq: 12,
type: CALL_SUCCESS,
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { awaitTime } from '@univerjs/core';
import { Subject } from 'rxjs';
import { describe, expect, it, vi } from 'vitest';
import { SheetsDataValidationReRenderController } from '../dv-rerender.controller';
@@ -42,7 +43,7 @@ describe('SheetsDataValidationReRenderController', () => {
validStatusChange$.next({ subUnitId: 'sheet-1' });
expect(controller).toBeTruthy();
await new Promise((resolve) => setTimeout(resolve, 30));
await awaitTime(30);
expect(makeDirty1).toHaveBeenCalledTimes(1);
expect(makeDirty2).toHaveBeenCalledTimes(1);
@@ -17,7 +17,7 @@
import type { IFormulaInputProps } from '@univerjs/data-validation';
import type { ListValidator } from '@univerjs/sheets-data-validation';
import type { IFormulaEditorRef } from '@univerjs/sheets-formula-ui';
import { DataValidationType, generateRandomId, isFormulaString, LocaleService } from '@univerjs/core';
import { awaitTime, DataValidationType, generateRandomId, isFormulaString, LocaleService } from '@univerjs/core';
import { DataValidationModel, DataValidatorRegistryService } from '@univerjs/data-validation';
import { borderClassName, clsx, DraggableList, Dropdown, FormLayout, Input, Radio, RadioGroup } from '@univerjs/design';
import { DeleteIcon, IncreaseIcon, MoreDownIcon, SequenceIcon } from '@univerjs/icons';
@@ -185,9 +185,7 @@ export function ListFormulaInput(props: IFormulaInputProps) {
useEffect(() => {
(async () => {
await new Promise<any>((resolve) => {
setTimeout(() => resolve(true), 100);
});
await awaitTime(100);
const rule = dataValidationModel.getRuleById(unitId, subUnitId, ruleId);
const formula1 = rule?.formula1;
@@ -19,7 +19,7 @@ import type { IEditorBridgeServiceVisibleParam } from '@univerjs/sheets-ui';
import type { IOpenFilterPanelOperationParams } from '../../commands/operations/sheets-filter.operation';
import type { IFilterConditionFormParams } from '../../models/conditions';
import type { IFilterByValueWithTreeItem } from '../sheets-filter-panel.service';
import { CommandType, ICommandService, Inject, Injector, LocaleService, Plugin, Univer, UniverInstanceType } from '@univerjs/core';
import { awaitTime, CommandType, ICommandService, Inject, Injector, LocaleService, Plugin, Univer, UniverInstanceType } from '@univerjs/core';
import { ActiveDirtyManagerService, IActiveDirtyManagerService, ISheetRowFilteredService, SheetRowFilteredService } from '@univerjs/engine-formula';
import { MarkDirtyFilterChangeMutation, RefRangeService, SheetInterceptorService, SheetRangeThemeModel, SheetsSelectionsService, ZebraCrossingCacheController } from '@univerjs/sheets';
import { CustomFilterOperator, FilterBy, SheetsFilterService, UniverSheetsFilterPlugin } from '@univerjs/sheets-filter';
@@ -262,7 +262,7 @@ describe('test "SheetsFilterPanelService"', () => {
subUnitId: 'sheet1',
col: 0,
} as IOpenFilterPanelOperationParams)).toBeTruthy();
await await tick();
await tick();
expect(sheetsFilterPanelService.filterBy).toBe(FilterBy.VALUES);
const filterByModel = sheetsFilterPanelService.filterByModel as ByValuesModel;
@@ -520,7 +520,7 @@ describe('test "SheetsFilterPanelService"', () => {
});
function tick(milliseconds: number = 0): Promise<void> {
const result = new Promise<void>((resolve) => setTimeout(resolve, milliseconds));
const result = awaitTime(milliseconds);
vitest.advanceTimersByTime(milliseconds + 1);
return result;
}
@@ -17,7 +17,17 @@
import type { IRange, Nullable, Styles, Workbook, Worksheet } from '@univerjs/core';
import type { FilterColumn } from '@univerjs/sheets-filter';
import type { IFilterByValueItem, IFilterByValueWithTreeItem } from '../services/sheets-filter-panel.service';
import { createIdentifier, Disposable, extractPureTextFromCell, ILogService, Inject, IUniverInstanceService, LocaleService, numfmt } from '@univerjs/core';
import {
createIdentifier,
Disposable,
extractPureTextFromCell,
ILogService,
Inject,
isNumeric,
IUniverInstanceService,
LocaleService,
numfmt,
} from '@univerjs/core';
import { FilterBy } from '@univerjs/sheets-filter';
export interface ISheetsGenerateFilterValuesService {
@@ -335,8 +345,6 @@ function generateFilterTreeBySort(tree: IFilterByValueWithTreeItem[]) {
});
}
const isNumeric = (str: string) => !Number.isNaN(Number(str)) && !Number.isNaN(Number.parseFloat(str)); ;
function compare(strA: string, strB: string) {
const aIsNumeric = isNumeric(strA);
const bIsNumeric = isNumeric(strB);
@@ -16,7 +16,7 @@
import type { Editor } from '@univerjs/docs-ui';
import type { IFunctionParam } from '@univerjs/engine-formula';
import { LocaleService } from '@univerjs/core';
import { LocaleService, noop } from '@univerjs/core';
import { borderClassName, borderTopClassName, clsx, scrollbarClassName } from '@univerjs/design';
import { CloseIcon, MoreIcon } from '@univerjs/icons';
import { IEditorBridgeService } from '@univerjs/sheets-ui';
@@ -91,7 +91,6 @@ interface IHelpFunctionProps {
formulaText: string;
};
const noop = () => { };
export function HelpFunction(props: IHelpFunctionProps) {
const { onParamsSwitch = noop, onClose: propColose = noop, isFocus, editor, formulaText } = props;
const { functionInfo, paramIndex, reset } = useFormulaDescribe(isFocus, formulaText, editor);
@@ -21,9 +21,25 @@ import type { Editor } from '@univerjs/docs-ui';
import type { ISelectionWithCoord, ISetSelectionsOperationParams } from '@univerjs/sheets';
import type { RefObject } from 'react';
import type { IRefSelection } from './use-highlight';
import { DisposableCollection, ICommandService, IUniverInstanceService, Rectangle, ThemeService, UniverInstanceType } from '@univerjs/core';
import {
DisposableCollection,
ICommandService,
IUniverInstanceService,
noop,
Rectangle,
ThemeService,
UniverInstanceType,
} from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import { deserializeRangeWithSheet, generateStringWithSequence, LexerTreeBuilder, sequenceNodeType, serializeRange, serializeRangeWithSheet, serializeRangeWithSpreadsheet } from '@univerjs/engine-formula';
import {
deserializeRangeWithSheet,
generateStringWithSequence,
LexerTreeBuilder,
sequenceNodeType,
serializeRange,
serializeRangeWithSheet,
serializeRangeWithSpreadsheet,
} from '@univerjs/engine-formula';
import { IRenderManagerService } from '@univerjs/engine-render';
import { IRefSelectionsService, SetSelectionsOperation } from '@univerjs/sheets';
import { SheetSkeletonManagerService } from '@univerjs/sheets-ui';
@@ -60,7 +76,6 @@ const prepareSelectionChangeContext = (opts: { editor?: Editor; lexerTreeBuilder
};
};
const noop = (() => { }) as any;
export const useSheetSelectionChange = (
isNeed: boolean,
isFocus: boolean,
@@ -71,7 +86,7 @@ export const useSheetSelectionChange = (
isSupportAcrossSheet: boolean,
listenSelectionSet: boolean,
editor?: Editor,
handleRangeChange: ((refString: string, offset: number, isEnd: boolean, isModify?: boolean) => void) = noop
handleRangeChange: ((refString: string, offset: number, isEnd: boolean, isModify?: boolean) => void) = noop as any
) => {
const renderManagerService = useDependency(IRenderManagerService);
const univerInstanceService = useDependency(IUniverInstanceService);
@@ -21,7 +21,15 @@ import type { CSSProperties, ReactNode, Ref } from 'react';
import type { IUniverSheetsFormulaUIConfig } from '../../config/config';
import type { FormulaSelectingType } from './hooks/use-formula-selection';
import type { IRefSelection } from './hooks/use-highlight';
import { BuildTextUtils, createInternalEditorID, generateRandomId, IConfigService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import {
BuildTextUtils,
createInternalEditorID,
generateRandomId,
IConfigService,
IUniverInstanceService,
noop,
UniverInstanceType,
} from '@univerjs/core';
import { clsx } from '@univerjs/design';
import { DocBackScrollRenderController, DocSelectionRenderService, IEditorService, useKeyboardEvent, useResize } from '@univerjs/docs-ui';
import { IRenderManagerService } from '@univerjs/engine-render';
@@ -74,8 +82,6 @@ export interface IFormulaEditorProps {
style?: CSSProperties;
}
const noop = () => { };
export interface IFormulaEditorRef {
isClickOutSide: (e: MouseEvent) => boolean;
}
@@ -16,7 +16,7 @@
import type { Editor } from '@univerjs/docs-ui';
import type { FunctionType, ISequenceNode } from '@univerjs/engine-formula';
import { CommandType, DisposableCollection, ICommandService } from '@univerjs/core';
import { CommandType, DisposableCollection, ICommandService, noop } from '@univerjs/core';
import { borderClassName, clsx, scrollbarClassName } from '@univerjs/design';
import { DeviceInputEventType } from '@univerjs/engine-render';
import { IShortcutService, KeyCode, RectPopup, useDependency } from '@univerjs/ui';
@@ -36,7 +36,6 @@ interface ISearchFunctionProps {
editor: Editor;
onClose?: () => void;
};
const noop = () => { };
export const SearchFunction = forwardRef<HTMLElement, ISearchFunctionProps>(SearchFunctionFactory);
function SearchFunctionFactory(props: ISearchFunctionProps, ref: any) {
const { isFocus, sequenceNodes, onSelect, editor, onClose = noop } = props;
@@ -16,11 +16,10 @@
import type { Dependency, IWorkbookData, Workbook, Worksheet } from '@univerjs/core';
import type { IImageFormulaInfo } from '@univerjs/engine-formula';
import { CellValueType, ICommandService, InterceptorEffectEnum, LocaleType, ObjectMatrix } from '@univerjs/core';
import { awaitTime, CellValueType, ICommandService, InterceptorEffectEnum, LocaleType, ObjectMatrix } from '@univerjs/core';
import { ErrorType, FormulaDataModel, SetImageFormulaDataMutation } from '@univerjs/engine-formula';
import { INTERCEPTOR_POINT, SheetInterceptorService } from '@univerjs/sheets';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { createFacadeTestBed } from '../../facade/__tests__/create-test-bed';
import { ImageFormulaCellInterceptorController } from '../image-formula-cell-interceptor.controller';
@@ -75,7 +74,7 @@ async function waitForAssertion(assertion: () => void, timeout = 1000, interval
assertion();
return;
} catch {
await new Promise((resolve) => setTimeout(resolve, interval));
await awaitTime(interval);
}
}
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { awaitTime } from '@univerjs/core';
import { Subject } from 'rxjs';
import { describe, expect, it, vi } from 'vitest';
import { SheetsHyperLinkRenderController } from '../render-controllers/render.controller';
@@ -30,7 +31,7 @@ describe('SheetsHyperLinkRenderController', () => {
linkUpdate$.next();
// debounced by 16ms
await new Promise((resolve) => setTimeout(resolve, 30));
await awaitTime(30);
expect(makeForceDirty).toHaveBeenCalledTimes(1);
controller.dispose();
@@ -337,10 +337,6 @@ export class NumfmtEditorController extends Disposable {
}
}
function isNumeric(str: string) {
return /^-?\d+(\.\d+)?$/.test(str);
}
function canConvertRichTextToNumfmt(body: IDocumentBody): boolean {
const { textRuns = [], paragraphs = [], customRanges, customBlocks = [] } = body;
@@ -14,12 +14,13 @@
* limitations under the License.
*/
import { generateRandomId } from '@univerjs/core';
import { describe, expect, it } from 'vitest';
import { CopyContentCache, extractId, genId } from '../copy-content-cache';
import { CopyContentCache, extractId } from '../copy-content-cache';
describe('copy-content-cache', () => {
it('should generate id with expected length and extract id from html', () => {
const id = genId();
const id = generateRandomId(6);
expect(typeof id).toBe('string');
expect(id.length).toBe(6);
@@ -24,7 +24,12 @@ import type {
Workbook,
Worksheet,
} from '@univerjs/core';
import type { IDiscreteRange, ISetRangeValuesMutationParams, ISetSelectionsOperationParams, ISetWorksheetRowAutoHeightMutationParams } from '@univerjs/sheets';
import type {
IDiscreteRange,
ISetRangeValuesMutationParams,
ISetSelectionsOperationParams,
ISetWorksheetRowAutoHeightMutationParams,
} from '@univerjs/sheets';
import type { Observable } from 'rxjs';
import type {
ICellDataWithSpanInfo,
@@ -46,6 +51,7 @@ import {
Disposable,
ErrorService,
extractPureTextFromCell,
generateRandomId,
getEmptyCell,
ICommandService,
ILogService,
@@ -71,21 +77,40 @@ import {
SetWorksheetRowAutoHeightMutationFactory,
SheetsSelectionsService,
} from '@univerjs/sheets';
import { FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FILE_PNG_CLIPBOARD_MIME_TYPE, HTML_CLIPBOARD_MIME_TYPE, IClipboardInterfaceService, imageMimeTypeSet, INotificationService, IPlatformService, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui';
import {
FILE__BMP_CLIPBOARD_MIME_TYPE,
FILE__JPEG_CLIPBOARD_MIME_TYPE,
FILE__WEBP_CLIPBOARD_MIME_TYPE,
FILE_PNG_CLIPBOARD_MIME_TYPE,
HTML_CLIPBOARD_MIME_TYPE,
IClipboardInterfaceService,
imageMimeTypeSet,
INotificationService,
IPlatformService,
PLAIN_TEXT_CLIPBOARD_MIME_TYPE,
} from '@univerjs/ui';
import { BehaviorSubject } from 'rxjs';
import { virtualizeDiscreteRanges } from '../../controllers/utils/range-tools';
import { IMarkSelectionService } from '../mark-selection/mark-selection.service';
import { SheetSkeletonManagerService } from '../sheet-skeleton-manager.service';
import { createCopyPasteSelectionStyle } from '../utils/selection-util';
import { cloneCellDataWithSpanInfo } from './clone';
import { CopyContentCache, extractId, genId } from './copy-content-cache';
import { CopyContentCache, extractId } from './copy-content-cache';
import { HtmlToUSMService } from './html-to-usm/converter';
import { LarkPastePlugin } from './html-to-usm/paste-plugins/plugin-lark';
import { UniverPastePlugin } from './html-to-usm/paste-plugins/plugin-univer';
import { WordPastePlugin } from './html-to-usm/paste-plugins/plugin-word';
import { COPY_TYPE } from './type';
import { USMToHtmlService } from './usm-to-html/convertor';
import { convertTextToTable, discreteRangeContainsRange, htmlContainsImage, htmlIsFromExcel, mergeSetRangeValues, rangeIntersectWithDiscreteRange, spilitLargeSetRangeValuesMutations } from './utils';
import {
convertTextToTable,
discreteRangeContainsRange,
htmlContainsImage,
htmlIsFromExcel,
mergeSetRangeValues,
rangeIntersectWithDiscreteRange,
spilitLargeSetRangeValuesMutations,
} from './utils';
export const PREDEFINED_HOOK_NAME_COPY = {
DEFAULT_COPY: 'default-copy',
@@ -498,7 +523,7 @@ export class SheetClipboardService extends Disposable implements ISheetClipboard
}
// convert matrix to html
const copyId = genId();
const copyId = generateRandomId(6);
const html = this._usmToHtml.convert(matrix, discreteRange, hooks, copyId);
const plain = getMatrixPlainText(plainMatrix);
@@ -17,11 +17,10 @@
import type { Nullable, ObjectMatrix } from '@univerjs/core';
import type { IDiscreteRange } from '@univerjs/sheets';
import type { COPY_TYPE, ICellDataWithSpanInfo } from './type';
import { generateRandomId, LRUMap } from '@univerjs/core';
import { LRUMap } from '@univerjs/core';
import { BehaviorSubject } from 'rxjs';
const COPY_CONTENT_CACHE_LIMIT = 10;
const ID_LENGTH = 6;
export interface ICopyContentCacheData {
subUnitId: string;
@@ -31,10 +30,6 @@ export interface ICopyContentCacheData {
matrix: Nullable<ObjectMatrix<ICellDataWithSpanInfo>>;
}
export function genId() {
return generateRandomId(ID_LENGTH);
}
export function extractId(html: string) {
const match = html.match(/data-copy-id="([^\s]+)"/);
@@ -18,6 +18,7 @@ import type { IDocumentBody, Injector, IWorkbookData } from '@univerjs/core';
import type { IThreadComment } from '../../types/interfaces/i-thread-comment';
import type { CommentUpdate } from '../thread-comment.model';
import {
awaitTime,
IUniverInstanceService,
LifecycleService,
LifecycleStages,
@@ -134,8 +135,8 @@ describe('ThreadCommentModel', () => {
expect(listComments).not.toHaveBeenCalled();
lifecycleService.stage = LifecycleStages.Rendered;
await new Promise((resolve) => setTimeout(resolve, 0));
await new Promise((resolve) => setTimeout(resolve, 0));
await awaitTime(0);
await awaitTime(0);
subscription.unsubscribe();
@@ -14,9 +14,9 @@
* 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';
@@ -46,12 +46,6 @@ vi.mock('@univerjs/engine-render', async () => {
};
});
function waitNextTick() {
return new Promise<void>((resolve) => {
setTimeout(resolve, 0);
});
}
describe('WatermarkRenderController', () => {
it('should init layer, load config and react to updates', async () => {
layerInstances.length = 0;
@@ -88,7 +82,7 @@ describe('WatermarkRenderController', () => {
expect(scene.addLayer).toHaveBeenCalledTimes(1);
expect(localStorageService.getItem).toHaveBeenCalledWith(UNIVER_WATERMARK_STORAGE_KEY);
await waitNextTick();
await awaitTime(0);
expect(updateWatermarkConfig).toHaveBeenCalledWith({
type: IWatermarkTypeEnum.Text,
config: { text: { content: 'init' } },
@@ -142,7 +136,7 @@ describe('WatermarkRenderController', () => {
);
expect(_controller).toBeDefined();
await waitNextTick();
await awaitTime(0);
expect(updateWatermarkConfig).not.toHaveBeenCalled();
expect(makeDirty).not.toHaveBeenCalled();
});