Skip to content

Commit

Permalink
refactor(editor): extensionalize html adapter (#9299)
Browse files Browse the repository at this point in the history
  • Loading branch information
Saul-Mirone committed Dec 25, 2024
1 parent a15009c commit 50ff365
Show file tree
Hide file tree
Showing 16 changed files with 183 additions and 144 deletions.
4 changes: 3 additions & 1 deletion blocksuite/affine/shared/src/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ export {
type BlockHtmlAdapterMatcher,
BlockHtmlAdapterMatcherIdentifier,
type Html,
HtmlASTToDeltaExtension,
type HtmlASTToDeltaMatcher,
HtmlASTToDeltaMatcherIdentifier,
HtmlDeltaConverter,
InlineDeltaToHtmlAdapterExtension,
type InlineDeltaToHtmlAdapterMatcher,
InlineDeltaToHtmlAdapterMatcherIdentifier,
} from './html-adapter/index.js';
} from './html/index.js';
export {
BlockMarkdownAdapterExtension,
type BlockMarkdownAdapterMatcher,
Expand Down
68 changes: 41 additions & 27 deletions blocksuite/blocks/src/__tests__/adapters/html.unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { Container } from '@blocksuite/global/di';
import type {
BlockSnapshot,
DocSnapshot,
Expand All @@ -10,11 +11,24 @@ import type {
import { AssetsManager, MemoryBlobCRUD } from '@blocksuite/store';
import { describe, expect, test } from 'vitest';

import { HtmlAdapter } from '../../_common/adapters/html-adapter/html.js';
import { defaultBlockHtmlAdapterMatchers } from '../../_common/adapters/html/block-matcher.js';
import { htmlInlineToDeltaMatchers } from '../../_common/adapters/html/delta-converter/html-inline.js';
import { inlineDeltaToHtmlAdapterMatchers } from '../../_common/adapters/html/delta-converter/inline-delta.js';
import { HtmlAdapter } from '../../_common/adapters/html/html.js';
import { nanoidReplacement } from '../../_common/test-utils/test-utils.js';
import { embedSyncedDocMiddleware } from '../../_common/transformers/middlewares.js';
import { createJob } from '../utils/create-job.js';

const container = new Container();
[
...htmlInlineToDeltaMatchers,
...defaultBlockHtmlAdapterMatchers,
...inlineDeltaToHtmlAdapterMatchers,
].forEach(ext => {
ext.setup(container);
});
const provider = container.provider();

describe('snapshot to html', () => {
const template = (html: string, title?: string) => {
let htmlTemplate = `
Expand Down Expand Up @@ -126,7 +140,7 @@ describe('snapshot to html', () => {
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span style="color:#AF00DB">import</span><span style="color:#000000"> this</span></span></code></pre>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -192,7 +206,7 @@ describe('snapshot to html', () => {
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span>import this</span></span></code></pre>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -258,7 +272,7 @@ describe('snapshot to html', () => {
`<pre class="shiki light-plus" style="background-color:#FFFFFF;color:#000000" tabindex="0"><code><span class="line"><span>import this</span></span></code></pre>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -444,7 +458,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><p>aaa</p><div class="affine-block-children-container" style="padding-left: 26px;"><div class="affine-paragraph-block-container"><p>bbb</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div><div class="affine-paragraph-block-container"><p>ccc</p><div class="affine-block-children-container" style="padding-left: 26px;"><div class="affine-paragraph-block-container"><p>ddd</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div><div class="affine-paragraph-block-container"><p>eee</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div><div class="affine-paragraph-block-container"><p>fff</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div></div></div><div class="affine-paragraph-block-container"><p>ggg</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div></div></div><div class="affine-paragraph-block-container"><p>hhh</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -589,7 +603,7 @@ describe('snapshot to html', () => {
`<ul class="bulleted-list"><li class="affine-list-block-container">aaa<ul class="bulleted-list"><li class="affine-list-block-container">bbb<ul class="bulleted-list"><li class="affine-list-block-container">ccc</li></ul></li><li class="affine-list-block-container">ddd</li></ul></li><li class="affine-list-block-container">eee</li></ul>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -694,7 +708,7 @@ describe('snapshot to html', () => {
`<ul class="bulleted-list"><li class="affine-list-block-container">aaa</li></ul><ul style="list-style-type: none; padding-inline-start: 18px;" class="todo-list"><li class="affine-list-block-container"><input type="checkbox"><label style="margin-right: 3px;"></label></input>bbb</li></ul><ul class="bulleted-list"><li class="affine-list-block-container">ccc</li></ul>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -768,7 +782,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><p>aaa <code>bbb</code> ccc</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -842,7 +856,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><p>aaa <a href="https://affine.pro/">bbb</a> ccc</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -917,7 +931,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><p>aaa<strong>bbb</strong>ccc</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -992,7 +1006,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><p>aaa<em>bbb</em>ccc</p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -1069,7 +1083,7 @@ describe('snapshot to html', () => {
`<figure class="affine-image-block-container"><img src="assets/YXXTjRmLlNyiOUnHb8nAIvUP6V7PAXhwW9F5_tc2LGs=.blob" alt="YXXTjRmLlNyiOUnHb8nAIvUP6V7PAXhwW9F5_tc2LGs=.blob" title="aaa"></figure><div class="affine-paragraph-block-container"><p></p><div class="affine-block-children-container" style="padding-left: 26px;"></div></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const blobManager = new MemoryBlobCRUD();
await blobManager.set(
'YXXTjRmLlNyiOUnHb8nAIvUP6V7PAXhwW9F5_tc2LGs=',
Expand Down Expand Up @@ -1171,7 +1185,7 @@ describe('snapshot to html', () => {
`<div class="affine-paragraph-block-container"><a href="${testCase.url}">${testCase.title}</a></div>`
);

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -1430,7 +1444,7 @@ describe('snapshot to html', () => {
const html = template(
'<table><thead><tr><th>Title</th><th>Status</th><th>Date</th><th>Number</th><th>Progress</th><th>MultiSelect</th><th>RichText</th><th>Link</th><th>Checkbox</th></tr></thead><tbody><tr><td>Task 1</td><td>TODO</td><td>2023-12-15</td><td>1</td><td>65</td><td>test1,test2</td><td><a href="https://google.com">test2</a></td><td>https://google.com</td><td>true</td></tr><tr><td>Task 2</td><td>In Progress</td><td>2023-12-20</td><td></td><td></td><td></td><td>test1</td><td></td><td></td></tr></tbody></table>'
);
const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapshot,
});
Expand Down Expand Up @@ -1510,7 +1524,7 @@ describe('snapshot to html', () => {
const html = template(
'<div class="affine-paragraph-block-container"><a href="https://example.com/4T5ObMgEIMII-4Bexyta1?mode=page&#x26;blockIds=abc%2C123&#x26;elementIds=def%2C456&#x26;databaseId=deadbeef&#x26;databaseRowId=123">Test Doc</a></div>'
);
const htmlAdapter = new HtmlAdapter(createJob([middleware]));
const htmlAdapter = new HtmlAdapter(createJob([middleware]), provider);
const target = await htmlAdapter.fromBlockSnapshot({
snapshot: blockSnapShot,
});
Expand Down Expand Up @@ -1896,7 +1910,7 @@ describe('snapshot to html', () => {
await job.snapshotToDoc(syncedDocSnapshot);
await job.snapshotToDoc(docSnapShot);

const mdAdapter = new HtmlAdapter(job);
const mdAdapter = new HtmlAdapter(job, provider);
const target = await mdAdapter.fromDocSnapshot({
snapshot: docSnapShot,
});
Expand Down Expand Up @@ -1981,7 +1995,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2091,7 +2105,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2157,7 +2171,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2202,7 +2216,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2238,7 +2252,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2350,7 +2364,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2394,7 +2408,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2438,7 +2452,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2491,7 +2505,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2544,7 +2558,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down Expand Up @@ -2585,7 +2599,7 @@ describe('html to snapshot', () => {
],
};

const htmlAdapter = new HtmlAdapter(createJob());
const htmlAdapter = new HtmlAdapter(createJob(), provider);
const rawBlockSnapshot = await htmlAdapter.toBlockSnapshot({
file: html,
});
Expand Down
6 changes: 5 additions & 1 deletion blocksuite/blocks/src/_common/adapters/extension.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { ExtensionType } from '@blocksuite/block-std';

import { AttachmentAdapterFactoryExtension } from './attachment.js';
import { HtmlAdapterFactoryExtension } from './html-adapter/html.js';
import { htmlInlineToDeltaMatchers } from './html/delta-converter/html-inline.js';
import { inlineDeltaToHtmlAdapterMatchers } from './html/delta-converter/inline-delta.js';
import { HtmlAdapterFactoryExtension } from './html/html.js';
import { ImageAdapterFactoryExtension } from './image.js';
import { MarkdownAdapterFactoryExtension } from './markdown/markdown.js';
import { MixTextAdapterFactoryExtension } from './mix-text.js';
Expand All @@ -10,6 +12,8 @@ import { NotionTextAdapterFactoryExtension } from './notion-text.js';
import { PlainTextAdapterFactoryExtension } from './plain-text/plain-text.js';

export const AdapterFactoryExtensions: ExtensionType[] = [
...htmlInlineToDeltaMatchers,
...inlineDeltaToHtmlAdapterMatchers,
AttachmentAdapterFactoryExtension,
ImageAdapterFactoryExtension,
MarkdownAdapterFactoryExtension,
Expand Down

This file was deleted.

34 changes: 34 additions & 0 deletions blocksuite/blocks/src/_common/adapters/html/block-matcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
EmbedFigmaBlockHtmlAdapterExtension,
EmbedGithubBlockHtmlAdapterExtension,
EmbedLinkedDocHtmlAdapterExtension,
EmbedLoomBlockHtmlAdapterExtension,
EmbedSyncedDocBlockHtmlAdapterExtension,
EmbedYoutubeBlockHtmlAdapterExtension,
} from '@blocksuite/affine-block-embed';
import { ListBlockHtmlAdapterExtension } from '@blocksuite/affine-block-list';
import { ParagraphBlockHtmlAdapterExtension } from '@blocksuite/affine-block-paragraph';

import { BookmarkBlockHtmlAdapterExtension } from '../../../bookmark-block/adapters/html.js';
import { CodeBlockHtmlAdapterExtension } from '../../../code-block/adapters/html.js';
import { DatabaseBlockHtmlAdapterExtension } from '../../../database-block/adapters/html.js';
import { DividerBlockHtmlAdapterExtension } from '../../../divider-block/adapters/html.js';
import { ImageBlockHtmlAdapterExtension } from '../../../image-block/adapters/html.js';
import { RootBlockHtmlAdapterExtension } from '../../../root-block/adapters/html.js';

export const defaultBlockHtmlAdapterMatchers = [
ListBlockHtmlAdapterExtension,
ParagraphBlockHtmlAdapterExtension,
CodeBlockHtmlAdapterExtension,
DividerBlockHtmlAdapterExtension,
ImageBlockHtmlAdapterExtension,
RootBlockHtmlAdapterExtension,
EmbedYoutubeBlockHtmlAdapterExtension,
EmbedFigmaBlockHtmlAdapterExtension,
EmbedLoomBlockHtmlAdapterExtension,
EmbedGithubBlockHtmlAdapterExtension,
BookmarkBlockHtmlAdapterExtension,
DatabaseBlockHtmlAdapterExtension,
EmbedLinkedDocHtmlAdapterExtension,
EmbedSyncedDocBlockHtmlAdapterExtension,
];
Loading

0 comments on commit 50ff365

Please sign in to comment.