snapshot of https://github.com/toeverything/AFFiNE.git (canary, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Build & Test / Analyze (javascript, affine) (push) Failing after 4s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 4s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 3s
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 4s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 3s
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Release / Canary Gate (push) Has been skipped
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Copilot Test Automatically / Setup Test (push) Failing after 1s
Release / Prepare (push) Failing after 2s
Release / Release Cloud (push) Has been skipped
Release / Release Desktop (push) Has been skipped
Release / Release Docker Image (push) Has been skipped
Release / Release Mobile (push) Has been skipped
Some checks failed
Build & Test / Analyze (javascript, affine) (push) Failing after 4s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 4s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 3s
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 4s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 3s
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Release / Canary Gate (push) Has been skipped
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Copilot Test Automatically / Setup Test (push) Failing after 1s
Release / Prepare (push) Failing after 2s
Release / Release Cloud (push) Has been skipped
Release / Release Desktop (push) Has been skipped
Release / Release Docker Image (push) Has been skipped
Release / Release Mobile (push) Has been skipped
This commit is contained in:
304
blocksuite/affine/all/package.json
Normal file
304
blocksuite/affine/all/package.json
Normal file
@@ -0,0 +1,304 @@
|
||||
{
|
||||
"name": "@blocksuite/affine",
|
||||
"description": "BlockSuite for Affine",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "yarn run -T tsc --build --verbose"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"keywords": [],
|
||||
"author": "toeverything",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blocksuite/affine-block-attachment": "workspace:*",
|
||||
"@blocksuite/affine-block-bookmark": "workspace:*",
|
||||
"@blocksuite/affine-block-callout": "workspace:*",
|
||||
"@blocksuite/affine-block-code": "workspace:*",
|
||||
"@blocksuite/affine-block-data-view": "workspace:*",
|
||||
"@blocksuite/affine-block-database": "workspace:*",
|
||||
"@blocksuite/affine-block-divider": "workspace:*",
|
||||
"@blocksuite/affine-block-edgeless-text": "workspace:*",
|
||||
"@blocksuite/affine-block-embed": "workspace:*",
|
||||
"@blocksuite/affine-block-embed-doc": "workspace:*",
|
||||
"@blocksuite/affine-block-frame": "workspace:*",
|
||||
"@blocksuite/affine-block-image": "workspace:*",
|
||||
"@blocksuite/affine-block-latex": "workspace:*",
|
||||
"@blocksuite/affine-block-list": "workspace:*",
|
||||
"@blocksuite/affine-block-note": "workspace:*",
|
||||
"@blocksuite/affine-block-paragraph": "workspace:*",
|
||||
"@blocksuite/affine-block-root": "workspace:*",
|
||||
"@blocksuite/affine-block-surface": "workspace:*",
|
||||
"@blocksuite/affine-block-surface-ref": "workspace:*",
|
||||
"@blocksuite/affine-block-table": "workspace:*",
|
||||
"@blocksuite/affine-components": "workspace:*",
|
||||
"@blocksuite/affine-ext-loader": "workspace:*",
|
||||
"@blocksuite/affine-foundation": "workspace:*",
|
||||
"@blocksuite/affine-fragment-adapter-panel": "workspace:*",
|
||||
"@blocksuite/affine-fragment-doc-title": "workspace:*",
|
||||
"@blocksuite/affine-fragment-frame-panel": "workspace:*",
|
||||
"@blocksuite/affine-fragment-outline": "workspace:*",
|
||||
"@blocksuite/affine-gfx-brush": "workspace:*",
|
||||
"@blocksuite/affine-gfx-connector": "workspace:*",
|
||||
"@blocksuite/affine-gfx-group": "workspace:*",
|
||||
"@blocksuite/affine-gfx-link": "workspace:*",
|
||||
"@blocksuite/affine-gfx-mindmap": "workspace:*",
|
||||
"@blocksuite/affine-gfx-note": "workspace:*",
|
||||
"@blocksuite/affine-gfx-pointer": "workspace:*",
|
||||
"@blocksuite/affine-gfx-shape": "workspace:*",
|
||||
"@blocksuite/affine-gfx-template": "workspace:*",
|
||||
"@blocksuite/affine-gfx-text": "workspace:*",
|
||||
"@blocksuite/affine-gfx-turbo-renderer": "workspace:*",
|
||||
"@blocksuite/affine-inline-comment": "workspace:*",
|
||||
"@blocksuite/affine-inline-footnote": "workspace:*",
|
||||
"@blocksuite/affine-inline-latex": "workspace:*",
|
||||
"@blocksuite/affine-inline-link": "workspace:*",
|
||||
"@blocksuite/affine-inline-mention": "workspace:*",
|
||||
"@blocksuite/affine-inline-preset": "workspace:*",
|
||||
"@blocksuite/affine-inline-reference": "workspace:*",
|
||||
"@blocksuite/affine-model": "workspace:*",
|
||||
"@blocksuite/affine-rich-text": "workspace:*",
|
||||
"@blocksuite/affine-shared": "workspace:*",
|
||||
"@blocksuite/affine-widget-drag-handle": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-auto-connect": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-dragging-area": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-selected-rect": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-edgeless-zoom-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-frame-title": "workspace:*",
|
||||
"@blocksuite/affine-widget-keyboard-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-linked-doc": "workspace:*",
|
||||
"@blocksuite/affine-widget-note-slicer": "workspace:*",
|
||||
"@blocksuite/affine-widget-page-dragging-area": "workspace:*",
|
||||
"@blocksuite/affine-widget-remote-selection": "workspace:*",
|
||||
"@blocksuite/affine-widget-scroll-anchoring": "workspace:*",
|
||||
"@blocksuite/affine-widget-slash-menu": "workspace:*",
|
||||
"@blocksuite/affine-widget-toolbar": "workspace:*",
|
||||
"@blocksuite/affine-widget-viewport-overlay": "workspace:*",
|
||||
"@blocksuite/data-view": "workspace:*",
|
||||
"@blocksuite/global": "workspace:*",
|
||||
"@blocksuite/std": "workspace:*",
|
||||
"@blocksuite/store": "workspace:*",
|
||||
"@blocksuite/sync": "workspace:*"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./effects": "./src/effects.ts",
|
||||
"./ext-loader": "./src/ext-loader/index.ts",
|
||||
"./std": "./src/std/index.ts",
|
||||
"./std/gfx": "./src/std/gfx.ts",
|
||||
"./std/inline": "./src/std/inline.ts",
|
||||
"./std/effects": "./src/std/effects.ts",
|
||||
"./global": "./src/global/index.ts",
|
||||
"./global/utils": "./src/global/utils.ts",
|
||||
"./global/env": "./src/global/env.ts",
|
||||
"./global/exceptions": "./src/global/exceptions.ts",
|
||||
"./global/di": "./src/global/di.ts",
|
||||
"./global/types": "./src/global/types.ts",
|
||||
"./global/gfx": "./src/global/gfx.ts",
|
||||
"./global/disposable": "./src/global/disposable.ts",
|
||||
"./global/lit": "./src/global/lit.ts",
|
||||
"./store": "./src/store/index.ts",
|
||||
"./store/test": "./src/store/test.ts",
|
||||
"./blocks/attachment": "./src/blocks/attachment/index.ts",
|
||||
"./blocks/attachment/store": "./src/blocks/attachment/store.ts",
|
||||
"./blocks/attachment/view": "./src/blocks/attachment/view.ts",
|
||||
"./blocks/bookmark": "./src/blocks/bookmark/index.ts",
|
||||
"./blocks/bookmark/store": "./src/blocks/bookmark/store.ts",
|
||||
"./blocks/bookmark/view": "./src/blocks/bookmark/view.ts",
|
||||
"./blocks/callout": "./src/blocks/callout/index.ts",
|
||||
"./blocks/callout/store": "./src/blocks/callout/store.ts",
|
||||
"./blocks/callout/view": "./src/blocks/callout/view.ts",
|
||||
"./blocks/code": "./src/blocks/code/index.ts",
|
||||
"./blocks/code/store": "./src/blocks/code/store.ts",
|
||||
"./blocks/code/view": "./src/blocks/code/view.ts",
|
||||
"./blocks/data-view": "./src/blocks/data-view/index.ts",
|
||||
"./blocks/data-view/store": "./src/blocks/data-view/store.ts",
|
||||
"./blocks/data-view/view": "./src/blocks/data-view/view.ts",
|
||||
"./blocks/database": "./src/blocks/database/index.ts",
|
||||
"./blocks/database/store": "./src/blocks/database/store.ts",
|
||||
"./blocks/database/view": "./src/blocks/database/view.ts",
|
||||
"./blocks/divider": "./src/blocks/divider/index.ts",
|
||||
"./blocks/divider/store": "./src/blocks/divider/store.ts",
|
||||
"./blocks/divider/view": "./src/blocks/divider/view.ts",
|
||||
"./blocks/edgeless-text": "./src/blocks/edgeless-text/index.ts",
|
||||
"./blocks/edgeless-text/store": "./src/blocks/edgeless-text/store.ts",
|
||||
"./blocks/edgeless-text/view": "./src/blocks/edgeless-text/view.ts",
|
||||
"./blocks/embed": "./src/blocks/embed/index.ts",
|
||||
"./blocks/embed/store": "./src/blocks/embed/store.ts",
|
||||
"./blocks/embed/view": "./src/blocks/embed/view.ts",
|
||||
"./blocks/embed-doc": "./src/blocks/embed-doc/index.ts",
|
||||
"./blocks/embed-doc/store": "./src/blocks/embed-doc/store.ts",
|
||||
"./blocks/embed-doc/view": "./src/blocks/embed-doc/view.ts",
|
||||
"./blocks/frame": "./src/blocks/frame/index.ts",
|
||||
"./blocks/frame/store": "./src/blocks/frame/store.ts",
|
||||
"./blocks/frame/view": "./src/blocks/frame/view.ts",
|
||||
"./blocks/image": "./src/blocks/image/index.ts",
|
||||
"./blocks/image/store": "./src/blocks/image/store.ts",
|
||||
"./blocks/image/view": "./src/blocks/image/view.ts",
|
||||
"./blocks/latex": "./src/blocks/latex/index.ts",
|
||||
"./blocks/latex/store": "./src/blocks/latex/store.ts",
|
||||
"./blocks/latex/view": "./src/blocks/latex/view.ts",
|
||||
"./blocks/list": "./src/blocks/list/index.ts",
|
||||
"./blocks/list/store": "./src/blocks/list/store.ts",
|
||||
"./blocks/list/view": "./src/blocks/list/view.ts",
|
||||
"./blocks/note": "./src/blocks/note/index.ts",
|
||||
"./blocks/note/store": "./src/blocks/note/store.ts",
|
||||
"./blocks/note/view": "./src/blocks/note/view.ts",
|
||||
"./blocks/paragraph": "./src/blocks/paragraph/index.ts",
|
||||
"./blocks/paragraph/store": "./src/blocks/paragraph/store.ts",
|
||||
"./blocks/paragraph/view": "./src/blocks/paragraph/view.ts",
|
||||
"./blocks/root": "./src/blocks/root/index.ts",
|
||||
"./blocks/root/store": "./src/blocks/root/store.ts",
|
||||
"./blocks/root/view": "./src/blocks/root/view.ts",
|
||||
"./blocks/surface": "./src/blocks/surface/index.ts",
|
||||
"./blocks/surface/store": "./src/blocks/surface/store.ts",
|
||||
"./blocks/surface/view": "./src/blocks/surface/view.ts",
|
||||
"./blocks/surface-ref": "./src/blocks/surface-ref/index.ts",
|
||||
"./blocks/surface-ref/store": "./src/blocks/surface-ref/store.ts",
|
||||
"./blocks/surface-ref/view": "./src/blocks/surface-ref/view.ts",
|
||||
"./blocks/table": "./src/blocks/table/index.ts",
|
||||
"./blocks/table/store": "./src/blocks/table/store.ts",
|
||||
"./blocks/table/view": "./src/blocks/table/view.ts",
|
||||
"./data-view": "./src/data-view/index.ts",
|
||||
"./data-view/effects": "./src/data-view/effects.ts",
|
||||
"./inlines/link": "./src/inlines/link/index.ts",
|
||||
"./inlines/link/store": "./src/inlines/link/store.ts",
|
||||
"./inlines/link/view": "./src/inlines/link/view.ts",
|
||||
"./inlines/reference": "./src/inlines/reference/index.ts",
|
||||
"./inlines/reference/store": "./src/inlines/reference/store.ts",
|
||||
"./inlines/reference/view": "./src/inlines/reference/view.ts",
|
||||
"./inlines/preset": "./src/inlines/preset/index.ts",
|
||||
"./inlines/preset/store": "./src/inlines/preset/store.ts",
|
||||
"./inlines/preset/view": "./src/inlines/preset/view.ts",
|
||||
"./inlines/footnote": "./src/inlines/footnote/index.ts",
|
||||
"./inlines/footnote/view": "./src/inlines/footnote/view.ts",
|
||||
"./inlines/footnote/store": "./src/inlines/footnote/store.ts",
|
||||
"./inlines/comment": "./src/inlines/comment/index.ts",
|
||||
"./inlines/latex": "./src/inlines/latex/index.ts",
|
||||
"./inlines/latex/store": "./src/inlines/latex/store.ts",
|
||||
"./inlines/latex/view": "./src/inlines/latex/view.ts",
|
||||
"./inlines/mention": "./src/inlines/mention/index.ts",
|
||||
"./inlines/mention/view": "./src/inlines/mention/view.ts",
|
||||
"./widgets/drag-handle": "./src/widgets/drag-handle/index.ts",
|
||||
"./widgets/drag-handle/view": "./src/widgets/drag-handle/view.ts",
|
||||
"./widgets/edgeless-auto-connect": "./src/widgets/edgeless-auto-connect/index.ts",
|
||||
"./widgets/edgeless-auto-connect/view": "./src/widgets/edgeless-auto-connect/view.ts",
|
||||
"./widgets/edgeless-dragging-area": "./src/widgets/edgeless-dragging-area/index.ts",
|
||||
"./widgets/edgeless-dragging-area/view": "./src/widgets/edgeless-dragging-area/view.ts",
|
||||
"./widgets/edgeless-toolbar": "./src/widgets/edgeless-toolbar/index.ts",
|
||||
"./widgets/edgeless-toolbar/view": "./src/widgets/edgeless-toolbar/view.ts",
|
||||
"./widgets/frame-title": "./src/widgets/frame-title/index.ts",
|
||||
"./widgets/frame-title/view": "./src/widgets/frame-title/view.ts",
|
||||
"./widgets/linked-doc": "./src/widgets/linked-doc/index.ts",
|
||||
"./widgets/linked-doc/view": "./src/widgets/linked-doc/view.ts",
|
||||
"./widgets/remote-selection": "./src/widgets/remote-selection/index.ts",
|
||||
"./widgets/remote-selection/view": "./src/widgets/remote-selection/view.ts",
|
||||
"./widgets/scroll-anchoring": "./src/widgets/scroll-anchoring/index.ts",
|
||||
"./widgets/scroll-anchoring/view": "./src/widgets/scroll-anchoring/view.ts",
|
||||
"./widgets/slash-menu": "./src/widgets/slash-menu/index.ts",
|
||||
"./widgets/slash-menu/view": "./src/widgets/slash-menu/view.ts",
|
||||
"./widgets/toolbar": "./src/widgets/toolbar/index.ts",
|
||||
"./widgets/toolbar/view": "./src/widgets/toolbar/view.ts",
|
||||
"./widgets/keyboard-toolbar": "./src/widgets/keyboard-toolbar/index.ts",
|
||||
"./widgets/keyboard-toolbar/view": "./src/widgets/keyboard-toolbar/view.ts",
|
||||
"./widgets/viewport-overlay": "./src/widgets/viewport-overlay/index.ts",
|
||||
"./widgets/viewport-overlay/view": "./src/widgets/viewport-overlay/view.ts",
|
||||
"./widgets/page-dragging-area": "./src/widgets/page-dragging-area/index.ts",
|
||||
"./widgets/page-dragging-area/view": "./src/widgets/page-dragging-area/view.ts",
|
||||
"./fragments/doc-title": "./src/fragments/doc-title/index.ts",
|
||||
"./fragments/doc-title/view": "./src/fragments/doc-title/view.ts",
|
||||
"./fragments/frame-panel": "./src/fragments/frame-panel/index.ts",
|
||||
"./fragments/frame-panel/view": "./src/fragments/frame-panel/view.ts",
|
||||
"./fragments/outline": "./src/fragments/outline/index.ts",
|
||||
"./fragments/outline/view": "./src/fragments/outline/view.ts",
|
||||
"./fragments/adapter-panel": "./src/fragments/adapter-panel/index.ts",
|
||||
"./fragments/adapter-panel/view": "./src/fragments/adapter-panel/view.ts",
|
||||
"./gfx/text": "./src/gfx/text/index.ts",
|
||||
"./gfx/text/store": "./src/gfx/text/store.ts",
|
||||
"./gfx/text/view": "./src/gfx/text/view.ts",
|
||||
"./gfx/brush": "./src/gfx/brush/index.ts",
|
||||
"./gfx/brush/store": "./src/gfx/brush/store.ts",
|
||||
"./gfx/brush/view": "./src/gfx/brush/view.ts",
|
||||
"./gfx/pointer": "./src/gfx/pointer/index.ts",
|
||||
"./gfx/pointer/view": "./src/gfx/pointer/view.ts",
|
||||
"./gfx/shape": "./src/gfx/shape/index.ts",
|
||||
"./gfx/shape/store": "./src/gfx/shape/store.ts",
|
||||
"./gfx/shape/view": "./src/gfx/shape/view.ts",
|
||||
"./gfx/link": "./src/gfx/link/index.ts",
|
||||
"./gfx/link/view": "./src/gfx/link/view.ts",
|
||||
"./gfx/note": "./src/gfx/note/index.ts",
|
||||
"./gfx/note/view": "./src/gfx/note/view.ts",
|
||||
"./gfx/mindmap": "./src/gfx/mindmap/index.ts",
|
||||
"./gfx/mindmap/store": "./src/gfx/mindmap/store.ts",
|
||||
"./gfx/mindmap/view": "./src/gfx/mindmap/view.ts",
|
||||
"./gfx/connector": "./src/gfx/connector/index.ts",
|
||||
"./gfx/connector/store": "./src/gfx/connector/store.ts",
|
||||
"./gfx/connector/view": "./src/gfx/connector/view.ts",
|
||||
"./gfx/group": "./src/gfx/group/index.ts",
|
||||
"./gfx/group/store": "./src/gfx/group/store.ts",
|
||||
"./gfx/group/view": "./src/gfx/group/view.ts",
|
||||
"./gfx/template": "./src/gfx/template/index.ts",
|
||||
"./gfx/template/view": "./src/gfx/template/view.ts",
|
||||
"./gfx/turbo-renderer": "./src/gfx/turbo-renderer.ts",
|
||||
"./components/block-selection": "./src/components/block-selection.ts",
|
||||
"./components/block-zero-width": "./src/components/block-zero-width.ts",
|
||||
"./components/caption": "./src/components/caption.ts",
|
||||
"./components/card-style-dropdown-menu": "./src/components/card-style-dropdown-menu.ts",
|
||||
"./components/citation": "./src/components/citation.ts",
|
||||
"./components/color-picker": "./src/components/color-picker.ts",
|
||||
"./components/context-menu": "./src/components/context-menu.ts",
|
||||
"./components/date-picker": "./src/components/date-picker.ts",
|
||||
"./components/drop-indicator": "./src/components/drop-indicator.ts",
|
||||
"./components/embed-card-modal": "./src/components/embed-card-modal.ts",
|
||||
"./components/filterable-list": "./src/components/filterable-list.ts",
|
||||
"./components/highlight-dropdown-menu": "./src/components/highlight-dropdown-menu.ts",
|
||||
"./components/hover": "./src/components/hover.ts",
|
||||
"./components/icon-button": "./src/components/icon-button.ts",
|
||||
"./components/icons": "./src/components/icons.ts",
|
||||
"./components/link-preview": "./src/components/link-preview.ts",
|
||||
"./components/linked-doc-title": "./src/components/linked-doc-title.ts",
|
||||
"./components/notification": "./src/components/notification.ts",
|
||||
"./components/peek": "./src/components/peek.ts",
|
||||
"./components/portal": "./src/components/portal.ts",
|
||||
"./components/smooth-corner": "./src/components/smooth-corner.ts",
|
||||
"./components/toast": "./src/components/toast.ts",
|
||||
"./components/toggle-button": "./src/components/toggle-button.ts",
|
||||
"./components/toggle-switch": "./src/components/toggle-switch.ts",
|
||||
"./components/toolbar": "./src/components/toolbar.ts",
|
||||
"./components/tooltip": "./src/components/tooltip.ts",
|
||||
"./components/view-dropdown-menu": "./src/components/view-dropdown-menu.ts",
|
||||
"./components/tooltip-content-with-shortcut": "./src/components/tooltip-content-with-shortcut.ts",
|
||||
"./components/resource": "./src/components/resource.ts",
|
||||
"./rich-text": "./src/rich-text/index.ts",
|
||||
"./rich-text/effects": "./src/rich-text/effects.ts",
|
||||
"./shared/adapters": "./src/shared/adapters.ts",
|
||||
"./shared/commands": "./src/shared/commands.ts",
|
||||
"./shared/consts": "./src/shared/consts.ts",
|
||||
"./shared/selection": "./src/shared/selection.ts",
|
||||
"./shared/services": "./src/shared/services.ts",
|
||||
"./shared/styles": "./src/shared/styles.ts",
|
||||
"./shared/theme": "./src/shared/theme.ts",
|
||||
"./shared/types": "./src/shared/types.ts",
|
||||
"./shared/utils": "./src/shared/utils.ts",
|
||||
"./schemas": "./src/schemas.ts",
|
||||
"./model": "./src/model/index.ts",
|
||||
"./sync": "./src/sync/index.ts",
|
||||
"./extensions/store": "./src/extensions/store.ts",
|
||||
"./extensions/view": "./src/extensions/view.ts",
|
||||
"./foundation/clipboard": "./src/foundation/clipboard.ts",
|
||||
"./foundation/store": "./src/foundation/store.ts",
|
||||
"./foundation/view": "./src/foundation/view.ts"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist",
|
||||
"!src/__tests__",
|
||||
"!dist/__tests__"
|
||||
],
|
||||
"version": "0.27.5",
|
||||
"devDependencies": {
|
||||
"@vanilla-extract/vite-plugin": "^5.0.0",
|
||||
"msw": "^2.13.2",
|
||||
"vitest": "^4.1.8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`snapshot to markdown > imports obsidian vault fixtures 1`] = `
|
||||
{
|
||||
"entry": {
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"delta": [
|
||||
{
|
||||
"insert": "Panel
|
||||
Body line",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:paragraph",
|
||||
"type": "text",
|
||||
},
|
||||
],
|
||||
"emoji": "💡",
|
||||
"flavour": "affine:callout",
|
||||
},
|
||||
{
|
||||
"flavour": "affine:attachment",
|
||||
"name": "archive.zip",
|
||||
"style": "horizontalThin",
|
||||
},
|
||||
{
|
||||
"delta": [
|
||||
{
|
||||
"footnote": {
|
||||
"label": "1",
|
||||
"reference": {
|
||||
"title": "reference body",
|
||||
"type": "url",
|
||||
},
|
||||
},
|
||||
"insert": " ",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:paragraph",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"flavour": "affine:divider",
|
||||
},
|
||||
{
|
||||
"delta": [
|
||||
{
|
||||
"insert": "after note",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:paragraph",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"delta": [
|
||||
{
|
||||
"insert": " ",
|
||||
"reference": {
|
||||
"page": "linked",
|
||||
"type": "LinkedPage",
|
||||
},
|
||||
},
|
||||
],
|
||||
"flavour": "affine:paragraph",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"delta": [
|
||||
{
|
||||
"insert": "Sources",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:paragraph",
|
||||
"type": "h6",
|
||||
},
|
||||
{
|
||||
"flavour": "affine:bookmark",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:note",
|
||||
},
|
||||
],
|
||||
"flavour": "affine:page",
|
||||
},
|
||||
"titles": [
|
||||
"entry",
|
||||
"linked",
|
||||
],
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,14 @@
|
||||
> [!custom] Panel
|
||||
> Body line
|
||||
|
||||
![[archive.zip]]
|
||||
|
||||
[^1]
|
||||
|
||||
---
|
||||
|
||||
after note
|
||||
|
||||
[[linked]]
|
||||
|
||||
[^1]: reference body
|
||||
@@ -0,0 +1 @@
|
||||
plain linked page
|
||||
3182
blocksuite/affine/all/src/__tests__/adapters/html.unit.spec.ts
Normal file
3182
blocksuite/affine/all/src/__tests__/adapters/html.unit.spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,170 @@
|
||||
import { DefaultTheme } from '@blocksuite/affine-model';
|
||||
import { NotionTextAdapter } from '@blocksuite/affine-shared/adapters';
|
||||
import type { SliceSnapshot } from '@blocksuite/store';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { createJob } from '../utils/create-job.js';
|
||||
import { getProvider } from '../utils/get-provider.js';
|
||||
import { nanoidReplacement } from '../utils/nanoid-replacement.js';
|
||||
|
||||
const provider = getProvider();
|
||||
|
||||
describe('notion-text to snapshot', () => {
|
||||
test('basic', () => {
|
||||
const notionText =
|
||||
'{"blockType":"text","editing":[["aaa ",[["_"],["b"],["i"]]],["nbbbb ",[["_"],["i"]]],["hjhj ",[["_"]]],["a",[["_"],["c"]]],[" ",[["_"]]],["ccc d",[["_"],["s"]]],["dd",[["_"],["s"]]]]}';
|
||||
|
||||
const sliceSnapshot: SliceSnapshot = {
|
||||
type: 'slice',
|
||||
content: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: 'both',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'aaa ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
bold: true,
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'nbbbb ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
italic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'hjhj ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'a',
|
||||
attributes: {
|
||||
underline: true,
|
||||
code: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: ' ',
|
||||
attributes: {
|
||||
underline: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'ccc d',
|
||||
attributes: {
|
||||
underline: true,
|
||||
strike: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: 'dd',
|
||||
attributes: {
|
||||
underline: true,
|
||||
strike: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
};
|
||||
|
||||
const ntAdapter = new NotionTextAdapter(createJob(), provider);
|
||||
const target = ntAdapter.toSliceSnapshot({
|
||||
file: notionText,
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
});
|
||||
expect(nanoidReplacement(target!)).toEqual(sliceSnapshot);
|
||||
});
|
||||
|
||||
test('notion text with empty styles array', () => {
|
||||
const notionText =
|
||||
'{"blockType":"text","editing":[["a "],["bold text",[["b"]]],[" hello world"]],"selection":{"startIndex":0,"endIndex":23},"action":"copy"}';
|
||||
|
||||
const sliceSnapshot: SliceSnapshot = {
|
||||
type: 'slice',
|
||||
content: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[0]',
|
||||
flavour: 'affine:note',
|
||||
props: {
|
||||
xywh: '[0,0,800,95]',
|
||||
background: DefaultTheme.noteBackgrounColor,
|
||||
index: 'a0',
|
||||
hidden: false,
|
||||
displayMode: 'both',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
id: 'matchesReplaceMap[1]',
|
||||
flavour: 'affine:paragraph',
|
||||
props: {
|
||||
type: 'text',
|
||||
text: {
|
||||
'$blocksuite:internal:text$': true,
|
||||
delta: [
|
||||
{
|
||||
insert: 'a ',
|
||||
},
|
||||
{
|
||||
insert: 'bold text',
|
||||
attributes: {
|
||||
bold: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
insert: ' hello world',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
};
|
||||
|
||||
const ntAdapter = new NotionTextAdapter(createJob(), provider);
|
||||
const target = ntAdapter.toSliceSnapshot({
|
||||
file: notionText,
|
||||
workspaceId: '',
|
||||
pageId: '',
|
||||
});
|
||||
expect(nanoidReplacement(target!)).toEqual(sliceSnapshot);
|
||||
});
|
||||
});
|
||||
1618
blocksuite/affine/all/src/__tests__/adapters/pdf.unit.spec.ts
Normal file
1618
blocksuite/affine/all/src/__tests__/adapters/pdf.unit.spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
1422
blocksuite/affine/all/src/__tests__/adapters/plain-text.unit.spec.ts
Normal file
1422
blocksuite/affine/all/src/__tests__/adapters/plain-text.unit.spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
import {
|
||||
addProperty,
|
||||
copyCellsByProperty,
|
||||
databaseBlockProperties,
|
||||
deleteColumn,
|
||||
getCell,
|
||||
getProperty,
|
||||
updateCell,
|
||||
} from '@blocksuite/affine-block-database';
|
||||
import {
|
||||
type CellDataType,
|
||||
type ColumnDataType,
|
||||
type DatabaseBlockModel,
|
||||
DatabaseBlockSchemaExtension,
|
||||
NoteBlockSchemaExtension,
|
||||
ParagraphBlockSchemaExtension,
|
||||
RootBlockSchemaExtension,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
import { Text } from '@blocksuite/store';
|
||||
import {
|
||||
createAutoIncrementIdGenerator,
|
||||
TestWorkspace,
|
||||
} from '@blocksuite/store/test';
|
||||
import { beforeEach, describe, expect, test } from 'vitest';
|
||||
|
||||
const extensions = [
|
||||
RootBlockSchemaExtension,
|
||||
NoteBlockSchemaExtension,
|
||||
ParagraphBlockSchemaExtension,
|
||||
DatabaseBlockSchemaExtension,
|
||||
];
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
return { id: 'test-collection', idGenerator };
|
||||
}
|
||||
|
||||
function createTestDoc(docId = 'doc0') {
|
||||
const options = createTestOptions();
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc(docId);
|
||||
doc.load();
|
||||
return doc.getStore({ extensions });
|
||||
}
|
||||
|
||||
describe('DatabaseManager', () => {
|
||||
let doc: Store;
|
||||
let db: DatabaseBlockModel;
|
||||
|
||||
let rootId: BlockModel['id'];
|
||||
let noteBlockId: BlockModel['id'];
|
||||
let databaseBlockId: BlockModel['id'];
|
||||
let p1: BlockModel['id'];
|
||||
let p2: BlockModel['id'];
|
||||
let col1: ColumnDataType['id'];
|
||||
let col2: ColumnDataType['id'];
|
||||
let col3: ColumnDataType['id'];
|
||||
|
||||
const selection = [
|
||||
{ id: '1', value: 'Done', color: 'var(--affine-tag-white)' },
|
||||
{ id: '2', value: 'TODO', color: 'var(--affine-tag-pink)' },
|
||||
{ id: '3', value: 'WIP', color: 'var(--affine-tag-blue)' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
doc = createTestDoc();
|
||||
|
||||
rootId = doc.addBlock('affine:page', {
|
||||
title: new Text('database test'),
|
||||
});
|
||||
noteBlockId = doc.addBlock('affine:note', {}, rootId);
|
||||
|
||||
databaseBlockId = doc.addBlock(
|
||||
'affine:database',
|
||||
{
|
||||
columns: [],
|
||||
titleColumn: 'Title',
|
||||
},
|
||||
noteBlockId
|
||||
);
|
||||
|
||||
const databaseModel = doc.getModelById(
|
||||
databaseBlockId
|
||||
) as DatabaseBlockModel;
|
||||
db = databaseModel;
|
||||
|
||||
col1 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
databaseBlockProperties.numberColumnConfig.create('Number')
|
||||
);
|
||||
col2 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
propertyModelPresets.selectPropertyModelConfig.create('Single Select', {
|
||||
options: selection,
|
||||
})
|
||||
);
|
||||
col3 = addProperty(
|
||||
db,
|
||||
'end',
|
||||
databaseBlockProperties.richTextColumnConfig.create('Rich Text')
|
||||
);
|
||||
|
||||
doc.updateBlock(databaseModel, {
|
||||
columns: [col1, col2, col3],
|
||||
});
|
||||
|
||||
p1 = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text1'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
p2 = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text2'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
|
||||
updateCell(db, p1, {
|
||||
columnId: col1,
|
||||
value: 0.1,
|
||||
});
|
||||
updateCell(db, p2, {
|
||||
columnId: col2,
|
||||
value: [selection[1]],
|
||||
});
|
||||
});
|
||||
|
||||
test('getColumn', () => {
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('testColumnId'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
addProperty(db, 'end', column);
|
||||
|
||||
const result = getProperty(db, column.id);
|
||||
expect(result).toEqual(column);
|
||||
});
|
||||
|
||||
test('addColumn', () => {
|
||||
const column =
|
||||
databaseBlockProperties.numberColumnConfig.create('Test Column');
|
||||
const id = addProperty(db, 'end', column);
|
||||
const result = getProperty(db, id);
|
||||
|
||||
expect(result).toMatchObject(column);
|
||||
expect(result).toHaveProperty('id');
|
||||
});
|
||||
|
||||
test('deleteColumn', () => {
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('Test Column'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
addProperty(db, 'end', column);
|
||||
expect(getProperty(db, column.id)).toEqual(column);
|
||||
|
||||
deleteColumn(db, column.id);
|
||||
expect(getProperty(db, column.id)).toBeUndefined();
|
||||
});
|
||||
|
||||
test('getCell', () => {
|
||||
const modelId = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('paragraph'),
|
||||
},
|
||||
noteBlockId
|
||||
);
|
||||
const column = {
|
||||
...databaseBlockProperties.numberColumnConfig.create('Test Column'),
|
||||
id: 'testColumnId',
|
||||
};
|
||||
const cell: CellDataType = {
|
||||
columnId: column.id,
|
||||
value: 42,
|
||||
};
|
||||
|
||||
addProperty(db, 'end', column);
|
||||
updateCell(db, modelId, cell);
|
||||
|
||||
const model = doc.getModelById(modelId);
|
||||
|
||||
expect(model).not.toBeNull();
|
||||
|
||||
const result = getCell(db, model!.id, column.id);
|
||||
expect(result).toEqual(cell);
|
||||
});
|
||||
|
||||
test('updateCell', () => {
|
||||
const newRowId = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{
|
||||
text: new Text('text3'),
|
||||
},
|
||||
databaseBlockId
|
||||
);
|
||||
|
||||
updateCell(db, newRowId, {
|
||||
columnId: col2,
|
||||
value: [selection[2]],
|
||||
});
|
||||
|
||||
const cell = getCell(db, newRowId, col2);
|
||||
expect(cell).toEqual({
|
||||
columnId: col2,
|
||||
value: [selection[2]],
|
||||
});
|
||||
});
|
||||
|
||||
test('copyCellsByColumn', () => {
|
||||
const newColId = addProperty(
|
||||
db,
|
||||
'end',
|
||||
propertyModelPresets.selectPropertyModelConfig.create('Copied Select', {
|
||||
options: selection,
|
||||
})
|
||||
);
|
||||
|
||||
copyCellsByProperty(db, col2, newColId);
|
||||
|
||||
const cell = getCell(db, p2, newColId);
|
||||
expect(cell).toEqual({
|
||||
columnId: newColId,
|
||||
value: [selection[1]],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { insertUrlTextSegments } from '../../../../blocks/database/src/properties/paste-url.js';
|
||||
|
||||
type InsertCall = {
|
||||
range: {
|
||||
index: number;
|
||||
length: number;
|
||||
};
|
||||
text: string;
|
||||
attributes?: AffineTextAttributes;
|
||||
};
|
||||
|
||||
describe('insertUrlTextSegments', () => {
|
||||
test('should replace selected text on first insert and append remaining segments', () => {
|
||||
const insertCalls: InsertCall[] = [];
|
||||
const selectionCalls: Array<{ index: number; length: number } | null> = [];
|
||||
const inlineEditor = {
|
||||
insertText: (
|
||||
range: { index: number; length: number },
|
||||
text: string,
|
||||
attributes?: AffineTextAttributes
|
||||
) => {
|
||||
insertCalls.push({ range, text, attributes });
|
||||
},
|
||||
setInlineRange: (range: { index: number; length: number } | null) => {
|
||||
selectionCalls.push(range);
|
||||
},
|
||||
};
|
||||
|
||||
const inlineRange = { index: 4, length: 6 };
|
||||
const segments = [
|
||||
{ text: 'hi - ' },
|
||||
{ text: 'https://google.com', link: 'https://google.com' },
|
||||
];
|
||||
|
||||
insertUrlTextSegments(inlineEditor, inlineRange, segments);
|
||||
|
||||
expect(insertCalls).toEqual([
|
||||
{
|
||||
range: { index: 4, length: 6 },
|
||||
text: 'hi - ',
|
||||
},
|
||||
{
|
||||
range: { index: 9, length: 0 },
|
||||
text: 'https://google.com',
|
||||
attributes: {
|
||||
link: 'https://google.com',
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(selectionCalls).toEqual([{ index: 27, length: 0 }]);
|
||||
});
|
||||
|
||||
test('should keep insertion range length zero when there is no selected text', () => {
|
||||
const insertCalls: InsertCall[] = [];
|
||||
const selectionCalls: Array<{ index: number; length: number } | null> = [];
|
||||
const inlineEditor = {
|
||||
insertText: (
|
||||
range: { index: number; length: number },
|
||||
text: string,
|
||||
attributes?: AffineTextAttributes
|
||||
) => {
|
||||
insertCalls.push({ range, text, attributes });
|
||||
},
|
||||
setInlineRange: (range: { index: number; length: number } | null) => {
|
||||
selectionCalls.push(range);
|
||||
},
|
||||
};
|
||||
|
||||
const inlineRange = { index: 2, length: 0 };
|
||||
const segments = [
|
||||
{ text: 'prefix ' },
|
||||
{ text: 'https://a.com', link: 'https://a.com' },
|
||||
];
|
||||
|
||||
insertUrlTextSegments(inlineEditor, inlineRange, segments);
|
||||
|
||||
expect(insertCalls).toEqual([
|
||||
{
|
||||
range: { index: 2, length: 0 },
|
||||
text: 'prefix ',
|
||||
},
|
||||
{
|
||||
range: { index: 9, length: 0 },
|
||||
text: 'https://a.com',
|
||||
attributes: {
|
||||
link: 'https://a.com',
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(selectionCalls).toEqual([{ index: 22, length: 0 }]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { type SelectTag, t, typeSystem } from '@blocksuite/data-view';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
describe('subtyping', () => {
|
||||
test('all type is subtype of unknown', () => {
|
||||
expect(typeSystem.unify(t.boolean.instance(), t.unknown.instance())).toBe(
|
||||
true
|
||||
);
|
||||
expect(typeSystem.unify(t.string.instance(), t.unknown.instance())).toBe(
|
||||
true
|
||||
);
|
||||
expect(
|
||||
typeSystem.unify(
|
||||
t.array.instance(t.string.instance()),
|
||||
t.unknown.instance()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(typeSystem.unify(t.tag.instance(), t.unknown.instance())).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('function apply', () => {
|
||||
test('generic type function', () => {
|
||||
const fn = t.fn.instance(
|
||||
[t.typeVarReference.create('A'), t.typeVarReference.create('A')],
|
||||
t.boolean.instance(),
|
||||
[t.typeVarDefine.create('A', t.unknown.instance())]
|
||||
);
|
||||
const instancedFn = typeSystem.instanceFn(
|
||||
fn,
|
||||
[t.boolean.instance()],
|
||||
t.boolean.instance(),
|
||||
{}
|
||||
);
|
||||
expect(instancedFn?.args[1]).toStrictEqual(t.boolean.instance());
|
||||
});
|
||||
test('tags infer', () => {
|
||||
const fn = t.fn.instance(
|
||||
[
|
||||
t.typeVarReference.create('A'),
|
||||
t.array.instance(t.typeVarReference.create('A')),
|
||||
] as const,
|
||||
t.boolean.instance(),
|
||||
[t.typeVarDefine.create('A', t.tag.instance())]
|
||||
);
|
||||
const fnArray = t.fn.instance(
|
||||
[
|
||||
t.array.instance(t.typeVarReference.create('A')),
|
||||
t.array.instance(t.typeVarReference.create('A')),
|
||||
] as const,
|
||||
t.boolean.instance(),
|
||||
[t.typeVarDefine.create('A', t.tag.instance())]
|
||||
);
|
||||
const tags: SelectTag[] = [{ id: 'a', value: 'b', color: 'c' }];
|
||||
const instancedFn = typeSystem.instanceFn(
|
||||
fn,
|
||||
[t.tag.instance(tags)],
|
||||
t.boolean.instance(),
|
||||
{}
|
||||
);
|
||||
const instancedFnArray = typeSystem.instanceFn(
|
||||
fnArray,
|
||||
[t.array.instance(t.tag.instance(tags))],
|
||||
t.boolean.instance(),
|
||||
{}
|
||||
);
|
||||
expect(
|
||||
typeSystem.unify(
|
||||
instancedFn?.args[1],
|
||||
t.array.instance(t.tag.instance(tags))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
typeSystem.unify(
|
||||
instancedFnArray?.args[1],
|
||||
t.array.instance(t.tag.instance(tags))
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,92 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { bilibiliConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/bilibili.js';
|
||||
import { excalidrawConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/excalidraw.js';
|
||||
import { genericConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/generic.js';
|
||||
import { googleDocsConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/google-docs.js';
|
||||
import { googleDriveConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/google-drive.js';
|
||||
import { miroConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/miro.js';
|
||||
import { spotifyConfig } from '../../../blocks/embed/src/embed-iframe-block/configs/providers/spotify.js';
|
||||
|
||||
describe('embed iframe provider config', () => {
|
||||
test('validates final iframe URLs from oEmbed providers', () => {
|
||||
expect(
|
||||
spotifyConfig.validateIframeUrl?.(
|
||||
'https://open.spotify.com/embed/track/0TK2YIli7K1leLovkQiNik'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
spotifyConfig.validateIframeUrl?.(
|
||||
'https://example.com/embed/track/0TK2YIli7K1leLovkQiNik'
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('validates provider-specific iframe URL shapes', () => {
|
||||
expect(
|
||||
googleDriveConfig.validateIframeUrl?.(
|
||||
'https://drive.google.com/file/d/file-id/preview?usp=embed_googleplus'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
googleDriveConfig.validateIframeUrl?.(
|
||||
'https://drive.google.com/drive/folders/folder-id?usp=sharing'
|
||||
)
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
bilibiliConfig.validateIframeUrl?.(
|
||||
'https://player.bilibili.com/player.html?bvid=BV1xx411c7mD&autoplay=0'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
bilibiliConfig.match(
|
||||
'https://player.bilibili.com/player.html?aid=123&autoplay=0'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
bilibiliConfig.buildOEmbedUrl(
|
||||
'https://player.bilibili.com/video/BV1xx411c7mD'
|
||||
)
|
||||
).toBe(
|
||||
'https://player.bilibili.com/player.html?bvid=BV1xx411c7mD&autoplay=0'
|
||||
);
|
||||
expect(
|
||||
bilibiliConfig.validateIframeUrl?.(
|
||||
'https://www.bilibili.com/video/BV1xx411c7mD'
|
||||
)
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
googleDocsConfig.validateIframeUrl?.(
|
||||
'https://docs.google.com/document/d/doc-id/edit?usp=sharing'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
miroConfig.validateIframeUrl?.(
|
||||
'https://miro.com/app/live-embed/board-id/'
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
excalidrawConfig.validateIframeUrl?.('https://excalidraw.com/#room-id')
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('generic iframe validation excludes affine and non-https URLs', () => {
|
||||
expect(genericConfig.validateIframeUrl?.('https://example.com/embed')).toBe(
|
||||
true
|
||||
);
|
||||
expect(genericConfig.validateIframeUrl?.('http://example.com/embed')).toBe(
|
||||
false
|
||||
);
|
||||
expect(
|
||||
genericConfig.validateIframeUrl?.('https://app.affine.pro/embed')
|
||||
).toBe(false);
|
||||
expect(genericConfig.validateIframeUrl?.('https://127.0.0.1/embed')).toBe(
|
||||
false
|
||||
);
|
||||
expect(genericConfig.validateIframeUrl?.('https://localhost/embed')).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,770 @@
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
import { Viewport, viewportRuntimeConfig } from '@blocksuite/std/gfx';
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import * as viewportModule from '../../../../../framework/std/src/gfx/viewport.js';
|
||||
import * as viewportElementModule from '../../../../../framework/std/src/gfx/viewport-element.js';
|
||||
import * as canvasRendererModule from '../../../../blocks/surface/src/renderer/canvas-renderer.js';
|
||||
import {
|
||||
paintPlaceholder,
|
||||
syncCanvasSize,
|
||||
} from '../../../../gfx/turbo-renderer/src/renderer-utils.js';
|
||||
import type { ViewportLayoutTree } from '../../../../gfx/turbo-renderer/src/types.js';
|
||||
|
||||
const originalCaps = [...viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM];
|
||||
const originalDevicePixelRatio = Object.getOwnPropertyDescriptor(
|
||||
window,
|
||||
'devicePixelRatio'
|
||||
);
|
||||
|
||||
function setDevicePixelRatio(value: number) {
|
||||
Object.defineProperty(window, 'devicePixelRatio', {
|
||||
configurable: true,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
function createRect(width: number, height: number): DOMRect {
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: width,
|
||||
bottom: height,
|
||||
x: 0,
|
||||
y: 0,
|
||||
toJSON: () => ({}),
|
||||
} as DOMRect;
|
||||
}
|
||||
|
||||
function createFakeBlockModel(
|
||||
id: string,
|
||||
x: number,
|
||||
y: number,
|
||||
w = 10,
|
||||
h = 10
|
||||
) {
|
||||
return {
|
||||
id,
|
||||
elementBound: new Bound(x, y, w, h),
|
||||
};
|
||||
}
|
||||
|
||||
type PaintPlaceholderForTest = (
|
||||
canvas: HTMLCanvasElement,
|
||||
layout: ViewportLayoutTree,
|
||||
viewport: {
|
||||
zoom: number;
|
||||
toViewCoord: (x: number, y: number) => [number, number];
|
||||
}
|
||||
) => void;
|
||||
|
||||
afterEach(() => {
|
||||
viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM = [...originalCaps];
|
||||
|
||||
if (originalDevicePixelRatio) {
|
||||
Object.defineProperty(window, 'devicePixelRatio', originalDevicePixelRatio);
|
||||
}
|
||||
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('edgeless canvas budget', () => {
|
||||
test('requests canvas budget sync when zoom crosses an effective dpr bucket', () => {
|
||||
viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM = [
|
||||
[0.5, 1],
|
||||
[0.8, 2],
|
||||
];
|
||||
|
||||
expect(
|
||||
'shouldSyncCanvasBudgetOnViewportUpdate' in canvasRendererModule
|
||||
).toBe(true);
|
||||
|
||||
const shouldSyncCanvasBudgetOnViewportUpdate = (
|
||||
canvasRendererModule as {
|
||||
shouldSyncCanvasBudgetOnViewportUpdate: (
|
||||
previousZoom: number,
|
||||
nextZoom: number,
|
||||
rawDpr?: number
|
||||
) => boolean;
|
||||
}
|
||||
).shouldSyncCanvasBudgetOnViewportUpdate;
|
||||
|
||||
expect(shouldSyncCanvasBudgetOnViewportUpdate(0.95, 0.4, 2)).toBe(true);
|
||||
expect(shouldSyncCanvasBudgetOnViewportUpdate(0.95, 0.75, 2)).toBe(false);
|
||||
expect(shouldSyncCanvasBudgetOnViewportUpdate(0.45, 0.4, 2)).toBe(false);
|
||||
expect(shouldSyncCanvasBudgetOnViewportUpdate(0.95, 0.4, 1)).toBe(false);
|
||||
});
|
||||
|
||||
test('enables low-zoom survival mode only for active iOS gestures', () => {
|
||||
expect('shouldUseLowZoomSurvivalMode' in canvasRendererModule).toBe(true);
|
||||
|
||||
const shouldUseLowZoomSurvivalMode = (
|
||||
canvasRendererModule as {
|
||||
shouldUseLowZoomSurvivalMode: (
|
||||
isIOS: boolean,
|
||||
zoom: number,
|
||||
gestureActive: boolean
|
||||
) => boolean;
|
||||
}
|
||||
).shouldUseLowZoomSurvivalMode;
|
||||
|
||||
expect(shouldUseLowZoomSurvivalMode(true, 0.4, true)).toBe(true);
|
||||
expect(shouldUseLowZoomSurvivalMode(true, 0.6, true)).toBe(false);
|
||||
expect(shouldUseLowZoomSurvivalMode(true, 0.4, false)).toBe(false);
|
||||
expect(shouldUseLowZoomSurvivalMode(false, 0.4, true)).toBe(false);
|
||||
});
|
||||
|
||||
test('does not enable canvas placeholders for low-zoom panning without zooming', () => {
|
||||
expect('shouldRenderCanvasPlaceholders' in canvasRendererModule).toBe(true);
|
||||
|
||||
const shouldRenderCanvasPlaceholders = (
|
||||
canvasRendererModule as {
|
||||
shouldRenderCanvasPlaceholders: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
isPanning: boolean;
|
||||
isZooming: boolean;
|
||||
skipRefreshDuringGesture: boolean;
|
||||
turboEnabled: boolean;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldRenderCanvasPlaceholders;
|
||||
|
||||
expect(
|
||||
shouldRenderCanvasPlaceholders({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
isPanning: true,
|
||||
isZooming: false,
|
||||
skipRefreshDuringGesture: true,
|
||||
turboEnabled: true,
|
||||
})
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
shouldRenderCanvasPlaceholders({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
isPanning: false,
|
||||
isZooming: true,
|
||||
skipRefreshDuringGesture: true,
|
||||
turboEnabled: true,
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('shares one bypass decision for placeholder and render paths only during the low-zoom iOS landscape gesture or recovery window', () => {
|
||||
expect('getStackingCanvasBypassState' in canvasRendererModule).toBe(true);
|
||||
expect(
|
||||
'shouldBypassStackingCanvasesDuringLowZoomGesture' in canvasRendererModule
|
||||
).toBe(true);
|
||||
|
||||
const getStackingCanvasBypassState = (
|
||||
canvasRendererModule as {
|
||||
getStackingCanvasBypassState: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
gestureActive: boolean;
|
||||
recoveryActive: boolean;
|
||||
viewportWidth: number;
|
||||
viewportHeight: number;
|
||||
}) => boolean;
|
||||
}
|
||||
).getStackingCanvasBypassState;
|
||||
const shouldBypassStackingCanvasesDuringLowZoomGesture = (
|
||||
canvasRendererModule as {
|
||||
shouldBypassStackingCanvasesDuringLowZoomGesture: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
gestureActive: boolean;
|
||||
recoveryActive: boolean;
|
||||
viewportWidth: number;
|
||||
viewportHeight: number;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldBypassStackingCanvasesDuringLowZoomGesture;
|
||||
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: true,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: false,
|
||||
recoveryActive: true,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: false,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldBypassStackingCanvasesDuringLowZoomGesture({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: false,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(false);
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: true,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 430,
|
||||
viewportHeight: 932,
|
||||
})
|
||||
).toBe(false);
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: true,
|
||||
zoom: 0.6,
|
||||
gestureActive: true,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(false);
|
||||
expect(
|
||||
getStackingCanvasBypassState({
|
||||
isIOS: false,
|
||||
zoom: 0.4,
|
||||
gestureActive: true,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('gesture low-zoom landscape bypass detaches stacking canvases through the existing attachment path', () => {
|
||||
expect(
|
||||
'shouldBypassStackingCanvasesDuringLowZoomGesture' in canvasRendererModule
|
||||
).toBe(true);
|
||||
expect('getStackingCanvasAttachmentDiff' in canvasRendererModule).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
const shouldBypassStackingCanvasesDuringLowZoomGesture = (
|
||||
canvasRendererModule as {
|
||||
shouldBypassStackingCanvasesDuringLowZoomGesture: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
gestureActive: boolean;
|
||||
recoveryActive: boolean;
|
||||
viewportWidth: number;
|
||||
viewportHeight: number;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldBypassStackingCanvasesDuringLowZoomGesture;
|
||||
const getStackingCanvasAttachmentDiff = (
|
||||
canvasRendererModule as {
|
||||
getStackingCanvasAttachmentDiff: (params: {
|
||||
canvases: HTMLCanvasElement[];
|
||||
wasAttached: boolean;
|
||||
shouldAttach: boolean;
|
||||
}) => {
|
||||
added: HTMLCanvasElement[];
|
||||
removed: HTMLCanvasElement[];
|
||||
};
|
||||
}
|
||||
).getStackingCanvasAttachmentDiff;
|
||||
|
||||
const canvases = [document.createElement('canvas')];
|
||||
const shouldBypass = shouldBypassStackingCanvasesDuringLowZoomGesture({
|
||||
isIOS: true,
|
||||
zoom: 0.4,
|
||||
gestureActive: true,
|
||||
recoveryActive: false,
|
||||
viewportWidth: 932,
|
||||
viewportHeight: 430,
|
||||
});
|
||||
|
||||
expect(shouldBypass).toBe(true);
|
||||
expect(
|
||||
getStackingCanvasAttachmentDiff({
|
||||
canvases,
|
||||
wasAttached: true,
|
||||
shouldAttach: !shouldBypass,
|
||||
})
|
||||
).toEqual({
|
||||
added: [],
|
||||
removed: canvases,
|
||||
});
|
||||
});
|
||||
|
||||
test('uses overscan for main-canvas fallback culling and render origin', () => {
|
||||
expect('getMainCanvasFallbackBounds' in canvasRendererModule).toBe(true);
|
||||
|
||||
const getMainCanvasFallbackBounds = (
|
||||
canvasRendererModule as {
|
||||
getMainCanvasFallbackBounds: (params: {
|
||||
viewportBounds: Bound;
|
||||
overscanViewportBounds: Bound;
|
||||
}) => {
|
||||
cullBound: Bound;
|
||||
renderBound: Bound;
|
||||
};
|
||||
}
|
||||
).getMainCanvasFallbackBounds;
|
||||
|
||||
const viewportBounds = new Bound(100, 200, 300, 150);
|
||||
const overscanViewportBounds = new Bound(40, 170, 420, 210);
|
||||
|
||||
expect(
|
||||
getMainCanvasFallbackBounds({
|
||||
viewportBounds,
|
||||
overscanViewportBounds,
|
||||
})
|
||||
).toEqual({
|
||||
cullBound: overscanViewportBounds,
|
||||
renderBound: overscanViewportBounds,
|
||||
});
|
||||
});
|
||||
|
||||
test('lays out overscan canvases relative to the exact viewport', () => {
|
||||
expect('getCanvasViewportLayout' in canvasRendererModule).toBe(true);
|
||||
|
||||
const getCanvasViewportLayout = (
|
||||
canvasRendererModule as {
|
||||
getCanvasViewportLayout: (params: {
|
||||
bound: Bound;
|
||||
viewportBounds: Bound;
|
||||
zoom: number;
|
||||
viewScale: number;
|
||||
dpr: number;
|
||||
}) => {
|
||||
actualHeight: number;
|
||||
actualWidth: number;
|
||||
height: number;
|
||||
transform: string;
|
||||
width: number;
|
||||
};
|
||||
}
|
||||
).getCanvasViewportLayout;
|
||||
|
||||
expect(
|
||||
getCanvasViewportLayout({
|
||||
bound: new Bound(40, 170, 420, 210),
|
||||
viewportBounds: new Bound(100, 200, 300, 150),
|
||||
zoom: 1,
|
||||
viewScale: 1,
|
||||
dpr: 2,
|
||||
})
|
||||
).toEqual({
|
||||
actualHeight: 420,
|
||||
actualWidth: 840,
|
||||
height: 210,
|
||||
transform: 'translate(-60px, -30px) scale(1)',
|
||||
width: 420,
|
||||
});
|
||||
});
|
||||
|
||||
test('computes stacking canvas DOM attachment diffs when bypass toggles', () => {
|
||||
expect('getStackingCanvasAttachmentDiff' in canvasRendererModule).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
const getStackingCanvasAttachmentDiff = (
|
||||
canvasRendererModule as {
|
||||
getStackingCanvasAttachmentDiff: (params: {
|
||||
canvases: HTMLCanvasElement[];
|
||||
wasAttached: boolean;
|
||||
shouldAttach: boolean;
|
||||
}) => {
|
||||
added: HTMLCanvasElement[];
|
||||
removed: HTMLCanvasElement[];
|
||||
};
|
||||
}
|
||||
).getStackingCanvasAttachmentDiff;
|
||||
|
||||
const canvasA = document.createElement('canvas');
|
||||
const canvasB = document.createElement('canvas');
|
||||
const canvases = [canvasA, canvasB];
|
||||
|
||||
expect(
|
||||
getStackingCanvasAttachmentDiff({
|
||||
canvases,
|
||||
wasAttached: true,
|
||||
shouldAttach: false,
|
||||
})
|
||||
).toEqual({
|
||||
added: [],
|
||||
removed: canvases,
|
||||
});
|
||||
|
||||
expect(
|
||||
getStackingCanvasAttachmentDiff({
|
||||
canvases,
|
||||
wasAttached: false,
|
||||
shouldAttach: true,
|
||||
})
|
||||
).toEqual({
|
||||
added: canvases,
|
||||
removed: [],
|
||||
});
|
||||
|
||||
expect(
|
||||
getStackingCanvasAttachmentDiff({
|
||||
canvases,
|
||||
wasAttached: true,
|
||||
shouldAttach: true,
|
||||
})
|
||||
).toEqual({
|
||||
added: [],
|
||||
removed: [],
|
||||
});
|
||||
});
|
||||
|
||||
test('emits a lightweight zoom signal during gesture-skipped zoom updates so canvas budgets can shrink', () => {
|
||||
viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM = [
|
||||
[0.5, 1],
|
||||
[0.8, 2],
|
||||
];
|
||||
|
||||
const viewport = new Viewport();
|
||||
viewport.SKIP_REFRESH_DURING_GESTURE = true;
|
||||
|
||||
const viewportUpdated = vi.fn();
|
||||
const zoomUpdates: Array<{ previousZoom: number; zoom: number }> = [];
|
||||
let lastCanvasBudgetZoom = viewport.zoom;
|
||||
let budgetSyncCount = 0;
|
||||
|
||||
viewport.viewportUpdated.subscribe(viewportUpdated);
|
||||
|
||||
expect('zoomUpdated' in viewport).toBe(true);
|
||||
const zoomUpdated = (
|
||||
viewport as unknown as {
|
||||
zoomUpdated: {
|
||||
subscribe: (
|
||||
callback: (update: { previousZoom: number; zoom: number }) => void
|
||||
) => void;
|
||||
};
|
||||
}
|
||||
).zoomUpdated;
|
||||
|
||||
zoomUpdated.subscribe(update => {
|
||||
zoomUpdates.push(update);
|
||||
if (
|
||||
(
|
||||
canvasRendererModule as {
|
||||
shouldSyncCanvasBudgetOnViewportUpdate: (
|
||||
previousZoom: number,
|
||||
nextZoom: number,
|
||||
rawDpr?: number
|
||||
) => boolean;
|
||||
}
|
||||
).shouldSyncCanvasBudgetOnViewportUpdate(
|
||||
lastCanvasBudgetZoom,
|
||||
update.zoom,
|
||||
2
|
||||
)
|
||||
) {
|
||||
budgetSyncCount += 1;
|
||||
}
|
||||
lastCanvasBudgetZoom = update.zoom;
|
||||
});
|
||||
|
||||
viewport.panning$.next(true);
|
||||
viewport.setZoom(0.4, { x: 0, y: 0 }, false, false, true);
|
||||
|
||||
expect(viewportUpdated).not.toHaveBeenCalled();
|
||||
expect(zoomUpdates).toEqual([{ previousZoom: 1, zoom: 0.4 }]);
|
||||
expect(budgetSyncCount).toBe(1);
|
||||
|
||||
viewport.dispose();
|
||||
});
|
||||
|
||||
test('keeps programmatic setZoom on the normal viewport update path in skip mode', () => {
|
||||
const viewport = new Viewport();
|
||||
viewport.SKIP_REFRESH_DURING_GESTURE = true;
|
||||
|
||||
const viewportUpdated = vi.fn();
|
||||
const zoomUpdated = vi.fn();
|
||||
|
||||
viewport.viewportUpdated.subscribe(viewportUpdated);
|
||||
viewport.zoomUpdated.subscribe(zoomUpdated);
|
||||
|
||||
viewport.setZoom(0.4, { x: 0, y: 0 });
|
||||
|
||||
expect(viewportUpdated).toHaveBeenCalledTimes(1);
|
||||
expect(zoomUpdated).toHaveBeenCalledWith({ previousZoom: 1, zoom: 0.4 });
|
||||
expect(viewport.panning$.value).toBe(false);
|
||||
expect(viewport.zooming$.value).toBe(false);
|
||||
|
||||
viewport.dispose();
|
||||
});
|
||||
|
||||
test('enables low-zoom block survival only while the gesture is still active', () => {
|
||||
expect('shouldUseLowZoomBlockSurvivalMode' in viewportElementModule).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
const shouldUseLowZoomBlockSurvivalMode = (
|
||||
viewportElementModule as {
|
||||
shouldUseLowZoomBlockSurvivalMode: (params: {
|
||||
zoom: number;
|
||||
skipRefreshDuringGesture: boolean;
|
||||
gestureActive: boolean;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldUseLowZoomBlockSurvivalMode;
|
||||
|
||||
expect(
|
||||
shouldUseLowZoomBlockSurvivalMode({
|
||||
zoom: 0.4,
|
||||
skipRefreshDuringGesture: true,
|
||||
gestureActive: true,
|
||||
})
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldUseLowZoomBlockSurvivalMode({
|
||||
zoom: 0.4,
|
||||
skipRefreshDuringGesture: true,
|
||||
gestureActive: false,
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('keeps selected and one nearby viewport block active during low-zoom gesture survival', () => {
|
||||
expect('getLowZoomGestureActiveModels' in viewportElementModule).toBe(true);
|
||||
|
||||
const getLowZoomGestureActiveModels = (
|
||||
viewportElementModule as {
|
||||
getLowZoomGestureActiveModels: (params: {
|
||||
selectedModels: Set<{ id: string; elementBound: Bound }>;
|
||||
viewportModels: Set<{ id: string; elementBound: Bound }>;
|
||||
viewportBounds: Bound;
|
||||
nearbyActiveBlockLimit: number;
|
||||
nearbyDistanceRatio: number;
|
||||
}) => Set<{ id: string; elementBound: Bound }>;
|
||||
}
|
||||
).getLowZoomGestureActiveModels;
|
||||
|
||||
const selected = createFakeBlockModel('selected', 10, 10);
|
||||
const nearby = createFakeBlockModel('nearby', 28, 12);
|
||||
const far = createFakeBlockModel('far', 78, 78);
|
||||
|
||||
const activeModels = getLowZoomGestureActiveModels({
|
||||
selectedModels: new Set([selected]),
|
||||
viewportModels: new Set([selected, nearby, far]),
|
||||
viewportBounds: new Bound(0, 0, 100, 100),
|
||||
nearbyActiveBlockLimit: 1,
|
||||
nearbyDistanceRatio: 0.35,
|
||||
});
|
||||
|
||||
expect([...activeModels].map(model => model.id).sort()).toEqual([
|
||||
'nearby',
|
||||
'selected',
|
||||
]);
|
||||
});
|
||||
|
||||
test('falls back to the nearest viewport block when nothing is selected', () => {
|
||||
expect('getLowZoomGestureActiveModels' in viewportElementModule).toBe(true);
|
||||
|
||||
const getLowZoomGestureActiveModels = (
|
||||
viewportElementModule as {
|
||||
getLowZoomGestureActiveModels: (params: {
|
||||
selectedModels: Set<{ id: string; elementBound: Bound }>;
|
||||
viewportModels: Set<{ id: string; elementBound: Bound }>;
|
||||
viewportBounds: Bound;
|
||||
nearbyActiveBlockLimit: number;
|
||||
nearbyDistanceRatio: number;
|
||||
}) => Set<{ id: string; elementBound: Bound }>;
|
||||
}
|
||||
).getLowZoomGestureActiveModels;
|
||||
|
||||
const nearest = createFakeBlockModel('nearest', 46, 46);
|
||||
const farther = createFakeBlockModel('farther', 78, 78);
|
||||
|
||||
const activeModels = getLowZoomGestureActiveModels({
|
||||
selectedModels: new Set(),
|
||||
viewportModels: new Set([nearest, farther]),
|
||||
viewportBounds: new Bound(0, 0, 100, 100),
|
||||
nearbyActiveBlockLimit: 1,
|
||||
nearbyDistanceRatio: 0.35,
|
||||
});
|
||||
|
||||
expect([...activeModels].map(model => model.id)).toEqual(['nearest']);
|
||||
});
|
||||
|
||||
test('starts post-gesture recovery immediately once gesture signals fully settle', () => {
|
||||
expect('getPostGestureRecoveryDelay' in viewportModule).toBe(true);
|
||||
|
||||
const getPostGestureRecoveryDelay = (
|
||||
viewportModule as {
|
||||
getPostGestureRecoveryDelay: (params: {
|
||||
isPanning: boolean;
|
||||
isZooming: boolean;
|
||||
fallbackDelayMs: number;
|
||||
}) => number;
|
||||
}
|
||||
).getPostGestureRecoveryDelay;
|
||||
|
||||
expect(
|
||||
getPostGestureRecoveryDelay({
|
||||
isPanning: false,
|
||||
isZooming: false,
|
||||
fallbackDelayMs: 220,
|
||||
})
|
||||
).toBe(0);
|
||||
});
|
||||
|
||||
test('keeps fallback post-gesture delay while a gesture signal is still active', () => {
|
||||
expect('getPostGestureRecoveryDelay' in viewportModule).toBe(true);
|
||||
|
||||
const getPostGestureRecoveryDelay = (
|
||||
viewportModule as {
|
||||
getPostGestureRecoveryDelay: (params: {
|
||||
isPanning: boolean;
|
||||
isZooming: boolean;
|
||||
fallbackDelayMs: number;
|
||||
}) => number;
|
||||
}
|
||||
).getPostGestureRecoveryDelay;
|
||||
|
||||
expect(
|
||||
getPostGestureRecoveryDelay({
|
||||
isPanning: true,
|
||||
isZooming: false,
|
||||
fallbackDelayMs: 220,
|
||||
})
|
||||
).toBe(220);
|
||||
expect(
|
||||
getPostGestureRecoveryDelay({
|
||||
isPanning: false,
|
||||
isZooming: true,
|
||||
fallbackDelayMs: 220,
|
||||
})
|
||||
).toBe(220);
|
||||
});
|
||||
|
||||
test('sizes turbo renderer canvas with effective dpr at low zoom', () => {
|
||||
viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM = [
|
||||
[0.5, 1],
|
||||
[0.8, 2],
|
||||
];
|
||||
setDevicePixelRatio(2);
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const host = document.createElement('div');
|
||||
vi.spyOn(host, 'getBoundingClientRect').mockReturnValue(
|
||||
createRect(200, 100)
|
||||
);
|
||||
|
||||
(
|
||||
syncCanvasSize as unknown as (
|
||||
canvas: HTMLCanvasElement,
|
||||
host: HTMLElement,
|
||||
zoom: number
|
||||
) => void
|
||||
)(canvas, host, 0.4);
|
||||
|
||||
expect(canvas.width).toBe(200);
|
||||
expect(canvas.height).toBe(100);
|
||||
|
||||
(
|
||||
syncCanvasSize as unknown as (
|
||||
canvas: HTMLCanvasElement,
|
||||
host: HTMLElement,
|
||||
zoom: number
|
||||
) => void
|
||||
)(canvas, host, 0.95);
|
||||
|
||||
expect(canvas.width).toBe(400);
|
||||
expect(canvas.height).toBe(200);
|
||||
});
|
||||
|
||||
test('paints turbo placeholders with effective dpr at low zoom', () => {
|
||||
const previousTheme = document.documentElement.dataset.theme;
|
||||
document.documentElement.dataset.theme = 'light';
|
||||
|
||||
try {
|
||||
viewportRuntimeConfig.CANVAS_DPR_CAP_BY_ZOOM = [
|
||||
[0.5, 1],
|
||||
[0.8, 2],
|
||||
];
|
||||
setDevicePixelRatio(2);
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const fillRect = vi.fn();
|
||||
const strokeRect = vi.fn();
|
||||
let fillStyle = '';
|
||||
let strokeStyle = '';
|
||||
vi.spyOn(canvas, 'getContext').mockReturnValue({
|
||||
get fillStyle() {
|
||||
return fillStyle;
|
||||
},
|
||||
set fillStyle(value: string) {
|
||||
fillStyle = value;
|
||||
},
|
||||
get strokeStyle() {
|
||||
return strokeStyle;
|
||||
},
|
||||
set strokeStyle(value: string) {
|
||||
strokeStyle = value;
|
||||
},
|
||||
fillRect,
|
||||
strokeRect,
|
||||
} as unknown as CanvasRenderingContext2D);
|
||||
|
||||
const layout: ViewportLayoutTree = {
|
||||
roots: [
|
||||
{
|
||||
blockId: 'root',
|
||||
type: 'affine:page',
|
||||
layout: {
|
||||
blockId: 'root',
|
||||
type: 'affine:page',
|
||||
rect: { x: 0, y: 0, w: 50, h: 20 },
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
overallRect: { x: 0, y: 0, w: 50, h: 20 },
|
||||
};
|
||||
|
||||
const paintPlaceholderForTest =
|
||||
paintPlaceholder as unknown as PaintPlaceholderForTest;
|
||||
|
||||
paintPlaceholderForTest(canvas, layout, {
|
||||
zoom: 0.4,
|
||||
toViewCoord: () => [0, 0],
|
||||
});
|
||||
|
||||
expect(fillStyle).toBe('rgba(0, 0, 0, 0.04)');
|
||||
expect(strokeStyle).toBe('rgba(0, 0, 0, 0.02)');
|
||||
expect(fillRect).toHaveBeenLastCalledWith(0, 0, 20, 8);
|
||||
|
||||
paintPlaceholderForTest(canvas, layout, {
|
||||
zoom: 0.95,
|
||||
toViewCoord: () => [0, 0],
|
||||
});
|
||||
|
||||
expect(fillRect).toHaveBeenLastCalledWith(0, 0, 95, 38);
|
||||
} finally {
|
||||
document.documentElement.dataset.theme = previousTheme;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ColorScheme } from '@blocksuite/affine-model';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
getAffinePlaceholderFillColor,
|
||||
getAffinePlaceholderStrokeColor,
|
||||
inferColorSchemeFromThemeMode,
|
||||
} from '../../../../shared/src/theme/placeholder-style.js';
|
||||
|
||||
describe('affine placeholder style', () => {
|
||||
it('returns subtle light placeholder colors', () => {
|
||||
expect(getAffinePlaceholderFillColor(ColorScheme.Light)).toBe(
|
||||
'rgba(0, 0, 0, 0.04)'
|
||||
);
|
||||
expect(getAffinePlaceholderStrokeColor(ColorScheme.Light)).toBe(
|
||||
'rgba(0, 0, 0, 0.02)'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns subtle dark placeholder colors', () => {
|
||||
expect(getAffinePlaceholderFillColor(ColorScheme.Dark)).toBe(
|
||||
'rgba(255, 255, 255, 0.08)'
|
||||
);
|
||||
expect(getAffinePlaceholderStrokeColor(ColorScheme.Dark)).toBe(
|
||||
'rgba(255, 255, 255, 0.04)'
|
||||
);
|
||||
});
|
||||
|
||||
it('infers color scheme from theme mode', () => {
|
||||
expect(inferColorSchemeFromThemeMode('dark')).toBe(ColorScheme.Dark);
|
||||
expect(inferColorSchemeFromThemeMode('light')).toBe(ColorScheme.Light);
|
||||
expect(inferColorSchemeFromThemeMode('')).toBe(ColorScheme.Light);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import * as turboRendererModule from '../../../../gfx/turbo-renderer/src/turbo-renderer.js';
|
||||
|
||||
describe('viewport turbo renderer policy', () => {
|
||||
test.each([
|
||||
{ isIOS: true, zoom: 0.4, hasBitmap: true, expected: true },
|
||||
{ isIOS: true, zoom: 0.4, hasBitmap: false, expected: false },
|
||||
{ isIOS: false, zoom: 0.4, hasBitmap: true, expected: false },
|
||||
{ isIOS: true, zoom: 0.8, hasBitmap: true, expected: false },
|
||||
])(
|
||||
'prefers cached bitmap only for iOS low-zoom gestures with a bitmap %#',
|
||||
({ isIOS, zoom, hasBitmap, expected }) => {
|
||||
expect(
|
||||
'shouldPreferBitmapCacheDuringLowZoomGesture' in turboRendererModule
|
||||
).toBe(true);
|
||||
|
||||
const shouldPreferBitmapCacheDuringLowZoomGesture = (
|
||||
turboRendererModule as {
|
||||
shouldPreferBitmapCacheDuringLowZoomGesture: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
hasBitmap: boolean;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldPreferBitmapCacheDuringLowZoomGesture;
|
||||
|
||||
expect(
|
||||
shouldPreferBitmapCacheDuringLowZoomGesture({
|
||||
isIOS,
|
||||
zoom,
|
||||
hasBitmap,
|
||||
})
|
||||
).toBe(expected);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([
|
||||
{ isIOS: true, zoom: 0.4, expected: false },
|
||||
{ isIOS: true, zoom: 0.8, expected: true },
|
||||
{ isIOS: false, zoom: 0.4, expected: true },
|
||||
])(
|
||||
'idles turbo blocks outside iOS low-zoom survival mode %#',
|
||||
({ isIOS, zoom, expected }) => {
|
||||
expect('shouldIdleTurboBlocksDuringZooming' in turboRendererModule).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
const shouldIdleTurboBlocksDuringZooming = (
|
||||
turboRendererModule as {
|
||||
shouldIdleTurboBlocksDuringZooming: (params: {
|
||||
isIOS: boolean;
|
||||
zoom: number;
|
||||
}) => boolean;
|
||||
}
|
||||
).shouldIdleTurboBlocksDuringZooming;
|
||||
|
||||
expect(
|
||||
shouldIdleTurboBlocksDuringZooming({
|
||||
isIOS,
|
||||
zoom,
|
||||
})
|
||||
).toBe(expected);
|
||||
}
|
||||
);
|
||||
});
|
||||
42
blocksuite/affine/all/src/__tests__/utils/create-job.ts
Normal file
42
blocksuite/affine/all/src/__tests__/utils/create-job.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { defaultImageProxyMiddleware } from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
Schema,
|
||||
Transformer,
|
||||
type TransformerMiddleware,
|
||||
} from '@blocksuite/store';
|
||||
import { TestWorkspace } from '@blocksuite/store/test';
|
||||
|
||||
import { AffineSchemas } from '../../schemas.js';
|
||||
import { testStoreExtensions } from './store.js';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
happyDOM: {
|
||||
settings: {
|
||||
fetch: {
|
||||
disableSameOriginPolicy: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function createJob(middlewares?: TransformerMiddleware[]) {
|
||||
window.happyDOM.settings.fetch.disableSameOriginPolicy = true;
|
||||
const testMiddlewares = middlewares ?? [];
|
||||
testMiddlewares.push(defaultImageProxyMiddleware);
|
||||
const schema = new Schema().register(AffineSchemas);
|
||||
const docCollection = new TestWorkspace();
|
||||
docCollection.storeExtensions = testStoreExtensions;
|
||||
docCollection.meta.initialize();
|
||||
return new Transformer({
|
||||
schema,
|
||||
blobCRUD: docCollection.blobSync,
|
||||
middlewares: testMiddlewares,
|
||||
docCRUD: {
|
||||
create: (id: string) => docCollection.createDoc(id).getStore({ id }),
|
||||
get: (id: string) => docCollection.getDoc(id)?.getStore({ id }) ?? null,
|
||||
delete: (id: string) => docCollection.removeDoc(id),
|
||||
},
|
||||
});
|
||||
}
|
||||
12
blocksuite/affine/all/src/__tests__/utils/get-provider.ts
Normal file
12
blocksuite/affine/all/src/__tests__/utils/get-provider.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Container } from '@blocksuite/global/di';
|
||||
|
||||
import { testStoreExtensions } from './store';
|
||||
|
||||
export function getProvider() {
|
||||
const container = new Container();
|
||||
const exts = testStoreExtensions;
|
||||
exts.forEach(ext => {
|
||||
ext.setup(container);
|
||||
});
|
||||
return container.provider();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { BlockSnapshot, SliceSnapshot } from '@blocksuite/store';
|
||||
|
||||
export function nanoidReplacement(snapshot: BlockSnapshot | SliceSnapshot) {
|
||||
return JSON.parse(nanoidReplacementString(JSON.stringify(snapshot)));
|
||||
}
|
||||
const escapedSnapshotAttributes = new Set([
|
||||
'"attributes"',
|
||||
'"conditions"',
|
||||
'"iconColumn"',
|
||||
'"background"',
|
||||
'"LinkedPage"',
|
||||
'"elementIds"',
|
||||
'"attachment"',
|
||||
]);
|
||||
|
||||
function nanoidReplacementString(snapshotString: string) {
|
||||
const re =
|
||||
/("block:[A-Za-z0-9-_]{10}")|("[A-Za-z0-9-_]{10}")|("[A-Za-z0-9-_]{35}")|("[A-Za-z0-9-_]{10}:[A-Za-z0-9-_]{10}")|("var\(--affine-v2-chip-label-[a-z]{3,10}\)")|("[A-Za-z0-9-_=]{44}")/g;
|
||||
const matches = snapshotString.matchAll(re);
|
||||
const matchesReplaceMap = new Map();
|
||||
let escapedNumber = 0;
|
||||
Array.from(matches).forEach((match, index) => {
|
||||
if (escapedSnapshotAttributes.has(match[0])) {
|
||||
matchesReplaceMap.set(match[0], match[0]);
|
||||
escapedNumber++;
|
||||
} else {
|
||||
matchesReplaceMap.set(
|
||||
match[0],
|
||||
`"matchesReplaceMap[${index - escapedNumber}]"`
|
||||
);
|
||||
}
|
||||
});
|
||||
return snapshotString.replace(re, match => matchesReplaceMap.get(match));
|
||||
}
|
||||
7
blocksuite/affine/all/src/__tests__/utils/store.ts
Normal file
7
blocksuite/affine/all/src/__tests__/utils/store.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { StoreExtensionManager } from '@blocksuite/affine-ext-loader';
|
||||
|
||||
import { getInternalStoreExtensions } from '../../extensions/store';
|
||||
|
||||
const manager = new StoreExtensionManager(getInternalStoreExtensions());
|
||||
|
||||
export const testStoreExtensions = manager.get('store');
|
||||
1
blocksuite/affine/all/src/blocks/attachment/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/attachment/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-attachment';
|
||||
1
blocksuite/affine/all/src/blocks/attachment/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/attachment/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-attachment/store';
|
||||
1
blocksuite/affine/all/src/blocks/attachment/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/attachment/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-attachment/view';
|
||||
1
blocksuite/affine/all/src/blocks/bookmark/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/bookmark/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-bookmark';
|
||||
1
blocksuite/affine/all/src/blocks/bookmark/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/bookmark/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-bookmark/store';
|
||||
1
blocksuite/affine/all/src/blocks/bookmark/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/bookmark/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-bookmark/view';
|
||||
1
blocksuite/affine/all/src/blocks/callout/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/callout/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-callout';
|
||||
1
blocksuite/affine/all/src/blocks/callout/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/callout/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-callout/store';
|
||||
1
blocksuite/affine/all/src/blocks/callout/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/callout/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-callout/view';
|
||||
1
blocksuite/affine/all/src/blocks/code/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/code/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-code';
|
||||
1
blocksuite/affine/all/src/blocks/code/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/code/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-code/store';
|
||||
1
blocksuite/affine/all/src/blocks/code/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/code/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-code/view';
|
||||
1
blocksuite/affine/all/src/blocks/data-view/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/data-view/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-data-view';
|
||||
1
blocksuite/affine/all/src/blocks/data-view/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/data-view/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-data-view/store';
|
||||
1
blocksuite/affine/all/src/blocks/data-view/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/data-view/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-data-view/view';
|
||||
1
blocksuite/affine/all/src/blocks/database/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/database/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-database';
|
||||
1
blocksuite/affine/all/src/blocks/database/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/database/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-database/store';
|
||||
1
blocksuite/affine/all/src/blocks/database/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/database/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-database/view';
|
||||
1
blocksuite/affine/all/src/blocks/divider/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/divider/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-divider';
|
||||
1
blocksuite/affine/all/src/blocks/divider/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/divider/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-divider/store';
|
||||
1
blocksuite/affine/all/src/blocks/divider/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/divider/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-divider/view';
|
||||
1
blocksuite/affine/all/src/blocks/edgeless-text/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/edgeless-text/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-edgeless-text';
|
||||
1
blocksuite/affine/all/src/blocks/edgeless-text/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/edgeless-text/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-edgeless-text/store';
|
||||
1
blocksuite/affine/all/src/blocks/edgeless-text/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/edgeless-text/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-edgeless-text/view';
|
||||
1
blocksuite/affine/all/src/blocks/embed-doc/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed-doc/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc';
|
||||
1
blocksuite/affine/all/src/blocks/embed-doc/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed-doc/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc/store';
|
||||
1
blocksuite/affine/all/src/blocks/embed-doc/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed-doc/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed-doc/view';
|
||||
1
blocksuite/affine/all/src/blocks/embed/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed';
|
||||
1
blocksuite/affine/all/src/blocks/embed/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed/store';
|
||||
1
blocksuite/affine/all/src/blocks/embed/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/embed/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-embed/view';
|
||||
1
blocksuite/affine/all/src/blocks/frame/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/frame/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-frame';
|
||||
1
blocksuite/affine/all/src/blocks/frame/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/frame/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-frame/store';
|
||||
1
blocksuite/affine/all/src/blocks/frame/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/frame/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-frame/view';
|
||||
1
blocksuite/affine/all/src/blocks/image/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/image/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-image';
|
||||
1
blocksuite/affine/all/src/blocks/image/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/image/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-image/store';
|
||||
1
blocksuite/affine/all/src/blocks/image/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/image/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-image/view';
|
||||
1
blocksuite/affine/all/src/blocks/latex/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/latex/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-latex';
|
||||
1
blocksuite/affine/all/src/blocks/latex/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/latex/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-latex/store';
|
||||
1
blocksuite/affine/all/src/blocks/latex/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/latex/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-latex/view';
|
||||
1
blocksuite/affine/all/src/blocks/list/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/list/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-list';
|
||||
1
blocksuite/affine/all/src/blocks/list/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/list/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-list/store';
|
||||
1
blocksuite/affine/all/src/blocks/list/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/list/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-list/view';
|
||||
1
blocksuite/affine/all/src/blocks/note/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/note/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-note';
|
||||
1
blocksuite/affine/all/src/blocks/note/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/note/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-note/store';
|
||||
1
blocksuite/affine/all/src/blocks/note/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/note/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-note/view';
|
||||
1
blocksuite/affine/all/src/blocks/paragraph/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/paragraph/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-paragraph';
|
||||
1
blocksuite/affine/all/src/blocks/paragraph/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/paragraph/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-paragraph/store';
|
||||
1
blocksuite/affine/all/src/blocks/paragraph/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/paragraph/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-paragraph/view';
|
||||
1
blocksuite/affine/all/src/blocks/root/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/root/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-root';
|
||||
1
blocksuite/affine/all/src/blocks/root/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/root/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-root/store';
|
||||
1
blocksuite/affine/all/src/blocks/root/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/root/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-root/view';
|
||||
1
blocksuite/affine/all/src/blocks/surface-ref/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface-ref/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface-ref';
|
||||
1
blocksuite/affine/all/src/blocks/surface-ref/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface-ref/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface-ref/store';
|
||||
1
blocksuite/affine/all/src/blocks/surface-ref/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface-ref/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface-ref/view';
|
||||
1
blocksuite/affine/all/src/blocks/surface/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface';
|
||||
1
blocksuite/affine/all/src/blocks/surface/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface/store';
|
||||
1
blocksuite/affine/all/src/blocks/surface/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/surface/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-surface/view';
|
||||
1
blocksuite/affine/all/src/blocks/table/index.ts
Normal file
1
blocksuite/affine/all/src/blocks/table/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-table';
|
||||
1
blocksuite/affine/all/src/blocks/table/store.ts
Normal file
1
blocksuite/affine/all/src/blocks/table/store.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-table/store';
|
||||
1
blocksuite/affine/all/src/blocks/table/view.ts
Normal file
1
blocksuite/affine/all/src/blocks/table/view.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-block-table/view';
|
||||
1
blocksuite/affine/all/src/components/block-selection.ts
Normal file
1
blocksuite/affine/all/src/components/block-selection.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/block-selection';
|
||||
1
blocksuite/affine/all/src/components/block-zero-width.ts
Normal file
1
blocksuite/affine/all/src/components/block-zero-width.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/block-zero-width';
|
||||
1
blocksuite/affine/all/src/components/caption.ts
Normal file
1
blocksuite/affine/all/src/components/caption.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/caption';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/card-style-dropdown-menu';
|
||||
1
blocksuite/affine/all/src/components/citation.ts
Normal file
1
blocksuite/affine/all/src/components/citation.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/citation';
|
||||
1
blocksuite/affine/all/src/components/color-picker.ts
Normal file
1
blocksuite/affine/all/src/components/color-picker.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/color-picker';
|
||||
1
blocksuite/affine/all/src/components/context-menu.ts
Normal file
1
blocksuite/affine/all/src/components/context-menu.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/context-menu';
|
||||
1
blocksuite/affine/all/src/components/date-picker.ts
Normal file
1
blocksuite/affine/all/src/components/date-picker.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/date-picker';
|
||||
1
blocksuite/affine/all/src/components/drop-indicator.ts
Normal file
1
blocksuite/affine/all/src/components/drop-indicator.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/drop-indicator';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/edgeless-line-styles-panel';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/edgeless-line-width-panel';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/edgeless-shape-color-picker';
|
||||
1
blocksuite/affine/all/src/components/embed-card-modal.ts
Normal file
1
blocksuite/affine/all/src/components/embed-card-modal.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/embed-card-modal';
|
||||
1
blocksuite/affine/all/src/components/filterable-list.ts
Normal file
1
blocksuite/affine/all/src/components/filterable-list.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/filterable-list';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/highlight-dropdown-menu';
|
||||
1
blocksuite/affine/all/src/components/hover.ts
Normal file
1
blocksuite/affine/all/src/components/hover.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/hover';
|
||||
1
blocksuite/affine/all/src/components/icon-button.ts
Normal file
1
blocksuite/affine/all/src/components/icon-button.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/icon-button';
|
||||
1
blocksuite/affine/all/src/components/icons.ts
Normal file
1
blocksuite/affine/all/src/components/icons.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/icons';
|
||||
1
blocksuite/affine/all/src/components/link-preview.ts
Normal file
1
blocksuite/affine/all/src/components/link-preview.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/link-preview';
|
||||
1
blocksuite/affine/all/src/components/linked-doc-title.ts
Normal file
1
blocksuite/affine/all/src/components/linked-doc-title.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from '@blocksuite/affine-components/linked-doc-title';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user