tutuca 0.9.36 → 0.9.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2066,6 +2066,2054 @@ var init_components = __esm(() => {
2066
2066
  init_attribute();
2067
2067
  });
2068
2068
 
2069
+ // tools/core/html-tokenizer.js
2070
+ function isWhitespace(c) {
2071
+ return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
2072
+ }
2073
+ function isEndOfTagSection(c) {
2074
+ return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);
2075
+ }
2076
+ function isASCIIAlpha(c) {
2077
+ return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ;
2078
+ }
2079
+
2080
+ class HtmlTokenizer {
2081
+ constructor({ xmlMode = false, recognizeSelfClosing = xmlMode } = {}, cbs) {
2082
+ this.cbs = cbs;
2083
+ this.xmlMode = xmlMode;
2084
+ this.recognizeSelfClosing = recognizeSelfClosing;
2085
+ this.state = State.Text;
2086
+ this.buffer = "";
2087
+ this.sectionStart = 0;
2088
+ this.index = 0;
2089
+ this.isSpecial = false;
2090
+ this.running = true;
2091
+ this.offset = 0;
2092
+ this.currentSequence = Sequences.Empty;
2093
+ this.sequenceIndex = 0;
2094
+ }
2095
+ reset() {
2096
+ this.state = State.Text;
2097
+ this.buffer = "";
2098
+ this.sectionStart = 0;
2099
+ this.index = 0;
2100
+ this.isSpecial = false;
2101
+ this.currentSequence = Sequences.Empty;
2102
+ this.sequenceIndex = 0;
2103
+ this.running = true;
2104
+ this.offset = 0;
2105
+ }
2106
+ write(chunk) {
2107
+ this.offset += this.buffer.length;
2108
+ this.buffer = chunk;
2109
+ this.parse();
2110
+ }
2111
+ end() {
2112
+ if (this.running)
2113
+ this.finish();
2114
+ }
2115
+ pause() {
2116
+ this.running = false;
2117
+ }
2118
+ resume() {
2119
+ this.running = true;
2120
+ if (this.index < this.buffer.length + this.offset) {
2121
+ this.parse();
2122
+ }
2123
+ }
2124
+ stateText(c) {
2125
+ if (c === CharCodes.Lt || this.fastForwardTo(CharCodes.Lt)) {
2126
+ if (this.index > this.sectionStart) {
2127
+ this.cbs.ontext(this.sectionStart, this.index);
2128
+ }
2129
+ this.state = State.BeforeTagName;
2130
+ this.sectionStart = this.index;
2131
+ }
2132
+ }
2133
+ enterTagBody() {
2134
+ if (this.currentSequence === Sequences.Plaintext) {
2135
+ this.currentSequence = Sequences.Empty;
2136
+ this.state = State.InPlainText;
2137
+ } else if (this.isSpecial) {
2138
+ this.state = State.InSpecialTag;
2139
+ this.sequenceIndex = 0;
2140
+ } else {
2141
+ this.state = State.Text;
2142
+ }
2143
+ }
2144
+ stateSpecialStartSequence(c) {
2145
+ const lower = c | 32;
2146
+ if (this.sequenceIndex < this.currentSequence.length) {
2147
+ if (lower === this.currentSequence[this.sequenceIndex]) {
2148
+ this.sequenceIndex++;
2149
+ return;
2150
+ }
2151
+ if (this.sequenceIndex === 3) {
2152
+ if (this.currentSequence === Sequences.ScriptEnd && lower === Sequences.StyleEnd[3]) {
2153
+ this.currentSequence = Sequences.StyleEnd;
2154
+ this.sequenceIndex = 4;
2155
+ return;
2156
+ }
2157
+ if (this.currentSequence === Sequences.TitleEnd && lower === Sequences.TextareaEnd[3]) {
2158
+ this.currentSequence = Sequences.TextareaEnd;
2159
+ this.sequenceIndex = 4;
2160
+ return;
2161
+ }
2162
+ } else if (this.sequenceIndex === 4 && this.currentSequence === Sequences.NoembedEnd && lower === Sequences.NoframesEnd[4]) {
2163
+ this.currentSequence = Sequences.NoframesEnd;
2164
+ this.sequenceIndex = 5;
2165
+ return;
2166
+ }
2167
+ } else if (isEndOfTagSection(c)) {
2168
+ this.sequenceIndex = 0;
2169
+ this.state = State.InTagName;
2170
+ this.stateInTagName(c);
2171
+ return;
2172
+ }
2173
+ this.isSpecial = false;
2174
+ this.currentSequence = Sequences.Empty;
2175
+ this.sequenceIndex = 0;
2176
+ this.state = State.InTagName;
2177
+ this.stateInTagName(c);
2178
+ }
2179
+ stateCDATASequence(c) {
2180
+ if (c === Sequences.Cdata[this.sequenceIndex]) {
2181
+ if (++this.sequenceIndex === Sequences.Cdata.length) {
2182
+ this.state = State.InCommentLike;
2183
+ this.currentSequence = Sequences.CdataEnd;
2184
+ this.sequenceIndex = 0;
2185
+ this.sectionStart = this.index + 1;
2186
+ }
2187
+ } else {
2188
+ this.sequenceIndex = 0;
2189
+ if (this.xmlMode) {
2190
+ this.state = State.InDeclaration;
2191
+ this.stateInDeclaration(c);
2192
+ } else {
2193
+ this.state = State.InSpecialComment;
2194
+ this.stateInSpecialComment(c);
2195
+ }
2196
+ }
2197
+ }
2198
+ fastForwardTo(c) {
2199
+ while (++this.index < this.buffer.length + this.offset) {
2200
+ if (this.buffer.charCodeAt(this.index - this.offset) === c) {
2201
+ return true;
2202
+ }
2203
+ }
2204
+ this.index = this.buffer.length + this.offset - 1;
2205
+ return false;
2206
+ }
2207
+ emitComment(offset) {
2208
+ this.cbs.oncomment(this.sectionStart, this.index, offset);
2209
+ this.sequenceIndex = 0;
2210
+ this.sectionStart = this.index + 1;
2211
+ this.state = State.Text;
2212
+ }
2213
+ stateInCommentLike(c) {
2214
+ if (!this.xmlMode && this.currentSequence === Sequences.CommentEnd && this.sequenceIndex <= 1 && this.index === this.sectionStart + this.sequenceIndex && c === CharCodes.Gt) {
2215
+ this.emitComment(this.sequenceIndex);
2216
+ } else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === 2 && c === CharCodes.Gt) {
2217
+ this.emitComment(2);
2218
+ } else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === this.currentSequence.length - 1 && c !== CharCodes.Gt) {
2219
+ this.sequenceIndex = Number(c === CharCodes.Dash);
2220
+ } else if (c === this.currentSequence[this.sequenceIndex]) {
2221
+ if (++this.sequenceIndex === this.currentSequence.length) {
2222
+ if (this.currentSequence === Sequences.CdataEnd) {
2223
+ this.cbs.oncdata(this.sectionStart, this.index, 2);
2224
+ } else {
2225
+ this.cbs.oncomment(this.sectionStart, this.index, 3);
2226
+ }
2227
+ this.sequenceIndex = 0;
2228
+ this.sectionStart = this.index + 1;
2229
+ this.state = State.Text;
2230
+ }
2231
+ } else if (this.sequenceIndex === 0) {
2232
+ if (this.fastForwardTo(this.currentSequence[0])) {
2233
+ this.sequenceIndex = 1;
2234
+ }
2235
+ } else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
2236
+ this.sequenceIndex = 0;
2237
+ }
2238
+ }
2239
+ isTagStartChar(c) {
2240
+ return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
2241
+ }
2242
+ stateInSpecialTag(c) {
2243
+ if (this.sequenceIndex === this.currentSequence.length) {
2244
+ if (isEndOfTagSection(c)) {
2245
+ const endOfText = this.index - this.currentSequence.length;
2246
+ if (this.sectionStart < endOfText) {
2247
+ const actualIndex = this.index;
2248
+ this.index = endOfText;
2249
+ this.cbs.ontext(this.sectionStart, endOfText);
2250
+ this.index = actualIndex;
2251
+ }
2252
+ this.isSpecial = false;
2253
+ this.sectionStart = endOfText + 2;
2254
+ this.stateInClosingTagName(c);
2255
+ return;
2256
+ }
2257
+ this.sequenceIndex = 0;
2258
+ }
2259
+ if ((c | 32) === this.currentSequence[this.sequenceIndex]) {
2260
+ this.sequenceIndex += 1;
2261
+ } else if (this.sequenceIndex === 0) {
2262
+ if (this.fastForwardTo(CharCodes.Lt)) {
2263
+ this.sequenceIndex = 1;
2264
+ }
2265
+ } else {
2266
+ this.sequenceIndex = Number(c === CharCodes.Lt);
2267
+ }
2268
+ }
2269
+ stateBeforeTagName(c) {
2270
+ if (c === CharCodes.ExclamationMark) {
2271
+ this.state = State.BeforeDeclaration;
2272
+ this.sectionStart = this.index + 1;
2273
+ } else if (c === CharCodes.Questionmark) {
2274
+ if (this.xmlMode) {
2275
+ this.state = State.InProcessingInstruction;
2276
+ this.sequenceIndex = 0;
2277
+ this.sectionStart = this.index + 1;
2278
+ } else {
2279
+ this.state = State.InSpecialComment;
2280
+ this.sectionStart = this.index;
2281
+ }
2282
+ } else if (this.isTagStartChar(c)) {
2283
+ this.sectionStart = this.index;
2284
+ const special = this.xmlMode || this.cbs.isInForeignContext?.() ? undefined : specialStartSequences.get(c | 32);
2285
+ if (special === undefined) {
2286
+ this.state = State.InTagName;
2287
+ } else {
2288
+ this.isSpecial = true;
2289
+ this.currentSequence = special;
2290
+ this.sequenceIndex = 3;
2291
+ this.state = State.SpecialStartSequence;
2292
+ }
2293
+ } else if (c === CharCodes.Slash) {
2294
+ this.state = State.BeforeClosingTagName;
2295
+ } else {
2296
+ this.state = State.Text;
2297
+ this.stateText(c);
2298
+ }
2299
+ }
2300
+ stateInTagName(c) {
2301
+ if (isEndOfTagSection(c)) {
2302
+ this.cbs.onopentagname(this.sectionStart, this.index);
2303
+ this.sectionStart = -1;
2304
+ this.state = State.BeforeAttributeName;
2305
+ this.stateBeforeAttributeName(c);
2306
+ }
2307
+ }
2308
+ stateBeforeClosingTagName(c) {
2309
+ if (isWhitespace(c)) {
2310
+ if (!this.xmlMode) {
2311
+ this.state = State.InSpecialComment;
2312
+ this.sectionStart = this.index;
2313
+ }
2314
+ } else if (c === CharCodes.Gt) {
2315
+ this.state = State.Text;
2316
+ if (!this.xmlMode) {
2317
+ this.sectionStart = this.index + 1;
2318
+ }
2319
+ } else {
2320
+ this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
2321
+ this.sectionStart = this.index;
2322
+ }
2323
+ }
2324
+ stateInClosingTagName(c) {
2325
+ if (isEndOfTagSection(c)) {
2326
+ this.cbs.onclosetag(this.sectionStart, this.index);
2327
+ this.sectionStart = -1;
2328
+ this.state = State.AfterClosingTagName;
2329
+ this.stateAfterClosingTagName(c);
2330
+ }
2331
+ }
2332
+ stateAfterClosingTagName(c) {
2333
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2334
+ this.state = State.Text;
2335
+ this.sectionStart = this.index + 1;
2336
+ }
2337
+ }
2338
+ stateBeforeAttributeName(c) {
2339
+ if (c === CharCodes.Gt) {
2340
+ this.cbs.onopentagend(this.index);
2341
+ this.enterTagBody();
2342
+ this.sectionStart = this.index + 1;
2343
+ } else if (c === CharCodes.Slash) {
2344
+ this.state = State.InSelfClosingTag;
2345
+ } else if (!isWhitespace(c)) {
2346
+ this.state = State.InAttributeName;
2347
+ this.sectionStart = this.index;
2348
+ }
2349
+ }
2350
+ stateInSelfClosingTag(c) {
2351
+ if (c === CharCodes.Gt) {
2352
+ this.cbs.onselfclosingtag(this.index);
2353
+ this.sectionStart = this.index + 1;
2354
+ if (!this.recognizeSelfClosing) {
2355
+ this.enterTagBody();
2356
+ return;
2357
+ }
2358
+ this.state = State.Text;
2359
+ this.isSpecial = false;
2360
+ this.currentSequence = Sequences.Empty;
2361
+ } else if (!isWhitespace(c)) {
2362
+ this.state = State.BeforeAttributeName;
2363
+ this.stateBeforeAttributeName(c);
2364
+ }
2365
+ }
2366
+ stateInAttributeName(c) {
2367
+ if (c === CharCodes.Eq || isEndOfTagSection(c)) {
2368
+ this.cbs.onattribname(this.sectionStart, this.index);
2369
+ this.sectionStart = this.index;
2370
+ this.state = State.AfterAttributeName;
2371
+ this.stateAfterAttributeName(c);
2372
+ }
2373
+ }
2374
+ stateAfterAttributeName(c) {
2375
+ if (c === CharCodes.Eq) {
2376
+ this.state = State.BeforeAttributeValue;
2377
+ } else if (c === CharCodes.Slash || c === CharCodes.Gt) {
2378
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
2379
+ this.sectionStart = -1;
2380
+ this.state = State.BeforeAttributeName;
2381
+ this.stateBeforeAttributeName(c);
2382
+ } else if (!isWhitespace(c)) {
2383
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
2384
+ this.state = State.InAttributeName;
2385
+ this.sectionStart = this.index;
2386
+ }
2387
+ }
2388
+ stateBeforeAttributeValue(c) {
2389
+ if (c === CharCodes.DoubleQuote) {
2390
+ this.state = State.InAttributeValueDq;
2391
+ this.sectionStart = this.index + 1;
2392
+ } else if (c === CharCodes.SingleQuote) {
2393
+ this.state = State.InAttributeValueSq;
2394
+ this.sectionStart = this.index + 1;
2395
+ } else if (!isWhitespace(c)) {
2396
+ this.sectionStart = this.index;
2397
+ this.state = State.InAttributeValueNq;
2398
+ this.stateInAttributeValueNoQuotes(c);
2399
+ }
2400
+ }
2401
+ handleInAttributeValue(c, quote) {
2402
+ if (c === quote || this.fastForwardTo(quote)) {
2403
+ this.cbs.onattribdata(this.sectionStart, this.index);
2404
+ this.sectionStart = -1;
2405
+ this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1);
2406
+ this.state = State.BeforeAttributeName;
2407
+ }
2408
+ }
2409
+ stateInAttributeValueDoubleQuotes(c) {
2410
+ this.handleInAttributeValue(c, CharCodes.DoubleQuote);
2411
+ }
2412
+ stateInAttributeValueSingleQuotes(c) {
2413
+ this.handleInAttributeValue(c, CharCodes.SingleQuote);
2414
+ }
2415
+ stateInAttributeValueNoQuotes(c) {
2416
+ if (isWhitespace(c) || c === CharCodes.Gt) {
2417
+ this.cbs.onattribdata(this.sectionStart, this.index);
2418
+ this.sectionStart = -1;
2419
+ this.cbs.onattribend(QuoteType.Unquoted, this.index);
2420
+ this.state = State.BeforeAttributeName;
2421
+ this.stateBeforeAttributeName(c);
2422
+ }
2423
+ }
2424
+ stateBeforeDeclaration(c) {
2425
+ if (c === CharCodes.OpeningSquareBracket) {
2426
+ this.state = State.CDATASequence;
2427
+ this.sequenceIndex = 0;
2428
+ } else if (this.xmlMode) {
2429
+ this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
2430
+ } else if ((c | 32) === Sequences.Doctype[0]) {
2431
+ this.state = State.DeclarationSequence;
2432
+ this.currentSequence = Sequences.Doctype;
2433
+ this.sequenceIndex = 1;
2434
+ } else if (c === CharCodes.Gt) {
2435
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2436
+ this.state = State.Text;
2437
+ this.sectionStart = this.index + 1;
2438
+ } else if (c === CharCodes.Dash) {
2439
+ this.state = State.BeforeComment;
2440
+ } else {
2441
+ this.state = State.InSpecialComment;
2442
+ }
2443
+ }
2444
+ stateDeclarationSequence(c) {
2445
+ if (this.sequenceIndex === this.currentSequence.length) {
2446
+ this.state = State.InDeclaration;
2447
+ this.stateInDeclaration(c);
2448
+ } else if ((c | 32) === this.currentSequence[this.sequenceIndex]) {
2449
+ this.sequenceIndex += 1;
2450
+ } else if (c === CharCodes.Gt) {
2451
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2452
+ this.state = State.Text;
2453
+ this.sectionStart = this.index + 1;
2454
+ } else {
2455
+ this.state = State.InSpecialComment;
2456
+ }
2457
+ }
2458
+ stateInDeclaration(c) {
2459
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2460
+ this.cbs.ondeclaration(this.sectionStart, this.index);
2461
+ this.state = State.Text;
2462
+ this.sectionStart = this.index + 1;
2463
+ }
2464
+ }
2465
+ stateInProcessingInstruction(c) {
2466
+ if (c === CharCodes.Questionmark) {
2467
+ this.sequenceIndex = 1;
2468
+ } else if (c === CharCodes.Gt && this.sequenceIndex === 1) {
2469
+ this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);
2470
+ this.sequenceIndex = 0;
2471
+ this.state = State.Text;
2472
+ this.sectionStart = this.index + 1;
2473
+ } else {
2474
+ this.sequenceIndex = Number(this.fastForwardTo(CharCodes.Questionmark));
2475
+ }
2476
+ }
2477
+ stateBeforeComment(c) {
2478
+ if (c === CharCodes.Dash) {
2479
+ this.state = State.InCommentLike;
2480
+ this.currentSequence = Sequences.CommentEnd;
2481
+ this.sequenceIndex = 0;
2482
+ this.sectionStart = this.index + 1;
2483
+ } else if (this.xmlMode) {
2484
+ this.state = State.InDeclaration;
2485
+ } else if (c === CharCodes.Gt) {
2486
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2487
+ this.state = State.Text;
2488
+ this.sectionStart = this.index + 1;
2489
+ } else {
2490
+ this.state = State.InSpecialComment;
2491
+ }
2492
+ }
2493
+ stateInSpecialComment(c) {
2494
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2495
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2496
+ this.state = State.Text;
2497
+ this.sectionStart = this.index + 1;
2498
+ }
2499
+ }
2500
+ cleanup() {
2501
+ if (this.running && this.sectionStart !== this.index) {
2502
+ if (this.state === State.Text || this.state === State.InPlainText || this.state === State.InSpecialTag && this.sequenceIndex === 0) {
2503
+ this.cbs.ontext(this.sectionStart, this.index);
2504
+ this.sectionStart = this.index;
2505
+ } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
2506
+ this.cbs.onattribdata(this.sectionStart, this.index);
2507
+ this.sectionStart = this.index;
2508
+ }
2509
+ }
2510
+ }
2511
+ shouldContinue() {
2512
+ return this.index < this.buffer.length + this.offset && this.running;
2513
+ }
2514
+ parse() {
2515
+ while (this.shouldContinue()) {
2516
+ const c = this.buffer.charCodeAt(this.index - this.offset);
2517
+ switch (this.state) {
2518
+ case State.Text:
2519
+ this.stateText(c);
2520
+ break;
2521
+ case State.InPlainText:
2522
+ this.index = this.buffer.length + this.offset - 1;
2523
+ break;
2524
+ case State.SpecialStartSequence:
2525
+ this.stateSpecialStartSequence(c);
2526
+ break;
2527
+ case State.InSpecialTag:
2528
+ this.stateInSpecialTag(c);
2529
+ break;
2530
+ case State.CDATASequence:
2531
+ this.stateCDATASequence(c);
2532
+ break;
2533
+ case State.DeclarationSequence:
2534
+ this.stateDeclarationSequence(c);
2535
+ break;
2536
+ case State.InAttributeValueDq:
2537
+ this.stateInAttributeValueDoubleQuotes(c);
2538
+ break;
2539
+ case State.InAttributeName:
2540
+ this.stateInAttributeName(c);
2541
+ break;
2542
+ case State.InCommentLike:
2543
+ this.stateInCommentLike(c);
2544
+ break;
2545
+ case State.InSpecialComment:
2546
+ this.stateInSpecialComment(c);
2547
+ break;
2548
+ case State.BeforeAttributeName:
2549
+ this.stateBeforeAttributeName(c);
2550
+ break;
2551
+ case State.InTagName:
2552
+ this.stateInTagName(c);
2553
+ break;
2554
+ case State.InClosingTagName:
2555
+ this.stateInClosingTagName(c);
2556
+ break;
2557
+ case State.BeforeTagName:
2558
+ this.stateBeforeTagName(c);
2559
+ break;
2560
+ case State.AfterAttributeName:
2561
+ this.stateAfterAttributeName(c);
2562
+ break;
2563
+ case State.InAttributeValueSq:
2564
+ this.stateInAttributeValueSingleQuotes(c);
2565
+ break;
2566
+ case State.BeforeAttributeValue:
2567
+ this.stateBeforeAttributeValue(c);
2568
+ break;
2569
+ case State.BeforeClosingTagName:
2570
+ this.stateBeforeClosingTagName(c);
2571
+ break;
2572
+ case State.AfterClosingTagName:
2573
+ this.stateAfterClosingTagName(c);
2574
+ break;
2575
+ case State.InAttributeValueNq:
2576
+ this.stateInAttributeValueNoQuotes(c);
2577
+ break;
2578
+ case State.InSelfClosingTag:
2579
+ this.stateInSelfClosingTag(c);
2580
+ break;
2581
+ case State.InDeclaration:
2582
+ this.stateInDeclaration(c);
2583
+ break;
2584
+ case State.BeforeDeclaration:
2585
+ this.stateBeforeDeclaration(c);
2586
+ break;
2587
+ case State.BeforeComment:
2588
+ this.stateBeforeComment(c);
2589
+ break;
2590
+ case State.InProcessingInstruction:
2591
+ this.stateInProcessingInstruction(c);
2592
+ break;
2593
+ }
2594
+ this.index++;
2595
+ }
2596
+ this.cleanup();
2597
+ }
2598
+ finish() {
2599
+ this.handleTrailingData();
2600
+ this.cbs.onend();
2601
+ }
2602
+ handleTrailingCommentLikeData(endIndex) {
2603
+ if (this.state !== State.InCommentLike)
2604
+ return false;
2605
+ if (this.currentSequence === Sequences.CdataEnd) {
2606
+ if (this.xmlMode) {
2607
+ if (this.sectionStart < endIndex) {
2608
+ this.cbs.oncdata(this.sectionStart, endIndex, 0);
2609
+ }
2610
+ } else {
2611
+ const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;
2612
+ this.cbs.oncomment(cdataStart, endIndex, 0);
2613
+ }
2614
+ } else {
2615
+ const offset = this.xmlMode ? 0 : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);
2616
+ this.cbs.oncomment(this.sectionStart, endIndex, offset);
2617
+ }
2618
+ return true;
2619
+ }
2620
+ handleTrailingMarkupDeclaration(endIndex) {
2621
+ if (this.xmlMode) {
2622
+ switch (this.state) {
2623
+ case State.InSpecialComment:
2624
+ case State.BeforeComment:
2625
+ case State.CDATASequence:
2626
+ case State.DeclarationSequence:
2627
+ case State.InDeclaration:
2628
+ this.cbs.ontext(this.sectionStart, endIndex);
2629
+ return true;
2630
+ default:
2631
+ return false;
2632
+ }
2633
+ }
2634
+ switch (this.state) {
2635
+ case State.BeforeDeclaration:
2636
+ case State.InSpecialComment:
2637
+ case State.BeforeComment:
2638
+ case State.CDATASequence:
2639
+ this.cbs.oncomment(this.sectionStart, endIndex, 0);
2640
+ return true;
2641
+ case State.DeclarationSequence:
2642
+ if (this.sequenceIndex !== Sequences.Doctype.length) {
2643
+ this.cbs.oncomment(this.sectionStart, endIndex, 0);
2644
+ }
2645
+ return true;
2646
+ case State.InDeclaration:
2647
+ return true;
2648
+ default:
2649
+ return false;
2650
+ }
2651
+ }
2652
+ handleTrailingData() {
2653
+ const endIndex = this.buffer.length + this.offset;
2654
+ if (this.handleTrailingCommentLikeData(endIndex) || this.handleTrailingMarkupDeclaration(endIndex)) {
2655
+ return;
2656
+ }
2657
+ if (this.sectionStart >= endIndex)
2658
+ return;
2659
+ switch (this.state) {
2660
+ case State.InTagName:
2661
+ case State.BeforeAttributeName:
2662
+ case State.BeforeAttributeValue:
2663
+ case State.AfterAttributeName:
2664
+ case State.InAttributeName:
2665
+ case State.InAttributeValueSq:
2666
+ case State.InAttributeValueDq:
2667
+ case State.InAttributeValueNq:
2668
+ case State.InClosingTagName:
2669
+ break;
2670
+ default:
2671
+ this.cbs.ontext(this.sectionStart, endIndex);
2672
+ }
2673
+ }
2674
+ }
2675
+ var CharCodes, State, QuoteType, Sequences, specialStartSequences;
2676
+ var init_html_tokenizer = __esm(() => {
2677
+ CharCodes = {
2678
+ Tab: 9,
2679
+ NewLine: 10,
2680
+ FormFeed: 12,
2681
+ CarriageReturn: 13,
2682
+ Space: 32,
2683
+ ExclamationMark: 33,
2684
+ Number: 35,
2685
+ SingleQuote: 39,
2686
+ DoubleQuote: 34,
2687
+ Dash: 45,
2688
+ Slash: 47,
2689
+ Zero: 48,
2690
+ Nine: 57,
2691
+ Semi: 59,
2692
+ Lt: 60,
2693
+ Eq: 61,
2694
+ Gt: 62,
2695
+ Questionmark: 63,
2696
+ UpperA: 65,
2697
+ LowerA: 97,
2698
+ UpperF: 70,
2699
+ LowerF: 102,
2700
+ UpperZ: 90,
2701
+ LowerZ: 122,
2702
+ LowerX: 120,
2703
+ OpeningSquareBracket: 91
2704
+ };
2705
+ State = {
2706
+ Text: 1,
2707
+ BeforeTagName: 2,
2708
+ InTagName: 3,
2709
+ InSelfClosingTag: 4,
2710
+ BeforeClosingTagName: 5,
2711
+ InClosingTagName: 6,
2712
+ AfterClosingTagName: 7,
2713
+ BeforeAttributeName: 8,
2714
+ InAttributeName: 9,
2715
+ AfterAttributeName: 10,
2716
+ BeforeAttributeValue: 11,
2717
+ InAttributeValueDq: 12,
2718
+ InAttributeValueSq: 13,
2719
+ InAttributeValueNq: 14,
2720
+ BeforeDeclaration: 15,
2721
+ InDeclaration: 16,
2722
+ InProcessingInstruction: 17,
2723
+ BeforeComment: 18,
2724
+ CDATASequence: 19,
2725
+ DeclarationSequence: 20,
2726
+ InSpecialComment: 21,
2727
+ InCommentLike: 22,
2728
+ SpecialStartSequence: 23,
2729
+ InSpecialTag: 24,
2730
+ InPlainText: 25
2731
+ };
2732
+ QuoteType = {
2733
+ NoValue: 0,
2734
+ Unquoted: 1,
2735
+ Single: 2,
2736
+ Double: 3
2737
+ };
2738
+ Sequences = {
2739
+ Empty: new Uint8Array(0),
2740
+ Cdata: new Uint8Array([67, 68, 65, 84, 65, 91]),
2741
+ CdataEnd: new Uint8Array([93, 93, 62]),
2742
+ CommentEnd: new Uint8Array([45, 45, 33, 62]),
2743
+ Doctype: new Uint8Array([100, 111, 99, 116, 121, 112, 101]),
2744
+ IframeEnd: new Uint8Array([60, 47, 105, 102, 114, 97, 109, 101]),
2745
+ NoembedEnd: new Uint8Array([60, 47, 110, 111, 101, 109, 98, 101, 100]),
2746
+ NoframesEnd: new Uint8Array([60, 47, 110, 111, 102, 114, 97, 109, 101, 115]),
2747
+ Plaintext: new Uint8Array([60, 47, 112, 108, 97, 105, 110, 116, 101, 120, 116]),
2748
+ ScriptEnd: new Uint8Array([60, 47, 115, 99, 114, 105, 112, 116]),
2749
+ StyleEnd: new Uint8Array([60, 47, 115, 116, 121, 108, 101]),
2750
+ TitleEnd: new Uint8Array([60, 47, 116, 105, 116, 108, 101]),
2751
+ TextareaEnd: new Uint8Array([60, 47, 116, 101, 120, 116, 97, 114, 101, 97]),
2752
+ XmpEnd: new Uint8Array([60, 47, 120, 109, 112])
2753
+ };
2754
+ specialStartSequences = new Map([
2755
+ [Sequences.IframeEnd[2], Sequences.IframeEnd],
2756
+ [Sequences.NoembedEnd[2], Sequences.NoembedEnd],
2757
+ [Sequences.Plaintext[2], Sequences.Plaintext],
2758
+ [Sequences.ScriptEnd[2], Sequences.ScriptEnd],
2759
+ [Sequences.TitleEnd[2], Sequences.TitleEnd],
2760
+ [Sequences.XmpEnd[2], Sequences.XmpEnd]
2761
+ ]);
2762
+ });
2763
+
2764
+ // tools/core/htmllinter-tables.js
2765
+ var VOID_ELEMENTS, RAW_TEXT_ELEMENTS, RCDATA_ELEMENTS, SPECIAL_ELEMENTS, FORMATTING_ELEMENTS, DEFAULT_SCOPE_BOUNDARIES, SCOPE_LIST_ITEM, SCOPE_BUTTON, SCOPE_DEFAULT, SCOPE_TABLE, SCOPE_SELECT, STANDARD_SVG_CAMEL_ELEMENTS, STANDARD_SVG_CAMEL_ATTRS, MATHML_CAMEL_ATTRS, FOREIGN_BREAKOUT_TAGS, MATHML_TEXT_INTEGRATION_POINTS, BLOCK_LEVEL_AUTO_CLOSE_P, SELECT_VALID_CHILDREN, SELECT_BREAKOUT_TAGS, MODES, NS, FRAGMENT_CONTEXT_MODES;
2766
+ var init_htmllinter_tables = __esm(() => {
2767
+ VOID_ELEMENTS = new Set([
2768
+ "area",
2769
+ "base",
2770
+ "br",
2771
+ "col",
2772
+ "embed",
2773
+ "hr",
2774
+ "img",
2775
+ "input",
2776
+ "link",
2777
+ "meta",
2778
+ "source",
2779
+ "track",
2780
+ "wbr"
2781
+ ]);
2782
+ RAW_TEXT_ELEMENTS = new Set([
2783
+ "script",
2784
+ "style",
2785
+ "iframe",
2786
+ "noembed",
2787
+ "noframes",
2788
+ "noscript",
2789
+ "xmp",
2790
+ "plaintext"
2791
+ ]);
2792
+ RCDATA_ELEMENTS = new Set(["textarea", "title"]);
2793
+ SPECIAL_ELEMENTS = new Set([
2794
+ "address",
2795
+ "applet",
2796
+ "area",
2797
+ "article",
2798
+ "aside",
2799
+ "base",
2800
+ "basefont",
2801
+ "bgsound",
2802
+ "blockquote",
2803
+ "br",
2804
+ "button",
2805
+ "caption",
2806
+ "center",
2807
+ "col",
2808
+ "colgroup",
2809
+ "dd",
2810
+ "details",
2811
+ "dir",
2812
+ "div",
2813
+ "dl",
2814
+ "dt",
2815
+ "embed",
2816
+ "fieldset",
2817
+ "figcaption",
2818
+ "figure",
2819
+ "footer",
2820
+ "form",
2821
+ "h1",
2822
+ "h2",
2823
+ "h3",
2824
+ "h4",
2825
+ "h5",
2826
+ "h6",
2827
+ "header",
2828
+ "hgroup",
2829
+ "hr",
2830
+ "iframe",
2831
+ "img",
2832
+ "input",
2833
+ "keygen",
2834
+ "li",
2835
+ "link",
2836
+ "listing",
2837
+ "main",
2838
+ "marquee",
2839
+ "menu",
2840
+ "meta",
2841
+ "nav",
2842
+ "noembed",
2843
+ "noframes",
2844
+ "noscript",
2845
+ "object",
2846
+ "ol",
2847
+ "p",
2848
+ "param",
2849
+ "plaintext",
2850
+ "pre",
2851
+ "script",
2852
+ "search",
2853
+ "section",
2854
+ "select",
2855
+ "source",
2856
+ "style",
2857
+ "summary",
2858
+ "table",
2859
+ "tbody",
2860
+ "td",
2861
+ "template",
2862
+ "textarea",
2863
+ "tfoot",
2864
+ "th",
2865
+ "thead",
2866
+ "title",
2867
+ "tr",
2868
+ "track",
2869
+ "ul",
2870
+ "wbr",
2871
+ "xmp"
2872
+ ]);
2873
+ FORMATTING_ELEMENTS = new Set([
2874
+ "a",
2875
+ "b",
2876
+ "big",
2877
+ "code",
2878
+ "em",
2879
+ "font",
2880
+ "i",
2881
+ "nobr",
2882
+ "s",
2883
+ "small",
2884
+ "strike",
2885
+ "strong",
2886
+ "tt",
2887
+ "u"
2888
+ ]);
2889
+ DEFAULT_SCOPE_BOUNDARIES = new Set([
2890
+ "applet",
2891
+ "caption",
2892
+ "html",
2893
+ "table",
2894
+ "td",
2895
+ "th",
2896
+ "marquee",
2897
+ "object",
2898
+ "template"
2899
+ ]);
2900
+ SCOPE_LIST_ITEM = new Set([...DEFAULT_SCOPE_BOUNDARIES, "ol", "ul"]);
2901
+ SCOPE_BUTTON = new Set([...DEFAULT_SCOPE_BOUNDARIES, "button"]);
2902
+ SCOPE_DEFAULT = DEFAULT_SCOPE_BOUNDARIES;
2903
+ SCOPE_TABLE = new Set(["html", "table", "template"]);
2904
+ SCOPE_SELECT = new Set;
2905
+ STANDARD_SVG_CAMEL_ELEMENTS = new Set([
2906
+ "altGlyph",
2907
+ "altGlyphDef",
2908
+ "altGlyphItem",
2909
+ "animateColor",
2910
+ "animateMotion",
2911
+ "animateTransform",
2912
+ "clipPath",
2913
+ "feBlend",
2914
+ "feColorMatrix",
2915
+ "feComponentTransfer",
2916
+ "feComposite",
2917
+ "feConvolveMatrix",
2918
+ "feDiffuseLighting",
2919
+ "feDisplacementMap",
2920
+ "feDistantLight",
2921
+ "feDropShadow",
2922
+ "feFlood",
2923
+ "feFuncA",
2924
+ "feFuncB",
2925
+ "feFuncG",
2926
+ "feFuncR",
2927
+ "feGaussianBlur",
2928
+ "feImage",
2929
+ "feMerge",
2930
+ "feMergeNode",
2931
+ "feMorphology",
2932
+ "feOffset",
2933
+ "fePointLight",
2934
+ "feSpecularLighting",
2935
+ "feSpotLight",
2936
+ "feTile",
2937
+ "feTurbulence",
2938
+ "foreignObject",
2939
+ "glyphRef",
2940
+ "linearGradient",
2941
+ "radialGradient",
2942
+ "textPath"
2943
+ ]);
2944
+ STANDARD_SVG_CAMEL_ATTRS = new Set([
2945
+ "attributeName",
2946
+ "attributeType",
2947
+ "baseFrequency",
2948
+ "baseProfile",
2949
+ "calcMode",
2950
+ "clipPathUnits",
2951
+ "diffuseConstant",
2952
+ "edgeMode",
2953
+ "filterUnits",
2954
+ "glyphRef",
2955
+ "gradientTransform",
2956
+ "gradientUnits",
2957
+ "kernelMatrix",
2958
+ "kernelUnitLength",
2959
+ "keyPoints",
2960
+ "keySplines",
2961
+ "keyTimes",
2962
+ "lengthAdjust",
2963
+ "limitingConeAngle",
2964
+ "markerHeight",
2965
+ "markerUnits",
2966
+ "markerWidth",
2967
+ "maskContentUnits",
2968
+ "maskUnits",
2969
+ "numOctaves",
2970
+ "pathLength",
2971
+ "patternContentUnits",
2972
+ "patternTransform",
2973
+ "patternUnits",
2974
+ "pointsAtX",
2975
+ "pointsAtY",
2976
+ "pointsAtZ",
2977
+ "preserveAlpha",
2978
+ "preserveAspectRatio",
2979
+ "primitiveUnits",
2980
+ "refX",
2981
+ "refY",
2982
+ "repeatCount",
2983
+ "repeatDur",
2984
+ "requiredExtensions",
2985
+ "requiredFeatures",
2986
+ "specularConstant",
2987
+ "specularExponent",
2988
+ "spreadMethod",
2989
+ "startOffset",
2990
+ "stdDeviation",
2991
+ "stitchTiles",
2992
+ "surfaceScale",
2993
+ "systemLanguage",
2994
+ "tableValues",
2995
+ "targetX",
2996
+ "targetY",
2997
+ "textLength",
2998
+ "viewBox",
2999
+ "xChannelSelector",
3000
+ "yChannelSelector",
3001
+ "zoomAndPan"
3002
+ ]);
3003
+ MATHML_CAMEL_ATTRS = new Set(["definitionURL"]);
3004
+ FOREIGN_BREAKOUT_TAGS = new Set([
3005
+ "b",
3006
+ "big",
3007
+ "blockquote",
3008
+ "body",
3009
+ "br",
3010
+ "center",
3011
+ "code",
3012
+ "dd",
3013
+ "div",
3014
+ "dl",
3015
+ "dt",
3016
+ "em",
3017
+ "embed",
3018
+ "h1",
3019
+ "h2",
3020
+ "h3",
3021
+ "h4",
3022
+ "h5",
3023
+ "h6",
3024
+ "head",
3025
+ "hr",
3026
+ "i",
3027
+ "img",
3028
+ "li",
3029
+ "listing",
3030
+ "menu",
3031
+ "meta",
3032
+ "nobr",
3033
+ "ol",
3034
+ "p",
3035
+ "pre",
3036
+ "ruby",
3037
+ "s",
3038
+ "small",
3039
+ "span",
3040
+ "strong",
3041
+ "strike",
3042
+ "sub",
3043
+ "sup",
3044
+ "table",
3045
+ "tt",
3046
+ "u",
3047
+ "ul",
3048
+ "var"
3049
+ ]);
3050
+ MATHML_TEXT_INTEGRATION_POINTS = new Set(["mi", "mo", "mn", "ms", "mtext"]);
3051
+ BLOCK_LEVEL_AUTO_CLOSE_P = new Set([
3052
+ "address",
3053
+ "article",
3054
+ "aside",
3055
+ "blockquote",
3056
+ "center",
3057
+ "details",
3058
+ "dialog",
3059
+ "dir",
3060
+ "div",
3061
+ "dl",
3062
+ "fieldset",
3063
+ "figcaption",
3064
+ "figure",
3065
+ "footer",
3066
+ "form",
3067
+ "h1",
3068
+ "h2",
3069
+ "h3",
3070
+ "h4",
3071
+ "h5",
3072
+ "h6",
3073
+ "header",
3074
+ "hgroup",
3075
+ "hr",
3076
+ "main",
3077
+ "menu",
3078
+ "nav",
3079
+ "ol",
3080
+ "p",
3081
+ "plaintext",
3082
+ "pre",
3083
+ "search",
3084
+ "section",
3085
+ "summary",
3086
+ "table",
3087
+ "ul",
3088
+ "xmp",
3089
+ "li",
3090
+ "dd",
3091
+ "dt"
3092
+ ]);
3093
+ SELECT_VALID_CHILDREN = new Set(["option", "optgroup", "hr", "script", "template"]);
3094
+ SELECT_BREAKOUT_TAGS = new Set(["input", "keygen", "textarea", "select"]);
3095
+ MODES = Object.freeze({
3096
+ inBody: "inBody",
3097
+ inTable: "inTable",
3098
+ inTableText: "inTableText",
3099
+ inCaption: "inCaption",
3100
+ inColumnGroup: "inColumnGroup",
3101
+ inTableBody: "inTableBody",
3102
+ inRow: "inRow",
3103
+ inCell: "inCell",
3104
+ inSelect: "inSelect",
3105
+ inSelectInTable: "inSelectInTable",
3106
+ inTemplate: "inTemplate",
3107
+ text: "text"
3108
+ });
3109
+ NS = Object.freeze({
3110
+ html: "html",
3111
+ svg: "svg",
3112
+ math: "math"
3113
+ });
3114
+ FRAGMENT_CONTEXT_MODES = Object.freeze({
3115
+ template: { mode: MODES.inTemplate, ns: NS.html },
3116
+ body: { mode: MODES.inBody, ns: NS.html },
3117
+ div: { mode: MODES.inBody, ns: NS.html },
3118
+ table: { mode: MODES.inTable, ns: NS.html },
3119
+ tbody: { mode: MODES.inTableBody, ns: NS.html },
3120
+ thead: { mode: MODES.inTableBody, ns: NS.html },
3121
+ tfoot: { mode: MODES.inTableBody, ns: NS.html },
3122
+ caption: { mode: MODES.inCaption, ns: NS.html },
3123
+ colgroup: { mode: MODES.inColumnGroup, ns: NS.html },
3124
+ tr: { mode: MODES.inRow, ns: NS.html },
3125
+ td: { mode: MODES.inCell, ns: NS.html },
3126
+ th: { mode: MODES.inCell, ns: NS.html },
3127
+ select: { mode: MODES.inSelect, ns: NS.html },
3128
+ svg: { mode: MODES.inBody, ns: NS.svg },
3129
+ math: { mode: MODES.inBody, ns: NS.math }
3130
+ });
3131
+ });
3132
+
3133
+ // tools/core/htmllinter.js
3134
+ function lintHtml(html, onFinding, opts = {}) {
3135
+ const TokenizerClass = opts.TokenizerClass ?? HtmlTokenizer;
3136
+ const ctx = new LinterCtx(html, onFinding, opts);
3137
+ const tokenizer = new TokenizerClass({ xmlMode: false, decodeEntities: false, recognizeSelfClosing: true }, ctx);
3138
+ ctx.tokenizer = tokenizer;
3139
+ tokenizer.write(html);
3140
+ tokenizer.end();
3141
+ return ctx.findingCount;
3142
+ }
3143
+
3144
+ class LinterCtx {
3145
+ constructor(html, onFinding, opts) {
3146
+ this.html = html;
3147
+ this.onFinding = onFinding;
3148
+ this.findingCount = 0;
3149
+ this.lineStarts = computeLineStarts(html);
3150
+ const ctxName = opts.fragmentContext ?? "template";
3151
+ const ctxInfo = FRAGMENT_CONTEXT_MODES[ctxName] ?? FRAGMENT_CONTEXT_MODES.template;
3152
+ this.openElements = [];
3153
+ if (ctxName === "tr") {
3154
+ this.openElements.push({ name: "table", ns: NS.html, start: -1 });
3155
+ this.openElements.push({ name: "tbody", ns: NS.html, start: -1 });
3156
+ } else if (ctxName === "tbody" || ctxName === "thead" || ctxName === "tfoot") {
3157
+ this.openElements.push({ name: "table", ns: NS.html, start: -1 });
3158
+ } else if (ctxName === "td" || ctxName === "th") {
3159
+ this.openElements.push({ name: "table", ns: NS.html, start: -1 });
3160
+ this.openElements.push({ name: "tbody", ns: NS.html, start: -1 });
3161
+ this.openElements.push({ name: "tr", ns: NS.html, start: -1 });
3162
+ } else if (ctxName === "caption") {
3163
+ this.openElements.push({ name: "table", ns: NS.html, start: -1 });
3164
+ } else if (ctxName === "colgroup") {
3165
+ this.openElements.push({ name: "table", ns: NS.html, start: -1 });
3166
+ } else if (ctxName === "svg") {
3167
+ this.openElements.push({ name: "svg", ns: NS.svg, start: -1 });
3168
+ } else if (ctxName === "math") {
3169
+ this.openElements.push({ name: "math", ns: NS.math, start: -1 });
3170
+ } else if (ctxName === "select") {
3171
+ this.openElements.push({ name: "select", ns: NS.html, start: -1 });
3172
+ }
3173
+ this.insertionMode = ctxInfo.mode;
3174
+ this.originalInsertionMode = MODES.inBody;
3175
+ this.templateInsertionModes = ctxName === "template" ? [MODES.inTemplate] : [];
3176
+ this.activeFormatting = [];
3177
+ this.formPointer = null;
3178
+ this.framesetOk = true;
3179
+ this.svgCamelElements = opts.svgCamelElements ?? STANDARD_SVG_CAMEL_ELEMENTS;
3180
+ this.transparentTagPrefixes = opts.transparentTagPrefixes ?? [];
3181
+ this.currentTagName = "";
3182
+ this.currentTagRawName = "";
3183
+ this.currentTagStart = 0;
3184
+ this.tokenizer = null;
3185
+ this.textRestoreMode = null;
3186
+ }
3187
+ onopentagname(start, end) {
3188
+ const raw = this.html.slice(start, end);
3189
+ this.currentTagRawName = raw;
3190
+ this.currentTagName = raw.toLowerCase();
3191
+ this.currentTagStart = start;
3192
+ }
3193
+ onattribname(_start, _end) {}
3194
+ onattribdata(_start, _end) {}
3195
+ onattribentity(_cp) {}
3196
+ onattribend(_quote, _end) {}
3197
+ ontextentity(_cp, _end) {}
3198
+ onopentagend(endIndex) {
3199
+ this.handleStartTag(false, endIndex);
3200
+ }
3201
+ onselfclosingtag(endIndex) {
3202
+ this.handleStartTag(true, endIndex);
3203
+ }
3204
+ onclosetag(start, end) {
3205
+ const raw = this.html.slice(start, end);
3206
+ const name = raw.toLowerCase();
3207
+ this.handleEndTag(name, start);
3208
+ }
3209
+ ontext(start, end) {
3210
+ if (start >= end)
3211
+ return;
3212
+ this.handleText(start, end);
3213
+ }
3214
+ oncomment(_start, _end, _endOffset) {}
3215
+ oncdata(start, _end, _endOffset) {
3216
+ if (this.currentNamespace() === NS.html) {
3217
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_WARN, start, {
3218
+ tag: "[CDATA[",
3219
+ mode: this.insertionMode,
3220
+ action: "ignored"
3221
+ });
3222
+ }
3223
+ }
3224
+ ondeclaration(_start, _end) {}
3225
+ onprocessinginstruction(_start, _end) {}
3226
+ isInForeignContext() {
3227
+ return this.currentNamespace() !== NS.html;
3228
+ }
3229
+ onend() {}
3230
+ report(id, level, offset, info) {
3231
+ this.findingCount++;
3232
+ const { line, column } = offsetToLineCol(this.lineStarts, offset);
3233
+ this.onFinding({
3234
+ id,
3235
+ level,
3236
+ info,
3237
+ location: { start: offset, end: offset + (info.tag?.length ?? 0), line, column }
3238
+ });
3239
+ }
3240
+ currentNode() {
3241
+ return this.openElements[this.openElements.length - 1] ?? null;
3242
+ }
3243
+ currentNamespace() {
3244
+ const top = this.currentNode();
3245
+ return top ? top.ns : NS.html;
3246
+ }
3247
+ push(name, ns, start) {
3248
+ this.openElements.push({ name, ns, start });
3249
+ }
3250
+ pop() {
3251
+ return this.openElements.pop();
3252
+ }
3253
+ hasInScope(target, scopeSet) {
3254
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3255
+ const f = this.openElements[i];
3256
+ if (f.name === target && f.ns === NS.html)
3257
+ return true;
3258
+ if (f.ns === NS.html && scopeSet.has(f.name))
3259
+ return false;
3260
+ if (f.ns !== NS.html) {
3261
+ return false;
3262
+ }
3263
+ }
3264
+ return false;
3265
+ }
3266
+ hasInDefaultScope(target) {
3267
+ return this.hasInScope(target, SCOPE_DEFAULT);
3268
+ }
3269
+ hasInButtonScope(target) {
3270
+ return this.hasInScope(target, SCOPE_BUTTON);
3271
+ }
3272
+ hasInListItemScope(target) {
3273
+ return this.hasInScope(target, SCOPE_LIST_ITEM);
3274
+ }
3275
+ hasInTableScope(target) {
3276
+ return this.hasInScope(target, SCOPE_TABLE);
3277
+ }
3278
+ hasInSelectScope(target) {
3279
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3280
+ const f = this.openElements[i];
3281
+ if (f.ns !== NS.html)
3282
+ return false;
3283
+ if (f.name === target)
3284
+ return true;
3285
+ if (f.name !== "optgroup" && f.name !== "option")
3286
+ return false;
3287
+ }
3288
+ return false;
3289
+ }
3290
+ popUntilName(name) {
3291
+ while (this.openElements.length) {
3292
+ const f = this.openElements.pop();
3293
+ if (f.name === name)
3294
+ return f;
3295
+ }
3296
+ return null;
3297
+ }
3298
+ generateImpliedEndTags(except = null) {
3299
+ const implied = new Set(["dd", "dt", "li", "optgroup", "option", "p", "rb", "rp", "rt", "rtc"]);
3300
+ while (this.openElements.length) {
3301
+ const top = this.currentNode();
3302
+ if (top.ns !== NS.html)
3303
+ break;
3304
+ if (!implied.has(top.name) || top.name === except)
3305
+ break;
3306
+ this.openElements.pop();
3307
+ }
3308
+ }
3309
+ isTransparentTag(name) {
3310
+ for (const prefix of this.transparentTagPrefixes) {
3311
+ if (name === prefix || name.startsWith(`${prefix}:`))
3312
+ return true;
3313
+ }
3314
+ return false;
3315
+ }
3316
+ handleStartTag(selfClosing, endIndex) {
3317
+ const name = this.currentTagName;
3318
+ const raw = this.currentTagRawName;
3319
+ const start = this.currentTagStart;
3320
+ const ns = this.currentNamespace();
3321
+ if (ns === NS.html) {
3322
+ if (raw !== name) {
3323
+ this.report(HTML_TAG_NAME_HAS_UPPERCASE, LEVEL_ERROR, start, {
3324
+ raw,
3325
+ lowercased: name
3326
+ });
3327
+ }
3328
+ } else if (ns === NS.svg) {
3329
+ if (raw !== raw.toLowerCase() && !this.svgCamelElements.has(raw)) {
3330
+ this.report(HTML_SVG_TAG_WILL_LOWERCASE, LEVEL_ERROR, start, {
3331
+ raw,
3332
+ lowercased: name
3333
+ });
3334
+ }
3335
+ }
3336
+ if (this.isTransparentTag(name))
3337
+ return;
3338
+ if (ns !== NS.html && !this.shouldBreakoutFromForeign(name)) {
3339
+ this.startTagInForeign(name, raw, selfClosing, start);
3340
+ return;
3341
+ }
3342
+ if (ns !== NS.html && this.shouldBreakoutFromForeign(name)) {
3343
+ while (this.openElements.length && this.currentNode()?.ns !== NS.html) {
3344
+ this.openElements.pop();
3345
+ }
3346
+ }
3347
+ this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3348
+ }
3349
+ shouldBreakoutFromForeign(name) {
3350
+ if (FOREIGN_BREAKOUT_TAGS.has(name))
3351
+ return true;
3352
+ if (name === "font")
3353
+ return true;
3354
+ return false;
3355
+ }
3356
+ startTagInForeign(name, raw, selfClosing, start) {
3357
+ const ns = name === "svg" ? NS.svg : name === "math" ? NS.math : this.currentNamespace();
3358
+ const top = this.currentNode();
3359
+ if (top && top.ns === NS.math && MATHML_TEXT_INTEGRATION_POINTS.has(top.name) && name !== "mglyph" && name !== "malignmark") {
3360
+ this.dispatchStartTag(name, raw, selfClosing, start, start + raw.length);
3361
+ return;
3362
+ }
3363
+ if (selfClosing)
3364
+ return;
3365
+ this.push(raw, ns, start);
3366
+ }
3367
+ dispatchStartTag(name, raw, selfClosing, start, endIndex) {
3368
+ switch (this.insertionMode) {
3369
+ case MODES.inTemplate:
3370
+ return this.startInTemplate(name, raw, selfClosing, start, endIndex);
3371
+ case MODES.inBody:
3372
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3373
+ case MODES.inTable:
3374
+ return this.startInTable(name, raw, selfClosing, start, endIndex);
3375
+ case MODES.inTableText:
3376
+ this.flushTableText();
3377
+ this.insertionMode = this.originalInsertionMode;
3378
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3379
+ case MODES.inCaption:
3380
+ return this.startInCaption(name, raw, selfClosing, start, endIndex);
3381
+ case MODES.inColumnGroup:
3382
+ return this.startInColumnGroup(name, raw, selfClosing, start, endIndex);
3383
+ case MODES.inTableBody:
3384
+ return this.startInTableBody(name, raw, selfClosing, start, endIndex);
3385
+ case MODES.inRow:
3386
+ return this.startInRow(name, raw, selfClosing, start, endIndex);
3387
+ case MODES.inCell:
3388
+ return this.startInCell(name, raw, selfClosing, start, endIndex);
3389
+ case MODES.inSelect:
3390
+ return this.startInSelect(name, raw, selfClosing, start, endIndex);
3391
+ case MODES.inSelectInTable:
3392
+ return this.startInSelectInTable(name, raw, selfClosing, start, endIndex);
3393
+ case MODES.text:
3394
+ return;
3395
+ }
3396
+ }
3397
+ startInBody(name, raw, selfClosing, start, _endIndex) {
3398
+ if (name === "html" || name === "head" || name === "body" || name === "frame" || name === "frameset") {
3399
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_WARN, start, {
3400
+ tag: raw,
3401
+ mode: this.insertionMode,
3402
+ action: "ignored"
3403
+ });
3404
+ return;
3405
+ }
3406
+ if (name === "address" || name === "article" || name === "aside" || name === "blockquote" || name === "center" || name === "details" || name === "dialog" || name === "dir" || name === "div" || name === "dl" || name === "fieldset" || name === "figcaption" || name === "figure" || name === "footer" || name === "header" || name === "hgroup" || name === "main" || name === "menu" || name === "nav" || name === "ol" || name === "p" || name === "search" || name === "section" || name === "summary" || name === "ul") {
3407
+ if (this.hasInButtonScope("p"))
3408
+ this.implicitlyClose("p", start, raw);
3409
+ this.push(raw, NS.html, start);
3410
+ return;
3411
+ }
3412
+ if (name === "h1" || name === "h2" || name === "h3" || name === "h4" || name === "h5" || name === "h6") {
3413
+ if (this.hasInButtonScope("p"))
3414
+ this.implicitlyClose("p", start, raw);
3415
+ const top = this.currentNode();
3416
+ if (top && /^h[1-6]$/.test(top.name)) {
3417
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3418
+ tag: raw,
3419
+ parent: top.name,
3420
+ mode: this.insertionMode,
3421
+ action: "auto-close-implicit"
3422
+ });
3423
+ this.openElements.pop();
3424
+ }
3425
+ this.push(raw, NS.html, start);
3426
+ return;
3427
+ }
3428
+ if (name === "pre" || name === "listing") {
3429
+ if (this.hasInButtonScope("p"))
3430
+ this.implicitlyClose("p", start, raw);
3431
+ this.push(raw, NS.html, start);
3432
+ this.framesetOk = false;
3433
+ return;
3434
+ }
3435
+ if (name === "form") {
3436
+ if (this.formPointer !== null && !this.openElementsHas("template")) {
3437
+ this.report(HTML_DUPLICATE_FORM, LEVEL_ERROR, start, {
3438
+ tag: raw,
3439
+ mode: this.insertionMode
3440
+ });
3441
+ return;
3442
+ }
3443
+ if (this.hasInButtonScope("p"))
3444
+ this.implicitlyClose("p", start, raw);
3445
+ this.push(raw, NS.html, start);
3446
+ this.formPointer = this.currentNode();
3447
+ return;
3448
+ }
3449
+ if (name === "li") {
3450
+ this.framesetOk = false;
3451
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3452
+ const f = this.openElements[i];
3453
+ if (f.ns !== NS.html)
3454
+ break;
3455
+ if (f.name === "li") {
3456
+ this.generateImpliedEndTags("li");
3457
+ while (this.openElements.length) {
3458
+ const popped = this.openElements.pop();
3459
+ if (popped.name === "li")
3460
+ break;
3461
+ }
3462
+ break;
3463
+ }
3464
+ if (SPECIAL_ELEMENTS.has(f.name) && f.name !== "address" && f.name !== "div" && f.name !== "p") {
3465
+ break;
3466
+ }
3467
+ }
3468
+ if (this.hasInButtonScope("p"))
3469
+ this.implicitlyClose("p", start, raw);
3470
+ this.push(raw, NS.html, start);
3471
+ return;
3472
+ }
3473
+ if (name === "dd" || name === "dt") {
3474
+ this.framesetOk = false;
3475
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3476
+ const f = this.openElements[i];
3477
+ if (f.ns !== NS.html)
3478
+ break;
3479
+ if (f.name === "dd" || f.name === "dt") {
3480
+ this.generateImpliedEndTags(f.name);
3481
+ while (this.openElements.length) {
3482
+ const popped = this.openElements.pop();
3483
+ if (popped.name === f.name)
3484
+ break;
3485
+ }
3486
+ break;
3487
+ }
3488
+ if (SPECIAL_ELEMENTS.has(f.name) && f.name !== "address" && f.name !== "div" && f.name !== "p") {
3489
+ break;
3490
+ }
3491
+ }
3492
+ if (this.hasInButtonScope("p"))
3493
+ this.implicitlyClose("p", start, raw);
3494
+ this.push(raw, NS.html, start);
3495
+ return;
3496
+ }
3497
+ if (name === "plaintext") {
3498
+ if (this.hasInButtonScope("p"))
3499
+ this.implicitlyClose("p", start, raw);
3500
+ this.push(raw, NS.html, start);
3501
+ return;
3502
+ }
3503
+ if (name === "button") {
3504
+ if (this.hasInDefaultScope("button")) {
3505
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3506
+ tag: raw,
3507
+ parent: "button",
3508
+ mode: this.insertionMode,
3509
+ action: "auto-close-implicit"
3510
+ });
3511
+ this.generateImpliedEndTags();
3512
+ this.popUntilName("button");
3513
+ }
3514
+ this.push(raw, NS.html, start);
3515
+ this.framesetOk = false;
3516
+ return;
3517
+ }
3518
+ if (name === "a") {
3519
+ if (this.openElementsHas("a") || this.activeFormattingHas("a")) {
3520
+ this.report(HTML_NESTED_INTERACTIVE, LEVEL_WARN, start, {
3521
+ tag: raw,
3522
+ mode: this.insertionMode
3523
+ });
3524
+ this.runAdoptionAgency("a");
3525
+ }
3526
+ this.push(raw, NS.html, start);
3527
+ this.activeFormatting.push(this.currentNode());
3528
+ return;
3529
+ }
3530
+ if (FORMATTING_ELEMENTS.has(name)) {
3531
+ this.push(raw, NS.html, start);
3532
+ this.activeFormatting.push(this.currentNode());
3533
+ return;
3534
+ }
3535
+ if (name === "nobr") {
3536
+ if (this.hasInDefaultScope("nobr")) {
3537
+ this.report(HTML_NESTED_INTERACTIVE, LEVEL_WARN, start, {
3538
+ tag: raw,
3539
+ mode: this.insertionMode
3540
+ });
3541
+ this.runAdoptionAgency("nobr");
3542
+ }
3543
+ this.push(raw, NS.html, start);
3544
+ this.activeFormatting.push(this.currentNode());
3545
+ return;
3546
+ }
3547
+ if (name === "table") {
3548
+ if (this.hasInButtonScope("p"))
3549
+ this.implicitlyClose("p", start, raw);
3550
+ this.push(raw, NS.html, start);
3551
+ this.framesetOk = false;
3552
+ this.insertionMode = MODES.inTable;
3553
+ return;
3554
+ }
3555
+ if (name === "area" || name === "br" || name === "embed" || name === "img" || name === "keygen" || name === "wbr" || name === "input" || name === "param" || name === "source" || name === "track" || name === "hr" || name === "meta" || name === "link" || name === "col" || name === "base") {
3556
+ this.framesetOk = false;
3557
+ return;
3558
+ }
3559
+ if (name === "select") {
3560
+ if (this.hasInButtonScope("p"))
3561
+ this.implicitlyClose("p", start, raw);
3562
+ this.push(raw, NS.html, start);
3563
+ this.framesetOk = false;
3564
+ this.insertionMode = MODES.inSelect;
3565
+ return;
3566
+ }
3567
+ if (name === "option" || name === "optgroup") {
3568
+ if (this.currentNode()?.name === "option") {
3569
+ this.openElements.pop();
3570
+ }
3571
+ this.push(raw, NS.html, start);
3572
+ return;
3573
+ }
3574
+ if (name === "textarea" || name === "title" || RAW_TEXT_ELEMENTS.has(name)) {
3575
+ this.push(raw, NS.html, start);
3576
+ return;
3577
+ }
3578
+ if (name === "math" || name === "svg") {
3579
+ this.push(raw, name === "svg" ? NS.svg : NS.math, start);
3580
+ this.framesetOk = false;
3581
+ return;
3582
+ }
3583
+ if (name === "caption" || name === "col" || name === "colgroup" || name === "frame" || name === "tbody" || name === "td" || name === "tfoot" || name === "th" || name === "thead" || name === "tr") {
3584
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3585
+ tag: raw,
3586
+ parent: this.currentNode()?.name ?? "(root)",
3587
+ mode: this.insertionMode,
3588
+ action: "ignored"
3589
+ });
3590
+ return;
3591
+ }
3592
+ if (selfClosing)
3593
+ return;
3594
+ this.push(raw, NS.html, start);
3595
+ }
3596
+ openElementsHas(name) {
3597
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3598
+ const f = this.openElements[i];
3599
+ if (f.ns === NS.html && f.name === name)
3600
+ return true;
3601
+ }
3602
+ return false;
3603
+ }
3604
+ activeFormattingHas(name) {
3605
+ for (let i = this.activeFormatting.length - 1;i >= 0; i--) {
3606
+ const e = this.activeFormatting[i];
3607
+ if (e === null)
3608
+ return false;
3609
+ if (e.name === name)
3610
+ return true;
3611
+ }
3612
+ return false;
3613
+ }
3614
+ runAdoptionAgency(name) {
3615
+ for (let i = this.activeFormatting.length - 1;i >= 0; i--) {
3616
+ const e = this.activeFormatting[i];
3617
+ if (e === null)
3618
+ break;
3619
+ if (e.name === name) {
3620
+ this.activeFormatting.splice(i, 1);
3621
+ const idx = this.openElements.indexOf(e);
3622
+ if (idx >= 0)
3623
+ this.openElements.splice(idx, 1);
3624
+ return;
3625
+ }
3626
+ }
3627
+ }
3628
+ implicitlyClose(name, _start, _newTagRaw) {
3629
+ while (this.openElements.length) {
3630
+ const popped = this.openElements.pop();
3631
+ if (popped.name === name)
3632
+ break;
3633
+ }
3634
+ }
3635
+ startInTemplate(name, raw, selfClosing, start, endIndex) {
3636
+ let next;
3637
+ if (name === "caption" || name === "colgroup" || name === "tbody" || name === "tfoot" || name === "thead") {
3638
+ next = MODES.inTable;
3639
+ } else if (name === "col") {
3640
+ next = MODES.inColumnGroup;
3641
+ } else if (name === "tr") {
3642
+ next = MODES.inTableBody;
3643
+ } else if (name === "td" || name === "th") {
3644
+ next = MODES.inRow;
3645
+ } else {
3646
+ this.popTemplateMode();
3647
+ this.pushTemplateMode(MODES.inBody);
3648
+ this.insertionMode = MODES.inBody;
3649
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3650
+ }
3651
+ this.popTemplateMode();
3652
+ this.pushTemplateMode(next);
3653
+ this.insertionMode = next;
3654
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3655
+ }
3656
+ popTemplateMode() {
3657
+ if (this.templateInsertionModes.length)
3658
+ this.templateInsertionModes.pop();
3659
+ }
3660
+ pushTemplateMode(mode) {
3661
+ this.templateInsertionModes.push(mode);
3662
+ }
3663
+ startInTable(name, raw, selfClosing, start, endIndex) {
3664
+ if (name === "caption") {
3665
+ this.clearStackBackToTable();
3666
+ this.activeFormatting.push(null);
3667
+ this.push(raw, NS.html, start);
3668
+ this.insertionMode = MODES.inCaption;
3669
+ return;
3670
+ }
3671
+ if (name === "colgroup") {
3672
+ this.clearStackBackToTable();
3673
+ this.push(raw, NS.html, start);
3674
+ this.insertionMode = MODES.inColumnGroup;
3675
+ return;
3676
+ }
3677
+ if (name === "col") {
3678
+ this.clearStackBackToTable();
3679
+ this.push("colgroup", NS.html, start);
3680
+ this.insertionMode = MODES.inColumnGroup;
3681
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3682
+ }
3683
+ if (name === "tbody" || name === "thead" || name === "tfoot") {
3684
+ this.clearStackBackToTable();
3685
+ this.push(raw, NS.html, start);
3686
+ this.insertionMode = MODES.inTableBody;
3687
+ return;
3688
+ }
3689
+ if (name === "td" || name === "th" || name === "tr") {
3690
+ this.clearStackBackToTable();
3691
+ this.push("tbody", NS.html, start);
3692
+ this.insertionMode = MODES.inTableBody;
3693
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3694
+ }
3695
+ if (name === "table") {
3696
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3697
+ tag: raw,
3698
+ parent: "table",
3699
+ mode: this.insertionMode,
3700
+ action: "auto-close-implicit"
3701
+ });
3702
+ if (this.hasInTableScope("table")) {
3703
+ this.popUntilName("table");
3704
+ this.resetInsertionModeAppropriately();
3705
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3706
+ }
3707
+ return;
3708
+ }
3709
+ if (name === "style" || name === "script" || name === "template") {
3710
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3711
+ }
3712
+ if (name === "input") {
3713
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_WARN, start, {
3714
+ tag: raw,
3715
+ parent: "table",
3716
+ mode: this.insertionMode,
3717
+ action: "foster-parent"
3718
+ });
3719
+ return;
3720
+ }
3721
+ if (name === "form") {
3722
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3723
+ tag: raw,
3724
+ parent: "table",
3725
+ mode: this.insertionMode,
3726
+ action: "ignored"
3727
+ });
3728
+ return;
3729
+ }
3730
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3731
+ tag: raw,
3732
+ parent: this.currentNode()?.name ?? "table",
3733
+ mode: this.insertionMode,
3734
+ action: "foster-parent"
3735
+ });
3736
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3737
+ }
3738
+ clearStackBackToTable() {
3739
+ while (this.openElements.length) {
3740
+ const top = this.currentNode();
3741
+ if (!top)
3742
+ break;
3743
+ if (top.name === "table" || top.name === "template")
3744
+ break;
3745
+ this.openElements.pop();
3746
+ }
3747
+ }
3748
+ flushTableText() {
3749
+ if (!this.pendingTableText)
3750
+ return;
3751
+ const { hasNonWhitespace, start, snippet } = this.pendingTableText;
3752
+ if (hasNonWhitespace) {
3753
+ this.report(HTML_TEXT_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3754
+ mode: this.originalInsertionMode,
3755
+ snippet
3756
+ });
3757
+ }
3758
+ this.pendingTableText = null;
3759
+ }
3760
+ startInCaption(name, raw, selfClosing, start, endIndex) {
3761
+ if (name === "caption" || name === "col" || name === "colgroup" || name === "tbody" || name === "td" || name === "tfoot" || name === "th" || name === "thead" || name === "tr") {
3762
+ if (this.hasInTableScope("caption")) {
3763
+ this.generateImpliedEndTags();
3764
+ this.popUntilName("caption");
3765
+ this.clearActiveFormattingToMarker();
3766
+ this.insertionMode = MODES.inTable;
3767
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3768
+ }
3769
+ return;
3770
+ }
3771
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3772
+ }
3773
+ clearActiveFormattingToMarker() {
3774
+ while (this.activeFormatting.length) {
3775
+ const e = this.activeFormatting.pop();
3776
+ if (e === null)
3777
+ return;
3778
+ }
3779
+ }
3780
+ startInColumnGroup(name, raw, selfClosing, start, endIndex) {
3781
+ if (name === "col") {
3782
+ return;
3783
+ }
3784
+ if (name === "template") {
3785
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3786
+ }
3787
+ if (this.currentNode()?.name === "colgroup") {
3788
+ this.openElements.pop();
3789
+ this.insertionMode = MODES.inTable;
3790
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3791
+ }
3792
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3793
+ tag: raw,
3794
+ parent: "colgroup",
3795
+ mode: this.insertionMode,
3796
+ action: "ignored"
3797
+ });
3798
+ }
3799
+ startInTableBody(name, raw, selfClosing, start, endIndex) {
3800
+ if (name === "tr") {
3801
+ this.clearStackBackToTableBody();
3802
+ this.push(raw, NS.html, start);
3803
+ this.insertionMode = MODES.inRow;
3804
+ return;
3805
+ }
3806
+ if (TABLE_BODY_CELL_TAGS.has(name)) {
3807
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_WARN, start, {
3808
+ tag: raw,
3809
+ parent: this.currentNode()?.name ?? "tbody",
3810
+ mode: this.insertionMode,
3811
+ action: "auto-close-implicit"
3812
+ });
3813
+ this.clearStackBackToTableBody();
3814
+ this.push("tr", NS.html, start);
3815
+ this.insertionMode = MODES.inRow;
3816
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3817
+ }
3818
+ if (name === "caption" || name === "col" || name === "colgroup" || name === "tbody" || name === "tfoot" || name === "thead") {
3819
+ if (this.hasInTableScope("tbody") || this.hasInTableScope("thead") || this.hasInTableScope("tfoot")) {
3820
+ this.clearStackBackToTableBody();
3821
+ this.openElements.pop();
3822
+ this.insertionMode = MODES.inTable;
3823
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3824
+ }
3825
+ return;
3826
+ }
3827
+ return this.startInTable(name, raw, selfClosing, start, endIndex);
3828
+ }
3829
+ clearStackBackToTableBody() {
3830
+ while (this.openElements.length) {
3831
+ const top = this.currentNode();
3832
+ if (!top)
3833
+ break;
3834
+ if (top.name === "tbody" || top.name === "thead" || top.name === "tfoot" || top.name === "template" || top.name === "table")
3835
+ break;
3836
+ this.openElements.pop();
3837
+ }
3838
+ }
3839
+ startInRow(name, raw, selfClosing, start, endIndex) {
3840
+ if (TABLE_BODY_CELL_TAGS.has(name)) {
3841
+ this.clearStackBackToTableRow();
3842
+ this.push(raw, NS.html, start);
3843
+ this.insertionMode = MODES.inCell;
3844
+ this.activeFormatting.push(null);
3845
+ return;
3846
+ }
3847
+ if (name === "caption" || name === "col" || name === "colgroup" || name === "tbody" || name === "tfoot" || name === "thead" || name === "tr") {
3848
+ if (this.hasInTableScope("tr")) {
3849
+ this.clearStackBackToTableRow();
3850
+ this.openElements.pop();
3851
+ this.insertionMode = MODES.inTableBody;
3852
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3853
+ }
3854
+ return;
3855
+ }
3856
+ return this.startInTable(name, raw, selfClosing, start, endIndex);
3857
+ }
3858
+ clearStackBackToTableRow() {
3859
+ while (this.openElements.length) {
3860
+ const top = this.currentNode();
3861
+ if (!top)
3862
+ break;
3863
+ if (top.name === "tr" || top.name === "template" || top.name === "table")
3864
+ break;
3865
+ this.openElements.pop();
3866
+ }
3867
+ }
3868
+ startInCell(name, raw, selfClosing, start, endIndex) {
3869
+ if (name === "caption" || name === "col" || name === "colgroup" || name === "tbody" || name === "td" || name === "tfoot" || name === "th" || name === "thead" || name === "tr") {
3870
+ if (this.hasInTableScope("td") || this.hasInTableScope("th")) {
3871
+ this.closeCell();
3872
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3873
+ }
3874
+ return;
3875
+ }
3876
+ return this.startInBody(name, raw, selfClosing, start, endIndex);
3877
+ }
3878
+ closeCell() {
3879
+ this.generateImpliedEndTags();
3880
+ while (this.openElements.length) {
3881
+ const popped = this.openElements.pop();
3882
+ if (popped.name === "td" || popped.name === "th")
3883
+ break;
3884
+ }
3885
+ this.clearActiveFormattingToMarker();
3886
+ this.insertionMode = MODES.inRow;
3887
+ }
3888
+ startInSelect(name, raw, _selfClosing, start, _endIndex) {
3889
+ if (name === "option") {
3890
+ if (this.currentNode()?.name === "option")
3891
+ this.openElements.pop();
3892
+ this.push(raw, NS.html, start);
3893
+ return;
3894
+ }
3895
+ if (name === "optgroup") {
3896
+ if (this.currentNode()?.name === "option")
3897
+ this.openElements.pop();
3898
+ if (this.currentNode()?.name === "optgroup")
3899
+ this.openElements.pop();
3900
+ this.push(raw, NS.html, start);
3901
+ return;
3902
+ }
3903
+ if (name === "hr")
3904
+ return;
3905
+ if (SELECT_BREAKOUT_TAGS.has(name)) {
3906
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3907
+ tag: raw,
3908
+ parent: "select",
3909
+ mode: this.insertionMode,
3910
+ action: "auto-close-implicit"
3911
+ });
3912
+ if (this.hasInSelectScope("select")) {
3913
+ this.popUntilName("select");
3914
+ this.resetInsertionModeAppropriately();
3915
+ }
3916
+ if (name === "select")
3917
+ return;
3918
+ return this.dispatchStartTag(name, raw, false, start, _endIndex);
3919
+ }
3920
+ if (name === "script" || name === "template") {
3921
+ return this.startInBody(name, raw, false, start, _endIndex);
3922
+ }
3923
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3924
+ tag: raw,
3925
+ parent: "select",
3926
+ mode: this.insertionMode,
3927
+ action: "ignored"
3928
+ });
3929
+ }
3930
+ startInSelectInTable(name, raw, selfClosing, start, endIndex) {
3931
+ if (name === "caption" || name === "table" || name === "tbody" || name === "tfoot" || name === "thead" || name === "tr" || name === "td" || name === "th") {
3932
+ this.report(HTML_TAG_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
3933
+ tag: raw,
3934
+ parent: "select",
3935
+ mode: this.insertionMode,
3936
+ action: "auto-close-implicit"
3937
+ });
3938
+ this.popUntilName("select");
3939
+ this.resetInsertionModeAppropriately();
3940
+ return this.dispatchStartTag(name, raw, selfClosing, start, endIndex);
3941
+ }
3942
+ return this.startInSelect(name, raw, selfClosing, start, endIndex);
3943
+ }
3944
+ resetInsertionModeAppropriately() {
3945
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3946
+ const f = this.openElements[i];
3947
+ if (f.ns !== NS.html)
3948
+ continue;
3949
+ const last = i === 0;
3950
+ switch (f.name) {
3951
+ case "select":
3952
+ this.insertionMode = MODES.inSelect;
3953
+ return;
3954
+ case "td":
3955
+ case "th":
3956
+ if (!last) {
3957
+ this.insertionMode = MODES.inCell;
3958
+ return;
3959
+ }
3960
+ break;
3961
+ case "tr":
3962
+ this.insertionMode = MODES.inRow;
3963
+ return;
3964
+ case "tbody":
3965
+ case "thead":
3966
+ case "tfoot":
3967
+ this.insertionMode = MODES.inTableBody;
3968
+ return;
3969
+ case "caption":
3970
+ this.insertionMode = MODES.inCaption;
3971
+ return;
3972
+ case "colgroup":
3973
+ this.insertionMode = MODES.inColumnGroup;
3974
+ return;
3975
+ case "table":
3976
+ this.insertionMode = MODES.inTable;
3977
+ return;
3978
+ case "template":
3979
+ this.insertionMode = this.templateInsertionModes[this.templateInsertionModes.length - 1] ?? MODES.inBody;
3980
+ return;
3981
+ default:
3982
+ break;
3983
+ }
3984
+ }
3985
+ this.insertionMode = MODES.inBody;
3986
+ }
3987
+ handleEndTag(name, start) {
3988
+ if (this.isTransparentTag(name))
3989
+ return;
3990
+ const ns = this.currentNamespace();
3991
+ if (ns !== NS.html) {
3992
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
3993
+ const f = this.openElements[i];
3994
+ if (f.ns === NS.html)
3995
+ break;
3996
+ if (f.name.toLowerCase() === name) {
3997
+ this.openElements.length = i;
3998
+ return;
3999
+ }
4000
+ }
4001
+ }
4002
+ if (VOID_ELEMENTS.has(name)) {
4003
+ this.report(HTML_VOID_ELEMENT_HAS_CLOSE_TAG, LEVEL_WARN, start, {
4004
+ tag: name,
4005
+ mode: this.insertionMode
4006
+ });
4007
+ return;
4008
+ }
4009
+ if (FORMATTING_ELEMENTS.has(name)) {
4010
+ const top = this.currentNode();
4011
+ if (top && top.ns === NS.html && top.name === name) {
4012
+ this.openElements.pop();
4013
+ this.removeFromActiveFormattingByRef(top);
4014
+ return;
4015
+ }
4016
+ if (this.activeFormattingHas(name) || this.openElementsHas(name)) {
4017
+ this.report(HTML_MISNESTED_FORMATTING, LEVEL_WARN, start, {
4018
+ tag: name,
4019
+ mode: this.insertionMode
4020
+ });
4021
+ this.runAdoptionAgency(name);
4022
+ return;
4023
+ }
4024
+ this.report(HTML_UNEXPECTED_END_TAG, LEVEL_WARN, start, {
4025
+ tag: name,
4026
+ mode: this.insertionMode
4027
+ });
4028
+ return;
4029
+ }
4030
+ for (let i = this.openElements.length - 1;i >= 0; i--) {
4031
+ const f = this.openElements[i];
4032
+ if (f.ns === NS.html && f.name === name) {
4033
+ this.openElements.length = i;
4034
+ if (name === "form")
4035
+ this.formPointer = null;
4036
+ if (TABLE_SCOPE_TAGS.has(name) || name === "select" || name === "template") {
4037
+ this.resetInsertionModeAppropriately();
4038
+ }
4039
+ return;
4040
+ }
4041
+ if (f.ns === NS.html && SPECIAL_ELEMENTS.has(f.name)) {
4042
+ break;
4043
+ }
4044
+ }
4045
+ }
4046
+ removeFromActiveFormattingByRef(ref) {
4047
+ const idx = this.activeFormatting.indexOf(ref);
4048
+ if (idx >= 0)
4049
+ this.activeFormatting.splice(idx, 1);
4050
+ }
4051
+ handleText(start, end) {
4052
+ if (this.insertionMode === MODES.inTable || this.insertionMode === MODES.inTableBody || this.insertionMode === MODES.inRow) {
4053
+ const slice = this.html.slice(start, end);
4054
+ const hasNonWhitespace = /\S/.test(slice);
4055
+ if (hasNonWhitespace) {
4056
+ this.report(HTML_TEXT_NOT_ALLOWED_IN_PARENT, LEVEL_ERROR, start, {
4057
+ mode: this.insertionMode,
4058
+ snippet: slice.length > 40 ? `${slice.slice(0, 40)}…` : slice
4059
+ });
4060
+ }
4061
+ return;
4062
+ }
4063
+ if (this.insertionMode === MODES.inColumnGroup) {
4064
+ const slice = this.html.slice(start, end);
4065
+ if (/\S/.test(slice)) {
4066
+ if (this.currentNode()?.name === "colgroup") {
4067
+ this.openElements.pop();
4068
+ this.insertionMode = MODES.inTable;
4069
+ return this.handleText(start, end);
4070
+ }
4071
+ }
4072
+ return;
4073
+ }
4074
+ if (this.insertionMode === MODES.inSelect || this.insertionMode === MODES.inSelectInTable) {
4075
+ return;
4076
+ }
4077
+ }
4078
+ }
4079
+ function computeLineStarts(html) {
4080
+ const arr = [0];
4081
+ for (let i = 0;i < html.length; i++) {
4082
+ if (html.charCodeAt(i) === 10)
4083
+ arr.push(i + 1);
4084
+ }
4085
+ return arr;
4086
+ }
4087
+ function offsetToLineCol(lineStarts, offset) {
4088
+ let lo = 0;
4089
+ let hi = lineStarts.length - 1;
4090
+ while (lo < hi) {
4091
+ const mid = lo + hi + 1 >>> 1;
4092
+ if (lineStarts[mid] <= offset)
4093
+ lo = mid;
4094
+ else
4095
+ hi = mid - 1;
4096
+ }
4097
+ return { line: lo + 1, column: offset - lineStarts[lo] + 1 };
4098
+ }
4099
+ var HTML_TAG_NAME_HAS_UPPERCASE = "HTML_TAG_NAME_HAS_UPPERCASE", HTML_SVG_TAG_WILL_LOWERCASE = "HTML_SVG_TAG_WILL_LOWERCASE", HTML_TAG_NOT_ALLOWED_IN_PARENT = "HTML_TAG_NOT_ALLOWED_IN_PARENT", HTML_TEXT_NOT_ALLOWED_IN_PARENT = "HTML_TEXT_NOT_ALLOWED_IN_PARENT", HTML_VOID_ELEMENT_HAS_CLOSE_TAG = "HTML_VOID_ELEMENT_HAS_CLOSE_TAG", HTML_DUPLICATE_FORM = "HTML_DUPLICATE_FORM", HTML_NESTED_INTERACTIVE = "HTML_NESTED_INTERACTIVE", HTML_MISNESTED_FORMATTING = "HTML_MISNESTED_FORMATTING", HTML_UNEXPECTED_END_TAG = "HTML_UNEXPECTED_END_TAG", LEVEL_ERROR = "error", LEVEL_WARN = "warn", TABLE_SCOPE_TAGS, TABLE_BODY_CELL_TAGS;
4100
+ var init_htmllinter = __esm(() => {
4101
+ init_html_tokenizer();
4102
+ init_htmllinter_tables();
4103
+ TABLE_SCOPE_TAGS = new Set([
4104
+ "caption",
4105
+ "colgroup",
4106
+ "thead",
4107
+ "tbody",
4108
+ "tfoot",
4109
+ "tr",
4110
+ "td",
4111
+ "th",
4112
+ "table"
4113
+ ]);
4114
+ TABLE_BODY_CELL_TAGS = new Set(["td", "th"]);
4115
+ });
4116
+
2069
4117
  // tools/core/lint-check.js
