From 88368150ec89a7af314692f5e39d68691f93c303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Mon, 3 Aug 2026 19:51:29 +0800 Subject: [PATCH] fix: support Chrome 88 browser compatibility (#7409) --- README.md | 2 +- common/shared/tsdown/constants.ts | 2 +- common/shared/tsdown/index.ts | 2 + docs/readme/es-ES.md | 2 +- docs/readme/ja-JP.md | 2 +- docs/readme/ko-KR.md | 2 +- docs/readme/zh-CN.md | 2 +- docs/readme/zh-TW.md | 2 +- examples/scripts/esbuild/build-config.mts | 3 +- examples/scripts/esbuild/build-tasks.mts | 3 +- .../core/src/common/__tests__/shims.spec.ts | 29 ++--- .../__tests__/rich-text-builder.test.ts | 17 ++- .../docs/data-model/document-data-model.ts | 9 +- .../src/docs/data-model/empty-snapshot.ts | 10 +- packages/core/src/docs/data-model/index.ts | 6 +- .../src/docs/data-model/rich-text-builder.ts | 8 +- .../text-x/apply-utils/update-apply.ts | 12 +- .../text-x/build-utils/paragraph.ts | 8 +- .../core/src/docs/data-model/text-x/text-x.ts | 6 +- .../docs/data-model/text-x/transform-utils.ts | 13 +- .../core/src/docs/data-model/text-x/utils.ts | 12 +- packages/core/src/facade/f-enum.ts | 118 ++++++++++++------ packages/core/src/facade/f-event.ts | 30 +++-- .../core/src/shared/numfmt/parse-value.ts | 4 +- packages/docs-ui/src/menu/menu.ts | 6 +- .../src/services/doc-event-manager.service.ts | 2 +- .../update-document-section.command.ts | 2 +- .../services/drawing-manager-impl.service.ts | 23 +++- .../src/basics/__tests__/regex.spec.ts | 7 ++ packages/engine-formula/src/basics/regex.ts | 2 +- .../src/formula-editor-helpers.ts | 2 +- .../src/services/super-table.service.ts | 2 +- .../src/__tests__/context.spec.ts | 13 ++ .../layout/block/paragraph/linebreaking.ts | 2 +- .../components/docs/layout/doc-skeleton.ts | 2 +- .../src/components/docs/layout/model/page.ts | 6 +- packages/engine-render/src/context.ts | 24 +++- .../f-conditional-formatting-builder.ts | 13 +- .../highlight-cell-calculate-unit.ts | 2 +- .../sheets-filter.render-controller.ts | 26 +++- .../sheets-filter-ui/src/worker/plugin.ts | 6 +- .../src/controllers/ui.controller.ts | 2 +- packages/slides-ui/src/index.ts | 7 +- .../services/slide-popup-manager.service.ts | 9 +- .../src/views/editor-container/index.ts | 17 --- .../panels/__tests__/ArrangePanel.spec.tsx | 9 +- .../panels/__tests__/TransformPanel.spec.tsx | 9 +- packages/thread-comment-ui/src/plugin.ts | 12 +- .../src/views/ThreadCommentTree.tsx | 10 +- .../src/commands/commands/comment.command.ts | 7 +- packages/thread-comment/src/plugin.ts | 28 ++++- packages/ui/src/facade/f-menu-builder.ts | 13 +- packages/ui/src/index.ts | 13 +- packages/ui/src/views/CommonLabel.tsx | 1 - .../watermark.render.controller.ts | 7 +- packages/watermark/src/index.ts | 7 +- packages/watermark/src/plugin.ts | 18 ++- 57 files changed, 441 insertions(+), 172 deletions(-) delete mode 100644 packages/slides-ui/src/views/editor-container/index.ts diff --git a/README.md b/README.md index 2fe7f64c11..fe1d7b04a9 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ For API compatibility expectations, experimental APIs, internal APIs, and deprec ## 🧭 Compatibility -- **Browser runtime**: Univer is compiled with a Chrome 70 target and aims to work on Edge `>=70`, Firefox `>=63`, Chrome `>=70`, Safari `>=12.0`, and Electron `>=5`. +- **Browser runtime**: Univer is compiled with a Chrome 88 target and aims to work on Edge `>=88`, Firefox `>=90`, Chrome `>=88`, Safari `>=14.1`, and Electron `>=12`. - **Polyfills**: Univer relies on `Intl.Segmenter`. Add a polyfill such as `@formatjs/intl-segmenter` if your target browser or runtime does not provide it. - **Build tools**: We recommend Vite, esbuild, or Webpack 5. If your build tool does not support the `exports` field in `package.json` (common in Webpack 4), you may need extra path mapping. - **React**: Univer's view layer is built on React 18, supports React 18 and 19, and provides minimal compatibility support for React 16.9+ and 17. diff --git a/common/shared/tsdown/constants.ts b/common/shared/tsdown/constants.ts index 93e1aac181..7c0fa4bf0b 100644 --- a/common/shared/tsdown/constants.ts +++ b/common/shared/tsdown/constants.ts @@ -7,7 +7,7 @@ export const BUILD_OUTPUT_DIRECTORIES = { } as const; export const CLEANUP_DIRECTORIES = ['dist', 'lib', 'coverage'] as const; -export const DEFAULT_BROWSER_TARGET = 'chrome70'; +export const DEFAULT_BROWSER_TARGET = 'chrome88'; export const DEFAULT_ENTRY_FILE = 'src/index.ts'; export const FACADE_ENTRY_FILE = 'src/facade/index.ts'; export const LOCALE_DIRECTORY = 'src/locale'; diff --git a/common/shared/tsdown/index.ts b/common/shared/tsdown/index.ts index 468a5f161c..4c3ccd85b1 100644 --- a/common/shared/tsdown/index.ts +++ b/common/shared/tsdown/index.ts @@ -15,6 +15,8 @@ import { removeCssArtifacts } from './utils/files.ts'; import { createExternalPackages, readPackageJson } from './utils/package.ts'; import { emitPublishPackageJson } from './utils/publish-manifest.ts'; +export { DEFAULT_BROWSER_TARGET } from './constants.ts'; + /** * Builds the shared context consumed by all output format factories. */ diff --git a/docs/readme/es-ES.md b/docs/readme/es-ES.md index 9fac356f69..44295f8eb7 100644 --- a/docs/readme/es-ES.md +++ b/docs/readme/es-ES.md @@ -234,7 +234,7 @@ Para expectativas de compatibilidad de API, APIs experimentales, APIs internas y ## 🧭 Compatibilidad -- **Runtime de navegador**: Univer se compila con objetivo Chrome 70 y busca funcionar en Edge `>=70`, Firefox `>=63`, Chrome `>=70`, Safari `>=12.0` y Electron `>=5`. +- **Runtime de navegador**: Univer se compila con objetivo Chrome 88 y busca funcionar en Edge `>=88`, Firefox `>=90`, Chrome `>=88`, Safari `>=14.1` y Electron `>=12`. - **Polyfills**: Univer depende de `Intl.Segmenter`. Añade un polyfill como `@formatjs/intl-segmenter` si tu navegador o runtime objetivo no lo incluye. - **Herramientas de build**: Recomendamos Vite, esbuild o Webpack 5. Si tu herramienta no soporta el campo `exports` de `package.json` (común en Webpack 4), puede que necesites configurar mapeos de ruta adicionales. - **React**: La capa de vista de Univer está construida sobre React 18, soporta React 18 y 19, y ofrece compatibilidad mínima para React 16.9+ y 17. diff --git a/docs/readme/ja-JP.md b/docs/readme/ja-JP.md index 7a1b5ba2ab..9963ceb4ae 100644 --- a/docs/readme/ja-JP.md +++ b/docs/readme/ja-JP.md @@ -235,7 +235,7 @@ API 互換性、experimental API、internal API、deprecation rules について ## 🧭 互換性 -- **ブラウザ実行環境**:Univer は Chrome 70 をターゲットとしてコンパイルされており、Edge `>=70`、Firefox `>=63`、Chrome `>=70`、Safari `>=12.0`、Electron `>=5` で動作することを目指しています。 +- **ブラウザ実行環境**:Univer は Chrome 88 をターゲットとしてコンパイルされており、Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1`、Electron `>=12` で動作することを目指しています。 - **Polyfills**:Univer は `Intl.Segmenter` に依存しています。対象ブラウザや実行環境が対応していない場合は、`@formatjs/intl-segmenter` などの polyfill を追加してください。 - **ビルドツール**:Vite、esbuild、Webpack 5 を推奨します。`package.json` の `exports` フィールドに対応していないビルドツール(Webpack 4 など)では、追加のパスマッピングが必要になる場合があります。 - **React**:Univer の view layer は React 18 ベースで構築されており、React 18 と 19 をサポートします。React 16.9+ と 17 には最小限の互換サポートを提供します。 diff --git a/docs/readme/ko-KR.md b/docs/readme/ko-KR.md index 328f9c2803..88fbd8c646 100644 --- a/docs/readme/ko-KR.md +++ b/docs/readme/ko-KR.md @@ -235,7 +235,7 @@ API 호환성 기대치, experimental APIs, internal APIs, deprecation rules는 ## 🧭 호환성 -- **브라우저 런타임**: Univer는 Chrome 70을 대상으로 컴파일되며 Edge `>=70`, Firefox `>=63`, Chrome `>=70`, Safari `>=12.0`, Electron `>=5`에서 잘 동작하도록 노력합니다. +- **브라우저 런타임**: Univer는 Chrome 88을 대상으로 컴파일되며 Edge `>=88`, Firefox `>=90`, Chrome `>=88`, Safari `>=14.1`, Electron `>=12`에서 잘 동작하도록 노력합니다. - **Polyfills**: Univer는 `Intl.Segmenter`에 의존합니다. 대상 브라우저나 런타임이 이를 제공하지 않는다면 `@formatjs/intl-segmenter` 같은 polyfill을 추가하세요. - **빌드 도구**: Vite, esbuild, Webpack 5를 권장합니다. 빌드 도구가 `package.json`의 `exports` 필드를 지원하지 않는 경우(Webpack 4에서 흔함) 추가 path mapping이 필요할 수 있습니다. - **React**: Univer의 view layer는 React 18 기반이며 React 18과 19를 지원합니다. React 16.9+ 및 17에는 최소한의 호환성 지원을 제공합니다. diff --git a/docs/readme/zh-CN.md b/docs/readme/zh-CN.md index 58fdc3733d..9f56439f60 100644 --- a/docs/readme/zh-CN.md +++ b/docs/readme/zh-CN.md @@ -234,7 +234,7 @@ univerAPI.createWorkbook({}) ## 🧭 兼容性 -- **浏览器运行时**:Univer 的编译目标是 Chrome 70,并尽力支持 Edge `>=70`、Firefox `>=63`、Chrome `>=70`、Safari `>=12.0` 和 Electron `>=5`。 +- **浏览器运行时**:Univer 的编译目标是 Chrome 88,并尽力支持 Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1` 和 Electron `>=12`。 - **Polyfills**:Univer 依赖 `Intl.Segmenter`。如果目标浏览器或运行时不支持,请添加 `@formatjs/intl-segmenter` 等 polyfill。 - **构建工具**:推荐使用 Vite、esbuild 或 Webpack 5。如果构建工具不支持 `package.json` 中的 `exports` 字段(Webpack 4 中较常见),可能需要额外配置路径映射。 - **React**:Univer 的视图层基于 React 18 构建,支持 React 18 和 19,并对 React 16.9+ 与 17 提供最低限度的兼容支持。 diff --git a/docs/readme/zh-TW.md b/docs/readme/zh-TW.md index 0e8002898e..9ee49395c1 100644 --- a/docs/readme/zh-TW.md +++ b/docs/readme/zh-TW.md @@ -234,7 +234,7 @@ univerAPI.createWorkbook({}) ## 🧭 相容性 -- **瀏覽器執行時**:Univer 的編譯目標是 Chrome 70,並盡力支援 Edge `>=70`、Firefox `>=63`、Chrome `>=70`、Safari `>=12.0` 和 Electron `>=5`。 +- **瀏覽器執行時**:Univer 的編譯目標是 Chrome 88,並盡力支援 Edge `>=88`、Firefox `>=90`、Chrome `>=88`、Safari `>=14.1` 和 Electron `>=12`。 - **Polyfills**:Univer 依賴 `Intl.Segmenter`。如果目標瀏覽器或執行時不支援,請新增 `@formatjs/intl-segmenter` 等 polyfill。 - **建構工具**:推薦使用 Vite、esbuild 或 Webpack 5。如果建構工具不支援 `package.json` 中的 `exports` 欄位(Webpack 4 中較常見),可能需要額外配置路徑映射。 - **React**:Univer 的視圖層基於 React 18 構建,支援 React 18 和 19,並對 React 16.9+ 與 17 提供最低限度的相容支援。 diff --git a/examples/scripts/esbuild/build-config.mts b/examples/scripts/esbuild/build-config.mts index b81c95d41f..4e5ba493e7 100644 --- a/examples/scripts/esbuild/build-config.mts +++ b/examples/scripts/esbuild/build-config.mts @@ -4,6 +4,7 @@ import path from 'node:path'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; import { ignoreGlobalCssPlugin, removeClassnameNewlinesPlugin } from '@univerjs-infra/shared/esbuild'; +import { DEFAULT_BROWSER_TARGET } from '@univerjs-infra/shared/tsdown'; import aliasPlugin from 'esbuild-plugin-alias'; import copyPlugin from 'esbuild-plugin-copy'; import vue3 from 'esbuild-plugin-vue3'; @@ -61,7 +62,7 @@ export async function createBuildConfig(args: IBuildArgs): Promise { let requestIdleDescriptor: RestorableDescriptor; let cancelIdleDescriptor: RestorableDescriptor; @@ -59,24 +67,9 @@ describe('installShims', () => { writable: true, value: undefined, }); - // eslint-disable-next-line no-extend-native - Object.defineProperty(Array.prototype, 'findLast', { - configurable: true, - writable: true, - value: undefined, - }); - // eslint-disable-next-line no-extend-native - Object.defineProperty(Array.prototype, 'findLastIndex', { - configurable: true, - writable: true, - value: undefined, - }); - // eslint-disable-next-line no-extend-native - Object.defineProperty(String.prototype, 'at', { - configurable: true, - writable: true, - value: undefined, - }); + setPropertyUndefined(Array.prototype, 'findLast'); + setPropertyUndefined(Array.prototype, 'findLastIndex'); + setPropertyUndefined(String.prototype, 'at'); }); afterEach(() => { diff --git a/packages/core/src/docs/data-model/__tests__/rich-text-builder.test.ts b/packages/core/src/docs/data-model/__tests__/rich-text-builder.test.ts index df6a715cc5..02a1676e3c 100644 --- a/packages/core/src/docs/data-model/__tests__/rich-text-builder.test.ts +++ b/packages/core/src/docs/data-model/__tests__/rich-text-builder.test.ts @@ -16,10 +16,23 @@ import type { IBullet } from '../../../types/interfaces'; import { describe, expect, it } from 'vitest'; -import { BaselineOffset, BooleanNumber, HorizontalAlign, TextDecoration, TextDirection, VerticalAlign } from '../../../types/enum'; +import { + BaselineOffset, + BooleanNumber, + HorizontalAlign, + TextDecoration, + TextDirection, + VerticalAlign, +} from '../../../types/enum'; import { CustomRangeType, SpacingRule } from '../../../types/interfaces'; import { PresetListType } from '../preset-list-type'; -import { ParagraphStyleBuilder, RichTextBuilder, RichTextValue, TextDecorationBuilder, TextStyleBuilder } from '../rich-text-builder'; +import { + ParagraphStyleBuilder, + RichTextBuilder, + RichTextValue, + TextDecorationBuilder, + TextStyleBuilder, +} from '../rich-text-builder'; describe('TextStyleBuilder', () => { it('should create empty text style', () => { diff --git a/packages/core/src/docs/data-model/document-data-model.ts b/packages/core/src/docs/data-model/document-data-model.ts index d5e0d9298a..492c19bf2b 100644 --- a/packages/core/src/docs/data-model/document-data-model.ts +++ b/packages/core/src/docs/data-model/document-data-model.ts @@ -15,7 +15,14 @@ */ import type { Nullable } from '../../shared'; -import type { IDocumentBody, IDocumentData, IDocumentRenderConfig, IDocumentStyle, IDrawings, IListData } from '../../types/interfaces/i-document-data'; +import type { + IDocumentBody, + IDocumentData, + IDocumentRenderConfig, + IDocumentStyle, + IDrawings, + IListData, +} from '../../types/interfaces/i-document-data'; import type { IPaddingData } from '../../types/interfaces/i-style-data'; import type { JSONXActions } from './json-x/json-x'; import { BehaviorSubject } from 'rxjs'; diff --git a/packages/core/src/docs/data-model/empty-snapshot.ts b/packages/core/src/docs/data-model/empty-snapshot.ts index e495e51c1e..2c9cfc8180 100644 --- a/packages/core/src/docs/data-model/empty-snapshot.ts +++ b/packages/core/src/docs/data-model/empty-snapshot.ts @@ -16,7 +16,15 @@ import type { IDocumentData } from '../../types/interfaces'; import { generateRandomId } from '../../shared/random-id'; -import { DEFAULT_DOCUMENT_PARAGRAPH_LINE_SPACING, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_ABOVE, DEFAULT_DOCUMENT_PARAGRAPH_SPACE_BELOW, MODERN_DOCUMENT_WIDTH, ModernDocumentWidthMode, PAGE_SIZE, TRADITIONAL_DOCUMENT_DEFAULT_MARGIN } from '../../types/const'; +import { + DEFAULT_DOCUMENT_PARAGRAPH_LINE_SPACING, + DEFAULT_DOCUMENT_PARAGRAPH_SPACE_ABOVE, + DEFAULT_DOCUMENT_PARAGRAPH_SPACE_BELOW, + MODERN_DOCUMENT_WIDTH, + ModernDocumentWidthMode, + PAGE_SIZE, + TRADITIONAL_DOCUMENT_DEFAULT_MARGIN, +} from '../../types/const'; import { BooleanNumber } from '../../types/enum'; import { LocaleType } from '../../types/enum/locale-type'; import { DocumentFlavor, PaperType } from '../../types/interfaces'; diff --git a/packages/core/src/docs/data-model/index.ts b/packages/core/src/docs/data-model/index.ts index 8630063597..228636c3f0 100644 --- a/packages/core/src/docs/data-model/index.ts +++ b/packages/core/src/docs/data-model/index.ts @@ -38,7 +38,11 @@ export { DEFAULT_DOCUMENT_SUB_COMPONENT_ID } from './subdocument'; export { ActionIterator } from './text-x/action-iterator'; export { PRESERVE_INSERTED_PARAGRAPH_IDS, TextXActionType } from './text-x/action-types'; export type { IDeleteAction, IInsertAction, IRetainAction, TextXAction } from './text-x/action-types'; -export { normalizeInsertedSectionIdsForDocument, normalizeTextRuns, RESTORE_INSERTED_PARAGRAPH_IDS } from './text-x/apply-utils/common'; +export { + normalizeInsertedSectionIdsForDocument, + normalizeTextRuns, + RESTORE_INSERTED_PARAGRAPH_IDS, +} from './text-x/apply-utils/common'; export { updateAttributeByDelete } from './text-x/apply-utils/delete-apply'; export { updateAttributeByInsert } from './text-x/apply-utils/insert-apply'; export * from './text-x/build-utils'; diff --git a/packages/core/src/docs/data-model/rich-text-builder.ts b/packages/core/src/docs/data-model/rich-text-builder.ts index e4ed71c72c..62895fd563 100644 --- a/packages/core/src/docs/data-model/rich-text-builder.ts +++ b/packages/core/src/docs/data-model/rich-text-builder.ts @@ -2442,7 +2442,7 @@ export class RichTextBuilder extends RichTextValue { */ listItem(text: string, options: IRichTextListItemOptions = {}): RichTextBuilder { const listType = options.type ?? PresetListType.BULLET_LIST; - const currentParagraph = this._data.body?.paragraphs?.at(-1); + const currentParagraph = this._data.body?.paragraphs?.slice(-1)[0]; const currentBullet = currentParagraph?.bullet; const listId = options.listId?.trim() || (currentBullet?.listType === listType ? currentBullet.listId : generateRandomId()); @@ -2453,7 +2453,7 @@ export class RichTextBuilder extends RichTextValue { this.paragraph(options.paragraphStyle); } - const targetParagraph = this._data.body?.paragraphs?.at(-1); + const targetParagraph = this._data.body?.paragraphs?.slice(-1)[0]; if (targetParagraph) { targetParagraph.bullet = { listId, @@ -2494,7 +2494,7 @@ export class RichTextBuilder extends RichTextValue { return this; } - const currentParagraph = this._data.body?.paragraphs?.at(-1); + const currentParagraph = this._data.body?.paragraphs?.slice(-1)[0]; const currentParagraphStyle = Tools.deepClone(currentParagraph?.paragraphStyle); const currentParagraphBullet = Tools.deepClone(currentParagraph?.bullet); const startIndex = Math.max(0, (this._data.body?.dataStream.length ?? 2) - 2); @@ -2511,7 +2511,7 @@ export class RichTextBuilder extends RichTextValue { }], }, })); - const nextParagraph = this._data.body?.paragraphs?.at(-1); + const nextParagraph = this._data.body?.paragraphs?.slice(-1)[0]; if (nextParagraphStyle) { if (nextParagraph) { nextParagraph.paragraphStyle = nextParagraphStyle; diff --git a/packages/core/src/docs/data-model/text-x/apply-utils/update-apply.ts b/packages/core/src/docs/data-model/text-x/apply-utils/update-apply.ts index 3441e9b882..afb151ae19 100644 --- a/packages/core/src/docs/data-model/text-x/apply-utils/update-apply.ts +++ b/packages/core/src/docs/data-model/text-x/apply-utils/update-apply.ts @@ -15,7 +15,17 @@ */ import type { Nullable } from '../../../../shared'; -import type { ICustomBlock, ICustomColumnGroup, ICustomDecoration, ICustomRange, ICustomTable, IDocumentBody, IParagraph, ISectionBreak, ITextRun } from '../../../../types/interfaces'; +import type { + ICustomBlock, + ICustomColumnGroup, + ICustomDecoration, + ICustomRange, + ICustomTable, + IDocumentBody, + IParagraph, + ISectionBreak, + ITextRun, +} from '../../../../types/interfaces'; import { Tools, UpdateDocsAttributeType } from '../../../../shared'; import { CustomDecorationType } from '../../../../types/interfaces'; import { PresetListType } from '../../preset-list-type'; diff --git a/packages/core/src/docs/data-model/text-x/build-utils/paragraph.ts b/packages/core/src/docs/data-model/text-x/build-utils/paragraph.ts index 0700da9bfd..c650d4dd35 100644 --- a/packages/core/src/docs/data-model/text-x/build-utils/paragraph.ts +++ b/packages/core/src/docs/data-model/text-x/build-utils/paragraph.ts @@ -15,7 +15,13 @@ */ import type { ITextRange } from '../../../../sheets/typedef'; -import type { ICustomTable, IDocumentBody, IParagraph, IParagraphStyle, ITextStyle } from '../../../../types/interfaces'; +import type { + ICustomTable, + IDocumentBody, + IParagraph, + IParagraphStyle, + ITextStyle, +} from '../../../../types/interfaces'; import type { DocumentDataModel } from '../../document-data-model'; import { MemoryCursor } from '../../../../common/memory-cursor'; import { UpdateDocsAttributeType } from '../../../../shared'; diff --git a/packages/core/src/docs/data-model/text-x/text-x.ts b/packages/core/src/docs/data-model/text-x/text-x.ts index 7fec18491c..1cb42dfe35 100644 --- a/packages/core/src/docs/data-model/text-x/text-x.ts +++ b/packages/core/src/docs/data-model/text-x/text-x.ts @@ -22,7 +22,11 @@ import { Tools } from '../../../shared/tools'; import { ActionIterator } from './action-iterator'; import { PRESERVE_INSERTED_PARAGRAPH_IDS, TextXActionType } from './action-types'; import { textXApply } from './apply'; -import { normalizeInsertedParagraphIdsForDocument, normalizeInsertedSectionIdsForDocument, RESTORE_INSERTED_PARAGRAPH_IDS } from './apply-utils/common'; +import { + normalizeInsertedParagraphIdsForDocument, + normalizeInsertedSectionIdsForDocument, + RESTORE_INSERTED_PARAGRAPH_IDS, +} from './apply-utils/common'; import { transformBody } from './transform-utils'; import { composeBody, getBodySlice, isUselessRetainAction } from './utils'; diff --git a/packages/core/src/docs/data-model/text-x/transform-utils.ts b/packages/core/src/docs/data-model/text-x/transform-utils.ts index 25207cb0de..10eb0a213b 100644 --- a/packages/core/src/docs/data-model/text-x/transform-utils.ts +++ b/packages/core/src/docs/data-model/text-x/transform-utils.ts @@ -14,10 +14,17 @@ * limitations under the License. */ -/* eslint-disable no-param-reassign */ - import type { Nullable } from '../../../shared'; -import type { ICustomDecoration, ICustomRange, IDocumentBlockRange, IDocumentBody, IParagraph, IParagraphStyle, ITextRun, ITextStyle } from '../../../types/interfaces'; +import type { + ICustomDecoration, + ICustomRange, + IDocumentBlockRange, + IDocumentBody, + IParagraph, + IParagraphStyle, + ITextRun, + ITextStyle, +} from '../../../types/interfaces'; import type { IRetainAction } from './action-types'; import { merge } from '../../../common/lodash'; import { Tools, UpdateDocsAttributeType } from '../../../shared'; diff --git a/packages/core/src/docs/data-model/text-x/utils.ts b/packages/core/src/docs/data-model/text-x/utils.ts index 97e3774da8..53f35ee6b4 100644 --- a/packages/core/src/docs/data-model/text-x/utils.ts +++ b/packages/core/src/docs/data-model/text-x/utils.ts @@ -14,7 +14,17 @@ * limitations under the License. */ -import type { ICustomBlock, ICustomColumnGroup, ICustomDecoration, ICustomRange, IDocumentBlockRange, IDocumentBody, IParagraph, ISectionBreak, ITextRun } from '../../../types/interfaces/i-document-data'; +import type { + ICustomBlock, + ICustomColumnGroup, + ICustomDecoration, + ICustomRange, + IDocumentBlockRange, + IDocumentBody, + IParagraph, + ISectionBreak, + ITextRun, +} from '../../../types/interfaces/i-document-data'; import type { DocumentDataModel } from '../../data-model'; import type { IRetainAction } from './action-types'; import { merge } from '../../../common/lodash'; diff --git a/packages/core/src/facade/f-enum.ts b/packages/core/src/facade/f-enum.ts index 33aae61601..1a38dc8008 100644 --- a/packages/core/src/facade/f-enum.ts +++ b/packages/core/src/facade/f-enum.ts @@ -14,9 +14,45 @@ * limitations under the License. */ -/* eslint-disable ts/explicit-function-return-type */ - -import { AbsoluteRefType, AutoFillSeries, BaselineOffset, BooleanNumber, BorderStyleTypes, BorderType, ColorType, CommandType, CommonHideTypes, CopyPasteType, DataValidationErrorStyle, DataValidationOperator, DataValidationRenderMode, DataValidationStatus, DataValidationType, DeleteDirection, DeveloperMetadataVisibility, Dimension, Direction, HorizontalAlign, ImageSourceType, InterpolationPointType, LifecycleStages, LocaleType, MentionType, NumberUnitType, PresetListType, ProtectionType, RelativeDate, SheetTypes, SpacingRule, TextDecoration, TextDirection, ThemeColorType, UniverInstanceType, VerticalAlign, WrapStrategy } from '@univerjs/core'; +import { + AbsoluteRefType, + AutoFillSeries, + BaselineOffset, + BooleanNumber, + BorderStyleTypes, + BorderType, + ColorType, + CommandType, + CommonHideTypes, + CopyPasteType, + DataValidationErrorStyle, + DataValidationOperator, + DataValidationRenderMode, + DataValidationStatus, + DataValidationType, + DeleteDirection, + DeveloperMetadataVisibility, + Dimension, + Direction, + HorizontalAlign, + ImageSourceType, + InterpolationPointType, + LifecycleStages, + LocaleType, + MentionType, + NumberUnitType, + PresetListType, + ProtectionType, + RelativeDate, + SheetTypes, + SpacingRule, + TextDecoration, + TextDirection, + ThemeColorType, + UniverInstanceType, + VerticalAlign, + WrapStrategy, +} from '@univerjs/core'; /** * @hideconstructor @@ -27,7 +63,7 @@ export class FEnum { */ static _instance: FEnum | null; - static get() { + static get(): FEnum { if (this._instance) { return this._instance; } @@ -71,7 +107,7 @@ export class FEnum { * console.log(univerAPI.Enum.AbsoluteRefType); * ``` */ - get AbsoluteRefType() { + get AbsoluteRefType(): typeof AbsoluteRefType { return AbsoluteRefType; } @@ -83,7 +119,7 @@ export class FEnum { * console.log(univerAPI.Enum.UniverInstanceType.UNIVER_SHEET); * ``` */ - get UniverInstanceType() { + get UniverInstanceType(): typeof UniverInstanceType { return UniverInstanceType; } @@ -95,7 +131,7 @@ export class FEnum { * console.log(univerAPI.Enum.LifecycleStages.Rendered); * ``` */ - get LifecycleStages() { + get LifecycleStages(): typeof LifecycleStages { return LifecycleStages; } @@ -107,7 +143,7 @@ export class FEnum { * console.log(univerAPI.Enum.DataValidationType.LIST); * ``` */ - get DataValidationType() { + get DataValidationType(): typeof DataValidationType { return DataValidationType; } @@ -119,7 +155,7 @@ export class FEnum { * console.log(univerAPI.Enum.DataValidationErrorStyle.WARNING); * ``` */ - get DataValidationErrorStyle() { + get DataValidationErrorStyle(): typeof DataValidationErrorStyle { return DataValidationErrorStyle; } @@ -131,7 +167,7 @@ export class FEnum { * console.log(univerAPI.Enum.DataValidationRenderMode.TEXT); * ``` */ - get DataValidationRenderMode() { + get DataValidationRenderMode(): typeof DataValidationRenderMode { return DataValidationRenderMode; } @@ -143,7 +179,7 @@ export class FEnum { * console.log(univerAPI.Enum.DataValidationOperator.BETWEEN); * ``` */ - get DataValidationOperator() { + get DataValidationOperator(): typeof DataValidationOperator { return DataValidationOperator; } @@ -155,7 +191,7 @@ export class FEnum { * console.log(univerAPI.Enum.DataValidationStatus.VALID); * ``` */ - get DataValidationStatus() { + get DataValidationStatus(): typeof DataValidationStatus { return DataValidationStatus; } @@ -167,7 +203,7 @@ export class FEnum { * console.log(univerAPI.Enum.CommandType.COMMAND); * ``` */ - get CommandType() { + get CommandType(): typeof CommandType { return CommandType; } @@ -179,7 +215,7 @@ export class FEnum { * console.log(univerAPI.Enum.BaselineOffset.SUPERSCRIPT); * ``` */ - get BaselineOffset() { + get BaselineOffset(): typeof BaselineOffset { return BaselineOffset; } @@ -191,7 +227,7 @@ export class FEnum { * console.log(univerAPI.Enum.BooleanNumber.TRUE); * ``` */ - get BooleanNumber() { + get BooleanNumber(): typeof BooleanNumber { return BooleanNumber; } @@ -203,7 +239,7 @@ export class FEnum { * console.log(univerAPI.Enum.HorizontalAlign.CENTER); * ``` */ - get HorizontalAlign() { + get HorizontalAlign(): typeof HorizontalAlign { return HorizontalAlign; } @@ -215,7 +251,7 @@ export class FEnum { * console.log(univerAPI.Enum.SpacingRule.EXACT); * ``` */ - get SpacingRule() { + get SpacingRule(): typeof SpacingRule { return SpacingRule; } @@ -230,7 +266,7 @@ export class FEnum { * console.log(univerAPI.Enum.NumberUnitType.POINT); * ``` */ - get NumberUnitType() { + get NumberUnitType(): typeof NumberUnitType { return NumberUnitType; } @@ -242,7 +278,7 @@ export class FEnum { * console.log(univerAPI.Enum.PresetListType.BULLET_LIST); * ``` */ - get PresetListType() { + get PresetListType(): typeof PresetListType { return PresetListType; } @@ -254,7 +290,7 @@ export class FEnum { * console.log(univerAPI.Enum.TextDecoration.DOUBLE); * ``` */ - get TextDecoration() { + get TextDecoration(): typeof TextDecoration { return TextDecoration; } @@ -266,7 +302,7 @@ export class FEnum { * console.log(univerAPI.Enum.TextDirection.LEFT_TO_RIGHT); * ``` */ - get TextDirection() { + get TextDirection(): typeof TextDirection { return TextDirection; } @@ -278,7 +314,7 @@ export class FEnum { * console.log(univerAPI.Enum.VerticalAlign.MIDDLE); * ``` */ - get VerticalAlign() { + get VerticalAlign(): typeof VerticalAlign { return VerticalAlign; } @@ -290,7 +326,7 @@ export class FEnum { * console.log(univerAPI.Enum.WrapStrategy.WRAP); * ``` */ - get WrapStrategy() { + get WrapStrategy(): typeof WrapStrategy { return WrapStrategy; } @@ -302,7 +338,7 @@ export class FEnum { * console.log(univerAPI.Enum.BorderType.OUTSIDE); * ``` */ - get BorderType() { + get BorderType(): typeof BorderType { return BorderType; } @@ -314,7 +350,7 @@ export class FEnum { * console.log(univerAPI.Enum.BorderStyleTypes.NONE); * ``` */ - get BorderStyleTypes() { + get BorderStyleTypes(): typeof BorderStyleTypes { return BorderStyleTypes; } @@ -326,7 +362,7 @@ export class FEnum { * console.log(univerAPI.Enum.AutoFillSeries.ALTERNATE_SERIES); * ``` */ - get AutoFillSeries() { + get AutoFillSeries(): typeof AutoFillSeries { return AutoFillSeries; } @@ -338,7 +374,7 @@ export class FEnum { * console.log(univerAPI.Enum.ColorType.RGB); * ``` */ - get ColorType() { + get ColorType(): typeof ColorType { return ColorType; } @@ -350,7 +386,7 @@ export class FEnum { * console.log(univerAPI.Enum.CommonHideTypes.ON); * ``` */ - get CommonHideTypes() { + get CommonHideTypes(): typeof CommonHideTypes { return CommonHideTypes; } @@ -362,7 +398,7 @@ export class FEnum { * console.log(univerAPI.Enum.CopyPasteType.PASTE_VALUES); * ``` */ - get CopyPasteType() { + get CopyPasteType(): typeof CopyPasteType { return CopyPasteType; } @@ -374,7 +410,7 @@ export class FEnum { * console.log(univerAPI.Enum.DeleteDirection.LEFT); * ``` */ - get DeleteDirection() { + get DeleteDirection(): typeof DeleteDirection { return DeleteDirection; } @@ -386,7 +422,7 @@ export class FEnum { * console.log(univerAPI.Enum.DeveloperMetadataVisibility.DOCUMENT); * ``` */ - get DeveloperMetadataVisibility() { + get DeveloperMetadataVisibility(): typeof DeveloperMetadataVisibility { return DeveloperMetadataVisibility; } @@ -398,7 +434,7 @@ export class FEnum { * console.log(univerAPI.Enum.Dimension.ROWS); * ``` */ - get Dimension() { + get Dimension(): typeof Dimension { return Dimension; } @@ -410,7 +446,7 @@ export class FEnum { * console.log(univerAPI.Enum.Direction.UP); * ``` */ - get Direction() { + get Direction(): typeof Direction { return Direction; } @@ -422,7 +458,7 @@ export class FEnum { * console.log(univerAPI.Enum.InterpolationPointType.NUMBER); * ``` */ - get InterpolationPointType() { + get InterpolationPointType(): typeof InterpolationPointType { return InterpolationPointType; } @@ -434,7 +470,7 @@ export class FEnum { * console.log(univerAPI.Enum.LocaleType.EN_US); * ``` */ - get LocaleType() { + get LocaleType(): typeof LocaleType { return LocaleType; } @@ -446,7 +482,7 @@ export class FEnum { * console.log(univerAPI.Enum.MentionType.PERSON); * ``` */ - get MentionType() { + get MentionType(): typeof MentionType { return MentionType; } @@ -458,7 +494,7 @@ export class FEnum { * console.log(univerAPI.Enum.ProtectionType.RANGE); * ``` */ - get ProtectionType() { + get ProtectionType(): typeof ProtectionType { return ProtectionType; } @@ -470,7 +506,7 @@ export class FEnum { * console.log(univerAPI.Enum.RelativeDate.TODAY); * ``` */ - get RelativeDate() { + get RelativeDate(): typeof RelativeDate { return RelativeDate; } @@ -482,7 +518,7 @@ export class FEnum { * console.log(univerAPI.Enum.SheetTypes.GRID); * ``` */ - get SheetTypes() { + get SheetTypes(): typeof SheetTypes { return SheetTypes; } @@ -494,7 +530,7 @@ export class FEnum { * console.log(univerAPI.Enum.ThemeColorType.ACCENT1); * ``` */ - get ThemeColorType() { + get ThemeColorType(): typeof ThemeColorType { return ThemeColorType; } @@ -506,7 +542,7 @@ export class FEnum { * console.log(univerAPI.Enum.ImageSourceType.URL); * ``` */ - get ImageSourceType() { + get ImageSourceType(): typeof ImageSourceType { return ImageSourceType; } } diff --git a/packages/core/src/facade/f-event.ts b/packages/core/src/facade/f-event.ts index e649455ea7..134e8c4bab 100644 --- a/packages/core/src/facade/f-event.ts +++ b/packages/core/src/facade/f-event.ts @@ -14,9 +14,13 @@ * limitations under the License. */ -/* eslint-disable ts/explicit-function-return-type */ - -import type { CommandType, IDocumentData, IExecutionOptions, LifecycleStages, UniverInstanceType } from '@univerjs/core'; +import type { + CommandType, + IDocumentData, + IExecutionOptions, + LifecycleStages, + UniverInstanceType, +} from '@univerjs/core'; import type { FDoc } from './f-doc'; /** @@ -94,7 +98,7 @@ export class FEventName { */ static _instance: FEventName | null; - static get() { + static get(): FEventName { if (this._instance) { return this._instance; } @@ -143,7 +147,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get DocCreated() { + get DocCreated(): 'DocCreated' { return 'DocCreated' as const; } @@ -160,7 +164,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get DocDisposed() { + get DocDisposed(): 'DocDisposed' { return 'DocDisposed' as const; } @@ -177,7 +181,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get LifeCycleChanged() { + get LifeCycleChanged(): 'LifeCycleChanged' { return 'LifeCycleChanged' as const; } @@ -194,7 +198,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get Redo() { + get Redo(): 'Redo' { return 'Redo' as const; } @@ -211,7 +215,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get Undo() { + get Undo(): 'Undo' { return 'Undo' as const; } @@ -231,7 +235,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get BeforeRedo() { + get BeforeRedo(): 'BeforeRedo' { return 'BeforeRedo' as const; } @@ -251,7 +255,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get BeforeUndo() { + get BeforeUndo(): 'BeforeUndo' { return 'BeforeUndo' as const; } @@ -268,7 +272,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get CommandExecuted() { + get CommandExecuted(): 'CommandExecuted' { return 'CommandExecuted' as const; } @@ -288,7 +292,7 @@ export class FEventName { * // Remove the event listener, use `disposable.dispose()` * ``` */ - get BeforeCommandExecute() { + get BeforeCommandExecute(): 'BeforeCommandExecute' { return 'BeforeCommandExecute' as const; } } diff --git a/packages/core/src/shared/numfmt/parse-value.ts b/packages/core/src/shared/numfmt/parse-value.ts index 6a1947cfa9..8fda9fcee1 100644 --- a/packages/core/src/shared/numfmt/parse-value.ts +++ b/packages/core/src/shared/numfmt/parse-value.ts @@ -612,9 +612,9 @@ const getDateLocaleLookups = (locale: LocaleData): DateLocaleLookups => { cached = { lookups: { mon: getLookups(locale.mmmm, 'F').concat(getLookups(locale.mmm, 'M')), - mp: locale.mmm[0].at(-1) === '.', + mp: locale.mmm[0].endsWith('.'), day: getLookups(locale.dddd, 'l').concat(getLookups(locale.ddd, 'D')), - dp: locale.ddd[0].at(-1) === '.', + dp: locale.ddd[0].endsWith('.'), }, mmmm: [...locale.mmmm], mmm: [...locale.mmm], diff --git a/packages/docs-ui/src/menu/menu.ts b/packages/docs-ui/src/menu/menu.ts index d4b8da4ba5..d7a60c9fba 100644 --- a/packages/docs-ui/src/menu/menu.ts +++ b/packages/docs-ui/src/menu/menu.ts @@ -86,10 +86,12 @@ import { AlignRightCommand, } from '../commands/commands/paragraph-align.command'; import { SetParagraphNamedStyleCommand } from '../commands/commands/set-heading.command'; -// import { SwitchDocModeCommand } from '../commands/commands/switch-doc-mode.command'; import { CreateDocTableCommand } from '../commands/commands/table/doc-table-create.command'; import { DocCreateTableOperation } from '../commands/operations/doc-create-table.operation'; -import { InsertDocumentColumnBreakOperation, InsertDocumentSectionBreakOperation } from '../commands/operations/insert-break.operation'; +import { + InsertDocumentColumnBreakOperation, + InsertDocumentSectionBreakOperation, +} from '../commands/operations/insert-break.operation'; import { DocOpenPageSettingCommand } from '../commands/operations/open-page-setting.operation'; import { getCommandSkeleton } from '../commands/util'; import { IDocEmbedRuntimeFocusCoordinator } from '../services/doc-embed-integration.service'; diff --git a/packages/docs-ui/src/services/doc-event-manager.service.ts b/packages/docs-ui/src/services/doc-event-manager.service.ts index e4ac30f642..8d8c448dd9 100644 --- a/packages/docs-ui/src/services/doc-event-manager.service.ts +++ b/packages/docs-ui/src/services/doc-event-manager.service.ts @@ -189,7 +189,7 @@ const calcParagraphPositionsFromLineContexts = ( function getParagraphLineBottom(context: IDocumentSkeletonLineContext, lineTop: number): number { const lineBottom = lineTop + context.line.lineHeight; - if (context.source !== 'column' || context.line !== context.column.lines.at(-1) || !Number.isFinite(context.page.pageHeight)) { + if (context.source !== 'column' || context.line !== context.column.lines[context.column.lines.length - 1] || !Number.isFinite(context.page.pageHeight)) { return lineBottom; } diff --git a/packages/docs/src/commands/commands/update-document-section.command.ts b/packages/docs/src/commands/commands/update-document-section.command.ts index ab538f8194..13635b308b 100644 --- a/packages/docs/src/commands/commands/update-document-section.command.ts +++ b/packages/docs/src/commands/commands/update-document-section.command.ts @@ -257,7 +257,7 @@ export const DeleteDocumentSectionBreakCommand: ICommand item.sectionId === params.sectionId); - if (!section || section === sections.at(-1)) { + if (!section || section === sections[sections.length - 1]) { return false; } diff --git a/packages/drawing/src/services/drawing-manager-impl.service.ts b/packages/drawing/src/services/drawing-manager-impl.service.ts index e16080fb70..17e9c04e38 100644 --- a/packages/drawing/src/services/drawing-manager-impl.service.ts +++ b/packages/drawing/src/services/drawing-manager-impl.service.ts @@ -14,10 +14,25 @@ * limitations under the License. */ -import type { IDrawingGroupNestedIds, IDrawingGroupNestedParam, IDrawingParam, IDrawingSearch, Nullable } from '@univerjs/core'; +import type { + IDrawingGroupNestedIds, + IDrawingGroupNestedParam, + IDrawingParam, + IDrawingSearch, + Nullable, +} from '@univerjs/core'; import type { JSONOp, JSONOpList } from 'ot-json1'; import type { Observable } from 'rxjs'; -import type { IDrawingGroupUpdateParam, IDrawingMap, IDrawingMapItemData, IDrawingOrderMapParam, IDrawingOrderUpdateParam, IDrawingSubunitMap, IDrawingVisibleParam, IUnitDrawingService } from './drawing-manager.service'; +import type { + IDrawingGroupUpdateParam, + IDrawingMap, + IDrawingMapItemData, + IDrawingOrderMapParam, + IDrawingOrderUpdateParam, + IDrawingSubunitMap, + IDrawingVisibleParam, + IUnitDrawingService, +} from './drawing-manager.service'; import { DrawingTypeEnum, sortRules, sortRulesByDesc } from '@univerjs/core'; import * as json1 from 'ot-json1'; import { Subject } from 'rxjs'; @@ -166,10 +181,10 @@ export class UnitDrawingService implements IUnitDrawing } param.transform = updateParam.transform; - if (Object.hasOwn(updateParam, 'transforms')) { + if (Object.prototype.hasOwnProperty.call(updateParam, 'transforms')) { param.transforms = updateParam.transforms; } - if (Object.hasOwn(updateParam, 'isMultiTransform')) { + if (Object.prototype.hasOwnProperty.call(updateParam, 'isMultiTransform')) { param.isMultiTransform = updateParam.isMultiTransform; } diff --git a/packages/engine-formula/src/basics/__tests__/regex.spec.ts b/packages/engine-formula/src/basics/__tests__/regex.spec.ts index 646a765ef1..4b4d81c7e7 100644 --- a/packages/engine-formula/src/basics/__tests__/regex.spec.ts +++ b/packages/engine-formula/src/basics/__tests__/regex.spec.ts @@ -64,6 +64,13 @@ describe('Test ref regex', () => { expect(new RegExp(REFERENCE_TABLE_SINGLE_COLUMN_REGEX).test('Table1[[#Title],[#Data],[Column1]]')).toBe(true); }); + it('allows a hash only at the end of a table column name', () => { + const regex = new RegExp(REFERENCE_TABLE_SINGLE_COLUMN_REGEX); + + expect(regex.test('Table1[Column#]')).toBe(true); + expect(regex.test('Table1[Column#Name]')).toBe(false); + }); + it('Table multiple range', () => { expect(new RegExp(REFERENCE_TABLE_MULTIPLE_COLUMN_REGEX).test('Table1[[#Title],[#Data],[Column1]:[Column10]]')).toBe(true); }); diff --git a/packages/engine-formula/src/basics/regex.ts b/packages/engine-formula/src/basics/regex.ts index 58a8465274..f80561f2ce 100644 --- a/packages/engine-formula/src/basics/regex.ts +++ b/packages/engine-formula/src/basics/regex.ts @@ -66,7 +66,7 @@ const TABLE_NAME_REGEX = '((?![~!@#$%^&*()_+<>?:,./;’,。、‘:“《》 const TABLE_TITLE_REGEX = '\\[#.+\\]\\s*?,\\s*?'; -const TABLE_CONTENT_REGEX = '\\[((? name.toLowerCase() === tableName.toLowerCase()); + return Array.from(unitIdMap.keys()).some((name) => name.toLowerCase() === tableName.toLowerCase()); } return false; diff --git a/packages/engine-render/src/__tests__/context.spec.ts b/packages/engine-render/src/__tests__/context.spec.ts index e8d7d4c5ba..dd8307463c 100644 --- a/packages/engine-render/src/__tests__/context.spec.ts +++ b/packages/engine-render/src/__tests__/context.spec.ts @@ -224,6 +224,19 @@ describe('context extra', () => { browserSpy.mockRestore(); }); + it('falls back when the native context does not support roundRect', () => { + const nativeCtx = createNativeContext(); + delete (nativeCtx as Partial).roundRect; + const renderCtx = new UniverRenderingContext2D(nativeCtx); + + renderCtx.roundRect(10, 20, 40, 20, 4); + + expect(nativeCtx.moveTo).toHaveBeenCalledWith(14, 20); + expect(nativeCtx.quadraticCurveTo).toHaveBeenNthCalledWith(1, 50, 20, 50, 24); + expect(nativeCtx.closePath).toHaveBeenCalledTimes(1); + expect(nativeCtx.rect).not.toHaveBeenCalled(); + }); + it('covers fallback line dash branches and printing context', () => { const nativeCtx = createNativeContext() as any; delete nativeCtx.setLineDash; diff --git a/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts b/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts index b9387c1388..5ef5b9bdcb 100644 --- a/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts +++ b/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts @@ -916,7 +916,7 @@ export function lineBreaking( ) { // Word treats a DOCX column break at the start of the final column as redundant. } else if (isTraditionalDocumentCompatibility(documentCompatibilityPolicy)) { - const lastColumn = getLastSection(lastPage)?.columns.at(-1); + const lastColumn = getLastSection(lastPage)?.columns.slice(-1)[0]; if (lastColumn && (isBlankColumn(lastColumn) || _isDocxColumnBreakVisuallyBlankColumn(lastColumn))) { setColumnFullState(lastColumn, false); } else { diff --git a/packages/engine-render/src/components/docs/layout/doc-skeleton.ts b/packages/engine-render/src/components/docs/layout/doc-skeleton.ts index 1f64b05358..2e26fd40b5 100644 --- a/packages/engine-render/src/components/docs/layout/doc-skeleton.ts +++ b/packages/engine-render/src/components/docs/layout/doc-skeleton.ts @@ -1572,7 +1572,7 @@ export class DocumentSkeleton extends Skeleton { marginLeft, marginRight, } = curSkeletonPage; - const sectionTop = curSkeletonPage.sections.at(-1)?.top ?? 0; + const sectionTop = curSkeletonPage.sections[curSkeletonPage.sections.length - 1]?.top ?? 0; const newSection = createSkeletonSection( columnProperties, columnSeparatorType, diff --git a/packages/engine-render/src/components/docs/layout/model/page.ts b/packages/engine-render/src/components/docs/layout/model/page.ts index 0e166cbc55..a5f12e2947 100644 --- a/packages/engine-render/src/components/docs/layout/model/page.ts +++ b/packages/engine-render/src/components/docs/layout/model/page.ts @@ -409,7 +409,7 @@ export function createSkeletonCellPages( break; } - const retryPage = pages.at(-1); + const retryPage = pages[pages.length - 1]; if (retryPage == null) { break; } @@ -461,7 +461,9 @@ export function applyTrailingBlockRangeSpaceBelow(pages: IDocumentSkeletonPage[] } for (const page of pages) { - const lastLine = page.sections.at(-1)?.columns.at(-1)?.lines.at(-1); + const lastSection = page.sections[page.sections.length - 1]; + const lastColumn = lastSection?.columns[lastSection.columns.length - 1]; + const lastLine = lastColumn?.lines[lastColumn.lines.length - 1]; if (!lastLine) { continue; } diff --git a/packages/engine-render/src/context.ts b/packages/engine-render/src/context.ts index 56ab7fbd8b..6d55712bd5 100644 --- a/packages/engine-render/src/context.ts +++ b/packages/engine-render/src/context.ts @@ -367,7 +367,29 @@ export class UniverRenderingContext2D implements CanvasRenderingContext2D { h: number, radii?: number | DOMPointInit | Array ): void { - this._context.roundRect(x, y, w, h, radii); + if (typeof this._context.roundRect === 'function') { + this._context.roundRect(x, y, w, h, radii); + return; + } + + const radius = typeof radii === 'number' ? Math.min(radii, w / 2, h / 2) : 0; + if (!(radius > 0) || !Number.isFinite(radius)) { + this._context.rect(x, y, w, h); + return; + } + + const right = x + w; + const bottom = y + h; + this._context.moveTo(x + radius, y); + this._context.lineTo(right - radius, y); + this._context.quadraticCurveTo(right, y, right, y + radius); + this._context.lineTo(right, bottom - radius); + this._context.quadraticCurveTo(right, bottom, right - radius, bottom); + this._context.lineTo(x + radius, bottom); + this._context.quadraticCurveTo(x, bottom, x, bottom - radius); + this._context.lineTo(x, y + radius); + this._context.quadraticCurveTo(x, y, x + radius, y); + this._context.closePath(); } roundRectByPrecision( diff --git a/packages/sheets-conditional-formatting/src/facade/f-conditional-formatting-builder.ts b/packages/sheets-conditional-formatting/src/facade/f-conditional-formatting-builder.ts index e19b94b93d..95f7dd4a3b 100644 --- a/packages/sheets-conditional-formatting/src/facade/f-conditional-formatting-builder.ts +++ b/packages/sheets-conditional-formatting/src/facade/f-conditional-formatting-builder.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -/* eslint-disable ts/explicit-function-return-type */ - import type { IRange } from '@univerjs/core'; import type { CFTimePeriodOperator, @@ -44,7 +42,7 @@ import { CFNumberOperator, CFRuleType, CFSubRuleType, CFTextOperator, CFValueTyp class ConditionalFormatRuleBaseBuilder { protected _rule: Partial = {}; - protected get _ruleConfig() { + protected get _ruleConfig(): IConditionalFormattingRuleConfig | null { return this._rule.rule || null; } @@ -105,14 +103,13 @@ class ConditionalFormatRuleBaseBuilder { this._ensureAttr(this._rule, ['rule']); } - // eslint-disable-next-line ts/no-explicit-any - protected _ensureAttr(obj: Record, keys: string[]) { + protected _ensureAttr(obj: T, keys: string[]): T { keys.reduce((pre, cur) => { if (!pre[cur]) { pre[cur] = {}; } - return pre[cur]; - }, obj); + return pre[cur] as Record; + }, obj as Record); return obj; } @@ -231,7 +228,7 @@ class ConditionalFormatRuleBaseBuilder { * fWorksheet.addConditionalFormattingRule(rule); * ``` */ - setRanges(ranges: IRange[]) { + setRanges(ranges: IRange[]): this { this._rule.ranges = ranges; return this; } diff --git a/packages/sheets-conditional-formatting/src/models/calculate-unit-v2/highlight-cell-calculate-unit.ts b/packages/sheets-conditional-formatting/src/models/calculate-unit-v2/highlight-cell-calculate-unit.ts index 62837411dc..7ed45b2cd2 100644 --- a/packages/sheets-conditional-formatting/src/models/calculate-unit-v2/highlight-cell-calculate-unit.ts +++ b/packages/sheets-conditional-formatting/src/models/calculate-unit-v2/highlight-cell-calculate-unit.ts @@ -96,7 +96,7 @@ export class HighlightCellCalculateUnit extends BaseCalculateUnit = {}; + const menuConfig: Record = {}; let obj = menuConfig; const schema = this.__getSchema(); @@ -131,7 +130,7 @@ abstract class FMenuBase extends FBase { } else { obj[p] = {}; } - obj = obj[p]; + obj = obj[p] as Record; }); this._menuManagerService.mergeMenu(menuConfig); @@ -174,15 +173,14 @@ export class FMenu extends FMenuBase { } this._buildingSchema = { - // eslint-disable-next-line ts/explicit-function-return-type - menuItemFactory: () => ({ + menuItemFactory: (): IMenuButtonItem => ({ id: _item.id, type: MenuItemType.BUTTON, // we only support button for now icon: _item.icon, title: _item.title, tooltip: _item.tooltip, commandId, - } as IMenuButtonItem), + }), }; if (typeof _item.order !== 'undefined') { @@ -235,8 +233,7 @@ export class FSubmenu extends FMenuBase { super(); this._buildingSchema = { - // eslint-disable-next-line ts/explicit-function-return-type - menuItemFactory: () => ({ + menuItemFactory: (): IMenuItem => ({ id: _item.id, type: MenuItemType.SUBITEMS, icon: _item.icon, diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 5223cb091e..8a9a37aa94 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -67,7 +67,12 @@ export type { IContextMenuHandler } from './services/contextmenu/contextmenu.ser export { DesktopDialogService } from './services/dialog/desktop-dialog.service'; export { IDialogService } from './services/dialog/dialog.service'; export { CanvasFloatDomPreviewService, CanvasFloatDomService } from './services/dom/canvas-dom-layer.service'; -export type { ICanvasFloatDomPreview, ICanvasFloatDomPreviewRequest, IFloatDom, IFloatDomLayout } from './services/dom/canvas-dom-layer.service'; +export type { + ICanvasFloatDomPreview, + ICanvasFloatDomPreviewRequest, + IFloatDom, + IFloatDomLayout, +} from './services/dom/canvas-dom-layer.service'; export { FontService, IFontService } from './services/font.service'; export type { IFontConfig } from './services/font.service'; export { DesktopGalleryService } from './services/gallery/desktop-gallery.service'; @@ -120,7 +125,11 @@ export { IUIRuntimeScopeService, UIRuntimeScopeService } from './services/runtim export type { IUIRuntimeScope } from './services/runtime-scope/ui-runtime-scope.service'; export { KeyCode, MetaKeys } from './services/shortcut/keycode'; export { ShortcutPanelService } from './services/shortcut/shortcut-panel.service'; -export { IShortcutService, NativeTextEditorShortcutBehavior, ShortcutService } from './services/shortcut/shortcut.service'; +export { + IShortcutService, + NativeTextEditorShortcutBehavior, + ShortcutService, +} from './services/shortcut/shortcut.service'; export type { IShortcutItem } from './services/shortcut/shortcut.service'; export { DesktopSidebarService } from './services/sidebar/desktop-sidebar.service'; export { useSidebarClick } from './services/sidebar/hooks/use-sidebar-click'; diff --git a/packages/ui/src/views/CommonLabel.tsx b/packages/ui/src/views/CommonLabel.tsx index ca666c11ae..cebb6a68ff 100644 --- a/packages/ui/src/views/CommonLabel.tsx +++ b/packages/ui/src/views/CommonLabel.tsx @@ -16,7 +16,6 @@ import { LocaleService } from '@univerjs/core'; import { useMemo } from 'react'; - import { useDependency } from '../utils/di'; export interface ICommonLabelProps { diff --git a/packages/watermark/src/controllers/watermark.render.controller.ts b/packages/watermark/src/controllers/watermark.render.controller.ts index e0e3f372b4..3548efee8a 100644 --- a/packages/watermark/src/controllers/watermark.render.controller.ts +++ b/packages/watermark/src/controllers/watermark.render.controller.ts @@ -17,7 +17,12 @@ 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 { + 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 { diff --git a/packages/watermark/src/index.ts b/packages/watermark/src/index.ts index 9e401b8e47..97d153b5e2 100644 --- a/packages/watermark/src/index.ts +++ b/packages/watermark/src/index.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -export { WATERMARK_IMAGE_ALLOW_IMAGE_LIST, WatermarkImageBaseConfig, WatermarkTextBaseConfig, WatermarkUserInfoBaseConfig } from './common/const'; +export { + WATERMARK_IMAGE_ALLOW_IMAGE_LIST, + WatermarkImageBaseConfig, + WatermarkTextBaseConfig, + WatermarkUserInfoBaseConfig, +} from './common/const'; export type { IUniverWatermarkConfig } from './config/config'; export { UniverWatermarkPlugin } from './plugin'; export { WatermarkService } from './services/watermark.service'; diff --git a/packages/watermark/src/plugin.ts b/packages/watermark/src/plugin.ts index 3a74c31d16..3d1742d3ee 100644 --- a/packages/watermark/src/plugin.ts +++ b/packages/watermark/src/plugin.ts @@ -17,8 +17,22 @@ import type { Dependency } from '@univerjs/core'; import type { IWatermarkConfigWithType } from '@univerjs/engine-render'; import type { IUniverWatermarkConfig } from './config/config'; -import { DependentOn, IConfigService, ILocalStorageService, Inject, Injector, merge, Plugin, UniverInstanceType } from '@univerjs/core'; -import { IRenderManagerService, IWatermarkTypeEnum, UNIVER_WATERMARK_STORAGE_KEY, UniverRenderEnginePlugin } from '@univerjs/engine-render'; +import { + DependentOn, + IConfigService, + ILocalStorageService, + Inject, + Injector, + merge, + Plugin, + UniverInstanceType, +} from '@univerjs/core'; +import { + IRenderManagerService, + IWatermarkTypeEnum, + UNIVER_WATERMARK_STORAGE_KEY, + UniverRenderEnginePlugin, +} from '@univerjs/engine-render'; import pkg from '../package.json'; import { WatermarkImageBaseConfig, WatermarkTextBaseConfig, WatermarkUserInfoBaseConfig } from './common/const'; import { defaultPluginConfig, WATERMARK_PLUGIN_CONFIG_KEY } from './config/config';