mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-18 18:46:19 +08:00
fix(editor): notion html adapter for embed link block (#9279)
[BS-1745](https://linear.app/affine-design/issue/BS-1745/[bug]-导入的notion-youtube-embed-错误)
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
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;
|
||||
|
||||
if (!embededURL || typeof embededURL !== 'string') {
|
||||
return false;
|
||||
}
|
||||
// To avoid polynomial regular expression used on uncontrolled data
|
||||
// https://codeql.github.com/codeql-query-help/javascript/js-polynomial-redos/
|
||||
if (embededURL.length > 1000) {
|
||||
return false;
|
||||
}
|
||||
return urlRegex.test(embededURL);
|
||||
},
|
||||
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,
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './html.js';
|
||||
export * from './markdown.js';
|
||||
export * from './notion-html.js';
|
||||
export * from './plain-text.js';
|
||||
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './html.js';
|
||||
export * from './markdown.js';
|
||||
export * from './notion-html.js';
|
||||
export * from './plain-text.js';
|
||||
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './html.js';
|
||||
export * from './markdown.js';
|
||||
export * from './notion-html.js';
|
||||
export * from './plain-text.js';
|
||||
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './html.js';
|
||||
export * from './markdown.js';
|
||||
export * from './notion-html.js';
|
||||
export * from './plain-text.js';
|
||||
|
||||
@@ -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);
|
||||
@@ -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';
|
||||
@@ -21,6 +27,10 @@ export const defaultBlockNotionHtmlAdapterMatchers: BlockNotionHtmlAdapterMatche
|
||||
rootBlockNotionHtmlAdapterMatcher,
|
||||
bookmarkBlockNotionHtmlAdapterMatcher,
|
||||
databaseBlockNotionHtmlAdapterMatcher,
|
||||
attachmentBlockNotionHtmlAdapterMatcher,
|
||||
latexBlockNotionHtmlAdapterMatcher,
|
||||
embedYoutubeBlockNotionHtmlAdapterMatcher,
|
||||
embedFigmaBlockNotionHtmlAdapterMatcher,
|
||||
embedGithubBlockNotionHtmlAdapterMatcher,
|
||||
embedLoomBlockNotionHtmlAdapterMatcher,
|
||||
attachmentBlockNotionHtmlAdapterMatcher,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user