357 lines
21 KiB
JavaScript
357 lines
21 KiB
JavaScript
import { ContextTracker, ExternalTokenizer, LRParser } from '@lezer/lr';
|
|
import { styleTags, tags } from '@lezer/highlight';
|
|
import { parseMixed } from '@lezer/common';
|
|
|
|
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
|
const scriptText = 54,
|
|
StartCloseScriptTag = 1,
|
|
styleText = 55,
|
|
StartCloseStyleTag = 2,
|
|
textareaText = 56,
|
|
StartCloseTextareaTag = 3,
|
|
EndTag = 4,
|
|
SelfClosingEndTag = 5,
|
|
StartTag = 6,
|
|
StartScriptTag = 7,
|
|
StartStyleTag = 8,
|
|
StartTextareaTag = 9,
|
|
StartSelfClosingTag = 10,
|
|
StartCloseTag = 11,
|
|
NoMatchStartCloseTag = 12,
|
|
MismatchedStartCloseTag = 13,
|
|
missingCloseTag = 57,
|
|
IncompleteCloseTag = 14,
|
|
commentContent$1 = 58,
|
|
Element = 20,
|
|
TagName = 22,
|
|
Attribute = 23,
|
|
AttributeName = 24,
|
|
AttributeValue = 26,
|
|
UnquotedAttributeValue = 27,
|
|
ScriptText = 28,
|
|
StyleText = 31,
|
|
TextareaText = 34,
|
|
OpenTag = 36,
|
|
CloseTag = 37,
|
|
Dialect_noMatch = 0,
|
|
Dialect_selfClosing = 1;
|
|
|
|
/* Hand-written tokenizers for HTML. */
|
|
|
|
const selfClosers = {
|
|
area: true, base: true, br: true, col: true, command: true,
|
|
embed: true, frame: true, hr: true, img: true, input: true,
|
|
keygen: true, link: true, meta: true, param: true, source: true,
|
|
track: true, wbr: true, menuitem: true
|
|
};
|
|
|
|
const implicitlyClosed = {
|
|
dd: true, li: true, optgroup: true, option: true, p: true,
|
|
rp: true, rt: true, tbody: true, td: true, tfoot: true,
|
|
th: true, tr: true
|
|
};
|
|
|
|
const closeOnOpen = {
|
|
dd: {dd: true, dt: true},
|
|
dt: {dd: true, dt: true},
|
|
li: {li: true},
|
|
option: {option: true, optgroup: true},
|
|
optgroup: {optgroup: true},
|
|
p: {
|
|
address: true, article: true, aside: true, blockquote: true, dir: true,
|
|
div: true, dl: true, fieldset: true, footer: true, form: true,
|
|
h1: true, h2: true, h3: true, h4: true, h5: true, h6: true,
|
|
header: true, hgroup: true, hr: true, menu: true, nav: true, ol: true,
|
|
p: true, pre: true, section: true, table: true, ul: true
|
|
},
|
|
rp: {rp: true, rt: true},
|
|
rt: {rp: true, rt: true},
|
|
tbody: {tbody: true, tfoot: true},
|
|
td: {td: true, th: true},
|
|
tfoot: {tbody: true},
|
|
th: {td: true, th: true},
|
|
thead: {tbody: true, tfoot: true},
|
|
tr: {tr: true}
|
|
};
|
|
|
|
function nameChar(ch) {
|
|
return ch == 45 || ch == 46 || ch == 58 || ch >= 65 && ch <= 90 || ch == 95 || ch >= 97 && ch <= 122 || ch >= 161
|
|
}
|
|
|
|
function isSpace(ch) {
|
|
return ch == 9 || ch == 10 || ch == 13 || ch == 32
|
|
}
|
|
|
|
let cachedName = null, cachedInput = null, cachedPos = 0;
|
|
function tagNameAfter(input, offset) {
|
|
let pos = input.pos + offset;
|
|
if (cachedPos == pos && cachedInput == input) return cachedName
|
|
let next = input.peek(offset);
|
|
while (isSpace(next)) next = input.peek(++offset);
|
|
let name = "";
|
|
for (;;) {
|
|
if (!nameChar(next)) break
|
|
name += String.fromCharCode(next);
|
|
next = input.peek(++offset);
|
|
}
|
|
// Undefined to signal there's a <? or <!, null for just missing
|
|
cachedInput = input; cachedPos = pos;
|
|
return cachedName = name ? name.toLowerCase() : next == question || next == bang ? undefined : null
|
|
}
|
|
|
|
const lessThan = 60, greaterThan = 62, slash = 47, question = 63, bang = 33, dash = 45;
|
|
|
|
function ElementContext(name, parent) {
|
|
this.name = name;
|
|
this.parent = parent;
|
|
this.hash = parent ? parent.hash : 0;
|
|
for (let i = 0; i < name.length; i++) this.hash += (this.hash << 4) + name.charCodeAt(i) + (name.charCodeAt(i) << 8);
|
|
}
|
|
|
|
const startTagTerms = [StartTag, StartSelfClosingTag, StartScriptTag, StartStyleTag, StartTextareaTag];
|
|
|
|
const elementContext = new ContextTracker({
|
|
start: null,
|
|
shift(context, term, stack, input) {
|
|
return startTagTerms.indexOf(term) > -1 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context
|
|
},
|
|
reduce(context, term) {
|
|
return term == Element && context ? context.parent : context
|
|
},
|
|
reuse(context, node, stack, input) {
|
|
let type = node.type.id;
|
|
return type == StartTag || type == OpenTag
|
|
? new ElementContext(tagNameAfter(input, 1) || "", context) : context
|
|
},
|
|
hash(context) { return context ? context.hash : 0 },
|
|
strict: false
|
|
});
|
|
|
|
const tagStart = new ExternalTokenizer((input, stack) => {
|
|
if (input.next != lessThan) {
|
|
// End of file, close any open tags
|
|
if (input.next < 0 && stack.context) input.acceptToken(missingCloseTag);
|
|
return
|
|
}
|
|
input.advance();
|
|
let close = input.next == slash;
|
|
if (close) input.advance();
|
|
let name = tagNameAfter(input, 0);
|
|
if (name === undefined) return
|
|
if (!name) return input.acceptToken(close ? IncompleteCloseTag : StartTag)
|
|
|
|
let parent = stack.context ? stack.context.name : null;
|
|
if (close) {
|
|
if (name == parent) return input.acceptToken(StartCloseTag)
|
|
if (parent && implicitlyClosed[parent]) return input.acceptToken(missingCloseTag, -2)
|
|
if (stack.dialectEnabled(Dialect_noMatch)) return input.acceptToken(NoMatchStartCloseTag)
|
|
for (let cx = stack.context; cx; cx = cx.parent) if (cx.name == name) return
|
|
input.acceptToken(MismatchedStartCloseTag);
|
|
} else {
|
|
if (name == "script") return input.acceptToken(StartScriptTag)
|
|
if (name == "style") return input.acceptToken(StartStyleTag)
|
|
if (name == "textarea") return input.acceptToken(StartTextareaTag)
|
|
if (selfClosers.hasOwnProperty(name)) return input.acceptToken(StartSelfClosingTag)
|
|
if (parent && closeOnOpen[parent] && closeOnOpen[parent][name]) input.acceptToken(missingCloseTag, -1);
|
|
else input.acceptToken(StartTag);
|
|
}
|
|
}, {contextual: true});
|
|
|
|
const commentContent = new ExternalTokenizer(input => {
|
|
for (let dashes = 0, i = 0;; i++) {
|
|
if (input.next < 0) {
|
|
if (i) input.acceptToken(commentContent$1);
|
|
break
|
|
}
|
|
if (input.next == dash) {
|
|
dashes++;
|
|
} else if (input.next == greaterThan && dashes >= 2) {
|
|
if (i > 3) input.acceptToken(commentContent$1, -2);
|
|
break
|
|
} else {
|
|
dashes = 0;
|
|
}
|
|
input.advance();
|
|
}
|
|
});
|
|
|
|
function inForeignElement(context) {
|
|
for (; context; context = context.parent)
|
|
if (context.name == "svg" || context.name == "math") return true
|
|
return false
|
|
}
|
|
|
|
const endTag = new ExternalTokenizer((input, stack) => {
|
|
if (input.next == slash && input.peek(1) == greaterThan) {
|
|
let selfClosing = stack.dialectEnabled(Dialect_selfClosing) || inForeignElement(stack.context);
|
|
input.acceptToken(selfClosing ? SelfClosingEndTag : EndTag, 2);
|
|
} else if (input.next == greaterThan) {
|
|
input.acceptToken(EndTag, 1);
|
|
}
|
|
});
|
|
|
|
function contentTokenizer(tag, textToken, endToken) {
|
|
let lastState = 2 + tag.length;
|
|
return new ExternalTokenizer(input => {
|
|
// state means:
|
|
// - 0 nothing matched
|
|
// - 1 '<' matched
|
|
// - 2 '</' + possibly whitespace matched
|
|
// - 3-(1+tag.length) part of the tag matched
|
|
// - lastState whole tag + possibly whitespace matched
|
|
for (let state = 0, matchedLen = 0, i = 0;; i++) {
|
|
if (input.next < 0) {
|
|
if (i) input.acceptToken(textToken);
|
|
break
|
|
}
|
|
if (state == 0 && input.next == lessThan ||
|
|
state == 1 && input.next == slash ||
|
|
state >= 2 && state < lastState && input.next == tag.charCodeAt(state - 2)) {
|
|
state++;
|
|
matchedLen++;
|
|
} else if ((state == 2 || state == lastState) && isSpace(input.next)) {
|
|
matchedLen++;
|
|
} else if (state == lastState && input.next == greaterThan) {
|
|
if (i > matchedLen)
|
|
input.acceptToken(textToken, -matchedLen);
|
|
else
|
|
input.acceptToken(endToken, -(matchedLen - 2));
|
|
break
|
|
} else if ((input.next == 10 /* '\n' */ || input.next == 13 /* '\r' */) && i) {
|
|
input.acceptToken(textToken, 1);
|
|
break
|
|
} else {
|
|
state = matchedLen = 0;
|
|
}
|
|
input.advance();
|
|
}
|
|
})
|
|
}
|
|
|
|
const scriptTokens = contentTokenizer("script", scriptText, StartCloseScriptTag);
|
|
|
|
const styleTokens = contentTokenizer("style", styleText, StartCloseStyleTag);
|
|
|
|
const textareaTokens = contentTokenizer("textarea", textareaText, StartCloseTextareaTag);
|
|
|
|
const htmlHighlighting = styleTags({
|
|
"Text RawText": tags.content,
|
|
"StartTag StartCloseTag SelfClosingEndTag EndTag": tags.angleBracket,
|
|
TagName: tags.tagName,
|
|
"MismatchedCloseTag/TagName": [tags.tagName, tags.invalid],
|
|
AttributeName: tags.attributeName,
|
|
"AttributeValue UnquotedAttributeValue": tags.attributeValue,
|
|
Is: tags.definitionOperator,
|
|
"EntityReference CharacterReference": tags.character,
|
|
Comment: tags.blockComment,
|
|
ProcessingInst: tags.processingInstruction,
|
|
DoctypeDecl: tags.documentMeta
|
|
});
|
|
|
|
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
|
const parser = LRParser.deserialize({
|
|
version: 14,
|
|
states: ",xOVO!rOOO!WQ#tO'#CqO!]Q#tO'#CzO!bQ#tO'#C}O!gQ#tO'#DQO!lQ#tO'#DSO!qOaO'#CpO!|ObO'#CpO#XOdO'#CpO$eO!rO'#CpOOO`'#Cp'#CpO$lO$fO'#DTO$tQ#tO'#DVO$yQ#tO'#DWOOO`'#Dk'#DkOOO`'#DY'#DYQVO!rOOO%OQ&rO,59]O%WQ&rO,59fO%`Q&rO,59iO%hQ&rO,59lO%sQ&rO,59nOOOa'#D^'#D^O%{OaO'#CxO&WOaO,59[OOOb'#D_'#D_O&`ObO'#C{O&kObO,59[OOOd'#D`'#D`O&sOdO'#DOO'OOdO,59[OOO`'#Da'#DaO'WO!rO,59[O'_Q#tO'#DROOO`,59[,59[OOOp'#Db'#DbO'dO$fO,59oOOO`,59o,59oO'lQ#|O,59qO'qQ#|O,59rOOO`-E7W-E7WO'vQ&rO'#CsOOQW'#DZ'#DZO(UQ&rO1G.wOOOa1G.w1G.wO(^Q&rO1G/QOOOb1G/Q1G/QO(fQ&rO1G/TOOOd1G/T1G/TO(nQ&rO1G/WOOO`1G/W1G/WOOO`1G/Y1G/YO(yQ&rO1G/YOOOa-E7[-E7[O)RQ#tO'#CyOOO`1G.v1G.vOOOb-E7]-E7]O)WQ#tO'#C|OOOd-E7^-E7^O)]Q#tO'#DPOOO`-E7_-E7_O)bQ#|O,59mOOOp-E7`-E7`OOO`1G/Z1G/ZOOO`1G/]1G/]OOO`1G/^1G/^O)gQ,UO,59_OOQW-E7X-E7XOOOa7+$c7+$cOOOb7+$l7+$lOOOd7+$o7+$oOOO`7+$r7+$rOOO`7+$t7+$tO)rQ#|O,59eO)wQ#|O,59hO)|Q#|O,59kOOO`1G/X1G/XO*RO7[O'#CvO*dOMhO'#CvOOQW1G.y1G.yOOO`1G/P1G/POOO`1G/S1G/SOOO`1G/V1G/VOOOO'#D['#D[O*uO7[O,59bOOQW,59b,59bOOOO'#D]'#D]O+WOMhO,59bOOOO-E7Y-E7YOOQW1G.|1G.|OOOO-E7Z-E7Z",
|
|
stateData: "+s~O!^OS~OUSOVPOWQOXROYTO[]O][O^^O`^Oa^Ob^Oc^Ox^O{_O!dZO~OfaO~OfbO~OfcO~OfdO~OfeO~O!WfOPlP!ZlP~O!XiOQoP!ZoP~O!YlORrP!ZrP~OUSOVPOWQOXROYTOZqO[]O][O^^O`^Oa^Ob^Oc^Ox^O!dZO~O!ZrO~P#dO![sO!euO~OfvO~OfwO~OS|OhyO~OS!OOhyO~OS!QOhyO~OS!SOT!TOhyO~OS!TOhyO~O!WfOPlX!ZlX~OP!WO!Z!XO~O!XiOQoX!ZoX~OQ!ZO!Z!XO~O!YlORrX!ZrX~OR!]O!Z!XO~O!Z!XO~P#dOf!_O~O![sO!e!aO~OS!bO~OS!cO~Oi!dOSgXhgXTgX~OS!fOhyO~OS!gOhyO~OS!hOhyO~OS!iOT!jOhyO~OS!jOhyO~Of!kO~Of!lO~Of!mO~OS!nO~Ok!qO!`!oO!b!pO~OS!rO~OS!sO~OS!tO~Oa!uOb!uOc!uO!`!wO!a!uO~Oa!xOb!xOc!xO!b!wO!c!xO~Oa!uOb!uOc!uO!`!{O!a!uO~Oa!xOb!xOc!xO!b!{O!c!xO~OT~bac!dx{!d~",
|
|
goto: "%p!`PPPPPPPPPPPPPPPPPPPP!a!gP!mPP!yP!|#P#S#Y#]#`#f#i#l#r#x!aP!a!aP$O$U$l$r$x%O%U%[%bPPPPPPPP%hX^OX`pXUOX`pezabcde{}!P!R!UR!q!dRhUR!XhXVOX`pRkVR!XkXWOX`pRnWR!XnXXOX`pQrXR!XpXYOX`pQ`ORx`Q{aQ}bQ!PcQ!RdQ!UeZ!e{}!P!R!UQ!v!oR!z!vQ!y!pR!|!yQgUR!VgQjVR!YjQmWR![mQpXR!^pQtZR!`tS_O`ToXp",
|
|
nodeNames: "⚠ StartCloseTag StartCloseTag StartCloseTag EndTag SelfClosingEndTag StartTag StartTag StartTag StartTag StartTag StartCloseTag StartCloseTag StartCloseTag IncompleteCloseTag Document Text EntityReference CharacterReference InvalidEntity Element OpenTag TagName Attribute AttributeName Is AttributeValue UnquotedAttributeValue ScriptText CloseTag OpenTag StyleText CloseTag OpenTag TextareaText CloseTag OpenTag CloseTag SelfClosingTag Comment ProcessingInst MismatchedCloseTag CloseTag DoctypeDecl",
|
|
maxTerm: 67,
|
|
context: elementContext,
|
|
nodeProps: [
|
|
["closedBy", -10,1,2,3,7,8,9,10,11,12,13,"EndTag",6,"EndTag SelfClosingEndTag",-4,21,30,33,36,"CloseTag"],
|
|
["openedBy", 4,"StartTag StartCloseTag",5,"StartTag",-4,29,32,35,37,"OpenTag"],
|
|
["group", -9,14,17,18,19,20,39,40,41,42,"Entity",16,"Entity TextContent",-3,28,31,34,"TextContent Entity"]
|
|
],
|
|
propSources: [htmlHighlighting],
|
|
skippedNodes: [0],
|
|
repeatNodeCount: 9,
|
|
tokenData: "!<p!aR!YOX$qXY,QYZ,QZ[$q[]&X]^,Q^p$qpq,Qqr-_rs3_sv-_vw3}wxHYx}-_}!OH{!O!P-_!P!Q$q!Q![-_![!]Mz!]!^-_!^!_!$S!_!`!;x!`!a&X!a!c-_!c!}Mz!}#R-_#R#SMz#S#T1k#T#oMz#o#s-_#s$f$q$f%W-_%W%oMz%o%p-_%p&aMz&a&b-_&b1pMz1p4U-_4U4dMz4d4e-_4e$ISMz$IS$I`-_$I`$IbMz$Ib$Kh-_$Kh%#tMz%#t&/x-_&/x&EtMz&Et&FV-_&FV;'SMz;'S;:j!#|;:j;=`3X<%l?&r-_?&r?AhMz?Ah?BY$q?BY?MnMz?MnO$q!Z$|c`PkW!a`!cpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr$qrs&}sv$qvw+Pwx(tx!^$q!^!_*V!_!a&X!a#S$q#S#T&X#T;'S$q;'S;=`+z<%lO$q!R&bX`P!a`!cpOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&Xq'UV`P!cpOv&}wx'kx!^&}!^!_(V!_;'S&};'S;=`(n<%lO&}P'pT`POv'kw!^'k!_;'S'k;'S;=`(P<%lO'kP(SP;=`<%l'kp([S!cpOv(Vx;'S(V;'S;=`(h<%lO(Vp(kP;=`<%l(Vq(qP;=`<%l&}a({W`P!a`Or(trs'ksv(tw!^(t!^!_)e!_;'S(t;'S;=`*P<%lO(t`)jT!a`Or)esv)ew;'S)e;'S;=`)y<%lO)e`)|P;=`<%l)ea*SP;=`<%l(t!Q*^V!a`!cpOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!Q*vP;=`<%l*V!R*|P;=`<%l&XW+UYkWOX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+PW+wP;=`<%l+P!Z+}P;=`<%l$q!a,]``P!a`!cp!^^OX&XXY,QYZ,QZ]&X]^,Q^p&Xpq,Qqr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X!_-ljhS`PkW!a`!cpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx!P-_!P!Q$q!Q!^-_!^!_*V!_!a&X!a#S-_#S#T1k#T#s-_#s$f$q$f;'S-_;'S;=`3X<%l?Ah-_?Ah?BY$q?BY?Mn-_?MnO$q[/ebhSkWOX+PZ[+P^p+Pqr/^sw/^x!P/^!P!Q+P!Q!^/^!a#S/^#S#T0m#T#s/^#s$f+P$f;'S/^;'S;=`1e<%l?Ah/^?Ah?BY+P?BY?Mn/^?MnO+PS0rXhSqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0mS1bP;=`<%l0m[1hP;=`<%l/^!V1vchS`P!a`!cpOq&Xqr1krs&}sv1kvw0mwx(tx!P1k!P!Q&X!Q!^1k!^!_*V!_!a&X!a#s1k#s$f&X$f;'S1k;'S;=`3R<%l?Ah1k?Ah?BY&X?BY?Mn1k?MnO&X!V3UP;=`<%l1k!_3[P;=`<%l-_!Z3hV!`h`P!cpOv&}wx'kx!^&}!^!_(V!_;'S&};'S;=`(n<%lO&}!_4WihSkWc!ROX5uXZ7SZ[5u[^7S^p5uqr8trs7Sst>]tw8twx7Sx!P8t!P!Q5u!Q!]8t!]!^/^!^!a7S!a#S8t#S#T;{#T#s8t#s$f5u$f;'S8t;'S;=`>V<%l?Ah8t?Ah?BY5u?BY?Mn8t?MnO5u!Z5zbkWOX5uXZ7SZ[5u[^7S^p5uqr5urs7Sst+Ptw5uwx7Sx!]5u!]!^7w!^!a7S!a#S5u#S#T7S#T;'S5u;'S;=`8n<%lO5u!R7VVOp7Sqs7St!]7S!]!^7l!^;'S7S;'S;=`7q<%lO7S!R7qOa!R!R7tP;=`<%l7S!Z8OYkWa!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!Z8qP;=`<%l5u!_8{ihSkWOX5uXZ7SZ[5u[^7S^p5uqr8trs7Sst/^tw8twx7Sx!P8t!P!Q5u!Q!]8t!]!^:j!^!a7S!a#S8t#S#T;{#T#s8t#s$f5u$f;'S8t;'S;=`>V<%l?Ah8t?Ah?BY5u?BY?Mn8t?MnO5u!_:sbhSkWa!ROX+PZ[+P^p+Pqr/^sw/^x!P/^!P!Q+P!Q!^/^!a#S/^#S#T0m#T#s/^#s$f+P$f;'S/^;'S;=`1e<%l?Ah/^?Ah?BY+P?BY?Mn/^?MnO+P!V<QchSOp7Sqr;{rs7Sst0mtw;{wx7Sx!P;{!P!Q7S!Q!];{!]!^=]!^!a7S!a#s;{#s$f7S$f;'S;{;'S;=`>P<%l?Ah;{?Ah?BY7S?BY?Mn;{?MnO7S!V=dXhSa!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!V>SP;=`<%l;{!_>YP;=`<%l8t!_>dhhSkWOX@OXZAYZ[@O[^AY^p@OqrBwrsAYswBwwxAYx!PBw!P!Q@O!Q!]Bw!]!^/^!^!aAY!a#SBw#S#TE{#T#sBw#s$f@O$f;'SBw;'S;=`HS<%l?AhBw?Ah?BY@O?BY?MnBw?MnO@O!Z@TakWOX@OXZAYZ[@O[^AY^p@Oqr@OrsAYsw@OwxAYx!]@O!]!^Az!^!aAY!a#S@O#S#TAY#T;'S@O;'S;=`Bq<%lO@O!RA]UOpAYq!]AY!]!^Ao!^;'SAY;'S;=`At<%lOAY!RAtOb!R!RAwP;=`<%lAY!ZBRYkWb!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!ZBtP;=`<%l@O!_COhhSkWOX@OXZAYZ[@O[^AY^p@OqrBwrsAYswBwwxAYx!PBw!P!Q@O!Q!]Bw!]!^Dj!^!aAY!a#SBw#S#TE{#T#sBw#s$f@O$f;'SBw;'S;=`HS<%l?AhBw?Ah?BY@O?BY?MnBw?MnO@O!_DsbhSkWb!ROX+PZ[+P^p+Pqr/^sw/^x!P/^!P!Q+P!Q!^/^!a#S/^#S#T0m#T#s/^#s$f+P$f;'S/^;'S;=`1e<%l?Ah/^?Ah?BY+P?BY?Mn/^?MnO+P!VFQbhSOpAYqrE{rsAYswE{wxAYx!PE{!P!QAY!Q!]E{!]!^GY!^!aAY!a#sE{#s$fAY$f;'SE{;'S;=`G|<%l?AhE{?Ah?BYAY?BY?MnE{?MnOAY!VGaXhSb!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!VHPP;=`<%lE{!_HVP;=`<%lBw!ZHcW!bx`P!a`Or(trs'ksv(tw!^(t!^!_)e!_;'S(t;'S;=`*P<%lO(t!aIYlhS`PkW!a`!cpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx}-_}!OKQ!O!P-_!P!Q$q!Q!^-_!^!_*V!_!a&X!a#S-_#S#T1k#T#s-_#s$f$q$f;'S-_;'S;=`3X<%l?Ah-_?Ah?BY$q?BY?Mn-_?MnO$q!aK_khS`PkW!a`!cpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx!P-_!P!Q$q!Q!^-_!^!_*V!_!`&X!`!aMS!a#S-_#S#T1k#T#s-_#s$f$q$f;'S-_;'S;=`3X<%l?Ah-_?Ah?BY$q?BY?Mn-_?MnO$q!TM_X`P!a`!cp!eQOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X!aNZ!ZhSfQ`PkW!a`!cpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx}-_}!OMz!O!PMz!P!Q$q!Q![Mz![!]Mz!]!^-_!^!_*V!_!a&X!a!c-_!c!}Mz!}#R-_#R#SMz#S#T1k#T#oMz#o#s-_#s$f$q$f$}-_$}%OMz%O%W-_%W%oMz%o%p-_%p&aMz&a&b-_&b1pMz1p4UMz4U4dMz4d4e-_4e$ISMz$IS$I`-_$I`$IbMz$Ib$Je-_$Je$JgMz$Jg$Kh-_$Kh%#tMz%#t&/x-_&/x&EtMz&Et&FV-_&FV;'SMz;'S;:j!#|;:j;=`3X<%l?&r-_?&r?AhMz?Ah?BY$q?BY?MnMz?MnO$q!a!$PP;=`<%lMz!R!$ZY!a`!cpOq*Vqr!$yrs(Vsv*Vwx)ex!a*V!a!b!4t!b;'S*V;'S;=`*s<%lO*V!R!%Q]!a`!cpOr*Vrs(Vsv*Vwx)ex}*V}!O!%y!O!f*V!f!g!']!g#W*V#W#X!0`#X;'S*V;'S;=`*s<%lO*V!R!&QX!a`!cpOr*Vrs(Vsv*Vwx)ex}*V}!O!&m!O;'S*V;'S;=`*s<%lO*V!R!&vV!a`!cp!dPOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!'dX!a`!cpOr*Vrs(Vsv*Vwx)ex!q*V!q!r!(P!r;'S*V;'S;=`*s<%lO*V!R!(WX!a`!cpOr*Vrs(Vsv*Vwx)ex!e*V!e!f!(s!f;'S*V;'S;=`*s<%lO*V!R!(zX!a`!cpOr*Vrs(Vsv*Vwx)ex!v*V!v!w!)g!w;'S*V;'S;=`*s<%lO*V!R!)nX!a`!cpOr*Vrs(Vsv*Vwx)ex!{*V!{!|!*Z!|;'S*V;'S;=`*s<%lO*V!R!*bX!a`!cpOr*Vrs(Vsv*Vwx)ex!r*V!r!s!*}!s;'S*V;'S;=`*s<%lO*V!R!+UX!a`!cpOr*Vrs(Vsv*Vwx)ex!g*V!g!h!+q!h;'S*V;'S;=`*s<%lO*V!R!+xY!a`!cpOr!+qrs!,hsv!+qvw!-Swx!.[x!`!+q!`!a!/j!a;'S!+q;'S;=`!0Y<%lO!+qq!,mV!cpOv!,hvx!-Sx!`!,h!`!a!-q!a;'S!,h;'S;=`!.U<%lO!,hP!-VTO!`!-S!`!a!-f!a;'S!-S;'S;=`!-k<%lO!-SP!-kO{PP!-nP;=`<%l!-Sq!-xS!cp{POv(Vx;'S(V;'S;=`(h<%lO(Vq!.XP;=`<%l!,ha!.aX!a`Or!.[rs!-Ssv!.[vw!-Sw!`!.[!`!a!.|!a;'S!.[;'S;=`!/d<%lO!.[a!/TT!a`{POr)esv)ew;'S)e;'S;=`)y<%lO)ea!/gP;=`<%l!.[!R!/sV!a`!cp{POr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!0]P;=`<%l!+q!R!0gX!a`!cpOr*Vrs(Vsv*Vwx)ex#c*V#c#d!1S#d;'S*V;'S;=`*s<%lO*V!R!1ZX!a`!cpOr*Vrs(Vsv*Vwx)ex#V*V#V#W!1v#W;'S*V;'S;=`*s<%lO*V!R!1}X!a`!cpOr*Vrs(Vsv*Vwx)ex#h*V#h#i!2j#i;'S*V;'S;=`*s<%lO*V!R!2qX!a`!cpOr*Vrs(Vsv*Vwx)ex#m*V#m#n!3^#n;'S*V;'S;=`*s<%lO*V!R!3eX!a`!cpOr*Vrs(Vsv*Vwx)ex#d*V#d#e!4Q#e;'S*V;'S;=`*s<%lO*V!R!4XX!a`!cpOr*Vrs(Vsv*Vwx)ex#X*V#X#Y!+q#Y;'S*V;'S;=`*s<%lO*V!R!4{Y!a`!cpOr!4trs!5ksv!4tvw!6Vwx!8]x!a!4t!a!b!:]!b;'S!4t;'S;=`!;r<%lO!4tq!5pV!cpOv!5kvx!6Vx!a!5k!a!b!7W!b;'S!5k;'S;=`!8V<%lO!5kP!6YTO!a!6V!a!b!6i!b;'S!6V;'S;=`!7Q<%lO!6VP!6lTO!`!6V!`!a!6{!a;'S!6V;'S;=`!7Q<%lO!6VP!7QOxPP!7TP;=`<%l!6Vq!7]V!cpOv!5kvx!6Vx!`!5k!`!a!7r!a;'S!5k;'S;=`!8V<%lO!5kq!7yS!cpxPOv(Vx;'S(V;'S;=`(h<%lO(Vq!8YP;=`<%l!5ka!8bX!a`Or!8]rs!6Vsv!8]vw!6Vw!a!8]!a!b!8}!b;'S!8];'S;=`!:V<%lO!8]a!9SX!a`Or!8]rs!6Vsv!8]vw!6Vw!`!8]!`!a!9o!a;'S!8];'S;=`!:V<%lO!8]a!9vT!a`xPOr)esv)ew;'S)e;'S;=`)y<%lO)ea!:YP;=`<%l!8]!R!:dY!a`!cpOr!4trs!5ksv!4tvw!6Vwx!8]x!`!4t!`!a!;S!a;'S!4t;'S;=`!;r<%lO!4t!R!;]V!a`!cpxPOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!;uP;=`<%l!4t!V!<TXiS`P!a`!cpOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X",
|
|
tokenizers: [scriptTokens, styleTokens, textareaTokens, endTag, tagStart, commentContent, 0, 1, 2, 3, 4, 5],
|
|
topRules: {"Document":[0,15]},
|
|
dialects: {noMatch: 0, selfClosing: 485},
|
|
tokenPrec: 487
|
|
});
|
|
|
|
function getAttrs(openTag, input) {
|
|
let attrs = Object.create(null);
|
|
for (let att of openTag.getChildren(Attribute)) {
|
|
let name = att.getChild(AttributeName), value = att.getChild(AttributeValue) || att.getChild(UnquotedAttributeValue);
|
|
if (name) attrs[input.read(name.from, name.to)] =
|
|
!value ? "" : value.type.id == AttributeValue ? input.read(value.from + 1, value.to - 1) : input.read(value.from, value.to);
|
|
}
|
|
return attrs
|
|
}
|
|
|
|
function findTagName(openTag, input) {
|
|
let tagNameNode = openTag.getChild(TagName);
|
|
return tagNameNode ? input.read(tagNameNode.from, tagNameNode.to) : " "
|
|
}
|
|
|
|
function maybeNest(node, input, tags) {
|
|
let attrs;
|
|
for (let tag of tags) {
|
|
if (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(node.node.parent.firstChild, input))))
|
|
return {parser: tag.parser}
|
|
}
|
|
return null
|
|
}
|
|
|
|
// tags?: {
|
|
// tag: string,
|
|
// attrs?: ({[attr: string]: string}) => boolean,
|
|
// parser: Parser
|
|
// }[]
|
|
// attributes?: {
|
|
// name: string,
|
|
// tagName?: string,
|
|
// parser: Parser
|
|
// }[]
|
|
|
|
function configureNesting(tags = [], attributes = []) {
|
|
let script = [], style = [], textarea = [], other = [];
|
|
for (let tag of tags) {
|
|
let array = tag.tag == "script" ? script : tag.tag == "style" ? style : tag.tag == "textarea" ? textarea : other;
|
|
array.push(tag);
|
|
}
|
|
let attrs = attributes.length ? Object.create(null) : null;
|
|
for (let attr of attributes) (attrs[attr.name] || (attrs[attr.name] = [])).push(attr);
|
|
|
|
return parseMixed((node, input) => {
|
|
let id = node.type.id;
|
|
if (id == ScriptText) return maybeNest(node, input, script)
|
|
if (id == StyleText) return maybeNest(node, input, style)
|
|
if (id == TextareaText) return maybeNest(node, input, textarea)
|
|
|
|
if (id == Element && other.length) {
|
|
let n = node.node, open = n.firstChild, tagName = open && findTagName(open, input), attrs;
|
|
if (tagName) for (let tag of other) {
|
|
if (tag.tag == tagName && (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(n, input))))) {
|
|
let close = n.lastChild;
|
|
return {parser: tag.parser, overlay: [{from: open.to, to: close.type.id == CloseTag ? close.from : n.to}]}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (attrs && id == Attribute) {
|
|
let n = node.node, nameNode;
|
|
if (nameNode = n.firstChild) {
|
|
let matches = attrs[input.read(nameNode.from, nameNode.to)];
|
|
if (matches) for (let attr of matches) {
|
|
if (attr.tagName && attr.tagName != findTagName(n.parent, input)) continue
|
|
let value = n.lastChild;
|
|
if (value.type.id == AttributeValue) {
|
|
let from = value.from + 1;
|
|
let last = value.lastChild, to = value.to - (last && last.isError ? 0 : 1);
|
|
if (to > from) return {parser: attr.parser, overlay: [{from, to}]}
|
|
} else if (value.type.id == UnquotedAttributeValue) {
|
|
return {parser: attr.parser, overlay: [{from: value.from, to: value.to}]}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
})
|
|
}
|
|
|
|
export { configureNesting, parser };
|