2070
4118
  function checkComponent(Comp, lx = new LintContext) {
2071
4119
  return lx.push({ componentName: Comp.name }, () => {
@@ -2087,6 +4135,12 @@ function checkView(lx, view, Comp, referencedAlters) {
2087
4135
  checkEventModifiers(lx, view);
2088
4136
  checkKnownHandlerNames(lx, view, Comp, referencedAlters);
2089
4137
  checkMacroCallArgs(lx, view, Comp);
4138
+ checkHtmlStructure(lx, view);
4139
+ }
4140
+ function checkHtmlStructure(lx, view) {
4141
+ if (typeof view.rawView !== "string" || !view.rawView)
4142
+ return;
4143
+ lintHtml(view.rawView, (f) => lx.report(f.id, { ...f.info, location: f.location }, f.level), HTML_LINT_OPTS);
2090
4144
  }
2091
4145
  function checkParseIssues(lx, view) {
2092
4146
  const issues = view.ctx.parseIssues;
@@ -2434,21 +4488,22 @@ class LintContext {
2434
4488
  }
2435
4489
  }
2436
4490
  error(id, info) {
2437
- this.report(id, info, LEVEL_ERROR);
4491
+ this.report(id, info, LEVEL_ERROR2);
2438
4492
  }
2439
4493
  warn(id, info) {
2440
- this.report(id, info, LEVEL_WARN);
4494
+ this.report(id, info, LEVEL_WARN2);
2441
4495
  }
2442
4496
  hint(id, info) {
2443
4497
  this.report(id, info, LEVEL_HINT);
2444
4498
  }
2445
- report(id, info = {}, level = LEVEL_ERROR) {
4499
+ report(id, info = {}, level = LEVEL_ERROR2) {
2446
4500
  this.reports.push({ id, info, level, context: { ...this.frame } });
2447
4501
  }
2448
4502
  }
2449
- var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN = "warn", LEVEL_ERROR = "error", LEVEL_HINT = "hint", NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
4503
+ var ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
2450
4504
  var init_lint_check = __esm(() => {
2451
4505
  init_anode();
4506
+ init_htmllinter();
2452
4507
  PARSE_ISSUE_KIND_TO_LINT_ID = {
2453
4508
  "unknown-directive": UNKNOWN_DIRECTIVE,
2454
4509
  "unknown-x-op": UNKNOWN_X_OP,
@@ -2469,6 +4524,10 @@ var init_lint_check = __esm(() => {
2469
4524
  "unknown-x-op": X_KNOWN_OP_NAMES,
2470
4525
  "unknown-x-attr": X_KNOWN_ATTR_NAMES
2471
4526
  };
4527
+ HTML_LINT_OPTS = {
4528
+ fragmentContext: "template",
4529
+ transparentTagPrefixes: ["x"]
4530
+ };
2472
4531
  NO_WRAPPERS = {};
2473
4532
  KNOWN_HANDLER_NAMES = new Set([
2474
4533
  "value",
@@ -2682,7 +4741,7 @@ var init_stack = __esm(() => {
2682
4741
  });
2683
4742
 
2684
4743
  // src/transactor.js
2685
- class State {
4744
+ class State2 {
2686
4745
  constructor(val) {
2687
4746
  this.val = val;
2688
4747
  this.changeSubs = [];
@@ -2705,7 +4764,7 @@ class Transactor {
2705
4764
  constructor(comps, rootValue) {
2706
4765
  this.comps = comps;
2707
4766
  this.transactions = [];
2708
- this.state = new State(rootValue);
4767
+ this.state = new State2(rootValue);
2709
4768
  this.onTransactionPushed = () => {};
2710
4769
  }
2711
4770
  pushTransaction(t) {
@@ -8570,12 +10629,36 @@ function lintIdToMessage(id, info) {
8570
10629
  }
8571
10630
  case "BAD_VALUE":
8572
10631
  return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
10632
+ case "HTML_TAG_NAME_HAS_UPPERCASE":
10633
+ return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
10634
+ case "HTML_SVG_TAG_WILL_LOWERCASE":
10635
+ return `SVG tag <${info.raw}> is not in the WHATWG case-correction list — will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
10636
+ case "HTML_TAG_NOT_ALLOWED_IN_PARENT":
10637
+ return `<${info.tag}> not allowed under <${info.parent ?? "?"}> in ${info.mode} (action: ${info.action})${fmtLocationSuffix(info)}`;
10638
+ case "HTML_TEXT_NOT_ALLOWED_IN_PARENT":
10639
+ return `Non-whitespace text not allowed in ${info.mode}: ${JSON.stringify(info.snippet)}${fmtLocationSuffix(info)}`;
10640
+ case "HTML_VOID_ELEMENT_HAS_CLOSE_TAG":
10641
+ return `Void element <${info.tag}> has an explicit close tag${fmtLocationSuffix(info)}`;
10642
+ case "HTML_DUPLICATE_FORM":
10643
+ return `Nested <form> — the inner form will be dropped by the parser${fmtLocationSuffix(info)}`;
10644
+ case "HTML_NESTED_INTERACTIVE":
10645
+ return `<${info.tag}> nested inside another <${info.tag}> — adoption agency will reorder${fmtLocationSuffix(info)}`;
10646
+ case "HTML_MISNESTED_FORMATTING":
10647
+ return `Misnested formatting tag </${info.tag}> — adoption agency will reorder nodes${fmtLocationSuffix(info)}`;
10648
+ case "HTML_UNEXPECTED_END_TAG":
10649
+ return `Unexpected end tag </${info.tag}>${fmtLocationSuffix(info)}`;
8573
10650
  case "LINT_ERROR":
8574
10651
  return info.message;
8575
10652
  default:
8576
10653
  return id;
8577
10654
  }
8578
10655
  }
10656
+ function fmtLocationSuffix(info) {
10657
+ const loc = info?.location;
10658
+ if (!loc)
10659
+ return "";
10660
+ return ` at L${loc.line}:C${loc.column}`;
10661
+ }
8579
10662
 
8580
10663
  // tools/format/cli.js
8581
10664
  function fmtModuleInfo(info) {