Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at 4fbddf8a36e2f679a0f490560cd9d74df92ba020 349 lines 21 kB view raw
1import { ContextTracker, ExternalTokenizer, LRParser } from '@lezer/lr'; 2import { styleTags, tags } from '@lezer/highlight'; 3import { parseMixed } from '@lezer/common'; 4 5// This file was generated by lezer-generator. You probably shouldn't edit it. 6const scriptText = 55, 7 StartCloseScriptTag = 1, 8 styleText = 56, 9 StartCloseStyleTag = 2, 10 textareaText = 57, 11 StartCloseTextareaTag = 3, 12 EndTag = 4, 13 SelfClosingEndTag = 5, 14 StartTag = 6, 15 StartScriptTag = 7, 16 StartStyleTag = 8, 17 StartTextareaTag = 9, 18 StartSelfClosingTag = 10, 19 StartCloseTag = 11, 20 NoMatchStartCloseTag = 12, 21 MismatchedStartCloseTag = 13, 22 missingCloseTag = 58, 23 IncompleteTag = 14, 24 IncompleteCloseTag = 15, 25 commentContent$1 = 59, 26 Element = 21, 27 TagName = 23, 28 Attribute = 24, 29 AttributeName = 25, 30 AttributeValue = 27, 31 UnquotedAttributeValue = 28, 32 ScriptText = 29, 33 StyleText = 32, 34 TextareaText = 35, 35 OpenTag = 37, 36 CloseTag = 38, 37 Dialect_noMatch = 0, 38 Dialect_selfClosing = 1; 39 40/* Hand-written tokenizers for HTML. */ 41 42const selfClosers = { 43 area: true, base: true, br: true, col: true, command: true, 44 embed: true, frame: true, hr: true, img: true, input: true, 45 keygen: true, link: true, meta: true, param: true, source: true, 46 track: true, wbr: true, menuitem: true 47}; 48 49const implicitlyClosed = { 50 dd: true, li: true, optgroup: true, option: true, p: true, 51 rp: true, rt: true, tbody: true, td: true, tfoot: true, 52 th: true, tr: true 53}; 54 55const closeOnOpen = { 56 dd: {dd: true, dt: true}, 57 dt: {dd: true, dt: true}, 58 li: {li: true}, 59 option: {option: true, optgroup: true}, 60 optgroup: {optgroup: true}, 61 p: { 62 address: true, article: true, aside: true, blockquote: true, dir: true, 63 div: true, dl: true, fieldset: true, footer: true, form: true, 64 h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, 65 header: true, hgroup: true, hr: true, menu: true, nav: true, ol: true, 66 p: true, pre: true, section: true, table: true, ul: true 67 }, 68 rp: {rp: true, rt: true}, 69 rt: {rp: true, rt: true}, 70 tbody: {tbody: true, tfoot: true}, 71 td: {td: true, th: true}, 72 tfoot: {tbody: true}, 73 th: {td: true, th: true}, 74 thead: {tbody: true, tfoot: true}, 75 tr: {tr: true} 76}; 77 78function nameChar(ch) { 79 return ch == 45 || ch == 46 || ch == 58 || ch >= 65 && ch <= 90 || ch == 95 || ch >= 97 && ch <= 122 || ch >= 161 80} 81 82let cachedName = null, cachedInput = null, cachedPos = 0; 83function tagNameAfter(input, offset) { 84 let pos = input.pos + offset; 85 if (cachedPos == pos && cachedInput == input) return cachedName 86 let next = input.peek(offset), name = ""; 87 for (;;) { 88 if (!nameChar(next)) break 89 name += String.fromCharCode(next); 90 next = input.peek(++offset); 91 } 92 // Undefined to signal there's a <? or <!, null for just missing 93 cachedInput = input; cachedPos = pos; 94 return cachedName = name ? name.toLowerCase() : next == question || next == bang ? undefined : null 95} 96 97const lessThan = 60, greaterThan = 62, slash = 47, question = 63, bang = 33, dash = 45; 98 99function ElementContext(name, parent) { 100 this.name = name; 101 this.parent = parent; 102} 103 104const startTagTerms = [StartTag, StartSelfClosingTag, StartScriptTag, StartStyleTag, StartTextareaTag]; 105 106const elementContext = new ContextTracker({ 107 start: null, 108 shift(context, term, stack, input) { 109 return startTagTerms.indexOf(term) > -1 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context 110 }, 111 reduce(context, term) { 112 return term == Element && context ? context.parent : context 113 }, 114 reuse(context, node, stack, input) { 115 let type = node.type.id; 116 return type == StartTag || type == OpenTag 117 ? new ElementContext(tagNameAfter(input, 1) || "", context) : context 118 }, 119 strict: false 120}); 121 122const tagStart = new ExternalTokenizer((input, stack) => { 123 if (input.next != lessThan) { 124 // End of file, close any open tags 125 if (input.next < 0 && stack.context) input.acceptToken(missingCloseTag); 126 return 127 } 128 input.advance(); 129 let close = input.next == slash; 130 if (close) input.advance(); 131 let name = tagNameAfter(input, 0); 132 if (name === undefined) return 133 if (!name) return input.acceptToken(close ? IncompleteCloseTag : IncompleteTag) 134 135 let parent = stack.context ? stack.context.name : null; 136 if (close) { 137 if (name == parent) return input.acceptToken(StartCloseTag) 138 if (parent && implicitlyClosed[parent]) return input.acceptToken(missingCloseTag, -2) 139 if (stack.dialectEnabled(Dialect_noMatch)) return input.acceptToken(NoMatchStartCloseTag) 140 for (let cx = stack.context; cx; cx = cx.parent) if (cx.name == name) return 141 input.acceptToken(MismatchedStartCloseTag); 142 } else { 143 if (name == "script") return input.acceptToken(StartScriptTag) 144 if (name == "style") return input.acceptToken(StartStyleTag) 145 if (name == "textarea") return input.acceptToken(StartTextareaTag) 146 if (selfClosers.hasOwnProperty(name)) return input.acceptToken(StartSelfClosingTag) 147 if (parent && closeOnOpen[parent] && closeOnOpen[parent][name]) input.acceptToken(missingCloseTag, -1); 148 else input.acceptToken(StartTag); 149 } 150}, {contextual: true}); 151 152const commentContent = new ExternalTokenizer(input => { 153 for (let dashes = 0, i = 0;; i++) { 154 if (input.next < 0) { 155 if (i) input.acceptToken(commentContent$1); 156 break 157 } 158 if (input.next == dash) { 159 dashes++; 160 } else if (input.next == greaterThan && dashes >= 2) { 161 if (i >= 3) input.acceptToken(commentContent$1, -2); 162 break 163 } else { 164 dashes = 0; 165 } 166 input.advance(); 167 } 168}); 169 170function inForeignElement(context) { 171 for (; context; context = context.parent) 172 if (context.name == "svg" || context.name == "math") return true 173 return false 174} 175 176const endTag = new ExternalTokenizer((input, stack) => { 177 if (input.next == slash && input.peek(1) == greaterThan) { 178 let selfClosing = stack.dialectEnabled(Dialect_selfClosing) || inForeignElement(stack.context); 179 input.acceptToken(selfClosing ? SelfClosingEndTag : EndTag, 2); 180 } else if (input.next == greaterThan) { 181 input.acceptToken(EndTag, 1); 182 } 183}); 184 185function contentTokenizer(tag, textToken, endToken) { 186 let lastState = 2 + tag.length; 187 return new ExternalTokenizer(input => { 188 // state means: 189 // - 0 nothing matched 190 // - 1 '<' matched 191 // - 2 '</' 192 // - 3-(1+tag.length) part of the tag matched 193 // - lastState whole tag + possibly whitespace matched 194 for (let state = 0, matchedLen = 0, i = 0;; i++) { 195 if (input.next < 0) { 196 if (i) input.acceptToken(textToken); 197 break 198 } 199 if (state == 0 && input.next == lessThan || 200 state == 1 && input.next == slash || 201 state >= 2 && state < lastState && input.next == tag.charCodeAt(state - 2)) { 202 state++; 203 matchedLen++; 204 } else if (state == lastState && input.next == greaterThan) { 205 if (i > matchedLen) 206 input.acceptToken(textToken, -matchedLen); 207 else 208 input.acceptToken(endToken, -(matchedLen - 2)); 209 break 210 } else if ((input.next == 10 /* '\n' */ || input.next == 13 /* '\r' */) && i) { 211 input.acceptToken(textToken, 1); 212 break 213 } else { 214 state = matchedLen = 0; 215 } 216 input.advance(); 217 } 218 }) 219} 220 221const scriptTokens = contentTokenizer("script", scriptText, StartCloseScriptTag); 222 223const styleTokens = contentTokenizer("style", styleText, StartCloseStyleTag); 224 225const textareaTokens = contentTokenizer("textarea", textareaText, StartCloseTextareaTag); 226 227const htmlHighlighting = styleTags({ 228 "Text RawText IncompleteTag IncompleteCloseTag": tags.content, 229 "StartTag StartCloseTag SelfClosingEndTag EndTag": tags.angleBracket, 230 TagName: tags.tagName, 231 "MismatchedCloseTag/TagName": [tags.tagName, tags.invalid], 232 AttributeName: tags.attributeName, 233 "AttributeValue UnquotedAttributeValue": tags.attributeValue, 234 Is: tags.definitionOperator, 235 "EntityReference CharacterReference": tags.character, 236 Comment: tags.blockComment, 237 ProcessingInst: tags.processingInstruction, 238 DoctypeDecl: tags.documentMeta 239}); 240 241// This file was generated by lezer-generator. You probably shouldn't edit it. 242const parser = LRParser.deserialize({ 243 version: 14, 244 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[", 245 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~", 246 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", 247 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", 248 maxTerm: 68, 249 context: elementContext, 250 nodeProps: [ 251 ["closedBy", -10,1,2,3,7,8,9,10,11,12,13,"EndTag",6,"EndTag SelfClosingEndTag",-4,22,31,34,37,"CloseTag"], 252 ["openedBy", 4,"StartTag StartCloseTag",5,"StartTag",-4,30,33,36,38,"OpenTag"], 253 ["group", -10,14,15,18,19,20,21,40,41,42,43,"Entity",17,"Entity TextContent",-3,29,32,35,"TextContent Entity"], 254 ["isolate", -11,22,30,31,33,34,36,37,38,39,42,43,"ltr",-3,27,28,40,""] 255 ], 256 propSources: [htmlHighlighting], 257 skippedNodes: [0], 258 repeatNodeCount: 9, 259 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", 260 tokenizers: [scriptTokens, styleTokens, textareaTokens, endTag, tagStart, commentContent, 0, 1, 2, 3, 4, 5], 261 topRules: {"Document":[0,16]}, 262 dialects: {noMatch: 0, selfClosing: 515}, 263 tokenPrec: 517 264}); 265 266function getAttrs(openTag, input) { 267 let attrs = Object.create(null); 268 for (let att of openTag.getChildren(Attribute)) { 269 let name = att.getChild(AttributeName), value = att.getChild(AttributeValue) || att.getChild(UnquotedAttributeValue); 270 if (name) attrs[input.read(name.from, name.to)] = 271 !value ? "" : value.type.id == AttributeValue ? input.read(value.from + 1, value.to - 1) : input.read(value.from, value.to); 272 } 273 return attrs 274} 275 276function findTagName(openTag, input) { 277 let tagNameNode = openTag.getChild(TagName); 278 return tagNameNode ? input.read(tagNameNode.from, tagNameNode.to) : " " 279} 280 281function maybeNest(node, input, tags) { 282 let attrs; 283 for (let tag of tags) { 284 if (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(node.node.parent.firstChild, input)))) 285 return {parser: tag.parser, bracketed: true} 286 } 287 return null 288} 289 290// tags?: { 291// tag: string, 292// attrs?: ({[attr: string]: string}) => boolean, 293// parser: Parser 294// }[] 295// attributes?: { 296// name: string, 297// tagName?: string, 298// parser: Parser 299// }[] 300 301function configureNesting(tags = [], attributes = []) { 302 let script = [], style = [], textarea = [], other = []; 303 for (let tag of tags) { 304 let array = tag.tag == "script" ? script : tag.tag == "style" ? style : tag.tag == "textarea" ? textarea : other; 305 array.push(tag); 306 } 307 let attrs = attributes.length ? Object.create(null) : null; 308 for (let attr of attributes) (attrs[attr.name] || (attrs[attr.name] = [])).push(attr); 309 310 return parseMixed((node, input) => { 311 let id = node.type.id; 312 if (id == ScriptText) return maybeNest(node, input, script) 313 if (id == StyleText) return maybeNest(node, input, style) 314 if (id == TextareaText) return maybeNest(node, input, textarea) 315 316 if (id == Element && other.length) { 317 let n = node.node, open = n.firstChild, tagName = open && findTagName(open, input), attrs; 318 if (tagName) for (let tag of other) { 319 if (tag.tag == tagName && (!tag.attrs || tag.attrs(attrs || (attrs = getAttrs(open, input))))) { 320 let close = n.lastChild; 321 let to = close.type.id == CloseTag ? close.from : n.to; 322 if (to > open.to) 323 return {parser: tag.parser, overlay: [{from: open.to, to}]} 324 } 325 } 326 } 327 328 if (attrs && id == Attribute) { 329 let n = node.node, nameNode; 330 if (nameNode = n.firstChild) { 331 let matches = attrs[input.read(nameNode.from, nameNode.to)]; 332 if (matches) for (let attr of matches) { 333 if (attr.tagName && attr.tagName != findTagName(n.parent, input)) continue 334 let value = n.lastChild; 335 if (value.type.id == AttributeValue) { 336 let from = value.from + 1; 337 let last = value.lastChild, to = value.to - (last && last.isError ? 0 : 1); 338 if (to > from) return {parser: attr.parser, overlay: [{from, to}], bracketed: true} 339 } else if (value.type.id == UnquotedAttributeValue) { 340 return {parser: attr.parser, overlay: [{from: value.from, to: value.to}]} 341 } 342 } 343 } 344 } 345 return null 346 }) 347} 348 349export { configureNesting, parser };