test/node_modules/@mdit-vue/plugin-component/dist/index.mjs
2024-08-13 09:27:52 +08:00

306 lines
7.0 KiB
JavaScript

const attr_name = "[a-zA-Z_:@][a-zA-Z0-9:._-]*";
const unquoted = "[^\"'=<>`\\x00-\\x20]+";
const single_quoted = "'[^']*'";
const double_quoted = '"[^"]*"';
const attr_value = "(?:" + unquoted + "|" + single_quoted + "|" + double_quoted + ")";
const attribute = "(?:\\s+" + attr_name + "(?:\\s*=\\s*" + attr_value + ")?)";
const open_tag = "<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/?>";
const close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>";
const comment = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->";
const processing = "<[?][\\s\\S]*?[?]>";
const declaration = "<![A-Z]+\\s+[^>]*>";
const cdata = "<!\\[CDATA\\[[\\s\\S]*?\\]\\]>";
const HTML_TAG_RE = new RegExp(
"^(?:" + open_tag + "|" + close_tag + "|" + comment + "|" + processing + "|" + declaration + "|" + cdata + ")"
);
const HTML_OPEN_CLOSE_TAG_RE = new RegExp(
"^(?:" + open_tag + "|" + close_tag + ")"
);
const HTML_SELF_CLOSING_TAG_RE = new RegExp(
"^<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/>"
);
const HTML_OPEN_AND_CLOSE_TAG_IN_THE_SAME_LINE_RE = new RegExp(
"^<([A-Za-z][A-Za-z0-9\\-]*)" + attribute + "*\\s*>.*<\\/\\1\\s*>"
);
const TAGS_BLOCK = [
"address",
"article",
"aside",
"base",
"basefont",
"blockquote",
"body",
"caption",
"center",
"col",
"colgroup",
"dd",
"details",
"dialog",
"dir",
"div",
"dl",
"dt",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"frame",
"frameset",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"head",
"header",
"hr",
"html",
"iframe",
"legend",
"li",
"link",
"main",
"menu",
"menuitem",
"nav",
"noframes",
"ol",
"optgroup",
"option",
"p",
"param",
"search",
"section",
"summary",
"table",
"tbody",
"td",
"tfoot",
"th",
"thead",
"title",
"tr",
"track",
"ul"
];
const TAGS_INLINE = [
"a",
"abbr",
"acronym",
"audio",
"b",
"bdi",
"bdo",
"big",
"br",
"button",
"canvas",
"cite",
"code",
"data",
"datalist",
"del",
"dfn",
"em",
"embed",
"i",
"iframe",
"img",
"input",
"ins",
"kbd",
"label",
"map",
"mark",
"meter",
"noscript",
"object",
"output",
"picture",
"progress",
"q",
"ruby",
"s",
"samp",
"script",
"select",
"slot",
"small",
"span",
"strong",
"sub",
"sup",
"svg",
"template",
"textarea",
"time",
"u",
"tt",
"var",
"video",
"wbr"
];
const TAGS_VUE_RESERVED = [
"template",
"component",
"transition",
"transition-group",
"keep-alive",
"slot",
"teleport"
];
const createHtmlSequences = ({
blockTags,
inlineTags
}) => {
const forceBlockTags = [...blockTags, ...TAGS_BLOCK];
const forceInlineTags = [
...inlineTags,
...TAGS_INLINE.filter((item) => !TAGS_VUE_RESERVED.includes(item))
];
const HTML_SEQUENCES = [
[/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
[/^<!--/, /-->/, true],
[/^<\?/, /\?>/, true],
[/^<![A-Z]/, />/, true],
[/^<!\[CDATA\[/, /\]\]>/, true],
// MODIFIED: Support extra block tags from user options
[
new RegExp("^</?(" + forceBlockTags.join("|") + ")(?=(\\s|/?>|$))", "i"),
/^$/,
true
],
// ADDED: Matching component tags (all unknown tags) (i = 6)
[
new RegExp(
"^</?(?!(" + forceInlineTags.join("|") + ")(?![\\w-]))[A-Za-z][A-Za-z0-9\\-]*(?=(\\s|/?>|$))"
),
/^$/,
true
],
// this line is to treat a line that only have a single self-closed html tag
// as html_block, even if it's a self-closed inline tag
// MODIFIED: Tweak the original HTML_OPEN_CLOSE_TAG_RE
[new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + "\\s*$"), /^$/, false]
];
return HTML_SEQUENCES;
};
const createHtmlBlockRule = (options) => {
const HTML_SEQUENCES = createHtmlSequences(options);
return (state, startLine, endLine, silent) => {
let i;
let nextLine;
let lineText;
let pos = state.bMarks[startLine] + state.tShift[startLine];
let max = state.eMarks[startLine];
if (state.sCount[startLine] - state.blkIndent >= 4) {
return false;
}
if (!state.md.options.html) {
return false;
}
if (state.src.charCodeAt(pos) !== 60) {
return false;
}
lineText = state.src.slice(pos, max);
for (i = 0; i < HTML_SEQUENCES.length; i++) {
if (HTML_SEQUENCES[i][0].test(lineText)) {
break;
}
}
if (i === HTML_SEQUENCES.length) {
return false;
}
if (silent) {
return HTML_SEQUENCES[i][2];
}
if (i === 6) {
const match = (
// if the component tag is self-closing
lineText.match(HTML_SELF_CLOSING_TAG_RE) ?? // or has open and close tag in the same line
lineText.match(HTML_OPEN_AND_CLOSE_TAG_IN_THE_SAME_LINE_RE)
);
if (match) {
state.line = startLine + 1;
let token2 = state.push("html_inline", "", 0);
token2.content = match[0];
token2.map = [startLine, state.line];
token2 = state.push("inline", "", 0);
token2.content = lineText.slice(match[0].length);
token2.map = [startLine, state.line];
token2.children = [];
return true;
}
}
nextLine = startLine + 1;
if (!HTML_SEQUENCES[i][1].test(lineText)) {
for (; nextLine < endLine; nextLine++) {
if (state.sCount[nextLine] < state.blkIndent) {
break;
}
pos = state.bMarks[nextLine] + state.tShift[nextLine];
max = state.eMarks[nextLine];
lineText = state.src.slice(pos, max);
if (HTML_SEQUENCES[i][1].test(lineText)) {
if (lineText.length !== 0) {
nextLine++;
}
break;
}
}
}
state.line = nextLine;
const token = state.push("html_block", "", 0);
token.map = [startLine, nextLine];
token.content = state.getLines(startLine, nextLine, state.blkIndent, true);
return true;
};
};
const isLetter = (ch) => {
const lc = ch | 32;
return lc >= 97 && lc <= 122;
};
const htmlInlineRule = (state, silent) => {
const { pos } = state;
if (!state.md.options.html) {
return false;
}
const max = state.posMax;
if (state.src.charCodeAt(pos) !== 60 || pos + 2 >= max) {
return false;
}
const ch = state.src.charCodeAt(pos + 1);
if (ch !== 33 && ch !== 63 && ch !== 47 && !isLetter(ch)) {
return false;
}
const match = state.src.slice(pos).match(HTML_TAG_RE);
if (!match) {
return false;
}
if (!silent) {
const token = state.push("html_inline", "", 0);
token.content = state.src.slice(pos, pos + match[0].length);
}
state.pos += match[0].length;
return true;
};
const componentPlugin = (md, { blockTags = [], inlineTags = [] } = {}) => {
const htmlBlockRule = createHtmlBlockRule({
blockTags,
inlineTags
});
md.block.ruler.at("html_block", htmlBlockRule, {
alt: ["paragraph", "reference", "blockquote"]
});
md.inline.ruler.at("html_inline", htmlInlineRule);
};
export { HTML_OPEN_AND_CLOSE_TAG_IN_THE_SAME_LINE_RE, HTML_OPEN_CLOSE_TAG_RE, HTML_SELF_CLOSING_TAG_RE, HTML_TAG_RE, TAGS_BLOCK, TAGS_INLINE, TAGS_VUE_RESERVED, componentPlugin, createHtmlBlockRule, htmlInlineRule };