Skip to content

Commit

Permalink
fix(blocksuite): notion html adapter embed link support
Browse files Browse the repository at this point in the history
  • Loading branch information
donteatfriedrice committed Dec 20, 2024
1 parent cf3cf0e commit 794a3e9
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 1 deletion.
84 changes: 84 additions & 0 deletions blocksuite/affine/block-embed/src/common/adapters/notion-html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {
type BlockNotionHtmlAdapterMatcher,
HastUtils,
} from '@blocksuite/affine-shared/adapters';
import { nanoid } from '@blocksuite/store';

export function createEmbedBlockNotionHtmlAdapterMatcher(
flavour: string,
urlRegex: RegExp,
{
toMatch = o => {
const isFigure =
HastUtils.isElement(o.node) && o.node.tagName === 'figure';
const embededFigureWrapper = HastUtils.querySelector(o.node, '.source');
if (!isFigure || !embededFigureWrapper) {
return false;
}
const embededURL = HastUtils.querySelector(embededFigureWrapper, 'a')
?.properties.href;
return (
!!embededURL &&
typeof embededURL === 'string' &&
urlRegex.test(embededURL)

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with 'youtube' and with many repetitions of 'a'.
);
},
fromMatch = o => o.node.flavour === flavour,
toBlockSnapshot = {
enter: (o, context) => {
if (!HastUtils.isElement(o.node)) {
return;
}
const { assets, walkerContext } = context;
if (!assets) {
return;
}

const embededFigureWrapper = HastUtils.querySelector(o.node, '.source');
if (!embededFigureWrapper) {
return;
}

let embededURL = '';
const embedA = HastUtils.querySelector(embededFigureWrapper, 'a');
embededURL =
typeof embedA?.properties.href === 'string'
? embedA.properties.href
: '';
if (!embededURL) {
return;
}

walkerContext
.openNode(
{
type: 'block',
id: nanoid(),
flavour,
props: {
url: embededURL,
},
children: [],
},
'children'
)
.closeNode();
walkerContext.skipAllChildren();
},
},
fromBlockSnapshot = {},
}: {
toMatch?: BlockNotionHtmlAdapterMatcher['toMatch'];
fromMatch?: BlockNotionHtmlAdapterMatcher['fromMatch'];
toBlockSnapshot?: BlockNotionHtmlAdapterMatcher['toBlockSnapshot'];
fromBlockSnapshot?: BlockNotionHtmlAdapterMatcher['fromBlockSnapshot'];
} = Object.create(null)
): BlockNotionHtmlAdapterMatcher {
return {
flavour,
toMatch,
fromMatch,
toBlockSnapshot,
fromBlockSnapshot,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type { ExtensionType } from '@blocksuite/block-std';

import { EmbedFigmaBlockHtmlAdapterExtension } from './html.js';
import { EmbedFigmaMarkdownAdapterExtension } from './markdown.js';
import { EmbedFigmaNotionHtmlAdapterExtension } from './notion-html.js';
import { EmbedFigmaBlockPlainTextAdapterExtension } from './plain-text.js';

export const EmbedFigmaBlockAdapterExtensions: ExtensionType[] = [
EmbedFigmaBlockHtmlAdapterExtension,
EmbedFigmaMarkdownAdapterExtension,
EmbedFigmaBlockPlainTextAdapterExtension,
EmbedFigmaNotionHtmlAdapterExtension,
];
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './html.js';
export * from './markdown.js';
export * from './notion-html.js';
export * from './plain-text.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { EmbedFigmaBlockSchema } from '@blocksuite/affine-model';
import { BlockNotionHtmlAdapterExtension } from '@blocksuite/affine-shared/adapters';

import { createEmbedBlockNotionHtmlAdapterMatcher } from '../../common/adapters/notion-html.js';
import { figmaUrlRegex } from '../embed-figma-model.js';

export const embedFigmaBlockNotionHtmlAdapterMatcher =
createEmbedBlockNotionHtmlAdapterMatcher(
EmbedFigmaBlockSchema.model.flavour,
figmaUrlRegex
);

export const EmbedFigmaNotionHtmlAdapterExtension =
BlockNotionHtmlAdapterExtension(embedFigmaBlockNotionHtmlAdapterMatcher);
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type { ExtensionType } from '@blocksuite/block-std';

import { EmbedGithubBlockHtmlAdapterExtension } from './html.js';
import { EmbedGithubMarkdownAdapterExtension } from './markdown.js';
import { EmbedGithubNotionHtmlAdapterExtension } from './notion-html.js';
import { EmbedGithubBlockPlainTextAdapterExtension } from './plain-text.js';

export const EmbedGithubBlockAdapterExtensions: ExtensionType[] = [
EmbedGithubBlockHtmlAdapterExtension,
EmbedGithubMarkdownAdapterExtension,
EmbedGithubBlockPlainTextAdapterExtension,
EmbedGithubNotionHtmlAdapterExtension,
];
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './html.js';
export * from './markdown.js';
export * from './notion-html.js';
export * from './plain-text.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { EmbedGithubBlockSchema } from '@blocksuite/affine-model';
import { BlockNotionHtmlAdapterExtension } from '@blocksuite/affine-shared/adapters';

import { createEmbedBlockNotionHtmlAdapterMatcher } from '../../common/adapters/notion-html.js';
import { githubUrlRegex } from '../embed-github-model.js';

export const embedGithubBlockNotionHtmlAdapterMatcher =
createEmbedBlockNotionHtmlAdapterMatcher(
EmbedGithubBlockSchema.model.flavour,
githubUrlRegex
);

export const EmbedGithubNotionHtmlAdapterExtension =
BlockNotionHtmlAdapterExtension(embedGithubBlockNotionHtmlAdapterMatcher);
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type { ExtensionType } from '@blocksuite/block-std';

import { EmbedLoomBlockHtmlAdapterExtension } from './html.js';
import { EmbedLoomMarkdownAdapterExtension } from './markdown.js';
import { EmbedLoomNotionHtmlAdapterExtension } from './notion-html.js';
import { EmbedLoomBlockPlainTextAdapterExtension } from './plain-text.js';

export const EmbedLoomBlockAdapterExtensions: ExtensionType[] = [
EmbedLoomBlockHtmlAdapterExtension,
EmbedLoomMarkdownAdapterExtension,
EmbedLoomBlockPlainTextAdapterExtension,
EmbedLoomNotionHtmlAdapterExtension,
];
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './html.js';
export * from './markdown.js';
export * from './notion-html.js';
export * from './plain-text.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { EmbedLoomBlockSchema } from '@blocksuite/affine-model';
import { BlockNotionHtmlAdapterExtension } from '@blocksuite/affine-shared/adapters';

import { createEmbedBlockNotionHtmlAdapterMatcher } from '../../common/adapters/notion-html.js';
import { loomUrlRegex } from '../embed-loom-model.js';

export const embedLoomBlockNotionHtmlAdapterMatcher =
createEmbedBlockNotionHtmlAdapterMatcher(
EmbedLoomBlockSchema.model.flavour,
loomUrlRegex
);

export const EmbedLoomNotionHtmlAdapterExtension =
BlockNotionHtmlAdapterExtension(embedLoomBlockNotionHtmlAdapterMatcher);
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type { ExtensionType } from '@blocksuite/block-std';

import { EmbedYoutubeBlockHtmlAdapterExtension } from './html.js';
import { EmbedYoutubeMarkdownAdapterExtension } from './markdown.js';
import { EmbedYoutubeNotionHtmlAdapterExtension } from './notion-html.js';
import { EmbedYoutubeBlockPlainTextAdapterExtension } from './plain-text.js';

export const EmbedYoutubeBlockAdapterExtensions: ExtensionType[] = [
EmbedYoutubeBlockHtmlAdapterExtension,
EmbedYoutubeMarkdownAdapterExtension,
EmbedYoutubeBlockPlainTextAdapterExtension,
EmbedYoutubeNotionHtmlAdapterExtension,
];
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './html.js';
export * from './markdown.js';
export * from './notion-html.js';
export * from './plain-text.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { EmbedYoutubeBlockSchema } from '@blocksuite/affine-model';
import { BlockNotionHtmlAdapterExtension } from '@blocksuite/affine-shared/adapters';

import { createEmbedBlockNotionHtmlAdapterMatcher } from '../../common/adapters/notion-html.js';
import { youtubeUrlRegex } from '../embed-youtube-model.js';

export const embedYoutubeBlockNotionHtmlAdapterMatcher =
createEmbedBlockNotionHtmlAdapterMatcher(
EmbedYoutubeBlockSchema.model.flavour,
youtubeUrlRegex
);

export const EmbedYoutubeNotionHtmlAdapterExtension =
BlockNotionHtmlAdapterExtension(embedYoutubeBlockNotionHtmlAdapterMatcher);
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
embedFigmaBlockNotionHtmlAdapterMatcher,
embedGithubBlockNotionHtmlAdapterMatcher,
embedLoomBlockNotionHtmlAdapterMatcher,
embedYoutubeBlockNotionHtmlAdapterMatcher,
} from '@blocksuite/affine-block-embed';
import { listBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-list';
import { paragraphBlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-block-paragraph';
import type { BlockNotionHtmlAdapterMatcher } from '@blocksuite/affine-shared/adapters';
Expand All @@ -21,6 +27,10 @@ export const defaultBlockNotionHtmlAdapterMatchers: BlockNotionHtmlAdapterMatche
rootBlockNotionHtmlAdapterMatcher,
bookmarkBlockNotionHtmlAdapterMatcher,
databaseBlockNotionHtmlAdapterMatcher,
attachmentBlockNotionHtmlAdapterMatcher,
latexBlockNotionHtmlAdapterMatcher,
embedYoutubeBlockNotionHtmlAdapterMatcher,
embedFigmaBlockNotionHtmlAdapterMatcher,
embedGithubBlockNotionHtmlAdapterMatcher,
embedLoomBlockNotionHtmlAdapterMatcher,
attachmentBlockNotionHtmlAdapterMatcher,
];

0 comments on commit 794a3e9

Please sign in to comment.