mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-21 12:06:35 +08:00
62b930f336
[BS-1745](https://linear.app/affine-design/issue/BS-1745/[bug]-导入的notion-youtube-embed-错误)
90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
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,
|
|
};
|
|
}
|