mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-30 00:29:46 +08:00
refactor(editor): move worker renderer to presets with basic test (#10127)
This commit is contained in:
@@ -1,22 +0,0 @@
|
|||||||
import '../../style.css';
|
|
||||||
|
|
||||||
import { ViewportTurboRendererExtension } from '@blocksuite/affine-shared/viewport-renderer';
|
|
||||||
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
|
|
||||||
import { AffineEditorContainer } from '@blocksuite/presets';
|
|
||||||
import { effects as presetsEffects } from '@blocksuite/presets/effects';
|
|
||||||
|
|
||||||
import { createEmptyDoc } from '../../apps/_common/helper';
|
|
||||||
|
|
||||||
blocksEffects();
|
|
||||||
presetsEffects();
|
|
||||||
|
|
||||||
export const { doc } = createEmptyDoc();
|
|
||||||
export const editor = new AffineEditorContainer();
|
|
||||||
|
|
||||||
editor.edgelessSpecs = [
|
|
||||||
...editor.edgelessSpecs,
|
|
||||||
ViewportTurboRendererExtension,
|
|
||||||
];
|
|
||||||
|
|
||||||
editor.doc = doc;
|
|
||||||
editor.mode = 'edgeless';
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Renderer Example</title>
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: var(--affine-white-90);
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
#container {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="container"></div>
|
|
||||||
<script type="module" src="./main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import { addSampleNotes } from './doc-generator.js';
|
|
||||||
import { doc, editor } from './editor.js';
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
doc.load();
|
|
||||||
addSampleNotes(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
document.querySelector('#container')?.append(editor);
|
|
||||||
@@ -120,10 +120,6 @@ export default defineConfig(({ mode }) => {
|
|||||||
'examples/multiple-editors/edgeless-edgeless/index.html'
|
'examples/multiple-editors/edgeless-edgeless/index.html'
|
||||||
),
|
),
|
||||||
'examples/inline': resolve(__dirname, 'examples/inline/index.html'),
|
'examples/inline': resolve(__dirname, 'examples/inline/index.html'),
|
||||||
'examples/renderer': resolve(
|
|
||||||
__dirname,
|
|
||||||
'examples/renderer/index.html'
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
treeshake: true,
|
treeshake: true,
|
||||||
output: {
|
output: {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"description": "Prebuilt BlockSuite editors and opt-in additional UI components.",
|
"description": "Prebuilt BlockSuite editors and opt-in additional UI components.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"test:unit": "vitest --browser.headless --run",
|
"test:unit": "vitest --browser.headless --run",
|
||||||
"test:debug": "PWDEBUG=1 npx vitest"
|
"test:debug": "PWDEBUG=1 npx vitest"
|
||||||
@@ -46,6 +47,9 @@
|
|||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vanilla-extract/vite-plugin": "^5.0.0",
|
"@vanilla-extract/vite-plugin": "^5.0.0",
|
||||||
|
"vite": "^6.1.0",
|
||||||
|
"vite-plugin-istanbul": "^6.0.2",
|
||||||
|
"vite-plugin-wasm": "^3.4.1",
|
||||||
"vitest": "^3.0.0"
|
"vitest": "^3.0.0"
|
||||||
},
|
},
|
||||||
"version": "0.19.0"
|
"version": "0.19.0"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Kalam&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Debug Entry</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="./src/__tests__/utils/renderer-entry.ts"
|
||||||
|
></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ViewportTurboRendererExtension } from '@blocksuite/affine-shared/viewport-renderer';
|
||||||
|
import { beforeEach, describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
|
import { wait } from '../utils/common.js';
|
||||||
|
import { addSampleNotes } from '../utils/doc-generator.js';
|
||||||
|
import { setupEditor } from '../utils/setup.js';
|
||||||
|
|
||||||
|
describe('viewport turbo renderer', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
const cleanup = await setupEditor('edgeless', [
|
||||||
|
ViewportTurboRendererExtension,
|
||||||
|
]);
|
||||||
|
return cleanup;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render 6 notes in viewport', async () => {
|
||||||
|
addSampleNotes(doc, 6);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
const notes = document.querySelectorAll('affine-edgeless-note');
|
||||||
|
expect(notes.length).toBe(6);
|
||||||
|
});
|
||||||
|
});
|
||||||
+10
-11
@@ -1,33 +1,32 @@
|
|||||||
import { Text } from '@blocksuite/store';
|
import { type Store, Text } from '@blocksuite/store';
|
||||||
|
|
||||||
import { doc } from './editor.js';
|
function addParagraph(doc: Store, noteId: string, content: string) {
|
||||||
|
|
||||||
function addParagraph(noteId: string, content: string) {
|
|
||||||
const props = { text: new Text(content) };
|
const props = { text: new Text(content) };
|
||||||
doc.addBlock('affine:paragraph', props, noteId);
|
doc.addBlock('affine:paragraph', props, noteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSampleNote(noteId: string, i: number) {
|
function addSampleNote(doc: Store, noteId: string, i: number) {
|
||||||
addParagraph(noteId, `Note ${i + 1}`);
|
addParagraph(doc, noteId, `Note ${i + 1}`);
|
||||||
addParagraph(noteId, 'Hello World!');
|
addParagraph(doc, noteId, 'Hello World!');
|
||||||
addParagraph(
|
addParagraph(
|
||||||
|
doc,
|
||||||
noteId,
|
noteId,
|
||||||
'Hello World! Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.'
|
'Hello World! Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.'
|
||||||
);
|
);
|
||||||
addParagraph(
|
addParagraph(
|
||||||
|
doc,
|
||||||
noteId,
|
noteId,
|
||||||
'你好这是测试,这是一个为了换行而写的中文段落。这个段落会自动换行。'
|
'你好这是测试,这是一个为了换行而写的中文段落。这个段落会自动换行。'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addSampleNotes(n: number) {
|
export function addSampleNotes(doc: Store, n: number) {
|
||||||
const cols = Math.ceil(Math.sqrt(n));
|
const cols = Math.ceil(Math.sqrt(n));
|
||||||
const NOTE_WIDTH = 500;
|
const NOTE_WIDTH = 500;
|
||||||
const NOTE_HEIGHT = 250;
|
const NOTE_HEIGHT = 250;
|
||||||
const SPACING = 50;
|
const SPACING = 50;
|
||||||
|
|
||||||
const rootId = doc.addBlock('affine:page', {});
|
const rootId = doc.getBlocksByFlavour('affine:page')[0]?.id;
|
||||||
doc.addBlock('affine:surface', {}, rootId);
|
|
||||||
|
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
const row = Math.floor(i / cols);
|
const row = Math.floor(i / cols);
|
||||||
@@ -37,6 +36,6 @@ export function addSampleNotes(n: number) {
|
|||||||
|
|
||||||
const xywh = `[${x},${y},${NOTE_WIDTH},${NOTE_HEIGHT}]`;
|
const xywh = `[${x},${y},${NOTE_WIDTH},${NOTE_HEIGHT}]`;
|
||||||
const noteId = doc.addBlock('affine:note', { xywh }, rootId);
|
const noteId = doc.addBlock('affine:note', { xywh }, rootId);
|
||||||
addSampleNote(noteId, i);
|
addSampleNote(doc, noteId, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { ViewportTurboRendererExtension } from '@blocksuite/affine-shared/viewport-renderer';
|
||||||
|
|
||||||
|
import { addSampleNotes } from './doc-generator.js';
|
||||||
|
import { setupEditor } from './setup.js';
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
setupEditor('edgeless', [ViewportTurboRendererExtension]);
|
||||||
|
addSampleNotes(doc, 6);
|
||||||
|
doc.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
@@ -2,7 +2,7 @@ import '@toeverything/theme/style.css';
|
|||||||
import '@toeverything/theme/fonts.css';
|
import '@toeverything/theme/fonts.css';
|
||||||
|
|
||||||
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
|
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
|
||||||
import type { Store, Transformer } from '@blocksuite/store';
|
import type { ExtensionType, Store, Transformer } from '@blocksuite/store';
|
||||||
|
|
||||||
import { effects } from '../../effects.js';
|
import { effects } from '../../effects.js';
|
||||||
|
|
||||||
@@ -59,7 +59,11 @@ function initCollection(collection: TestWorkspace) {
|
|||||||
doc.resetHistory();
|
doc.resetHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
async function createEditor(
|
||||||
|
collection: TestWorkspace,
|
||||||
|
mode: DocMode = 'page',
|
||||||
|
extensions: ExtensionType[] = []
|
||||||
|
) {
|
||||||
const app = document.createElement('div');
|
const app = document.createElement('div');
|
||||||
const blockCollection = collection.docs.values().next().value;
|
const blockCollection = collection.docs.values().next().value;
|
||||||
assertExists(blockCollection, 'Need to create a doc first');
|
assertExists(blockCollection, 'Need to create a doc first');
|
||||||
@@ -69,9 +73,11 @@ async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
|||||||
editor.mode = mode;
|
editor.mode = mode;
|
||||||
editor.pageSpecs = editor.pageSpecs.concat([
|
editor.pageSpecs = editor.pageSpecs.concat([
|
||||||
FontConfigExtension(CommunityCanvasTextFonts),
|
FontConfigExtension(CommunityCanvasTextFonts),
|
||||||
|
...extensions,
|
||||||
]);
|
]);
|
||||||
editor.edgelessSpecs = editor.edgelessSpecs.concat([
|
editor.edgelessSpecs = editor.edgelessSpecs.concat([
|
||||||
FontConfigExtension(CommunityCanvasTextFonts),
|
FontConfigExtension(CommunityCanvasTextFonts),
|
||||||
|
...extensions,
|
||||||
]);
|
]);
|
||||||
app.append(editor);
|
app.append(editor);
|
||||||
|
|
||||||
@@ -87,7 +93,10 @@ async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setupEditor(mode: DocMode = 'page') {
|
export async function setupEditor(
|
||||||
|
mode: DocMode = 'page',
|
||||||
|
extensions: ExtensionType[] = []
|
||||||
|
) {
|
||||||
const collection = new TestWorkspace(createCollectionOptions());
|
const collection = new TestWorkspace(createCollectionOptions());
|
||||||
collection.storeExtensions = StoreExtensions;
|
collection.storeExtensions = StoreExtensions;
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
@@ -95,7 +104,7 @@ export async function setupEditor(mode: DocMode = 'page') {
|
|||||||
window.collection = collection;
|
window.collection = collection;
|
||||||
|
|
||||||
initCollection(collection);
|
initCollection(collection);
|
||||||
const appElement = await createEditor(collection, mode);
|
const appElement = await createEditor(collection, mode, extensions);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
appElement.remove();
|
appElement.remove();
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { cpus } from 'node:os';
|
||||||
|
|
||||||
|
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import wasm from 'vite-plugin-wasm';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig(() => {
|
||||||
|
return {
|
||||||
|
plugins: [wasm(), vanillaExtractPlugin()],
|
||||||
|
esbuild: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
sourcemap: true,
|
||||||
|
rollupOptions: {
|
||||||
|
cache: false,
|
||||||
|
maxParallelFileOps: Math.max(1, cpus().length - 1),
|
||||||
|
onwarn(warning, defaultHandler) {
|
||||||
|
if (
|
||||||
|
warning.code &&
|
||||||
|
['EVAL', 'SOURCEMAP_ERROR'].includes(warning.code)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
defaultHandler(warning);
|
||||||
|
},
|
||||||
|
treeshake: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -4106,6 +4106,9 @@ __metadata:
|
|||||||
"@vanilla-extract/css": "npm:^1.17.0"
|
"@vanilla-extract/css": "npm:^1.17.0"
|
||||||
"@vanilla-extract/vite-plugin": "npm:^5.0.0"
|
"@vanilla-extract/vite-plugin": "npm:^5.0.0"
|
||||||
lit: "npm:^3.2.0"
|
lit: "npm:^3.2.0"
|
||||||
|
vite: "npm:^6.1.0"
|
||||||
|
vite-plugin-istanbul: "npm:^6.0.2"
|
||||||
|
vite-plugin-wasm: "npm:^3.4.1"
|
||||||
vitest: "npm:^3.0.0"
|
vitest: "npm:^3.0.0"
|
||||||
yjs: "npm:^13.6.21"
|
yjs: "npm:^13.6.21"
|
||||||
zod: "npm:^3.23.8"
|
zod: "npm:^3.23.8"
|
||||||
@@ -33794,7 +33797,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"vite-plugin-wasm@npm:^3.3.0":
|
"vite-plugin-wasm@npm:^3.3.0, vite-plugin-wasm@npm:^3.4.1":
|
||||||
version: 3.4.1
|
version: 3.4.1
|
||||||
resolution: "vite-plugin-wasm@npm:3.4.1"
|
resolution: "vite-plugin-wasm@npm:3.4.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -33818,7 +33821,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.0.3":
|
"vite@npm:^5.0.0 || ^6.0.0, vite@npm:^6.0.3, vite@npm:^6.1.0":
|
||||||
version: 6.1.0
|
version: 6.1.0
|
||||||
resolution: "vite@npm:6.1.0"
|
resolution: "vite@npm:6.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user