Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol
diffdown.com
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var lr = require('@lezer/lr');
6var highlight = require('@lezer/highlight');
7var common = require('@lezer/common');
8
9// This file was generated by lezer-generator. You probably shouldn't edit it.
10const scriptText = 55,
11 StartCloseScriptTag = 1,
12 styleText = 56,
13 StartCloseStyleTag = 2,
14 textareaText = 57,
15 StartCloseTextareaTag = 3,
16 EndTag = 4,
17 SelfClosingEndTag = 5,
18 StartTag = 6,
19 StartScriptTag = 7,
20 StartStyleTag = 8,
21 StartTextareaTag = 9,
22 StartSelfClosingTag = 10,
23 StartCloseTag = 11,
24 NoMatchStartCloseTag = 12,
25 MismatchedStartCloseTag = 13,
26 missingCloseTag = 58,
27 IncompleteTag = 14,
28 IncompleteCloseTag = 15,
29 commentContent$1 = 59,
30 Element = 21,
31 TagName = 23,
32 Attribute = 24,
33 AttributeName = 25,
34 AttributeValue = 27,
35 UnquotedAttributeValue = 28,
36 ScriptText = 29,
37 StyleText = 32,
38 TextareaText = 35,
39 OpenTag = 37,
40 CloseTag = 38,
41 Dialect_noMatch = 0,
42 Dialect_selfClosing = 1;
43
44/* Hand-written tokenizers for HTML. */
45
46const selfClosers = {
47 area: true, base: true, br: true, col: true, command: true,
48 embed: true, frame: true, hr: true, img: true, input: true,
49 keygen: true, link: true, meta: true, param: true, source: true,
50 track: true, wbr: true, menuitem: true
51};
52
53const implicitlyClosed = {
54 dd: true, li: true, optgroup: true, option: true, p: true,
55 rp: true, rt: true, tbody: true, td: true, tfoot: true,
56 th: true, tr: true
57};
58
59const closeOnOpen = {
60 dd: {dd: true, dt: true},
61 dt: {dd: true, dt: true},
62 li: {li: true},
63 option: {option: true, optgroup: true},
64 optgroup: {optgroup: true},
65 p: {
66 address: true, article: true, aside: true, blockquote: true, dir: true,
67 div: true, dl: true, fieldset: true, footer: true, form: true,
68 h1: true, h2: true, h3: true, h4: true, h5: true, h6: true,
69 header: true, hgroup: true, hr: true, menu: true, nav: true, ol: true,
70 p: true, pre: true, section: true, table: true, ul: true
71 },
72 rp: {rp: true, rt: true},
73 rt: {rp: true, rt: true},
74 tbody: {tbody: true, tfoot: true},
75 td: {td: true, th: true},
76 tfoot: {tbody: true},
77 th: {td: true, th: true},
78 thead: {tbody: true, tfoot: true},
79 tr: {tr: true}
80};
81
82function nameChar(ch) {
83 return ch == 45 || ch == 46 || ch == 58 || ch >= 65 && ch <= 90 || ch == 95 || ch >= 97 && ch <= 122 || ch >= 161
84}
85
86let cachedName = null, cachedInput = null, cachedPos = 0;
87function tagNameAfter(input, offset) {
88 let pos = input.pos + offset;
89 if (cachedPos == pos && cachedInput == input) return cachedName
90 let next = input.peek(offset), name = "";
91 for (;;) {
92 if (!nameChar(next)) break
93 name += String.fromCharCode(next);
94 next = input.peek(++offset);
95 }
96 // Undefined to signal there's a <? or <!, null for just missing
97 cachedInput = input; cachedPos = pos;
98 return cachedName = name ? name.toLowerCase() : next == question || next == bang ? undefined : null
99}
100
101const lessThan = 60, greaterThan = 62, slash = 47, question = 63, bang = 33, dash = 45;
102
103function ElementContext(name, parent) {
104 this.name = name;
105 this.parent = parent;
106}
107
108const startTagTerms = [StartTag, StartSelfClosingTag, StartScriptTag, StartStyleTag, StartTextareaTag];
109
110const elementContext = new lr.ContextTracker({
111 start: null,
112 shift(context, term, stack, input) {
113 return startTagTerms.indexOf(term) > -1 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context
114 },
115 reduce(context, term) {
116 return term == Element && context ? context.parent : context
117 },
118 reuse(context, node, stack, input) {
119 let type = node.type.id;
120 return type == StartTag || type == OpenTag
121 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context
122 },
123 strict: false
124});
125
126const tagStart = new lr.ExternalTokenizer((input, stack) => {
127 if (input.next != lessThan) {
128 // End of file, close any open tags
129 if (input.next < 0 && stack.context) input.acceptToken(missingCloseTag);
130 return
131 }
132 input.advance();
133 let close = input.next == slash;
134 if (close) input.advance();
135 let name = tagNameAfter(input, 0);
136 if (name === undefined) return
137 if (!name) return input.acceptToken(close ? IncompleteCloseTag : IncompleteTag)
138
139 let parent = stack.context ? stack.context.name : null;
140 if (close) {
141 if (name == parent) return input.acceptToken(StartCloseTag)
142 if (parent && implicitlyClosed[parent]) return input.acceptToken(missingCloseTag, -2)
143 if (stack.dialectEnabled(Dialect_noMatch)) return input.acceptToken(NoMatchStartCloseTag)
144 for (let cx = stack.context; cx; cx = cx.parent) if (cx.name == name) return
145 input.acceptToken(MismatchedStartCloseTag);
146 } else {
147 if (name == "script") return input.acceptToken(StartScriptTag)
148 if (name == "style") return input.acceptToken(StartStyleTag)
149 if (name == "textarea") return input.acceptToken(StartTextareaTag)
150 if (selfClosers.hasOwnProperty(name)) return input.acceptToken(StartSelfClosingTag)
151 if (parent && closeOnOpen[parent] && closeOnOpen[parent][name]) input.acceptToken(missingCloseTag, -1);
152 else input.acceptToken(StartTag);
153 }
154}, {contextual: true});
155
156const commentContent = new lr.ExternalTokenizer(input => {
157 for (let dashes = 0, i = 0;; i++) {
158 if (input.next < 0) {
159 if (i) input.acceptToken(commentContent$1);
160 break
161 }
162 if (input.next == dash) {
163 dashes++;
164 } else if (input.next == greaterThan && dashes >= 2) {
165 if (i >= 3) input.acceptToken(commentContent$1, -2);
166 break
167 } else {
168 dashes = 0;
169 }
170 input.advance();
171 }
172});
173
174function inForeignElement(context) {
175 for (; context; context = context.parent)
176 if (context.name == "svg" || context.name == "math") return true
177 return false
178}
179
180const endTag = new lr.ExternalTokenizer((input, stack) => {
181 if (input.next == slash && input.peek(1) == greaterThan) {
182 let selfClosing = stack.dialectEnabled(Dialect_selfClosing) || inForeignElement(stack.context);
183 input.acceptToken(selfClosing ? SelfClosingEndTag : EndTag, 2);
184 } else if (input.next == greaterThan) {
185 input.acceptToken(EndTag, 1);
186 }
187});
188
189function contentTokenizer(tag, textToken, endToken) {
190 let lastState = 2 + tag.length;
191 return new lr.ExternalTokenizer(input => {
192 // state means:
193 // - 0 nothing matched
194 // - 1 '<' matched
195 // - 2 '</'
196 // - 3-(1+tag.length) part of the tag matched
197 // - lastState whole tag + possibly whitespace matched
198 for (let state = 0, matchedLen = 0, i = 0;; i++) {
199 if (input.next < 0) {
200 if (i) input.acceptToken(textToken);
201 break
202 }
203 if (state == 0 && input.next == lessThan ||
204 state == 1 && input.next == slash ||
205 state >= 2 && state < lastState && input.next == tag.charCodeAt(state - 2)) {
206 state++;
207 matchedLen++;
208 } else if (state == lastState && input.next == greaterThan) {
209 if (i > matchedLen)
210 input.acceptToken(textToken, -matchedLen);
211 else
212 input.acceptToken(endToken, -(matchedLen - 2));
213 break
214 } else if ((input.next == 10 /* '\n' */ || input.next == 13 /* '\r' */) && i) {
215 input.acceptToken(textToken, 1);
216 break
217 } else {
218 state = matchedLen = 0;
219 }
220 input.advance();
221 }
222 })
223}
224
225const scriptTokens = contentTokenizer("script", scriptText, StartCloseScriptTag);
226
227const styleTokens = contentTokenizer("style", styleText, StartCloseStyleTag);
228
229const textareaTokens = contentTokenizer("textarea", textareaText, StartCloseTextareaTag);
230
231const htmlHighlighting = highlight.styleTags({
232 "Text RawText IncompleteTag IncompleteCloseTag": highlight.tags.content,
233 "StartTag StartCloseTag SelfClosingEndTag EndTag": highlight.tags.angleBracket,
234 TagName: highlight.tags.tagName,
235 "MismatchedCloseTag/TagName": [highlight.tags.tagName, highlight.tags.invalid],
236 AttributeName: highlight.tags.attributeName,
237 "AttributeValue UnquotedAttributeValue": highlight.tags.attributeValue,
238 Is: highlight.tags.definitionOperator,
239 "EntityReference CharacterReference": highlight.tags.character,
240 Comment: highlight.tags.blockComment,
241 ProcessingInst: highlight.tags.processingInstruction,
242 DoctypeDecl: highlight.tags.documentMeta
243});
244
245// This file was generated by lezer-generator. You probably shouldn't edit it.
246const parser = lr.LRParser.deserialize({
247 version: 14,
248 states: ",xOVO!rOOO!ZQ#tO'#CrO!`Q#tO'#C{O!eQ#tO'#DOO!jQ#tO'#DRO!oQ#tO'#DTO!tOaO'#CqO#PObO'#CqO#[OdO'#CqO$kO!rO'#CqOOO`'#Cq'#CqO$rO$fO'#DUO$zQ#tO'#DWO%PQ#tO'#DXOOO`'#Dl'#DlOOO`'#DZ'#DZQVO!rOOO%UQ&rO,59^O%aQ&rO,59gO%lQ&rO,59jO%wQ&rO,59mO&SQ&rO,59oOOOa'#D_'#D_O&_OaO'#CyO&jOaO,59]OOOb'#D`'#D`O&rObO'#C|O&}ObO,59]OOOd'#Da'#DaO'VOdO'#DPO'bOdO,59]OOO`'#Db'#DbO'jO!rO,59]O'qQ#tO'#DSOOO`,59],59]OOOp'#Dc'#DcO'vO$fO,59pOOO`,59p,59pO(OQ#|O,59rO(TQ#|O,59sOOO`-E7X-E7XO(YQ&rO'#CtOOQW'#D['#D[O(hQ&rO1G.xOOOa1G.x1G.xOOO`1G/Z1G/ZO(sQ&rO1G/ROOOb1G/R1G/RO)OQ&rO1G/UOOOd1G/U1G/UO)ZQ&rO1G/XOOO`1G/X1G/XO)fQ&rO1G/ZOOOa-E7]-E7]O)qQ#tO'#CzOOO`1G.w1G.wOOOb-E7^-E7^O)vQ#tO'#C}OOOd-E7_-E7_O){Q#tO'#DQOOO`-E7`-E7`O*QQ#|O,59nOOOp-E7a-E7aOOO`1G/[1G/[OOO`1G/^1G/^OOO`1G/_1G/_O*VQ,UO,59`OOQW-E7Y-E7YOOOa7+$d7+$dOOO`7+$u7+$uOOOb7+$m7+$mOOOd7+$p7+$pOOO`7+$s7+$sO*bQ#|O,59fO*gQ#|O,59iO*lQ#|O,59lOOO`1G/Y1G/YO*qO7[O'#CwO+SOMhO'#CwOOQW1G.z1G.zOOO`1G/Q1G/QOOO`1G/T1G/TOOO`1G/W1G/WOOOO'#D]'#D]O+eO7[O,59cOOQW,59c,59cOOOO'#D^'#D^O+vOMhO,59cOOOO-E7Z-E7ZOOQW1G.}1G.}OOOO-E7[-E7[",
249 stateData: ",c~O!_OS~OUSOVPOWQOXROYTO[]O][O^^O_^Oa^Ob^Oc^Od^Oy^O|_O!eZO~OgaO~OgbO~OgcO~OgdO~OgeO~O!XfOPmP![mP~O!YiOQpP![pP~O!ZlORsP![sP~OUSOVPOWQOXROYTOZqO[]O][O^^O_^Oa^Ob^Oc^Od^Oy^O!eZO~O![rO~P#gO!]sO!fuO~OgvO~OgwO~OS|OT}OiyO~OS!POT}OiyO~OS!ROT}OiyO~OS!TOT}OiyO~OS}OT}OiyO~O!XfOPmX![mX~OP!WO![!XO~O!YiOQpX![pX~OQ!ZO![!XO~O!ZlORsX![sX~OR!]O![!XO~O![!XO~P#gOg!_O~O!]sO!f!aO~OS!bO~OS!cO~Oj!dOShXThXihX~OS!fOT!gOiyO~OS!hOT!gOiyO~OS!iOT!gOiyO~OS!jOT!gOiyO~OS!gOT!gOiyO~Og!kO~Og!lO~Og!mO~OS!nO~Ol!qO!a!oO!c!pO~OS!rO~OS!sO~OS!tO~Ob!uOc!uOd!uO!a!wO!b!uO~Ob!xOc!xOd!xO!c!wO!d!xO~Ob!uOc!uOd!uO!a!{O!b!uO~Ob!xOc!xOd!xO!c!{O!d!xO~OT~cbd!ey|!e~",
250 goto: "%q!aPPPPPPPPPPPPPPPPPPPPP!b!hP!nPP!zP!}#Q#T#Z#^#a#g#j#m#s#y!bP!b!bP$P$V$m$s$y%P%V%]%cPPPPPPPP%iX^OX`pXUOX`pezabcde{!O!Q!S!UR!q!dRhUR!XhXVOX`pRkVR!XkXWOX`pRnWR!XnXXOX`pQrXR!XpXYOX`pQ`ORx`Q{aQ!ObQ!QcQ!SdQ!UeZ!e{!O!Q!S!UQ!v!oR!z!vQ!y!pR!|!yQgUR!VgQjVR!YjQmWR![mQpXR!^pQtZR!`tS_O`ToXp",
251 nodeNames: "⚠ StartCloseTag StartCloseTag StartCloseTag EndTag SelfClosingEndTag StartTag StartTag StartTag StartTag StartTag StartCloseTag StartCloseTag StartCloseTag IncompleteTag 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",
252 maxTerm: 68,
253 context: elementContext,
254 nodeProps: [
255 ["closedBy", -10,1,2,3,7,8,9,10,11,12,13,"EndTag",6,"EndTag SelfClosingEndTag",-4,22,31,34,37,"CloseTag"],
256 ["openedBy", 4,"StartTag StartCloseTag",5,"StartTag",-4,30,33,36,38,"OpenTag"],
257 ["group", -10,14,15,18,19,20,21,40,41,42,43,"Entity",17,"Entity TextContent",-3,29,32,35,"TextContent Entity"],
258 ["isolate", -11,22,30,31,33,34,36,37,38,39,42,43,"ltr",-3,27,28,40,""]
259 ],
260 propSources: [htmlHighlighting],
261 skippedNodes: [0],
262 repeatNodeCount: 9,
263 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$|caPlW!b`!dpOX$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&bXaP!b`!dpOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&Xq'UVaP!dpOv&}wx'kx!^&}!^!_(V!_;'S&};'S;=`(n<%lO&}P'pTaPOv'kw!^'k!_;'S'k;'S;=`(P<%lO'kP(SP;=`<%l'kp([S!dpOv(Vx;'S(V;'S;=`(h<%lO(Vp(kP;=`<%l(Vq(qP;=`<%l&}a({WaP!b`Or(trs'ksv(tw!^(t!^!_)e!_;'S(t;'S;=`*P<%lO(t`)jT!b`Or)esv)ew;'S)e;'S;=`)y<%lO)e`)|P;=`<%l)ea*SP;=`<%l(t!Q*^V!b`!dpOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!Q*vP;=`<%l*V!R*|P;=`<%l&XW+UYlWOX+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,]`aP!b`!dp!_^OX&XXY,QYZ,QZ]&X]^,Q^p&Xpq,Qqr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X!_-ljiSaPlW!b`!dpOX$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[/ebiSlWOX+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+PS0rXiSqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0mS1bP;=`<%l0m[1hP;=`<%l/^!V1vciSaP!b`!dpOq&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!ahaP!dpOv&}wx'kx!^&}!^!_(V!_;'S&};'S;=`(n<%lO&}!_4WiiSlWd!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!Z5zblWOX5uXZ7SZ[5u[^7S^p5uqr5urs7Sst+Ptw5uwx7Sx!]5u!]!^7w!^!a7S!a#S5u#S#T7S#T;'S5u;'S;=`8n<%lO5u!R7VVOp7Sqs7St!]7S!]!^7l!^;'S7S;'S;=`7q<%lO7S!R7qOb!R!R7tP;=`<%l7S!Z8OYlWb!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!Z8qP;=`<%l5u!_8{iiSlWOX5uXZ7SZ[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!_:sbiSlWb!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<QciSOp7Sqr;{rs7Sst0mtw;{wx7Sx!P;{!P!Q7S!Q!];{!]!^=]!^!a7S!a#s;{#s$f7S$f;'S;{;'S;=`>P<%l?Ah;{?Ah?BY7S?BY?Mn;{?MnO7S!V=dXiSb!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!V>SP;=`<%l;{!_>YP;=`<%l8t!_>dhiSlWOX@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@TalWOX@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!RAtOc!R!RAwP;=`<%lAY!ZBRYlWc!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!ZBtP;=`<%l@O!_COhiSlWOX@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!_DsbiSlWc!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!VFQbiSOpAYqrE{rsAYswE{wxAYx!PE{!P!QAY!Q!]E{!]!^GY!^!aAY!a#sE{#s$fAY$f;'SE{;'S;=`G|<%l?AhE{?Ah?BYAY?BY?MnE{?MnOAY!VGaXiSc!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!VHPP;=`<%lE{!_HVP;=`<%lBw!ZHcW!cxaP!b`Or(trs'ksv(tw!^(t!^!_)e!_;'S(t;'S;=`*P<%lO(t!aIYliSaPlW!b`!dpOX$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_kiSaPlW!b`!dpOX$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_XaP!b`!dp!fQOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X!aNZ!ZiSgQaPlW!b`!dpOX$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!b`!dpOq*Vqr!$yrs(Vsv*Vwx)ex!a*V!a!b!4t!b;'S*V;'S;=`*s<%lO*V!R!%Q]!b`!dpOr*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!b`!dpOr*Vrs(Vsv*Vwx)ex}*V}!O!&m!O;'S*V;'S;=`*s<%lO*V!R!&vV!b`!dp!ePOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!'dX!b`!dpOr*Vrs(Vsv*Vwx)ex!q*V!q!r!(P!r;'S*V;'S;=`*s<%lO*V!R!(WX!b`!dpOr*Vrs(Vsv*Vwx)ex!e*V!e!f!(s!f;'S*V;'S;=`*s<%lO*V!R!(zX!b`!dpOr*Vrs(Vsv*Vwx)ex!v*V!v!w!)g!w;'S*V;'S;=`*s<%lO*V!R!)nX!b`!dpOr*Vrs(Vsv*Vwx)ex!{*V!{!|!*Z!|;'S*V;'S;=`*s<%lO*V!R!*bX!b`!dpOr*Vrs(Vsv*Vwx)ex!r*V!r!s!*}!s;'S*V;'S;=`*s<%lO*V!R!+UX!b`!dpOr*Vrs(Vsv*Vwx)ex!g*V!g!h!+q!h;'S*V;'S;=`*s<%lO*V!R!+xY!b`!dpOr!+qrs!,hsv!+qvw!-Swx!.[x!`!+q!`!a!/j!a;'S!+q;'S;=`!0Y<%lO!+qq!,mV!dpOv!,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!dp|POv(Vx;'S(V;'S;=`(h<%lO(Vq!.XP;=`<%l!,ha!.aX!b`Or!.[rs!-Ssv!.[vw!-Sw!`!.[!`!a!.|!a;'S!.[;'S;=`!/d<%lO!.[a!/TT!b`|POr)esv)ew;'S)e;'S;=`)y<%lO)ea!/gP;=`<%l!.[!R!/sV!b`!dp|POr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!0]P;=`<%l!+q!R!0gX!b`!dpOr*Vrs(Vsv*Vwx)ex#c*V#c#d!1S#d;'S*V;'S;=`*s<%lO*V!R!1ZX!b`!dpOr*Vrs(Vsv*Vwx)ex#V*V#V#W!1v#W;'S*V;'S;=`*s<%lO*V!R!1}X!b`!dpOr*Vrs(Vsv*Vwx)ex#h*V#h#i!2j#i;'S*V;'S;=`*s<%lO*V!R!2qX!b`!dpOr*Vrs(Vsv*Vwx)ex#m*V#m#n!3^#n;'S*V;'S;=`*s<%lO*V!R!3eX!b`!dpOr*Vrs(Vsv*Vwx)ex#d*V#d#e!4Q#e;'S*V;'S;=`*s<%lO*V!R!4XX!b`!dpOr*Vrs(Vsv*Vwx)ex#X*V#X#Y!+q#Y;'S*V;'S;=`*s<%lO*V!R!4{Y!b`!dpOr!4trs!5ksv!4tvw!6Vwx!8]x!a!4t!a!b!:]!b;'S!4t;'S;=`!;r<%lO!4tq!5pV!dpOv!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!7QOyPP!7TP;=`<%l!6Vq!7]V!dpOv!5kvx!6Vx!`!5k!`!a!7r!a;'S!5k;'S;=`!8V<%lO!5kq!7yS!dpyPOv(Vx;'S(V;'S;=`(h<%lO(Vq!8YP;=`<%l!5ka!8bX!b`Or!8]rs!6Vsv!8]vw!6Vw!a!8]!a!b!8}!b;'S!8];'S;=`!:V<%lO!8]a!9SX!b`Or!8]rs!6Vsv!8]vw!6Vw!`!8]!`!a!9o!a;'S!8];'S;=`!:V<%lO!8]a!9vT!b`yPOr)esv)ew;'S)e;'S;=`)y<%lO)ea!:YP;=`<%l!8]!R!:dY!b`!dpOr!4trs!5ksv!4tvw!6Vwx!8]x!`!4t!`!a!;S!a;'S!4t;'S;=`!;r<%lO!4t!R!;]V!b`!dpyPOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!;uP;=`<%l!4t!V!<TXjSaP!b`!dpOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X",
264 tokenizers: [scriptTokens, styleTokens, textareaTokens, endTag, tagStart, commentContent, 0, 1, 2, 3, 4, 5],
265 topRules: {"Document":[0,16]},
266 dialects: {noMatch: 0, selfClosing: 515},
267 tokenPrec: 517
268});
269
270function getAttrs(openTag, input) {
271 let attrs = Object.create(null);
272 for (let att of openTag.getChildren(Attribute)) {
273 let name = att.getChild(AttributeName), value = att.getChild(AttributeValue) || att.getChild(UnquotedAttributeValue);
274 if (name) attrs[input.read(name.from, name.to)] =
275 !value ? "" : value.type.id == AttributeValue ? input.read(value.from + 1, value.to - 1) : input.read(value.from, value.to);
276 }
277 return attrs
278}
279
280function findTagName(openTag, input) {
281 let tagNameNode = openTag.getChild(TagName);
282 return tagNameNode ? input.read(tagNameNode.from, tagNameNode.to) : " "
283}
284
285function maybeNest(node, input, tags) {
286 let attrs;
287 for (let tag of tags) {
288 if (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(node.node.parent.firstChild, input))))
289 return {parser: tag.parser, bracketed: true}
290 }
291 return null
292}
293
294// tags?: {
295// tag: string,
296// attrs?: ({[attr: string]: string}) => boolean,
297// parser: Parser
298// }[]
299// attributes?: {
300// name: string,
301// tagName?: string,
302// parser: Parser
303// }[]
304
305function configureNesting(tags = [], attributes = []) {
306 let script = [], style = [], textarea = [], other = [];
307 for (let tag of tags) {
308 let array = tag.tag == "script" ? script : tag.tag == "style" ? style : tag.tag == "textarea" ? textarea : other;
309 array.push(tag);
310 }
311 let attrs = attributes.length ? Object.create(null) : null;
312 for (let attr of attributes) (attrs[attr.name] || (attrs[attr.name] = [])).push(attr);
313
314 return common.parseMixed((node, input) => {
315 let id = node.type.id;
316 if (id == ScriptText) return maybeNest(node, input, script)
317 if (id == StyleText) return maybeNest(node, input, style)
318 if (id == TextareaText) return maybeNest(node, input, textarea)
319
320 if (id == Element && other.length) {
321 let n = node.node, open = n.firstChild, tagName = open && findTagName(open, input), attrs;
322 if (tagName) for (let tag of other) {
323 if (tag.tag == tagName && (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(open, input))))) {
324 let close = n.lastChild;
325 let to = close.type.id == CloseTag ? close.from : n.to;
326 if (to > open.to)
327 return {parser: tag.parser, overlay: [{from: open.to, to}]}
328 }
329 }
330 }
331
332 if (attrs && id == Attribute) {
333 let n = node.node, nameNode;
334 if (nameNode = n.firstChild) {
335 let matches = attrs[input.read(nameNode.from, nameNode.to)];
336 if (matches) for (let attr of matches) {
337 if (attr.tagName && attr.tagName != findTagName(n.parent, input)) continue
338 let value = n.lastChild;
339 if (value.type.id == AttributeValue) {
340 let from = value.from + 1;
341 let last = value.lastChild, to = value.to - (last && last.isError ? 0 : 1);
342 if (to > from) return {parser: attr.parser, overlay: [{from, to}], bracketed: true}
343 } else if (value.type.id == UnquotedAttributeValue) {
344 return {parser: attr.parser, overlay: [{from: value.from, to: value.to}]}
345 }
346 }
347 }
348 }
349 return null
350 })
351}
352
353exports.configureNesting = configureNesting;
354exports.parser = parser;