@readme/markdown 14.2.4 → 14.2.6
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.
- package/dist/main.js +2872 -151
- package/dist/main.node.js +2872 -151
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/tables/normalize-tag-spacing.d.ts +20 -0
- package/dist/processor/transform/mdxish/tables/remap-positions.d.ts +9 -0
- package/dist/processor/transform/mdxish/tables/repair-unclosed-tags.d.ts +11 -0
- package/dist/processor/transform/mdxish/tables/tag-walker.d.ts +19 -0
- package/dist/processor/transform/mdxish/tables/utils.d.ts +14 -0
- package/dist/utils/common-html-words.d.ts +6 -0
- package/package.json +3 -2
package/dist/main.node.js
CHANGED
|
@@ -93085,35 +93085,2793 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
93085
93085
|
};
|
|
93086
93086
|
/* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
|
|
93087
93087
|
|
|
93088
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/decode-codepoint.js
|
|
93089
|
+
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
|
|
93090
|
+
const dist_decode_codepoint_decodeMap = new Map([
|
|
93091
|
+
[0, 65_533],
|
|
93092
|
+
// C1 Unicode control character reference replacements
|
|
93093
|
+
[128, 8364],
|
|
93094
|
+
[130, 8218],
|
|
93095
|
+
[131, 402],
|
|
93096
|
+
[132, 8222],
|
|
93097
|
+
[133, 8230],
|
|
93098
|
+
[134, 8224],
|
|
93099
|
+
[135, 8225],
|
|
93100
|
+
[136, 710],
|
|
93101
|
+
[137, 8240],
|
|
93102
|
+
[138, 352],
|
|
93103
|
+
[139, 8249],
|
|
93104
|
+
[140, 338],
|
|
93105
|
+
[142, 381],
|
|
93106
|
+
[145, 8216],
|
|
93107
|
+
[146, 8217],
|
|
93108
|
+
[147, 8220],
|
|
93109
|
+
[148, 8221],
|
|
93110
|
+
[149, 8226],
|
|
93111
|
+
[150, 8211],
|
|
93112
|
+
[151, 8212],
|
|
93113
|
+
[152, 732],
|
|
93114
|
+
[153, 8482],
|
|
93115
|
+
[154, 353],
|
|
93116
|
+
[155, 8250],
|
|
93117
|
+
[156, 339],
|
|
93118
|
+
[158, 382],
|
|
93119
|
+
[159, 376],
|
|
93120
|
+
]);
|
|
93121
|
+
/**
|
|
93122
|
+
* Replace the given code point with a replacement character if it is a
|
|
93123
|
+
* surrogate or is outside the valid range. Otherwise return the code
|
|
93124
|
+
* point unchanged.
|
|
93125
|
+
* @param codePoint Unicode code point to convert.
|
|
93126
|
+
*/
|
|
93127
|
+
function dist_decode_codepoint_replaceCodePoint(codePoint) {
|
|
93128
|
+
if ((codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||
|
|
93129
|
+
codePoint > 0x10_ff_ff) {
|
|
93130
|
+
return 0xff_fd;
|
|
93131
|
+
}
|
|
93132
|
+
return dist_decode_codepoint_decodeMap.get(codePoint) ?? codePoint;
|
|
93133
|
+
}
|
|
93134
|
+
//# sourceMappingURL=decode-codepoint.js.map
|
|
93135
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/internal/bin-trie-flags.js
|
|
93136
|
+
/**
|
|
93137
|
+
* Bit flags & masks for the binary trie encoding used for entity decoding.
|
|
93138
|
+
*
|
|
93139
|
+
* Bit layout (16 bits total):
|
|
93140
|
+
* 15..14 VALUE_LENGTH (+1 encoding; 0 => no value)
|
|
93141
|
+
* 13 FLAG13. If valueLength>0: semicolon required flag (implicit ';').
|
|
93142
|
+
* If valueLength==0: compact run flag.
|
|
93143
|
+
* 12..7 BRANCH_LENGTH Branch length (0 => single branch in 6..0 if jumpOffset==char) OR run length (when compact run)
|
|
93144
|
+
* 6..0 JUMP_TABLE Jump offset (jump table) OR single-branch char code OR first run char
|
|
93145
|
+
*/
|
|
93146
|
+
var bin_trie_flags_BinTrieFlags;
|
|
93147
|
+
(function (BinTrieFlags) {
|
|
93148
|
+
BinTrieFlags[BinTrieFlags["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
|
|
93149
|
+
BinTrieFlags[BinTrieFlags["FLAG13"] = 8192] = "FLAG13";
|
|
93150
|
+
BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 8064] = "BRANCH_LENGTH";
|
|
93151
|
+
BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE";
|
|
93152
|
+
})(bin_trie_flags_BinTrieFlags || (bin_trie_flags_BinTrieFlags = {}));
|
|
93153
|
+
//# sourceMappingURL=bin-trie-flags.js.map
|
|
93154
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/decode.js
|
|
93155
|
+
|
|
93156
|
+
|
|
93157
|
+
|
|
93158
|
+
|
|
93159
|
+
var dist_decode_CharCodes;
|
|
93160
|
+
(function (CharCodes) {
|
|
93161
|
+
CharCodes[CharCodes["NUM"] = 35] = "NUM";
|
|
93162
|
+
CharCodes[CharCodes["SEMI"] = 59] = "SEMI";
|
|
93163
|
+
CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS";
|
|
93164
|
+
CharCodes[CharCodes["ZERO"] = 48] = "ZERO";
|
|
93165
|
+
CharCodes[CharCodes["NINE"] = 57] = "NINE";
|
|
93166
|
+
CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A";
|
|
93167
|
+
CharCodes[CharCodes["LOWER_F"] = 102] = "LOWER_F";
|
|
93168
|
+
CharCodes[CharCodes["LOWER_X"] = 120] = "LOWER_X";
|
|
93169
|
+
CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z";
|
|
93170
|
+
CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A";
|
|
93171
|
+
CharCodes[CharCodes["UPPER_F"] = 70] = "UPPER_F";
|
|
93172
|
+
CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z";
|
|
93173
|
+
})(dist_decode_CharCodes || (dist_decode_CharCodes = {}));
|
|
93174
|
+
/** Bit that needs to be set to convert an upper case ASCII character to lower case */
|
|
93175
|
+
const dist_decode_TO_LOWER_BIT = 0b10_0000;
|
|
93176
|
+
function dist_decode_isNumber(code) {
|
|
93177
|
+
return code >= dist_decode_CharCodes.ZERO && code <= dist_decode_CharCodes.NINE;
|
|
93178
|
+
}
|
|
93179
|
+
function dist_decode_isHexadecimalCharacter(code) {
|
|
93180
|
+
return ((code >= dist_decode_CharCodes.UPPER_A && code <= dist_decode_CharCodes.UPPER_F) ||
|
|
93181
|
+
(code >= dist_decode_CharCodes.LOWER_A && code <= dist_decode_CharCodes.LOWER_F));
|
|
93182
|
+
}
|
|
93183
|
+
function dist_decode_isAsciiAlphaNumeric(code) {
|
|
93184
|
+
return ((code >= dist_decode_CharCodes.UPPER_A && code <= dist_decode_CharCodes.UPPER_Z) ||
|
|
93185
|
+
(code >= dist_decode_CharCodes.LOWER_A && code <= dist_decode_CharCodes.LOWER_Z) ||
|
|
93186
|
+
dist_decode_isNumber(code));
|
|
93187
|
+
}
|
|
93188
|
+
/**
|
|
93189
|
+
* Checks if the given character is a valid end character for an entity in an attribute.
|
|
93190
|
+
*
|
|
93191
|
+
* Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.
|
|
93192
|
+
* See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
|
|
93193
|
+
* @param code Code point to decode.
|
|
93194
|
+
*/
|
|
93195
|
+
function dist_decode_isEntityInAttributeInvalidEnd(code) {
|
|
93196
|
+
return code === dist_decode_CharCodes.EQUALS || dist_decode_isAsciiAlphaNumeric(code);
|
|
93197
|
+
}
|
|
93198
|
+
var dist_decode_EntityDecoderState;
|
|
93199
|
+
(function (EntityDecoderState) {
|
|
93200
|
+
EntityDecoderState[EntityDecoderState["EntityStart"] = 0] = "EntityStart";
|
|
93201
|
+
EntityDecoderState[EntityDecoderState["NumericStart"] = 1] = "NumericStart";
|
|
93202
|
+
EntityDecoderState[EntityDecoderState["NumericDecimal"] = 2] = "NumericDecimal";
|
|
93203
|
+
EntityDecoderState[EntityDecoderState["NumericHex"] = 3] = "NumericHex";
|
|
93204
|
+
EntityDecoderState[EntityDecoderState["NamedEntity"] = 4] = "NamedEntity";
|
|
93205
|
+
})(dist_decode_EntityDecoderState || (dist_decode_EntityDecoderState = {}));
|
|
93206
|
+
/**
|
|
93207
|
+
* Decoding mode for named entities.
|
|
93208
|
+
*/
|
|
93209
|
+
var dist_decode_DecodingMode;
|
|
93210
|
+
(function (DecodingMode) {
|
|
93211
|
+
/** Entities in text nodes that can end with any character. */
|
|
93212
|
+
DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy";
|
|
93213
|
+
/** Only allow entities terminated with a semicolon. */
|
|
93214
|
+
DecodingMode[DecodingMode["Strict"] = 1] = "Strict";
|
|
93215
|
+
/** Entities in attributes have limitations on ending characters. */
|
|
93216
|
+
DecodingMode[DecodingMode["Attribute"] = 2] = "Attribute";
|
|
93217
|
+
})(dist_decode_DecodingMode || (dist_decode_DecodingMode = {}));
|
|
93218
|
+
/**
|
|
93219
|
+
* Token decoder with support of writing partial entities.
|
|
93220
|
+
*/
|
|
93221
|
+
class dist_decode_EntityDecoder {
|
|
93222
|
+
decodeTree;
|
|
93223
|
+
emitCodePoint;
|
|
93224
|
+
errors;
|
|
93225
|
+
constructor(
|
|
93226
|
+
/** The tree used to decode entities. */
|
|
93227
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive
|
|
93228
|
+
decodeTree,
|
|
93229
|
+
/**
|
|
93230
|
+
* The function that is called when a codepoint is decoded.
|
|
93231
|
+
*
|
|
93232
|
+
* For multi-byte named entities, this will be called multiple times,
|
|
93233
|
+
* with the second codepoint, and the same `consumed` value.
|
|
93234
|
+
* @param codepoint The decoded codepoint.
|
|
93235
|
+
* @param consumed The number of bytes consumed by the decoder.
|
|
93236
|
+
*/
|
|
93237
|
+
emitCodePoint,
|
|
93238
|
+
/** An object that is used to produce errors. */
|
|
93239
|
+
errors) {
|
|
93240
|
+
this.decodeTree = decodeTree;
|
|
93241
|
+
this.emitCodePoint = emitCodePoint;
|
|
93242
|
+
this.errors = errors;
|
|
93243
|
+
}
|
|
93244
|
+
/** The current state of the decoder. */
|
|
93245
|
+
state = dist_decode_EntityDecoderState.EntityStart;
|
|
93246
|
+
/** Characters that were consumed while parsing an entity. */
|
|
93247
|
+
consumed = 1;
|
|
93248
|
+
/**
|
|
93249
|
+
* The result of the entity.
|
|
93250
|
+
*
|
|
93251
|
+
* Either the result index of a numeric entity, or the codepoint of a
|
|
93252
|
+
* numeric entity.
|
|
93253
|
+
*/
|
|
93254
|
+
result = 0;
|
|
93255
|
+
/** The current index in the decode tree. */
|
|
93256
|
+
treeIndex = 0;
|
|
93257
|
+
/** The number of characters that were consumed in excess. */
|
|
93258
|
+
excess = 1;
|
|
93259
|
+
/** The mode in which the decoder is operating. */
|
|
93260
|
+
decodeMode = dist_decode_DecodingMode.Strict;
|
|
93261
|
+
/** The number of characters that have been consumed in the current run. */
|
|
93262
|
+
runConsumed = 0;
|
|
93263
|
+
/**
|
|
93264
|
+
* Resets the instance to make it reusable.
|
|
93265
|
+
* @param decodeMode Entity decoding mode to use.
|
|
93266
|
+
*/
|
|
93267
|
+
startEntity(decodeMode) {
|
|
93268
|
+
this.decodeMode = decodeMode;
|
|
93269
|
+
this.state = dist_decode_EntityDecoderState.EntityStart;
|
|
93270
|
+
this.result = 0;
|
|
93271
|
+
this.treeIndex = 0;
|
|
93272
|
+
this.excess = 1;
|
|
93273
|
+
this.consumed = 1;
|
|
93274
|
+
this.runConsumed = 0;
|
|
93275
|
+
}
|
|
93276
|
+
/**
|
|
93277
|
+
* Write an entity to the decoder. This can be called multiple times with partial entities.
|
|
93278
|
+
* If the entity is incomplete, the decoder will return -1.
|
|
93279
|
+
*
|
|
93280
|
+
* Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
|
|
93281
|
+
* entity is incomplete, and resume when the next string is written.
|
|
93282
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
93283
|
+
* @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
|
|
93284
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
93285
|
+
*/
|
|
93286
|
+
write(input, offset) {
|
|
93287
|
+
switch (this.state) {
|
|
93288
|
+
case dist_decode_EntityDecoderState.EntityStart: {
|
|
93289
|
+
if (input.charCodeAt(offset) === dist_decode_CharCodes.NUM) {
|
|
93290
|
+
this.state = dist_decode_EntityDecoderState.NumericStart;
|
|
93291
|
+
this.consumed += 1;
|
|
93292
|
+
return this.stateNumericStart(input, offset + 1);
|
|
93293
|
+
}
|
|
93294
|
+
this.state = dist_decode_EntityDecoderState.NamedEntity;
|
|
93295
|
+
return this.stateNamedEntity(input, offset);
|
|
93296
|
+
}
|
|
93297
|
+
case dist_decode_EntityDecoderState.NumericStart: {
|
|
93298
|
+
return this.stateNumericStart(input, offset);
|
|
93299
|
+
}
|
|
93300
|
+
case dist_decode_EntityDecoderState.NumericDecimal: {
|
|
93301
|
+
return this.stateNumericDecimal(input, offset);
|
|
93302
|
+
}
|
|
93303
|
+
case dist_decode_EntityDecoderState.NumericHex: {
|
|
93304
|
+
return this.stateNumericHex(input, offset);
|
|
93305
|
+
}
|
|
93306
|
+
case dist_decode_EntityDecoderState.NamedEntity: {
|
|
93307
|
+
return this.stateNamedEntity(input, offset);
|
|
93308
|
+
}
|
|
93309
|
+
}
|
|
93310
|
+
}
|
|
93311
|
+
/**
|
|
93312
|
+
* Switches between the numeric decimal and hexadecimal states.
|
|
93313
|
+
*
|
|
93314
|
+
* Equivalent to the `Numeric character reference state` in the HTML spec.
|
|
93315
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
93316
|
+
* @param offset The current offset.
|
|
93317
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
93318
|
+
*/
|
|
93319
|
+
stateNumericStart(input, offset) {
|
|
93320
|
+
if (offset >= input.length) {
|
|
93321
|
+
return -1;
|
|
93322
|
+
}
|
|
93323
|
+
if ((input.charCodeAt(offset) | dist_decode_TO_LOWER_BIT) === dist_decode_CharCodes.LOWER_X) {
|
|
93324
|
+
this.state = dist_decode_EntityDecoderState.NumericHex;
|
|
93325
|
+
this.consumed += 1;
|
|
93326
|
+
return this.stateNumericHex(input, offset + 1);
|
|
93327
|
+
}
|
|
93328
|
+
this.state = dist_decode_EntityDecoderState.NumericDecimal;
|
|
93329
|
+
return this.stateNumericDecimal(input, offset);
|
|
93330
|
+
}
|
|
93331
|
+
/**
|
|
93332
|
+
* Parses a hexadecimal numeric entity.
|
|
93333
|
+
*
|
|
93334
|
+
* Equivalent to the `Hexademical character reference state` in the HTML spec.
|
|
93335
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
93336
|
+
* @param offset The current offset.
|
|
93337
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
93338
|
+
*/
|
|
93339
|
+
stateNumericHex(input, offset) {
|
|
93340
|
+
while (offset < input.length) {
|
|
93341
|
+
const char = input.charCodeAt(offset);
|
|
93342
|
+
if (dist_decode_isNumber(char) || dist_decode_isHexadecimalCharacter(char)) {
|
|
93343
|
+
// Convert hex digit to value (0-15); 'a'/'A' -> 10.
|
|
93344
|
+
const digit = char <= dist_decode_CharCodes.NINE
|
|
93345
|
+
? char - dist_decode_CharCodes.ZERO
|
|
93346
|
+
: (char | dist_decode_TO_LOWER_BIT) - dist_decode_CharCodes.LOWER_A + 10;
|
|
93347
|
+
this.result = this.result * 16 + digit;
|
|
93348
|
+
this.consumed++;
|
|
93349
|
+
offset++;
|
|
93350
|
+
}
|
|
93351
|
+
else {
|
|
93352
|
+
return this.emitNumericEntity(char, 3);
|
|
93353
|
+
}
|
|
93354
|
+
}
|
|
93355
|
+
return -1; // Incomplete entity
|
|
93356
|
+
}
|
|
93357
|
+
/**
|
|
93358
|
+
* Parses a decimal numeric entity.
|
|
93359
|
+
*
|
|
93360
|
+
* Equivalent to the `Decimal character reference state` in the HTML spec.
|
|
93361
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
93362
|
+
* @param offset The current offset.
|
|
93363
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
93364
|
+
*/
|
|
93365
|
+
stateNumericDecimal(input, offset) {
|
|
93366
|
+
while (offset < input.length) {
|
|
93367
|
+
const char = input.charCodeAt(offset);
|
|
93368
|
+
if (dist_decode_isNumber(char)) {
|
|
93369
|
+
this.result = this.result * 10 + (char - dist_decode_CharCodes.ZERO);
|
|
93370
|
+
this.consumed++;
|
|
93371
|
+
offset++;
|
|
93372
|
+
}
|
|
93373
|
+
else {
|
|
93374
|
+
return this.emitNumericEntity(char, 2);
|
|
93375
|
+
}
|
|
93376
|
+
}
|
|
93377
|
+
return -1; // Incomplete entity
|
|
93378
|
+
}
|
|
93379
|
+
/**
|
|
93380
|
+
* Validate and emit a numeric entity.
|
|
93381
|
+
*
|
|
93382
|
+
* Implements the logic from the `Hexademical character reference start
|
|
93383
|
+
* state` and `Numeric character reference end state` in the HTML spec.
|
|
93384
|
+
* @param lastCp The last code point of the entity. Used to see if the
|
|
93385
|
+
* entity was terminated with a semicolon.
|
|
93386
|
+
* @param expectedLength The minimum number of characters that should be
|
|
93387
|
+
* consumed. Used to validate that at least one digit
|
|
93388
|
+
* was consumed.
|
|
93389
|
+
* @returns The number of characters that were consumed.
|
|
93390
|
+
*/
|
|
93391
|
+
emitNumericEntity(lastCp, expectedLength) {
|
|
93392
|
+
// Ensure we consumed at least one digit.
|
|
93393
|
+
if (this.consumed <= expectedLength) {
|
|
93394
|
+
this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
|
93395
|
+
return 0;
|
|
93396
|
+
}
|
|
93397
|
+
// Figure out if this is a legit end of the entity
|
|
93398
|
+
if (lastCp === dist_decode_CharCodes.SEMI) {
|
|
93399
|
+
this.consumed += 1;
|
|
93400
|
+
}
|
|
93401
|
+
else if (this.decodeMode === dist_decode_DecodingMode.Strict) {
|
|
93402
|
+
return 0;
|
|
93403
|
+
}
|
|
93404
|
+
this.emitCodePoint(dist_decode_codepoint_replaceCodePoint(this.result), this.consumed);
|
|
93405
|
+
if (this.errors) {
|
|
93406
|
+
if (lastCp !== dist_decode_CharCodes.SEMI) {
|
|
93407
|
+
this.errors.missingSemicolonAfterCharacterReference();
|
|
93408
|
+
}
|
|
93409
|
+
this.errors.validateNumericCharacterReference(this.result);
|
|
93410
|
+
}
|
|
93411
|
+
return this.consumed;
|
|
93412
|
+
}
|
|
93413
|
+
/**
|
|
93414
|
+
* Parses a named entity.
|
|
93415
|
+
*
|
|
93416
|
+
* Equivalent to the `Named character reference state` in the HTML spec.
|
|
93417
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
93418
|
+
* @param offset The current offset.
|
|
93419
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
93420
|
+
*/
|
|
93421
|
+
stateNamedEntity(input, offset) {
|
|
93422
|
+
const { decodeTree } = this;
|
|
93423
|
+
let current = decodeTree[this.treeIndex];
|
|
93424
|
+
// The length is the number of bytes of the value, including the current byte.
|
|
93425
|
+
let valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
93426
|
+
while (offset < input.length) {
|
|
93427
|
+
// Handle compact runs (possibly inline): valueLength == 0 and SEMI_REQUIRED bit set.
|
|
93428
|
+
if (valueLength === 0 && (current & bin_trie_flags_BinTrieFlags.FLAG13) !== 0) {
|
|
93429
|
+
const runLength = (current & bin_trie_flags_BinTrieFlags.BRANCH_LENGTH) >> 7; /* 2..63 */
|
|
93430
|
+
// If we are starting a run, check the first char.
|
|
93431
|
+
if (this.runConsumed === 0) {
|
|
93432
|
+
const firstChar = current & bin_trie_flags_BinTrieFlags.JUMP_TABLE;
|
|
93433
|
+
if (input.charCodeAt(offset) !== firstChar) {
|
|
93434
|
+
return this.result === 0
|
|
93435
|
+
? 0
|
|
93436
|
+
: this.emitNotTerminatedNamedEntity();
|
|
93437
|
+
}
|
|
93438
|
+
offset++;
|
|
93439
|
+
this.excess++;
|
|
93440
|
+
this.runConsumed++;
|
|
93441
|
+
}
|
|
93442
|
+
// Check remaining characters in the run.
|
|
93443
|
+
while (this.runConsumed < runLength) {
|
|
93444
|
+
if (offset >= input.length) {
|
|
93445
|
+
return -1;
|
|
93446
|
+
}
|
|
93447
|
+
const charIndexInPacked = this.runConsumed - 1;
|
|
93448
|
+
const packedWord = decodeTree[this.treeIndex + 1 + (charIndexInPacked >> 1)];
|
|
93449
|
+
const expectedChar = charIndexInPacked % 2 === 0
|
|
93450
|
+
? packedWord & 0xff
|
|
93451
|
+
: (packedWord >> 8) & 0xff;
|
|
93452
|
+
if (input.charCodeAt(offset) !== expectedChar) {
|
|
93453
|
+
this.runConsumed = 0;
|
|
93454
|
+
return this.result === 0
|
|
93455
|
+
? 0
|
|
93456
|
+
: this.emitNotTerminatedNamedEntity();
|
|
93457
|
+
}
|
|
93458
|
+
offset++;
|
|
93459
|
+
this.excess++;
|
|
93460
|
+
this.runConsumed++;
|
|
93461
|
+
}
|
|
93462
|
+
this.runConsumed = 0;
|
|
93463
|
+
this.treeIndex += 1 + (runLength >> 1);
|
|
93464
|
+
current = decodeTree[this.treeIndex];
|
|
93465
|
+
valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
93466
|
+
}
|
|
93467
|
+
if (offset >= input.length)
|
|
93468
|
+
break;
|
|
93469
|
+
const char = input.charCodeAt(offset);
|
|
93470
|
+
/*
|
|
93471
|
+
* Implicit semicolon handling for nodes that require a semicolon but
|
|
93472
|
+
* don't have an explicit ';' branch stored in the trie. If we have
|
|
93473
|
+
* a value on the current node, it requires a semicolon, and the
|
|
93474
|
+
* current input character is a semicolon, emit the entity using the
|
|
93475
|
+
* current node (without descending further).
|
|
93476
|
+
*/
|
|
93477
|
+
if (char === dist_decode_CharCodes.SEMI &&
|
|
93478
|
+
valueLength !== 0 &&
|
|
93479
|
+
(current & bin_trie_flags_BinTrieFlags.FLAG13) !== 0) {
|
|
93480
|
+
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
|
93481
|
+
}
|
|
93482
|
+
this.treeIndex = dist_decode_determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
|
|
93483
|
+
if (this.treeIndex < 0) {
|
|
93484
|
+
return this.result === 0 ||
|
|
93485
|
+
// If we are parsing an attribute
|
|
93486
|
+
(this.decodeMode === dist_decode_DecodingMode.Attribute &&
|
|
93487
|
+
// We shouldn't have consumed any characters after the entity,
|
|
93488
|
+
(valueLength === 0 ||
|
|
93489
|
+
// And there should be no invalid characters.
|
|
93490
|
+
dist_decode_isEntityInAttributeInvalidEnd(char)))
|
|
93491
|
+
? 0
|
|
93492
|
+
: this.emitNotTerminatedNamedEntity();
|
|
93493
|
+
}
|
|
93494
|
+
current = decodeTree[this.treeIndex];
|
|
93495
|
+
valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
93496
|
+
// If the branch is a value, store it and continue
|
|
93497
|
+
if (valueLength !== 0) {
|
|
93498
|
+
// If the entity is terminated by a semicolon, we are done.
|
|
93499
|
+
if (char === dist_decode_CharCodes.SEMI) {
|
|
93500
|
+
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
|
93501
|
+
}
|
|
93502
|
+
// If we encounter a non-terminated (legacy) entity while parsing strictly, then ignore it.
|
|
93503
|
+
if (this.decodeMode !== dist_decode_DecodingMode.Strict &&
|
|
93504
|
+
(current & bin_trie_flags_BinTrieFlags.FLAG13) === 0) {
|
|
93505
|
+
this.result = this.treeIndex;
|
|
93506
|
+
this.consumed += this.excess;
|
|
93507
|
+
this.excess = 0;
|
|
93508
|
+
}
|
|
93509
|
+
}
|
|
93510
|
+
// Increment offset & excess for next iteration
|
|
93511
|
+
offset++;
|
|
93512
|
+
this.excess++;
|
|
93513
|
+
}
|
|
93514
|
+
return -1;
|
|
93515
|
+
}
|
|
93516
|
+
/**
|
|
93517
|
+
* Emit a named entity that was not terminated with a semicolon.
|
|
93518
|
+
* @returns The number of characters consumed.
|
|
93519
|
+
*/
|
|
93520
|
+
emitNotTerminatedNamedEntity() {
|
|
93521
|
+
const { result, decodeTree } = this;
|
|
93522
|
+
const valueLength = (decodeTree[result] & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
93523
|
+
this.emitNamedEntityData(result, valueLength, this.consumed);
|
|
93524
|
+
this.errors?.missingSemicolonAfterCharacterReference();
|
|
93525
|
+
return this.consumed;
|
|
93526
|
+
}
|
|
93527
|
+
/**
|
|
93528
|
+
* Emit a named entity.
|
|
93529
|
+
* @param result The index of the entity in the decode tree.
|
|
93530
|
+
* @param valueLength The number of bytes in the entity.
|
|
93531
|
+
* @param consumed The number of characters consumed.
|
|
93532
|
+
* @returns The number of characters consumed.
|
|
93533
|
+
*/
|
|
93534
|
+
emitNamedEntityData(result, valueLength, consumed) {
|
|
93535
|
+
const { decodeTree } = this;
|
|
93536
|
+
this.emitCodePoint(valueLength === 1
|
|
93537
|
+
? decodeTree[result] &
|
|
93538
|
+
~(bin_trie_flags_BinTrieFlags.VALUE_LENGTH | bin_trie_flags_BinTrieFlags.FLAG13)
|
|
93539
|
+
: decodeTree[result + 1], consumed);
|
|
93540
|
+
if (valueLength === 3) {
|
|
93541
|
+
// For multi-byte values, we need to emit the second byte.
|
|
93542
|
+
this.emitCodePoint(decodeTree[result + 2], consumed);
|
|
93543
|
+
}
|
|
93544
|
+
return consumed;
|
|
93545
|
+
}
|
|
93546
|
+
/**
|
|
93547
|
+
* Signal to the parser that the end of the input was reached.
|
|
93548
|
+
*
|
|
93549
|
+
* Remaining data will be emitted and relevant errors will be produced.
|
|
93550
|
+
* @returns The number of characters consumed.
|
|
93551
|
+
*/
|
|
93552
|
+
end() {
|
|
93553
|
+
switch (this.state) {
|
|
93554
|
+
case dist_decode_EntityDecoderState.NamedEntity: {
|
|
93555
|
+
// Emit a named entity if we have one.
|
|
93556
|
+
return this.result !== 0 &&
|
|
93557
|
+
(this.decodeMode !== dist_decode_DecodingMode.Attribute ||
|
|
93558
|
+
this.result === this.treeIndex)
|
|
93559
|
+
? this.emitNotTerminatedNamedEntity()
|
|
93560
|
+
: 0;
|
|
93561
|
+
}
|
|
93562
|
+
// Otherwise, emit a numeric entity if we have one.
|
|
93563
|
+
case dist_decode_EntityDecoderState.NumericDecimal: {
|
|
93564
|
+
return this.emitNumericEntity(0, 2);
|
|
93565
|
+
}
|
|
93566
|
+
case dist_decode_EntityDecoderState.NumericHex: {
|
|
93567
|
+
return this.emitNumericEntity(0, 3);
|
|
93568
|
+
}
|
|
93569
|
+
case dist_decode_EntityDecoderState.NumericStart: {
|
|
93570
|
+
this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
|
93571
|
+
return 0;
|
|
93572
|
+
}
|
|
93573
|
+
case dist_decode_EntityDecoderState.EntityStart: {
|
|
93574
|
+
// Return 0 if we have no entity.
|
|
93575
|
+
return 0;
|
|
93576
|
+
}
|
|
93577
|
+
}
|
|
93578
|
+
}
|
|
93579
|
+
}
|
|
93580
|
+
/**
|
|
93581
|
+
* Creates a function that decodes entities in a string.
|
|
93582
|
+
* @param decodeTree The decode tree.
|
|
93583
|
+
* @returns A function that decodes entities in a string.
|
|
93584
|
+
*/
|
|
93585
|
+
function dist_decode_getDecoder(decodeTree) {
|
|
93586
|
+
let returnValue = "";
|
|
93587
|
+
const decoder = new dist_decode_EntityDecoder(decodeTree, (data) => (returnValue += String.fromCodePoint(data)));
|
|
93588
|
+
return function decodeWithTrie(input, decodeMode) {
|
|
93589
|
+
let lastIndex = 0;
|
|
93590
|
+
let offset = 0;
|
|
93591
|
+
while ((offset = input.indexOf("&", offset)) >= 0) {
|
|
93592
|
+
returnValue += input.slice(lastIndex, offset);
|
|
93593
|
+
decoder.startEntity(decodeMode);
|
|
93594
|
+
const length = decoder.write(input,
|
|
93595
|
+
// Skip the "&"
|
|
93596
|
+
offset + 1);
|
|
93597
|
+
if (length < 0) {
|
|
93598
|
+
lastIndex = offset + decoder.end();
|
|
93599
|
+
break;
|
|
93600
|
+
}
|
|
93601
|
+
lastIndex = offset + length;
|
|
93602
|
+
// If `length` is 0, skip the current `&` and continue.
|
|
93603
|
+
offset = length === 0 ? lastIndex + 1 : lastIndex;
|
|
93604
|
+
}
|
|
93605
|
+
const result = returnValue + input.slice(lastIndex);
|
|
93606
|
+
// Make sure we don't keep a reference to the final string.
|
|
93607
|
+
returnValue = "";
|
|
93608
|
+
return result;
|
|
93609
|
+
};
|
|
93610
|
+
}
|
|
93611
|
+
/**
|
|
93612
|
+
* Determines the branch of the current node that is taken given the current
|
|
93613
|
+
* character. This function is used to traverse the trie.
|
|
93614
|
+
* @param decodeTree The trie.
|
|
93615
|
+
* @param current The current node.
|
|
93616
|
+
* @param nodeIndex Index immediately after the current node header.
|
|
93617
|
+
* @param char The current character.
|
|
93618
|
+
* @returns The index of the next node, or -1 if no branch is taken.
|
|
93619
|
+
*/
|
|
93620
|
+
function dist_decode_determineBranch(decodeTree, current, nodeIndex, char) {
|
|
93621
|
+
const branchCount = (current & bin_trie_flags_BinTrieFlags.BRANCH_LENGTH) >> 7;
|
|
93622
|
+
const jumpOffset = current & bin_trie_flags_BinTrieFlags.JUMP_TABLE;
|
|
93623
|
+
// Case 1: Single branch encoded in jump offset
|
|
93624
|
+
if (branchCount === 0) {
|
|
93625
|
+
return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;
|
|
93626
|
+
}
|
|
93627
|
+
// Case 2: Multiple branches encoded in jump table
|
|
93628
|
+
if (jumpOffset) {
|
|
93629
|
+
const value = char - jumpOffset;
|
|
93630
|
+
return value < 0 || value >= branchCount
|
|
93631
|
+
? -1
|
|
93632
|
+
: decodeTree[nodeIndex + value] - 1;
|
|
93633
|
+
}
|
|
93634
|
+
// Case 3: Multiple branches encoded in packed dictionary (two keys per uint16)
|
|
93635
|
+
const packedKeySlots = (branchCount + 1) >> 1;
|
|
93636
|
+
/*
|
|
93637
|
+
* Treat packed keys as a virtual sorted array of length `branchCount`.
|
|
93638
|
+
* Key(i) = low byte for even i, high byte for odd i in slot i>>1.
|
|
93639
|
+
*/
|
|
93640
|
+
let lo = 0;
|
|
93641
|
+
let hi = branchCount - 1;
|
|
93642
|
+
while (lo <= hi) {
|
|
93643
|
+
const mid = (lo + hi) >>> 1;
|
|
93644
|
+
const slot = mid >> 1;
|
|
93645
|
+
const packed = decodeTree[nodeIndex + slot];
|
|
93646
|
+
const midKey = (packed >> ((mid & 1) * 8)) & 0xff;
|
|
93647
|
+
if (midKey < char) {
|
|
93648
|
+
lo = mid + 1;
|
|
93649
|
+
}
|
|
93650
|
+
else if (midKey > char) {
|
|
93651
|
+
hi = mid - 1;
|
|
93652
|
+
}
|
|
93653
|
+
else {
|
|
93654
|
+
return decodeTree[nodeIndex + packedKeySlots + mid];
|
|
93655
|
+
}
|
|
93656
|
+
}
|
|
93657
|
+
return -1;
|
|
93658
|
+
}
|
|
93659
|
+
const dist_decode_htmlDecoder = /* #__PURE__ */ (/* unused pure expression or super */ null && (dist_decode_getDecoder(htmlDecodeTree)));
|
|
93660
|
+
const dist_decode_xmlDecoder = /* #__PURE__ */ (/* unused pure expression or super */ null && (dist_decode_getDecoder(xmlDecodeTree)));
|
|
93661
|
+
/**
|
|
93662
|
+
* Decodes an HTML string.
|
|
93663
|
+
* @param htmlString The string to decode.
|
|
93664
|
+
* @param mode The decoding mode.
|
|
93665
|
+
* @returns The decoded string.
|
|
93666
|
+
*/
|
|
93667
|
+
function dist_decode_decodeHTML(htmlString, mode = dist_decode_DecodingMode.Legacy) {
|
|
93668
|
+
return dist_decode_htmlDecoder(htmlString, mode);
|
|
93669
|
+
}
|
|
93670
|
+
/**
|
|
93671
|
+
* Decodes an HTML string in an attribute.
|
|
93672
|
+
* @param htmlAttribute The string to decode.
|
|
93673
|
+
* @returns The decoded string.
|
|
93674
|
+
*/
|
|
93675
|
+
function dist_decode_decodeHTMLAttribute(htmlAttribute) {
|
|
93676
|
+
return dist_decode_htmlDecoder(htmlAttribute, dist_decode_DecodingMode.Attribute);
|
|
93677
|
+
}
|
|
93678
|
+
/**
|
|
93679
|
+
* Decodes an HTML string, requiring all entities to be terminated by a semicolon.
|
|
93680
|
+
* @param htmlString The string to decode.
|
|
93681
|
+
* @returns The decoded string.
|
|
93682
|
+
*/
|
|
93683
|
+
function dist_decode_decodeHTMLStrict(htmlString) {
|
|
93684
|
+
return dist_decode_htmlDecoder(htmlString, dist_decode_DecodingMode.Strict);
|
|
93685
|
+
}
|
|
93686
|
+
/**
|
|
93687
|
+
* Decodes an XML string, requiring all entities to be terminated by a semicolon.
|
|
93688
|
+
* @param xmlString The string to decode.
|
|
93689
|
+
* @returns The decoded string.
|
|
93690
|
+
*/
|
|
93691
|
+
function dist_decode_decodeXML(xmlString) {
|
|
93692
|
+
return dist_decode_xmlDecoder(xmlString, dist_decode_DecodingMode.Strict);
|
|
93693
|
+
}
|
|
93694
|
+
|
|
93695
|
+
// Re-export for use by eg. htmlparser2
|
|
93696
|
+
|
|
93697
|
+
|
|
93698
|
+
//# sourceMappingURL=decode.js.map
|
|
93699
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/internal/decode-shared.js
|
|
93700
|
+
/**
|
|
93701
|
+
* Shared base64 decode helper for generated decode data.
|
|
93702
|
+
* Assumes global atob is available.
|
|
93703
|
+
* @param input Input string to encode or decode.
|
|
93704
|
+
*/
|
|
93705
|
+
function decodeBase64(input) {
|
|
93706
|
+
const binary = atob(input);
|
|
93707
|
+
const evenLength = binary.length & ~1; // Round down to even length
|
|
93708
|
+
const out = new Uint16Array(evenLength / 2);
|
|
93709
|
+
for (let index = 0, outIndex = 0; index < evenLength; index += 2) {
|
|
93710
|
+
const lo = binary.charCodeAt(index);
|
|
93711
|
+
const hi = binary.charCodeAt(index + 1);
|
|
93712
|
+
out[outIndex++] = lo | (hi << 8);
|
|
93713
|
+
}
|
|
93714
|
+
return out;
|
|
93715
|
+
}
|
|
93716
|
+
//# sourceMappingURL=decode-shared.js.map
|
|
93717
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/generated/decode-data-xml.js
|
|
93718
|
+
// Generated using scripts/write-decode-map.ts
|
|
93719
|
+
|
|
93720
|
+
/** Packed XML decode trie data. */
|
|
93721
|
+
const generated_decode_data_xml_xmlDecodeTree = /* #__PURE__ */ decodeBase64("AAJhZ2xxBwARABMAFQBtAg0AAAAAAA8AcAAmYG8AcwAnYHQAPmB0ADxg9SFvdCJg");
|
|
93722
|
+
//# sourceMappingURL=decode-data-xml.js.map
|
|
93723
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/generated/decode-data-html.js
|
|
93724
|
+
// Generated using scripts/write-decode-map.ts
|
|
93725
|
+
|
|
93726
|
+
/** Packed HTML decode trie data. */
|
|
93727
|
+
const generated_decode_data_html_htmlDecodeTree = /* #__PURE__ */ decodeBase64("QR08ALkAAgH6AYsDNQR2BO0EPgXZBQEGLAbdBxMISQrvCmQLfQurDKQNLw4fD4YPpA+6D/IPAAAAAAAAAAAAAAAAKhBMEY8TmxUWF2EYLBkxGuAa3RsJHDscWR8YIC8jSCSIJcMl6ie3Ku8rEC0CLjoupS7kLgAIRU1hYmNmZ2xtbm9wcnN0dVQAWgBeAGUAaQBzAHcAfgCBAIQAhwCSAJoAoACsALMAbABpAGcAO4DGAMZAUAA7gCYAJkBjAHUAdABlADuAwQDBQHIiZXZlAAJhAAFpeW0AcgByAGMAO4DCAMJAEGRyAADgNdgE3XIAYQB2AGUAO4DAAMBA8CFoYZFj4SFjcgBhZAAAoFMqAAFncIsAjgBvAG4ABGFmAADgNdg43fAlbHlGdW5jdGlvbgCgYSBpAG4AZwA7gMUAxUAAAWNzpACoAHIAAOA12Jzc6SFnbgCgVCJpAGwAZABlADuAwwDDQG0AbAA7gMQAxEAABGFjZWZvcnN1xQDYANoA7QDxAPYA+QD8AAABY3LJAM8AayNzbGFzaAAAoBYidgHTANUAAKDnKmUAZAAAoAYjeQARZIABY3J0AOAA5QDrAGEidXNlAACgNSLuI291bGxpcwCgLCFhAJJjcgAA4DXYBd1wAGYAAOA12Dnd5SF2ZdhiYwDyAOoAbSJwZXEAAKBOIgAHSE9hY2RlZmhpbG9yc3UXARoBHwE6AVIBVQFiAWQBZgGCAakB6QHtAfIBYwB5ACdkUABZADuAqQCpQIABY3B5ACUBKAE1AfUhdGUGYWmg0iJ0KGFsRGlmZmVyZW50aWFsRAAAoEUhbCJleXMAAKAtIQACYWVpb0EBRAFKAU0B8iFvbgxhZABpAGwAO4DHAMdAcgBjAAhhbiJpbnQAAKAwIm8AdAAKYQABZG5ZAV0BaSJsbGEAuGB0I2VyRG90ALdg8gA5AWkAp2NyImNsZQAAAkRNUFRwAXQBeQF9AW8AdAAAoJkiaSJudXMAAKCWIuwhdXMAoJUiaSJtZXMAAKCXIm8AAAFjc4cBlAFrKndpc2VDb250b3VySW50ZWdyYWwAAKAyImUjQ3VybHkAAAFEUZwBpAFvJXVibGVRdW90ZQAAoB0gdSJvdGUAAKAZIAACbG5wdbABtgHNAdgBbwBuAGWgNyIAoHQqgAFnaXQAvAHBAcUB8iJ1ZW50AKBhIm4AdAAAoC8i7yV1ckludGVncmFsAKAuIgABZnLRAdMBAKACIe8iZHVjdACgECJuLnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbAAAoDMi7yFzcwCgLypjAHIAAOA12J7ccABDoNMiYQBwAACgTSKABURKU1phY2VmaW9zAAsCEgIVAhgCGwIsAjQCOQI9AnMCfwNvoEUh9CJyYWhkAKARKWMAeQACZGMAeQAFZGMAeQAPZIABZ3JzACECJQIoAuchZXIAoCEgcgAAoKEhaAB2AACg5CoAAWF5MAIzAvIhb24OYRRkbAB0oAciYQCUY3IAAOA12AfdAAFhZkECawIAAWNtRQJnAvIjaXRpY2FsAAJBREdUUAJUAl8CYwJjInV0ZQC0YG8AdAFZAloC2WJiJGxlQWN1dGUA3WJyImF2ZQBgYGkibGRlANxi7yFuZACgxCJmJWVyZW50aWFsRAAAoEYhcAR9AgAAAAAAAIECjgIAABoDZgAA4DXYO91EoagAhQKJAm8AdAAAoNwgcSJ1YWwAAKBQIuIhbGUAA0NETFJVVpkCqAK1Au8C/wIRA28AbgB0AG8AdQByAEkAbgB0AGUAZwByAGEA7ADEAW8AdAKvAgAAAACwAqhgbiNBcnJvdwAAoNMhAAFlb7kC0AJmAHQAgAFBUlQAwQLGAs0CciJyb3cAAKDQIekkZ2h0QXJyb3cAoNQhZQDlACsCbgBnAAABTFLWAugC5SFmdAABQVLcAuECciJyb3cAAKD4J+kkZ2h0QXJyb3cAoPon6SRnaHRBcnJvdwCg+SdpImdodAAAAUFU9gL7AnIicm93AACg0iFlAGUAAKCoInAAQQIGAwAAAAALA3Iicm93AACg0SFvJHduQXJyb3cAAKDVIWUlcnRpY2FsQmFyAACgJSJuAAADQUJMUlRhJAM2AzoDWgNxA3oDciJyb3cAAKGTIUJVLAMwA2EAcgAAoBMpcCNBcnJvdwAAoPUhciJldmUAEWPlIWZ00gJDAwAASwMAAFIDaSVnaHRWZWN0b3IAAKBQKWUkZVZlY3RvcgAAoF4p5SJjdG9yQqC9IWEAcgAAoFYpaSJnaHQA1AFiAwAAaQNlJGVWZWN0b3IAAKBfKeUiY3RvckKgwSFhAHIAAKBXKWUAZQBBoKQiciJyb3cAAKCnIXIAcgBvAPcAtAIAAWN0gwOHA3IA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YwAAoN8i4SFycnCgtiEAoD0pgKIqImJjZG9zACsVMBU6FT4VQRVyImNhcAAAoEgqAAFhdTQVNxVwAACgRipwAACgSipvAHQAAKCNInIAAKBFKgDgKiIA/gACYWxydksVURVuFXMVcgByAG2gtyEAoDwpeQCAAWV2dwBYFWUVaRVxAHACXxUAAAAAYxVyAGUA4wAXFXUA4wAZFWUAZQAAoM4iZSJkZ2UAAKDPImUAbgA7gKQApEBlI2Fycm93AAABbHJ7FX8V5SFmdACgtiFpImdodAAAoLchZQDkAG0VAAFjaYsVkRVvAG4AaQBuAPQAkwFuAHQAAKAxImwiY3R5AACgLSOACUFIYWJjZGVmaGlqbG9yc3R1d3oAuBW7Fb8V1RXgFegV+RUKFhUWHxZUFlcWZRbFFtsW7xb7FgUXChdyAPIAtAJhAHIAAKBlKQACZ2xyc8YVyhXOFdAV5yFlcgCgICDlIXRoAKA4IfIA9QxoAHagECAAoKMiawHZFd4VYSJyb3cAAKAPKWEA4wBfAgABYXnkFecV8iFvbg9hNGQAoUYhYW/tFfQVAAFnciEC8RVyAACgyiF0InNlcQAAoHcqgAFnbG0A/xUCFgUWO4CwALBAdABhALRjcCJ0eXYAAKCxKQABaXIOFhIW8yFodACgfykA4DXYId1hAHIAAAFschsWHRYAoMMhAKDCIYACYWVnc3YAKBauAjYWOhY+Fm0AAKHEIm9zLhY0Fm4AZABzoMQi9SFpdACgZiZhIm1tYQDdY2kAbgAAoPIiAKH3AGlvQxZRFmQAZQAAgfcAO29KFksW90BuI3RpbWVzAACgxyJuAPgAUBZjAHkAUmRjAG8CXhYAAAAAYhZyAG4AAKAeI28AcAAAoA0jgAJscHR1dwBuFnEWdRaSFp4W7CFhciRgZgAA4DXYVd0AotkCZW1wc30WhBaJFo0WcQBkoFAibwB0AACgUSJpIm51cwAAoDgi7CF1cwCgFCLxInVhcmUAoKEiYgBsAGUAYgBhAHIAdwBlAGQAZwDlANcAbgCAAWFkaAClFqoWtBZyAHIAbwD3APUMbwB3AG4AYQByAHIAbwB3APMA8xVhI3Jwb29uAAABbHK8FsAWZQBmAPQAHBZpAGcAaAD0AB4WYgHJFs8WawBhAHIAbwD3AJILbwLUFgAAAADYFnIAbgAAoB8jbwBwAACgDCOAAWNvdADhFukW7BYAAXJ55RboFgDgNdi53FVkbAAAoPYp8iFvaxFhAAFkcvMW9xZvAHQAAKDxImkA5qC/JVsSAAFhaP8WAhdyAPIANQNhAPIA1wvhIm5nbGUAoKYpAAFjaQ4XEBd5AF9k5yJyYXJyAKD/JwAJRGFjZGVmZ2xtbm9wcXJzdHV4MRc4F0YXWxcyBF4XaRd5F40XrBe0F78X2RcVGCEYLRg1GEAYAAFEbzUXgRZvAPQA+BUAAWNzPBdCF3UAdABlADuA6QDpQPQhZXIAoG4qAAJhaW95TRdQF1YXWhfyIW9uG2FyAGOgViI7gOoA6kDsIW9uAKBVIk1kbwB0ABdhAAFEcmIXZhdvAHQAAKBSIgDgNdgi3XKhmipuF3QXYQB2AGUAO4DoAOhAZKCWKm8AdAAAoJgqgKGZKmlscwCAF4UXhxfuInRlcnMAoOcjAKATIWSglSpvAHQAAKCXKoABYXBzAJMXlheiF2MAcgATYXQAeQBzogUinxcAAAAAoRdlAHQAAKAFInAAMaADIDMBqRerFwCgBCAAoAUgAAFnc7AXsRdLYXAAAKACIAABZ3C4F7sXbwBuABlhZgAA4DXYVt2AAWFscwDFF8sXzxdyAHOg1SJsAACg4yl1AHMAAKBxKmkAAKG1A2x21RfYF28AbgC1Y/VjAAJjc3V24BfoF/0XEBgAAWlv5BdWF3IAYwAAoFYiaQLuFwAAAADwF+0ADQThIW50AAFnbPUX+Rd0AHIAAKCWKuUhc3MAoJUqgAFhZWkAAxgGGAoYbABzAD1gcwB0AACgXyJ2AESgYSJEAACgeCrwImFyc2wAoOUpAAFEYRkYHRhvAHQAAKBTInIAcgAAoHEpgAFjZGkAJxgqGO0XcgAAoC8hbwD0AIwCAAFhaDEYMhi3YzuA8ADwQAABbXI5GD0YbAA7gOsA60BvAACgrCCAAWNpcABGGEgYSxhsACFgcwD0ACwEAAFlb08YVxhjAHQAYQB0AGkAbwDuABoEbgBlAG4AdABpAGEAbADlADME4Ql1GAAAgRgAAIMYiBgAAAAAoRilGAAAqhgAALsYvhjRGAAA1xgnGWwAbABpAG4AZwBkAG8AdABzAGUA8QBlF3kARGRtImFsZQAAoEAmgAFpbHIAjRiRGJ0Y7CFpZwCgA/tpApcYAAAAAJoYZwAAoAD7aQBnAACgBPsA4DXYI93sIWlnAKAB++whaWcA4GYAagCAAWFsdACvGLIYthh0AACgbSZpAGcAAKAC+24AcwAAoLElbwBmAJJh8AHCGAAAxhhmAADgNdhX3QABYWvJGMwYbADsAGsEdqDUIgCg2SphI3J0aW50AACgDSoAAWFv2hgiGQABY3PeGB8ZsQPnGP0YBRkSGRUZAAAdGbID7xjyGPQY9xj5GAAA+xg7gL0AvUAAoFMhO4C8ALxAAKBVIQCgWSEAoFshswEBGQAAAxkAoFQhAKBWIbQCCxkOGQAAAAAQGTuAvgC+QACgVyEAoFwhNQAAoFghtgEZGQAAGxkAoFohAKBdITgAAKBeIWwAAKBEIHcAbgAAoCIjYwByAADgNdi73IAIRWFiY2RlZmdpamxub3JzdHYARhlKGVoZXhlmGWkZkhmWGZkZnRmgGa0ZxhnLGc8Z4BkjGmygZyIAoIwqgAFjbXAAUBlTGVgZ9SF0ZfVhbQBhAOSgswM6FgCghipyImV2ZQAfYQABaXliGWUZcgBjAB1hM2RvAHQAIWGAoWUibHFzAMYEcBl6GfGhZSLOBAAAdhlsAGEAbgD0AN8EgKF+KmNkbACBGYQZjBljAACgqSpvAHQAb6CAKmyggioAoIQqZeDbIgD+cwAAoJQqcgAA4DXYJN3noGsirATtIWVsAKA3IWMAeQBTZIChdyJFYWoApxmpGasZAKCSKgCgpSoAoKQqAAJFYWVztBm2Gb0ZwhkAoGkicABwoIoq8iFveACgiipxoIgq8aCIKrUZaQBtAACg5yJwAGYAAOA12FjdYQB2AOUAYwIAAWNp0xnWGXIAAKAKIW0AAKFzImVs3BneGQCgjioAoJAqAIM+ADtjZGxxco0E6xn0GfgZ/BkBGgABY2nvGfEZAKCnKnIAAKB6Km8AdAAAoNci0CFhcgCglSl1ImVzdAAAoHwqgAJhZGVscwAKGvQZFhrVBCAa8AEPGgAAFBpwAHIAbwD4AFkZcgAAoHgpcQAAAWxxxAQbGmwAZQBzAPMASRlpAO0A5AQAAWVuJxouGnIjdG5lcXEAAOBpIgD+xQAsGgAFQWFiY2Vma29zeUAaQxpmGmoabRqDGocalhrCGtMacgDyAMwCAAJpbG1yShpOGlAaVBpyAHMA8ABxD2YAvWBpAGwA9AASBQABZHJYGlsaYwB5AEpkAKGUIWN3YBpkGmkAcgAAoEgpAKCtIWEAcgAAoA8h6SFyYyVhgAFhbHIAcxp7Gn8a8iF0c3WgZSZpAHQAAKBlJuwhaXAAoCYg4yFvbgCguSJyAADgNdgl3XMAAAFld4wakRphInJvdwAAoCUpYSJyb3cAAKAmKYACYW1vcHIAnxqjGqcauhq+GnIAcgAAoP8h9CFodACgOyJrAAABbHKsGrMaZSRmdGFycm93AACgqSHpJGdodGFycm93AKCqIWYAAOA12Fnd4iFhcgCgFSCAAWNsdADIGswa0BpyAADgNdi93GEAcwDoAGka8iFvaydhAAFicNca2xr1IWxsAKBDIOghZW4AoBAg4Qr2GgAA/RoAAAgbExsaGwAAIRs7GwAAAAA+G2IbmRuVG6sbAACyG80b0htjAHUAdABlADuA7QDtQAChYyBpeQEbBhtyAGMAO4DuAO5AOGQAAWN4CxsNG3kANWRjAGwAO4ChAKFAAAFmcssCFhsA4DXYJt1yAGEAdgBlADuA7ADsQIChSCFpbm8AJxsyGzYbAAFpbisbLxtuAHQAAKAMKnQAAKAtIuYhaW4AoNwpdABhAACgKSHsIWlnM2GAAWFvcABDG1sbXhuAAWNndABJG0sbWRtyACthgAFlbHAAcQVRG1UbaQBuAOUAyAVhAHIA9AByBWgAMWFmAACgtyJlAGQAtWEAoggiY2ZvdGkbbRt1G3kb4SFyZQCgBSFpAG4AdKAeImkAZQAAoN0pZABvAPQAWxsAoisiY2VscIEbhRuPG5QbYQBsAACguiIAAWdyiRuNG2UAcgDzACMQ4wCCG2EicmhrAACgFyryIW9kAKA8KgACY2dwdJ8boRukG6gbeQBRZG8AbgAvYWYAAOA12FrdYQC5Y3UAZQBzAHQAO4C/AL9AAAFjabUbuRtyAADgNdi+3G4AAKIIIkVkc3bCG8QbyBvQAwCg+SJvAHQAAKD1Inag9CIAoPMiaaBiIOwhZGUpYesB1hsAANkbYwB5AFZkbAA7gO8A70AAA2NmbW9zdeYb7hvyG/Ub+hsFHAABaXnqG+0bcgBjADVhOWRyAADgNdgn3eEhdGg3YnAAZgAA4DXYW93jAf8bAAADHHIAAOA12L/c8iFjeVhk6yFjeVRkAARhY2ZnaGpvcxUcGhwiHCYcKhwtHDAcNRzwIXBhdqC6A/BjAAFleR4cIRzkIWls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ZmdobG1vcHJzdHV3CiwNLBEsHSwnLDEsQCxLLFIsYix6LIQsjyzLLOgs7Sz/LAotcgDyAAkDYQByAACgYykAAWNyFSwbLHUAdABlADuA+gD6QPIACQ1yAOMBIywAACUseQBeZHYAZQBtYQABaXkrLDAscgBjADuA+wD7QENkgAFhYmgANyw6LD0scgDyANEO7CFhY3FhYQDyAOAOAAFpckQsSCzzIWh0AKB+KQDgNdgy3XIAYQB2AGUAO4D5APlAYQFWLF8scgAAAWxyWixcLACgvyEAoL4hbABrAACggCUAAWN0Zix2LG8CbCwAAAAAcyxyAG4AZaAcI3IAAKAcI28AcAAAoA8jcgBpAACg+CUAAWFsfiyBLGMAcgBrYTuAqACoQAABZ3CILIssbwBuAHNhZgAA4DXYZt0AA2FkaGxzdZksniynLLgsuyzFLHIAcgBvAPcACQ1vAHcAbgBhAHIAcgBvAPcA2A5hI3Jwb29uAAABbHKvLLMsZQBmAPQAWyxpAGcAaAD0AF0sdQDzAKYOaQAAocUDaGzBLMIs0mNvAG4AxWPwI2Fycm93cwCgyCGAAWNpdADRLOEs5CxvAtcsAAAAAN4scgBuAGWgHSNyAACgHSNvAHAAAKAOI24AZwBvYXIAaQAAoPklYwByAADgNdjK3IABZGlyAPMs9yz6LG8AdAAAoPAi7CFkZWlhaQBmoLUlAKC0JQABYW0DLQYtcgDyAMosbAA7gPwA/EDhIm5nbGUAoKcpgAdBQkRhY2RlZmxub3Byc3oAJy0qLTAtNC2bLZ0toS2/LcMtxy3TLdgt3C3gLfwtcgDyABADYQByAHag6CoAoOkqYQBzAOgA/gIAAW5yOC08LechcnQAoJwpgANla25wcnN0AJkpSC1NLVQtXi1iLYItYQBwAHAA4QAaHG8AdABoAGkAbgDnAKEXgAFoaXIAoSmzJFotbwBwAPQAdCVooJUh7wD4JgABaXVmLWotZwBtAOEAuygAAWJwbi14LXMjZXRuZXEAceCKIgD+AODLKgD+cyNldG5lcQBx4IsiAP4A4MwqAP4AAWhyhi2KLWUAdADhABIraSNhbmdsZQAAAWxyki2WLeUhZnQAoLIiaSJnaHQAAKCzInkAMmThIXNoAKCiIoABZWxyAKcttC24LWKiKCKuLQAAAACyLWEAcgAAoLsicQAAoFoi7CFpcACg7iIAAWJ0vC1eD2EA8gBfD3IAAOA12DPddAByAOkAlS1zAHUAAAFicM0t0C0A4IIi0iAA4IMi0iBwAGYAAOA12GfdcgBvAPAAWQt0AHIA6QCaLQABY3XkLegtcgAA4DXYy9wAAWJw7C30LW4AAAFFZXUt8S0A4IoiAP5uAAABRWV/LfktAOCLIgD+6SJnemFnAKCaKYADY2Vmb3BycwANLhAuJS4pLiMuLi40LukhcmN1YQABZGkULiEuAAFiZxguHC5hAHIAAKBfKmUAcaAnIgCgWSLlIXJwAKAYIXIAAOA12DTdcABmAADgNdho3WWgQCJhAHQA6ABqD2MAcgAA4DXYzNzjCuQRUC4AAFQuAABYLmIuAAAAAGMubS5wLnQuAAAAAIguki4AAJouJxIqEnQAcgDpAB0ScgAA4DXYNd0AAUFhWy5eLnIA8gDnAnIA8gCTB75jAAFBYWYuaS5yAPIA4AJyAPIAjAdhAPAAeh5pAHMAAKD7IoABZHB0APgReS6DLgABZmx9LoAuAOA12GnddQDzAP8RaQBtAOUABBIAAUFhiy6OLnIA8gDuAnIA8gCaBwABY3GVLgoScgAA4DXYzdwAAXB0nS6hLmwAdQDzACUScgDpACASAARhY2VmaW9zdbEuvC7ELsguzC7PLtQu2S5jAAABdXm2LrsudABlADuA/QD9QE9kAAFpecAuwy5yAGMAd2FLZG4AO4ClAKVAcgAA4DXYNt1jAHkAV2RwAGYAAOA12GrdYwByAADgNdjO3AABY23dLt8ueQBOZGwAO4D/AP9AAAVhY2RlZmhpb3N38y73Lv8uAi8MLxAvEy8YLx0vIi9jInV0ZQB6YQABYXn7Lv4u8iFvbn5hN2RvAHQAfGEAAWV0Bi8KL3QAcgDmAB8QYQC2Y3IAAOA12DfdYwB5ADZk5yJyYXJyAKDdIXAAZgAA4DXYa91jAHIAAOA12M/cAAFqbiYvKC8AoA0gagAAoAwg");
|
|
93728
|
+
//# sourceMappingURL=decode-data-html.js.map
|
|
93729
|
+
;// ./node_modules/htmlparser2/dist/Tokenizer.js
|
|
93730
|
+
|
|
93731
|
+
var Tokenizer_CharCodes;
|
|
93732
|
+
(function (CharCodes) {
|
|
93733
|
+
CharCodes[CharCodes["Tab"] = 9] = "Tab";
|
|
93734
|
+
CharCodes[CharCodes["NewLine"] = 10] = "NewLine";
|
|
93735
|
+
CharCodes[CharCodes["FormFeed"] = 12] = "FormFeed";
|
|
93736
|
+
CharCodes[CharCodes["CarriageReturn"] = 13] = "CarriageReturn";
|
|
93737
|
+
CharCodes[CharCodes["Space"] = 32] = "Space";
|
|
93738
|
+
CharCodes[CharCodes["ExclamationMark"] = 33] = "ExclamationMark";
|
|
93739
|
+
CharCodes[CharCodes["Number"] = 35] = "Number";
|
|
93740
|
+
CharCodes[CharCodes["Amp"] = 38] = "Amp";
|
|
93741
|
+
CharCodes[CharCodes["SingleQuote"] = 39] = "SingleQuote";
|
|
93742
|
+
CharCodes[CharCodes["DoubleQuote"] = 34] = "DoubleQuote";
|
|
93743
|
+
CharCodes[CharCodes["Dash"] = 45] = "Dash";
|
|
93744
|
+
CharCodes[CharCodes["Slash"] = 47] = "Slash";
|
|
93745
|
+
CharCodes[CharCodes["Zero"] = 48] = "Zero";
|
|
93746
|
+
CharCodes[CharCodes["Nine"] = 57] = "Nine";
|
|
93747
|
+
CharCodes[CharCodes["Semi"] = 59] = "Semi";
|
|
93748
|
+
CharCodes[CharCodes["Lt"] = 60] = "Lt";
|
|
93749
|
+
CharCodes[CharCodes["Eq"] = 61] = "Eq";
|
|
93750
|
+
CharCodes[CharCodes["Gt"] = 62] = "Gt";
|
|
93751
|
+
CharCodes[CharCodes["Questionmark"] = 63] = "Questionmark";
|
|
93752
|
+
CharCodes[CharCodes["UpperA"] = 65] = "UpperA";
|
|
93753
|
+
CharCodes[CharCodes["LowerA"] = 97] = "LowerA";
|
|
93754
|
+
CharCodes[CharCodes["UpperF"] = 70] = "UpperF";
|
|
93755
|
+
CharCodes[CharCodes["LowerF"] = 102] = "LowerF";
|
|
93756
|
+
CharCodes[CharCodes["UpperZ"] = 90] = "UpperZ";
|
|
93757
|
+
CharCodes[CharCodes["LowerZ"] = 122] = "LowerZ";
|
|
93758
|
+
CharCodes[CharCodes["LowerX"] = 120] = "LowerX";
|
|
93759
|
+
CharCodes[CharCodes["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
|
|
93760
|
+
})(Tokenizer_CharCodes || (Tokenizer_CharCodes = {}));
|
|
93761
|
+
/** All the states the tokenizer can be in. */
|
|
93762
|
+
var Tokenizer_State;
|
|
93763
|
+
(function (State) {
|
|
93764
|
+
State[State["Text"] = 1] = "Text";
|
|
93765
|
+
State[State["BeforeTagName"] = 2] = "BeforeTagName";
|
|
93766
|
+
State[State["InTagName"] = 3] = "InTagName";
|
|
93767
|
+
State[State["InSelfClosingTag"] = 4] = "InSelfClosingTag";
|
|
93768
|
+
State[State["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
|
|
93769
|
+
State[State["InClosingTagName"] = 6] = "InClosingTagName";
|
|
93770
|
+
State[State["AfterClosingTagName"] = 7] = "AfterClosingTagName";
|
|
93771
|
+
// Attributes
|
|
93772
|
+
State[State["BeforeAttributeName"] = 8] = "BeforeAttributeName";
|
|
93773
|
+
State[State["InAttributeName"] = 9] = "InAttributeName";
|
|
93774
|
+
State[State["AfterAttributeName"] = 10] = "AfterAttributeName";
|
|
93775
|
+
State[State["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
|
|
93776
|
+
State[State["InAttributeValueDq"] = 12] = "InAttributeValueDq";
|
|
93777
|
+
State[State["InAttributeValueSq"] = 13] = "InAttributeValueSq";
|
|
93778
|
+
State[State["InAttributeValueNq"] = 14] = "InAttributeValueNq";
|
|
93779
|
+
// Declarations
|
|
93780
|
+
State[State["BeforeDeclaration"] = 15] = "BeforeDeclaration";
|
|
93781
|
+
State[State["InDeclaration"] = 16] = "InDeclaration";
|
|
93782
|
+
// Processing instructions
|
|
93783
|
+
State[State["InProcessingInstruction"] = 17] = "InProcessingInstruction";
|
|
93784
|
+
// Comments & CDATA
|
|
93785
|
+
State[State["BeforeComment"] = 18] = "BeforeComment";
|
|
93786
|
+
State[State["CDATASequence"] = 19] = "CDATASequence";
|
|
93787
|
+
State[State["DeclarationSequence"] = 20] = "DeclarationSequence";
|
|
93788
|
+
State[State["InSpecialComment"] = 21] = "InSpecialComment";
|
|
93789
|
+
State[State["InCommentLike"] = 22] = "InCommentLike";
|
|
93790
|
+
// Special tags
|
|
93791
|
+
State[State["SpecialStartSequence"] = 23] = "SpecialStartSequence";
|
|
93792
|
+
State[State["InSpecialTag"] = 24] = "InSpecialTag";
|
|
93793
|
+
State[State["InPlainText"] = 25] = "InPlainText";
|
|
93794
|
+
State[State["InEntity"] = 26] = "InEntity";
|
|
93795
|
+
})(Tokenizer_State || (Tokenizer_State = {}));
|
|
93796
|
+
function Tokenizer_isWhitespace(c) {
|
|
93797
|
+
return (c === Tokenizer_CharCodes.Space ||
|
|
93798
|
+
c === Tokenizer_CharCodes.NewLine ||
|
|
93799
|
+
c === Tokenizer_CharCodes.Tab ||
|
|
93800
|
+
c === Tokenizer_CharCodes.FormFeed ||
|
|
93801
|
+
c === Tokenizer_CharCodes.CarriageReturn);
|
|
93802
|
+
}
|
|
93803
|
+
function isEndOfTagSection(c) {
|
|
93804
|
+
return c === Tokenizer_CharCodes.Slash || c === Tokenizer_CharCodes.Gt || Tokenizer_isWhitespace(c);
|
|
93805
|
+
}
|
|
93806
|
+
function isASCIIAlpha(c) {
|
|
93807
|
+
return ((c >= Tokenizer_CharCodes.LowerA && c <= Tokenizer_CharCodes.LowerZ) ||
|
|
93808
|
+
(c >= Tokenizer_CharCodes.UpperA && c <= Tokenizer_CharCodes.UpperZ));
|
|
93809
|
+
}
|
|
93810
|
+
/**
|
|
93811
|
+
* Quote style used for parsed attributes.
|
|
93812
|
+
*/
|
|
93813
|
+
var QuoteType;
|
|
93814
|
+
(function (QuoteType) {
|
|
93815
|
+
QuoteType[QuoteType["NoValue"] = 0] = "NoValue";
|
|
93816
|
+
QuoteType[QuoteType["Unquoted"] = 1] = "Unquoted";
|
|
93817
|
+
QuoteType[QuoteType["Single"] = 2] = "Single";
|
|
93818
|
+
QuoteType[QuoteType["Double"] = 3] = "Double";
|
|
93819
|
+
})(QuoteType || (QuoteType = {}));
|
|
93820
|
+
/**
|
|
93821
|
+
* Sequences used to match longer strings.
|
|
93822
|
+
*
|
|
93823
|
+
* We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End
|
|
93824
|
+
* sequences with an increased offset.
|
|
93825
|
+
*/
|
|
93826
|
+
const Sequences = {
|
|
93827
|
+
Empty: new Uint8Array(0),
|
|
93828
|
+
Cdata: new Uint8Array([0x43, 0x44, 0x41, 0x54, 0x41, 0x5b]), // CDATA[
|
|
93829
|
+
CdataEnd: new Uint8Array([0x5d, 0x5d, 0x3e]), // ]]>
|
|
93830
|
+
CommentEnd: new Uint8Array([0x2d, 0x2d, 0x21, 0x3e]), // `--!>`
|
|
93831
|
+
Doctype: new Uint8Array([0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65]), // `doctype`
|
|
93832
|
+
IframeEnd: new Uint8Array([0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65]), // `</iframe`
|
|
93833
|
+
NoembedEnd: new Uint8Array([
|
|
93834
|
+
0x3c, 0x2f, 0x6e, 0x6f, 0x65, 0x6d, 0x62, 0x65, 0x64,
|
|
93835
|
+
]), // `</noembed`
|
|
93836
|
+
NoframesEnd: new Uint8Array([
|
|
93837
|
+
0x3c, 0x2f, 0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73,
|
|
93838
|
+
]), // `</noframes`
|
|
93839
|
+
Plaintext: new Uint8Array([
|
|
93840
|
+
0x3c, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,
|
|
93841
|
+
]), // `</plaintext`
|
|
93842
|
+
ScriptEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74]), // `</script`
|
|
93843
|
+
StyleEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65]), // `</style`
|
|
93844
|
+
TitleEnd: new Uint8Array([0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65]), // `</title`
|
|
93845
|
+
TextareaEnd: new Uint8Array([
|
|
93846
|
+
0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61,
|
|
93847
|
+
]), // `</textarea`
|
|
93848
|
+
XmpEnd: new Uint8Array([0x3c, 0x2f, 0x78, 0x6d, 0x70]), // `</xmp`
|
|
93849
|
+
};
|
|
93850
|
+
/**
|
|
93851
|
+
* Maps the first lowercase character of an HTML tag name to the sequence
|
|
93852
|
+
* used for special-tag detection. All sequences share a common layout
|
|
93853
|
+
* where index 2 is the first tag-name character, so matching always
|
|
93854
|
+
* continues from offset 3.
|
|
93855
|
+
*/
|
|
93856
|
+
const specialStartSequences = new Map([
|
|
93857
|
+
[Sequences.IframeEnd[2], Sequences.IframeEnd],
|
|
93858
|
+
[Sequences.NoembedEnd[2], Sequences.NoembedEnd],
|
|
93859
|
+
[Sequences.Plaintext[2], Sequences.Plaintext],
|
|
93860
|
+
[Sequences.ScriptEnd[2], Sequences.ScriptEnd],
|
|
93861
|
+
[Sequences.TitleEnd[2], Sequences.TitleEnd],
|
|
93862
|
+
[Sequences.XmpEnd[2], Sequences.XmpEnd],
|
|
93863
|
+
]);
|
|
93864
|
+
/**
|
|
93865
|
+
* Tokenizer implementation used by `Parser`.
|
|
93866
|
+
*/
|
|
93867
|
+
class Tokenizer_Tokenizer {
|
|
93868
|
+
cbs;
|
|
93869
|
+
/** The current state the tokenizer is in. */
|
|
93870
|
+
state = Tokenizer_State.Text;
|
|
93871
|
+
/** The read buffer. */
|
|
93872
|
+
buffer = "";
|
|
93873
|
+
/** The beginning of the section that is currently being read. */
|
|
93874
|
+
sectionStart = 0;
|
|
93875
|
+
/** The index within the buffer that we are currently looking at. */
|
|
93876
|
+
index = 0;
|
|
93877
|
+
/** The start of the last entity. */
|
|
93878
|
+
entityStart = 0;
|
|
93879
|
+
/** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
|
|
93880
|
+
baseState = Tokenizer_State.Text;
|
|
93881
|
+
/** For special parsing behavior inside of script and style tags. */
|
|
93882
|
+
isSpecial = false;
|
|
93883
|
+
/** Indicates whether the tokenizer has been paused. */
|
|
93884
|
+
running = true;
|
|
93885
|
+
/** The offset of the current buffer. */
|
|
93886
|
+
offset = 0;
|
|
93887
|
+
xmlMode;
|
|
93888
|
+
decodeEntities;
|
|
93889
|
+
recognizeSelfClosing;
|
|
93890
|
+
entityDecoder;
|
|
93891
|
+
constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode, }, cbs) {
|
|
93892
|
+
this.cbs = cbs;
|
|
93893
|
+
this.xmlMode = xmlMode;
|
|
93894
|
+
this.decodeEntities = decodeEntities;
|
|
93895
|
+
this.recognizeSelfClosing = recognizeSelfClosing;
|
|
93896
|
+
this.entityDecoder = new dist_decode_EntityDecoder(xmlMode ? generated_decode_data_xml_xmlDecodeTree : generated_decode_data_html_htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
|
|
93897
|
+
}
|
|
93898
|
+
reset() {
|
|
93899
|
+
this.state = Tokenizer_State.Text;
|
|
93900
|
+
this.buffer = "";
|
|
93901
|
+
this.sectionStart = 0;
|
|
93902
|
+
this.index = 0;
|
|
93903
|
+
this.baseState = Tokenizer_State.Text;
|
|
93904
|
+
this.isSpecial = false;
|
|
93905
|
+
this.currentSequence = Sequences.Empty;
|
|
93906
|
+
this.sequenceIndex = 0;
|
|
93907
|
+
this.running = true;
|
|
93908
|
+
this.offset = 0;
|
|
93909
|
+
}
|
|
93910
|
+
write(chunk) {
|
|
93911
|
+
this.offset += this.buffer.length;
|
|
93912
|
+
this.buffer = chunk;
|
|
93913
|
+
this.parse();
|
|
93914
|
+
}
|
|
93915
|
+
end() {
|
|
93916
|
+
if (this.running)
|
|
93917
|
+
this.finish();
|
|
93918
|
+
}
|
|
93919
|
+
pause() {
|
|
93920
|
+
this.running = false;
|
|
93921
|
+
}
|
|
93922
|
+
resume() {
|
|
93923
|
+
this.running = true;
|
|
93924
|
+
if (this.index < this.buffer.length + this.offset) {
|
|
93925
|
+
this.parse();
|
|
93926
|
+
}
|
|
93927
|
+
}
|
|
93928
|
+
stateText(c) {
|
|
93929
|
+
if (c === Tokenizer_CharCodes.Lt ||
|
|
93930
|
+
(!this.decodeEntities && this.fastForwardTo(Tokenizer_CharCodes.Lt))) {
|
|
93931
|
+
if (this.index > this.sectionStart) {
|
|
93932
|
+
this.cbs.ontext(this.sectionStart, this.index);
|
|
93933
|
+
}
|
|
93934
|
+
this.state = Tokenizer_State.BeforeTagName;
|
|
93935
|
+
this.sectionStart = this.index;
|
|
93936
|
+
}
|
|
93937
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
93938
|
+
this.startEntity();
|
|
93939
|
+
}
|
|
93940
|
+
}
|
|
93941
|
+
currentSequence = Sequences.Empty;
|
|
93942
|
+
sequenceIndex = 0;
|
|
93943
|
+
enterTagBody() {
|
|
93944
|
+
if (this.currentSequence === Sequences.Plaintext) {
|
|
93945
|
+
this.currentSequence = Sequences.Empty;
|
|
93946
|
+
this.state = Tokenizer_State.InPlainText;
|
|
93947
|
+
}
|
|
93948
|
+
else if (this.isSpecial) {
|
|
93949
|
+
this.state = Tokenizer_State.InSpecialTag;
|
|
93950
|
+
this.sequenceIndex = 0;
|
|
93951
|
+
}
|
|
93952
|
+
else {
|
|
93953
|
+
this.state = Tokenizer_State.Text;
|
|
93954
|
+
}
|
|
93955
|
+
}
|
|
93956
|
+
/**
|
|
93957
|
+
* Match the opening tag name against an HTML text-only tag sequence.
|
|
93958
|
+
*
|
|
93959
|
+
* Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,
|
|
93960
|
+
* `noembed`/`noframes`), so we may switch to an alternate sequence at the
|
|
93961
|
+
* first distinguishing byte. On a successful full match we fall back to
|
|
93962
|
+
* the normal tag-name state; a later `>` will enter raw-text, RCDATA, or
|
|
93963
|
+
* plaintext mode based on `currentSequence` / `isSpecial`.
|
|
93964
|
+
* @param c Current character code point.
|
|
93965
|
+
*/
|
|
93966
|
+
stateSpecialStartSequence(c) {
|
|
93967
|
+
const lower = c | 0x20;
|
|
93968
|
+
// Still matching — check for an alternate sequence at branch points.
|
|
93969
|
+
if (this.sequenceIndex < this.currentSequence.length) {
|
|
93970
|
+
if (lower === this.currentSequence[this.sequenceIndex]) {
|
|
93971
|
+
this.sequenceIndex++;
|
|
93972
|
+
return;
|
|
93973
|
+
}
|
|
93974
|
+
if (this.sequenceIndex === 3) {
|
|
93975
|
+
if (this.currentSequence === Sequences.ScriptEnd &&
|
|
93976
|
+
lower === Sequences.StyleEnd[3]) {
|
|
93977
|
+
this.currentSequence = Sequences.StyleEnd;
|
|
93978
|
+
this.sequenceIndex = 4;
|
|
93979
|
+
return;
|
|
93980
|
+
}
|
|
93981
|
+
if (this.currentSequence === Sequences.TitleEnd &&
|
|
93982
|
+
lower === Sequences.TextareaEnd[3]) {
|
|
93983
|
+
this.currentSequence = Sequences.TextareaEnd;
|
|
93984
|
+
this.sequenceIndex = 4;
|
|
93985
|
+
return;
|
|
93986
|
+
}
|
|
93987
|
+
}
|
|
93988
|
+
else if (this.sequenceIndex === 4 &&
|
|
93989
|
+
this.currentSequence === Sequences.NoembedEnd &&
|
|
93990
|
+
lower === Sequences.NoframesEnd[4]) {
|
|
93991
|
+
this.currentSequence = Sequences.NoframesEnd;
|
|
93992
|
+
this.sequenceIndex = 5;
|
|
93993
|
+
return;
|
|
93994
|
+
}
|
|
93995
|
+
}
|
|
93996
|
+
else if (isEndOfTagSection(c)) {
|
|
93997
|
+
// Full match on a valid tag boundary — keep the sequence.
|
|
93998
|
+
this.sequenceIndex = 0;
|
|
93999
|
+
this.state = Tokenizer_State.InTagName;
|
|
94000
|
+
this.stateInTagName(c);
|
|
94001
|
+
return;
|
|
94002
|
+
}
|
|
94003
|
+
// No match — abandon special-tag detection.
|
|
94004
|
+
this.isSpecial = false;
|
|
94005
|
+
this.currentSequence = Sequences.Empty;
|
|
94006
|
+
this.sequenceIndex = 0;
|
|
94007
|
+
this.state = Tokenizer_State.InTagName;
|
|
94008
|
+
this.stateInTagName(c);
|
|
94009
|
+
}
|
|
94010
|
+
stateCDATASequence(c) {
|
|
94011
|
+
if (c === Sequences.Cdata[this.sequenceIndex]) {
|
|
94012
|
+
if (++this.sequenceIndex === Sequences.Cdata.length) {
|
|
94013
|
+
this.state = Tokenizer_State.InCommentLike;
|
|
94014
|
+
this.currentSequence = Sequences.CdataEnd;
|
|
94015
|
+
this.sequenceIndex = 0;
|
|
94016
|
+
this.sectionStart = this.index + 1;
|
|
94017
|
+
}
|
|
94018
|
+
}
|
|
94019
|
+
else {
|
|
94020
|
+
this.sequenceIndex = 0;
|
|
94021
|
+
if (this.xmlMode) {
|
|
94022
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
94023
|
+
this.stateInDeclaration(c); // Reconsume the character
|
|
94024
|
+
}
|
|
94025
|
+
else {
|
|
94026
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94027
|
+
this.stateInSpecialComment(c); // Reconsume the character
|
|
94028
|
+
}
|
|
94029
|
+
}
|
|
94030
|
+
}
|
|
94031
|
+
/**
|
|
94032
|
+
* When we wait for one specific character, we can speed things up
|
|
94033
|
+
* by skipping through the buffer until we find it.
|
|
94034
|
+
* @param c Current character code point.
|
|
94035
|
+
* @returns Whether the character was found.
|
|
94036
|
+
*/
|
|
94037
|
+
fastForwardTo(c) {
|
|
94038
|
+
while (++this.index < this.buffer.length + this.offset) {
|
|
94039
|
+
if (this.buffer.charCodeAt(this.index - this.offset) === c) {
|
|
94040
|
+
return true;
|
|
94041
|
+
}
|
|
94042
|
+
}
|
|
94043
|
+
/*
|
|
94044
|
+
* We increment the index at the end of the `parse` loop,
|
|
94045
|
+
* so set it to `buffer.length - 1` here.
|
|
94046
|
+
*
|
|
94047
|
+
* TODO: Refactor `parse` to increment index before calling states.
|
|
94048
|
+
*/
|
|
94049
|
+
this.index = this.buffer.length + this.offset - 1;
|
|
94050
|
+
return false;
|
|
94051
|
+
}
|
|
94052
|
+
/**
|
|
94053
|
+
* Emit a comment token and return to the text state.
|
|
94054
|
+
* @param offset Number of characters in the end sequence that have already been matched.
|
|
94055
|
+
*/
|
|
94056
|
+
emitComment(offset) {
|
|
94057
|
+
this.cbs.oncomment(this.sectionStart, this.index, offset);
|
|
94058
|
+
this.sequenceIndex = 0;
|
|
94059
|
+
this.sectionStart = this.index + 1;
|
|
94060
|
+
this.state = Tokenizer_State.Text;
|
|
94061
|
+
}
|
|
94062
|
+
/**
|
|
94063
|
+
* Comments and CDATA end with `-->` and `]]>`.
|
|
94064
|
+
*
|
|
94065
|
+
* Their common qualities are:
|
|
94066
|
+
* - Their end sequences have a distinct character they start with.
|
|
94067
|
+
* - That character is then repeated, so we have to check multiple repeats.
|
|
94068
|
+
* - All characters but the start character of the sequence can be skipped.
|
|
94069
|
+
* @param c Current character code point.
|
|
94070
|
+
*/
|
|
94071
|
+
stateInCommentLike(c) {
|
|
94072
|
+
if (!this.xmlMode &&
|
|
94073
|
+
this.currentSequence === Sequences.CommentEnd &&
|
|
94074
|
+
this.sequenceIndex <= 1 &&
|
|
94075
|
+
/*
|
|
94076
|
+
* We're still at the very start of the comment: the only
|
|
94077
|
+
* characters consumed since `<!--` are the dashes that
|
|
94078
|
+
* advanced sequenceIndex (0 for `<!-->`, 1 for `<!--->`).
|
|
94079
|
+
*/
|
|
94080
|
+
this.index === this.sectionStart + this.sequenceIndex &&
|
|
94081
|
+
c === Tokenizer_CharCodes.Gt) {
|
|
94082
|
+
// Abruptly closed empty HTML comment.
|
|
94083
|
+
this.emitComment(this.sequenceIndex);
|
|
94084
|
+
}
|
|
94085
|
+
else if (this.currentSequence === Sequences.CommentEnd &&
|
|
94086
|
+
this.sequenceIndex === 2 &&
|
|
94087
|
+
c === Tokenizer_CharCodes.Gt) {
|
|
94088
|
+
// `!` is optional here, so the same sequence also accepts `-->`.
|
|
94089
|
+
this.emitComment(2);
|
|
94090
|
+
}
|
|
94091
|
+
else if (this.currentSequence === Sequences.CommentEnd &&
|
|
94092
|
+
this.sequenceIndex === this.currentSequence.length - 1 &&
|
|
94093
|
+
c !== Tokenizer_CharCodes.Gt) {
|
|
94094
|
+
this.sequenceIndex = Number(c === Tokenizer_CharCodes.Dash);
|
|
94095
|
+
}
|
|
94096
|
+
else if (c === this.currentSequence[this.sequenceIndex]) {
|
|
94097
|
+
if (++this.sequenceIndex === this.currentSequence.length) {
|
|
94098
|
+
if (this.currentSequence === Sequences.CdataEnd) {
|
|
94099
|
+
this.cbs.oncdata(this.sectionStart, this.index, 2);
|
|
94100
|
+
}
|
|
94101
|
+
else {
|
|
94102
|
+
this.cbs.oncomment(this.sectionStart, this.index, 3);
|
|
94103
|
+
}
|
|
94104
|
+
this.sequenceIndex = 0;
|
|
94105
|
+
this.sectionStart = this.index + 1;
|
|
94106
|
+
this.state = Tokenizer_State.Text;
|
|
94107
|
+
}
|
|
94108
|
+
}
|
|
94109
|
+
else if (this.sequenceIndex === 0) {
|
|
94110
|
+
// Fast-forward to the first character of the sequence
|
|
94111
|
+
if (this.fastForwardTo(this.currentSequence[0])) {
|
|
94112
|
+
this.sequenceIndex = 1;
|
|
94113
|
+
}
|
|
94114
|
+
}
|
|
94115
|
+
else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
|
|
94116
|
+
// Allow long sequences, eg. --->, ]]]>
|
|
94117
|
+
this.sequenceIndex = 0;
|
|
94118
|
+
}
|
|
94119
|
+
}
|
|
94120
|
+
/**
|
|
94121
|
+
* HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
|
|
94122
|
+
*
|
|
94123
|
+
* XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
|
|
94124
|
+
* We allow anything that wouldn't end the tag.
|
|
94125
|
+
* @param c Current character code point.
|
|
94126
|
+
*/
|
|
94127
|
+
isTagStartChar(c) {
|
|
94128
|
+
return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
|
|
94129
|
+
}
|
|
94130
|
+
/**
|
|
94131
|
+
* Scan raw-text / RCDATA content for the matching end tag.
|
|
94132
|
+
*
|
|
94133
|
+
* For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.
|
|
94134
|
+
* For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.
|
|
94135
|
+
* @param c Current character code point.
|
|
94136
|
+
*/
|
|
94137
|
+
stateInSpecialTag(c) {
|
|
94138
|
+
if (this.sequenceIndex === this.currentSequence.length) {
|
|
94139
|
+
if (isEndOfTagSection(c)) {
|
|
94140
|
+
const endOfText = this.index - this.currentSequence.length;
|
|
94141
|
+
if (this.sectionStart < endOfText) {
|
|
94142
|
+
// Spoof the index so that reported locations match up.
|
|
94143
|
+
const actualIndex = this.index;
|
|
94144
|
+
this.index = endOfText;
|
|
94145
|
+
this.cbs.ontext(this.sectionStart, endOfText);
|
|
94146
|
+
this.index = actualIndex;
|
|
94147
|
+
}
|
|
94148
|
+
this.isSpecial = false;
|
|
94149
|
+
this.sectionStart = endOfText + 2; // Skip over the `</`
|
|
94150
|
+
this.stateInClosingTagName(c);
|
|
94151
|
+
return; // We are done; skip the rest of the function.
|
|
94152
|
+
}
|
|
94153
|
+
this.sequenceIndex = 0;
|
|
94154
|
+
}
|
|
94155
|
+
if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {
|
|
94156
|
+
this.sequenceIndex += 1;
|
|
94157
|
+
}
|
|
94158
|
+
else if (this.sequenceIndex === 0) {
|
|
94159
|
+
if (this.currentSequence === Sequences.TitleEnd ||
|
|
94160
|
+
this.currentSequence === Sequences.TextareaEnd) {
|
|
94161
|
+
// RCDATA tags have to parse entities while still looking for their end tag.
|
|
94162
|
+
if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
94163
|
+
this.startEntity();
|
|
94164
|
+
}
|
|
94165
|
+
}
|
|
94166
|
+
else if (this.fastForwardTo(Tokenizer_CharCodes.Lt)) {
|
|
94167
|
+
// Outside of RCDATA tags, we can fast-forward.
|
|
94168
|
+
this.sequenceIndex = 1;
|
|
94169
|
+
}
|
|
94170
|
+
}
|
|
94171
|
+
else {
|
|
94172
|
+
// If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.
|
|
94173
|
+
this.sequenceIndex = Number(c === Tokenizer_CharCodes.Lt);
|
|
94174
|
+
}
|
|
94175
|
+
}
|
|
94176
|
+
stateBeforeTagName(c) {
|
|
94177
|
+
if (c === Tokenizer_CharCodes.ExclamationMark) {
|
|
94178
|
+
this.state = Tokenizer_State.BeforeDeclaration;
|
|
94179
|
+
this.sectionStart = this.index + 1;
|
|
94180
|
+
}
|
|
94181
|
+
else if (c === Tokenizer_CharCodes.Questionmark) {
|
|
94182
|
+
if (this.xmlMode) {
|
|
94183
|
+
this.state = Tokenizer_State.InProcessingInstruction;
|
|
94184
|
+
this.sequenceIndex = 0;
|
|
94185
|
+
this.sectionStart = this.index + 1;
|
|
94186
|
+
}
|
|
94187
|
+
else {
|
|
94188
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94189
|
+
this.sectionStart = this.index;
|
|
94190
|
+
}
|
|
94191
|
+
}
|
|
94192
|
+
else if (this.isTagStartChar(c)) {
|
|
94193
|
+
this.sectionStart = this.index;
|
|
94194
|
+
const special = this.xmlMode || this.cbs.isInForeignContext?.()
|
|
94195
|
+
? undefined
|
|
94196
|
+
: specialStartSequences.get(c | 0x20);
|
|
94197
|
+
if (special === undefined) {
|
|
94198
|
+
this.state = Tokenizer_State.InTagName;
|
|
94199
|
+
}
|
|
94200
|
+
else {
|
|
94201
|
+
this.isSpecial = true;
|
|
94202
|
+
this.currentSequence = special;
|
|
94203
|
+
this.sequenceIndex = 3;
|
|
94204
|
+
this.state = Tokenizer_State.SpecialStartSequence;
|
|
94205
|
+
}
|
|
94206
|
+
}
|
|
94207
|
+
else if (c === Tokenizer_CharCodes.Slash) {
|
|
94208
|
+
this.state = Tokenizer_State.BeforeClosingTagName;
|
|
94209
|
+
}
|
|
94210
|
+
else {
|
|
94211
|
+
this.state = Tokenizer_State.Text;
|
|
94212
|
+
this.stateText(c);
|
|
94213
|
+
}
|
|
94214
|
+
}
|
|
94215
|
+
stateInTagName(c) {
|
|
94216
|
+
if (isEndOfTagSection(c)) {
|
|
94217
|
+
this.cbs.onopentagname(this.sectionStart, this.index);
|
|
94218
|
+
this.sectionStart = -1;
|
|
94219
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
94220
|
+
this.stateBeforeAttributeName(c);
|
|
94221
|
+
}
|
|
94222
|
+
}
|
|
94223
|
+
stateBeforeClosingTagName(c) {
|
|
94224
|
+
if (Tokenizer_isWhitespace(c)) {
|
|
94225
|
+
if (this.xmlMode) {
|
|
94226
|
+
// Ignore
|
|
94227
|
+
}
|
|
94228
|
+
else {
|
|
94229
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94230
|
+
this.sectionStart = this.index;
|
|
94231
|
+
}
|
|
94232
|
+
}
|
|
94233
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
94234
|
+
this.state = Tokenizer_State.Text;
|
|
94235
|
+
if (!this.xmlMode) {
|
|
94236
|
+
this.sectionStart = this.index + 1;
|
|
94237
|
+
}
|
|
94238
|
+
}
|
|
94239
|
+
else {
|
|
94240
|
+
this.state = this.isTagStartChar(c)
|
|
94241
|
+
? Tokenizer_State.InClosingTagName
|
|
94242
|
+
: Tokenizer_State.InSpecialComment;
|
|
94243
|
+
this.sectionStart = this.index;
|
|
94244
|
+
}
|
|
94245
|
+
}
|
|
94246
|
+
stateInClosingTagName(c) {
|
|
94247
|
+
if (isEndOfTagSection(c)) {
|
|
94248
|
+
this.cbs.onclosetag(this.sectionStart, this.index);
|
|
94249
|
+
this.sectionStart = -1;
|
|
94250
|
+
this.state = Tokenizer_State.AfterClosingTagName;
|
|
94251
|
+
this.stateAfterClosingTagName(c);
|
|
94252
|
+
}
|
|
94253
|
+
}
|
|
94254
|
+
stateAfterClosingTagName(c) {
|
|
94255
|
+
// Skip everything until ">"
|
|
94256
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
94257
|
+
this.state = Tokenizer_State.Text;
|
|
94258
|
+
this.sectionStart = this.index + 1;
|
|
94259
|
+
}
|
|
94260
|
+
}
|
|
94261
|
+
stateBeforeAttributeName(c) {
|
|
94262
|
+
if (c === Tokenizer_CharCodes.Gt) {
|
|
94263
|
+
this.cbs.onopentagend(this.index);
|
|
94264
|
+
this.enterTagBody();
|
|
94265
|
+
this.sectionStart = this.index + 1;
|
|
94266
|
+
}
|
|
94267
|
+
else if (c === Tokenizer_CharCodes.Slash) {
|
|
94268
|
+
this.state = Tokenizer_State.InSelfClosingTag;
|
|
94269
|
+
}
|
|
94270
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
94271
|
+
this.state = Tokenizer_State.InAttributeName;
|
|
94272
|
+
this.sectionStart = this.index;
|
|
94273
|
+
}
|
|
94274
|
+
}
|
|
94275
|
+
/**
|
|
94276
|
+
* Handle `/` before `>` in an opening tag.
|
|
94277
|
+
*
|
|
94278
|
+
* In HTML mode, text-only tags ignore the self-closing flag and still enter
|
|
94279
|
+
* their raw-text/RCDATA/plaintext state unless self-closing tags are being
|
|
94280
|
+
* recognized. In XML mode, or for ordinary tags, the tokenizer returns to
|
|
94281
|
+
* regular text parsing after emitting the self-closing callback.
|
|
94282
|
+
* @param c Current character code point.
|
|
94283
|
+
*/
|
|
94284
|
+
stateInSelfClosingTag(c) {
|
|
94285
|
+
if (c === Tokenizer_CharCodes.Gt) {
|
|
94286
|
+
this.cbs.onselfclosingtag(this.index);
|
|
94287
|
+
this.sectionStart = this.index + 1;
|
|
94288
|
+
if (!this.recognizeSelfClosing) {
|
|
94289
|
+
this.enterTagBody();
|
|
94290
|
+
return;
|
|
94291
|
+
}
|
|
94292
|
+
this.state = Tokenizer_State.Text;
|
|
94293
|
+
this.isSpecial = false; // Reset special state, in case of self-closing special tags
|
|
94294
|
+
this.currentSequence = Sequences.Empty;
|
|
94295
|
+
}
|
|
94296
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
94297
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
94298
|
+
this.stateBeforeAttributeName(c);
|
|
94299
|
+
}
|
|
94300
|
+
}
|
|
94301
|
+
stateInAttributeName(c) {
|
|
94302
|
+
if (c === Tokenizer_CharCodes.Eq || isEndOfTagSection(c)) {
|
|
94303
|
+
this.cbs.onattribname(this.sectionStart, this.index);
|
|
94304
|
+
this.sectionStart = this.index;
|
|
94305
|
+
this.state = Tokenizer_State.AfterAttributeName;
|
|
94306
|
+
this.stateAfterAttributeName(c);
|
|
94307
|
+
}
|
|
94308
|
+
}
|
|
94309
|
+
stateAfterAttributeName(c) {
|
|
94310
|
+
if (c === Tokenizer_CharCodes.Eq) {
|
|
94311
|
+
this.state = Tokenizer_State.BeforeAttributeValue;
|
|
94312
|
+
}
|
|
94313
|
+
else if (c === Tokenizer_CharCodes.Slash || c === Tokenizer_CharCodes.Gt) {
|
|
94314
|
+
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
|
94315
|
+
this.sectionStart = -1;
|
|
94316
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
94317
|
+
this.stateBeforeAttributeName(c);
|
|
94318
|
+
}
|
|
94319
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
94320
|
+
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
|
94321
|
+
this.state = Tokenizer_State.InAttributeName;
|
|
94322
|
+
this.sectionStart = this.index;
|
|
94323
|
+
}
|
|
94324
|
+
}
|
|
94325
|
+
stateBeforeAttributeValue(c) {
|
|
94326
|
+
if (c === Tokenizer_CharCodes.DoubleQuote) {
|
|
94327
|
+
this.state = Tokenizer_State.InAttributeValueDq;
|
|
94328
|
+
this.sectionStart = this.index + 1;
|
|
94329
|
+
}
|
|
94330
|
+
else if (c === Tokenizer_CharCodes.SingleQuote) {
|
|
94331
|
+
this.state = Tokenizer_State.InAttributeValueSq;
|
|
94332
|
+
this.sectionStart = this.index + 1;
|
|
94333
|
+
}
|
|
94334
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
94335
|
+
this.sectionStart = this.index;
|
|
94336
|
+
this.state = Tokenizer_State.InAttributeValueNq;
|
|
94337
|
+
this.stateInAttributeValueNoQuotes(c); // Reconsume token
|
|
94338
|
+
}
|
|
94339
|
+
}
|
|
94340
|
+
handleInAttributeValue(c, quote) {
|
|
94341
|
+
if (c === quote ||
|
|
94342
|
+
(!this.decodeEntities && this.fastForwardTo(quote))) {
|
|
94343
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
94344
|
+
this.sectionStart = -1;
|
|
94345
|
+
this.cbs.onattribend(quote === Tokenizer_CharCodes.DoubleQuote
|
|
94346
|
+
? QuoteType.Double
|
|
94347
|
+
: QuoteType.Single, this.index + 1);
|
|
94348
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
94349
|
+
}
|
|
94350
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
94351
|
+
this.startEntity();
|
|
94352
|
+
}
|
|
94353
|
+
}
|
|
94354
|
+
stateInAttributeValueDoubleQuotes(c) {
|
|
94355
|
+
this.handleInAttributeValue(c, Tokenizer_CharCodes.DoubleQuote);
|
|
94356
|
+
}
|
|
94357
|
+
stateInAttributeValueSingleQuotes(c) {
|
|
94358
|
+
this.handleInAttributeValue(c, Tokenizer_CharCodes.SingleQuote);
|
|
94359
|
+
}
|
|
94360
|
+
stateInAttributeValueNoQuotes(c) {
|
|
94361
|
+
if (Tokenizer_isWhitespace(c) || c === Tokenizer_CharCodes.Gt) {
|
|
94362
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
94363
|
+
this.sectionStart = -1;
|
|
94364
|
+
this.cbs.onattribend(QuoteType.Unquoted, this.index);
|
|
94365
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
94366
|
+
this.stateBeforeAttributeName(c);
|
|
94367
|
+
}
|
|
94368
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
94369
|
+
this.startEntity();
|
|
94370
|
+
}
|
|
94371
|
+
}
|
|
94372
|
+
/**
|
|
94373
|
+
* Distinguish between CDATA, declarations, HTML comments, and HTML bogus
|
|
94374
|
+
* comments after `<!`.
|
|
94375
|
+
*
|
|
94376
|
+
* In HTML mode, only real comments and doctypes stay on declaration paths;
|
|
94377
|
+
* everything else becomes a bogus comment terminated by the next `>`.
|
|
94378
|
+
* @param c Current character code point.
|
|
94379
|
+
*/
|
|
94380
|
+
stateBeforeDeclaration(c) {
|
|
94381
|
+
if (c === Tokenizer_CharCodes.OpeningSquareBracket) {
|
|
94382
|
+
this.state = Tokenizer_State.CDATASequence;
|
|
94383
|
+
this.sequenceIndex = 0;
|
|
94384
|
+
}
|
|
94385
|
+
else if (this.xmlMode) {
|
|
94386
|
+
this.state =
|
|
94387
|
+
c === Tokenizer_CharCodes.Dash
|
|
94388
|
+
? Tokenizer_State.BeforeComment
|
|
94389
|
+
: Tokenizer_State.InDeclaration;
|
|
94390
|
+
}
|
|
94391
|
+
else if ((c | 0x20) === Sequences.Doctype[0]) {
|
|
94392
|
+
this.state = Tokenizer_State.DeclarationSequence;
|
|
94393
|
+
this.currentSequence = Sequences.Doctype;
|
|
94394
|
+
this.sequenceIndex = 1;
|
|
94395
|
+
}
|
|
94396
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
94397
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
94398
|
+
this.state = Tokenizer_State.Text;
|
|
94399
|
+
this.sectionStart = this.index + 1;
|
|
94400
|
+
}
|
|
94401
|
+
else if (c === Tokenizer_CharCodes.Dash) {
|
|
94402
|
+
this.state = Tokenizer_State.BeforeComment;
|
|
94403
|
+
}
|
|
94404
|
+
else {
|
|
94405
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94406
|
+
}
|
|
94407
|
+
}
|
|
94408
|
+
/**
|
|
94409
|
+
* Continue matching `doctype` after `<!d`.
|
|
94410
|
+
*
|
|
94411
|
+
* A full `doctype` match stays on the declaration path; any other name falls
|
|
94412
|
+
* back to an HTML bogus comment, which matches browser behavior for
|
|
94413
|
+
* non-doctype `<!...>` constructs.
|
|
94414
|
+
* @param c Current character code point.
|
|
94415
|
+
*/
|
|
94416
|
+
stateDeclarationSequence(c) {
|
|
94417
|
+
if (this.sequenceIndex === this.currentSequence.length) {
|
|
94418
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
94419
|
+
this.stateInDeclaration(c);
|
|
94420
|
+
}
|
|
94421
|
+
else if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {
|
|
94422
|
+
this.sequenceIndex += 1;
|
|
94423
|
+
}
|
|
94424
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
94425
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
94426
|
+
this.state = Tokenizer_State.Text;
|
|
94427
|
+
this.sectionStart = this.index + 1;
|
|
94428
|
+
}
|
|
94429
|
+
else {
|
|
94430
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94431
|
+
}
|
|
94432
|
+
}
|
|
94433
|
+
stateInDeclaration(c) {
|
|
94434
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
94435
|
+
this.cbs.ondeclaration(this.sectionStart, this.index);
|
|
94436
|
+
this.state = Tokenizer_State.Text;
|
|
94437
|
+
this.sectionStart = this.index + 1;
|
|
94438
|
+
}
|
|
94439
|
+
}
|
|
94440
|
+
/**
|
|
94441
|
+
* XML processing instructions (`<?...?>`).
|
|
94442
|
+
*
|
|
94443
|
+
* In HTML mode `<?` is routed to `InSpecialComment` instead, so this
|
|
94444
|
+
* state is only reachable in XML mode.
|
|
94445
|
+
* @param c Current character code point.
|
|
94446
|
+
*/
|
|
94447
|
+
stateInProcessingInstruction(c) {
|
|
94448
|
+
if (c === Tokenizer_CharCodes.Questionmark) {
|
|
94449
|
+
// Remember that we just consumed `?`, so the next `>` closes the PI.
|
|
94450
|
+
this.sequenceIndex = 1;
|
|
94451
|
+
}
|
|
94452
|
+
else if (c === Tokenizer_CharCodes.Gt && this.sequenceIndex === 1) {
|
|
94453
|
+
this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);
|
|
94454
|
+
this.sequenceIndex = 0;
|
|
94455
|
+
this.state = Tokenizer_State.Text;
|
|
94456
|
+
this.sectionStart = this.index + 1;
|
|
94457
|
+
}
|
|
94458
|
+
else {
|
|
94459
|
+
// Keep scanning for the next `?`, which can start a closing `?>`.
|
|
94460
|
+
this.sequenceIndex = Number(this.fastForwardTo(Tokenizer_CharCodes.Questionmark));
|
|
94461
|
+
}
|
|
94462
|
+
}
|
|
94463
|
+
stateBeforeComment(c) {
|
|
94464
|
+
if (c === Tokenizer_CharCodes.Dash) {
|
|
94465
|
+
this.state = Tokenizer_State.InCommentLike;
|
|
94466
|
+
this.currentSequence = Sequences.CommentEnd;
|
|
94467
|
+
this.sequenceIndex = 0;
|
|
94468
|
+
this.sectionStart = this.index + 1;
|
|
94469
|
+
}
|
|
94470
|
+
else if (this.xmlMode) {
|
|
94471
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
94472
|
+
}
|
|
94473
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
94474
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
94475
|
+
this.state = Tokenizer_State.Text;
|
|
94476
|
+
this.sectionStart = this.index + 1;
|
|
94477
|
+
}
|
|
94478
|
+
else {
|
|
94479
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
94480
|
+
}
|
|
94481
|
+
}
|
|
94482
|
+
stateInSpecialComment(c) {
|
|
94483
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
94484
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
94485
|
+
this.state = Tokenizer_State.Text;
|
|
94486
|
+
this.sectionStart = this.index + 1;
|
|
94487
|
+
}
|
|
94488
|
+
}
|
|
94489
|
+
startEntity() {
|
|
94490
|
+
this.baseState = this.state;
|
|
94491
|
+
this.state = Tokenizer_State.InEntity;
|
|
94492
|
+
this.entityStart = this.index;
|
|
94493
|
+
this.entityDecoder.startEntity(this.xmlMode
|
|
94494
|
+
? dist_decode_DecodingMode.Strict
|
|
94495
|
+
: this.baseState === Tokenizer_State.Text ||
|
|
94496
|
+
this.baseState === Tokenizer_State.InSpecialTag
|
|
94497
|
+
? dist_decode_DecodingMode.Legacy
|
|
94498
|
+
: dist_decode_DecodingMode.Attribute);
|
|
94499
|
+
}
|
|
94500
|
+
stateInEntity() {
|
|
94501
|
+
const indexInBuffer = this.index - this.offset;
|
|
94502
|
+
const length = this.entityDecoder.write(this.buffer, indexInBuffer);
|
|
94503
|
+
// If `length` is positive, we are done with the entity.
|
|
94504
|
+
if (length >= 0) {
|
|
94505
|
+
this.state = this.baseState;
|
|
94506
|
+
if (length === 0) {
|
|
94507
|
+
this.index -= 1;
|
|
94508
|
+
}
|
|
94509
|
+
}
|
|
94510
|
+
else {
|
|
94511
|
+
if (indexInBuffer < this.buffer.length &&
|
|
94512
|
+
this.buffer.charCodeAt(indexInBuffer) === Tokenizer_CharCodes.Amp) {
|
|
94513
|
+
this.state = this.baseState;
|
|
94514
|
+
this.index -= 1;
|
|
94515
|
+
return;
|
|
94516
|
+
}
|
|
94517
|
+
// Mark buffer as consumed.
|
|
94518
|
+
this.index = this.offset + this.buffer.length - 1;
|
|
94519
|
+
}
|
|
94520
|
+
}
|
|
94521
|
+
/**
|
|
94522
|
+
* Remove data that has already been consumed from the buffer.
|
|
94523
|
+
*/
|
|
94524
|
+
cleanup() {
|
|
94525
|
+
// If we are inside of text or attributes, emit what we already have.
|
|
94526
|
+
if (this.running && this.sectionStart !== this.index) {
|
|
94527
|
+
if (this.state === Tokenizer_State.Text ||
|
|
94528
|
+
this.state === Tokenizer_State.InPlainText ||
|
|
94529
|
+
(this.state === Tokenizer_State.InSpecialTag && this.sequenceIndex === 0)) {
|
|
94530
|
+
this.cbs.ontext(this.sectionStart, this.index);
|
|
94531
|
+
this.sectionStart = this.index;
|
|
94532
|
+
}
|
|
94533
|
+
else if (this.state === Tokenizer_State.InAttributeValueDq ||
|
|
94534
|
+
this.state === Tokenizer_State.InAttributeValueSq ||
|
|
94535
|
+
this.state === Tokenizer_State.InAttributeValueNq) {
|
|
94536
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
94537
|
+
this.sectionStart = this.index;
|
|
94538
|
+
}
|
|
94539
|
+
}
|
|
94540
|
+
}
|
|
94541
|
+
shouldContinue() {
|
|
94542
|
+
return this.index < this.buffer.length + this.offset && this.running;
|
|
94543
|
+
}
|
|
94544
|
+
/**
|
|
94545
|
+
* Iterates through the buffer, calling the function corresponding to the current state.
|
|
94546
|
+
*
|
|
94547
|
+
* States that are more likely to be hit are higher up, as a performance improvement.
|
|
94548
|
+
*/
|
|
94549
|
+
parse() {
|
|
94550
|
+
while (this.shouldContinue()) {
|
|
94551
|
+
const c = this.buffer.charCodeAt(this.index - this.offset);
|
|
94552
|
+
switch (this.state) {
|
|
94553
|
+
case Tokenizer_State.Text: {
|
|
94554
|
+
this.stateText(c);
|
|
94555
|
+
break;
|
|
94556
|
+
}
|
|
94557
|
+
case Tokenizer_State.InPlainText: {
|
|
94558
|
+
// Skip to end of buffer; cleanup() emits the text.
|
|
94559
|
+
this.index = this.buffer.length + this.offset - 1;
|
|
94560
|
+
break;
|
|
94561
|
+
}
|
|
94562
|
+
case Tokenizer_State.SpecialStartSequence: {
|
|
94563
|
+
this.stateSpecialStartSequence(c);
|
|
94564
|
+
break;
|
|
94565
|
+
}
|
|
94566
|
+
case Tokenizer_State.InSpecialTag: {
|
|
94567
|
+
this.stateInSpecialTag(c);
|
|
94568
|
+
break;
|
|
94569
|
+
}
|
|
94570
|
+
case Tokenizer_State.CDATASequence: {
|
|
94571
|
+
this.stateCDATASequence(c);
|
|
94572
|
+
break;
|
|
94573
|
+
}
|
|
94574
|
+
case Tokenizer_State.DeclarationSequence: {
|
|
94575
|
+
this.stateDeclarationSequence(c);
|
|
94576
|
+
break;
|
|
94577
|
+
}
|
|
94578
|
+
case Tokenizer_State.InAttributeValueDq: {
|
|
94579
|
+
this.stateInAttributeValueDoubleQuotes(c);
|
|
94580
|
+
break;
|
|
94581
|
+
}
|
|
94582
|
+
case Tokenizer_State.InAttributeName: {
|
|
94583
|
+
this.stateInAttributeName(c);
|
|
94584
|
+
break;
|
|
94585
|
+
}
|
|
94586
|
+
case Tokenizer_State.InCommentLike: {
|
|
94587
|
+
this.stateInCommentLike(c);
|
|
94588
|
+
break;
|
|
94589
|
+
}
|
|
94590
|
+
case Tokenizer_State.InSpecialComment: {
|
|
94591
|
+
this.stateInSpecialComment(c);
|
|
94592
|
+
break;
|
|
94593
|
+
}
|
|
94594
|
+
case Tokenizer_State.BeforeAttributeName: {
|
|
94595
|
+
this.stateBeforeAttributeName(c);
|
|
94596
|
+
break;
|
|
94597
|
+
}
|
|
94598
|
+
case Tokenizer_State.InTagName: {
|
|
94599
|
+
this.stateInTagName(c);
|
|
94600
|
+
break;
|
|
94601
|
+
}
|
|
94602
|
+
case Tokenizer_State.InClosingTagName: {
|
|
94603
|
+
this.stateInClosingTagName(c);
|
|
94604
|
+
break;
|
|
94605
|
+
}
|
|
94606
|
+
case Tokenizer_State.BeforeTagName: {
|
|
94607
|
+
this.stateBeforeTagName(c);
|
|
94608
|
+
break;
|
|
94609
|
+
}
|
|
94610
|
+
case Tokenizer_State.AfterAttributeName: {
|
|
94611
|
+
this.stateAfterAttributeName(c);
|
|
94612
|
+
break;
|
|
94613
|
+
}
|
|
94614
|
+
case Tokenizer_State.InAttributeValueSq: {
|
|
94615
|
+
this.stateInAttributeValueSingleQuotes(c);
|
|
94616
|
+
break;
|
|
94617
|
+
}
|
|
94618
|
+
case Tokenizer_State.BeforeAttributeValue: {
|
|
94619
|
+
this.stateBeforeAttributeValue(c);
|
|
94620
|
+
break;
|
|
94621
|
+
}
|
|
94622
|
+
case Tokenizer_State.BeforeClosingTagName: {
|
|
94623
|
+
this.stateBeforeClosingTagName(c);
|
|
94624
|
+
break;
|
|
94625
|
+
}
|
|
94626
|
+
case Tokenizer_State.AfterClosingTagName: {
|
|
94627
|
+
this.stateAfterClosingTagName(c);
|
|
94628
|
+
break;
|
|
94629
|
+
}
|
|
94630
|
+
case Tokenizer_State.InAttributeValueNq: {
|
|
94631
|
+
this.stateInAttributeValueNoQuotes(c);
|
|
94632
|
+
break;
|
|
94633
|
+
}
|
|
94634
|
+
case Tokenizer_State.InSelfClosingTag: {
|
|
94635
|
+
this.stateInSelfClosingTag(c);
|
|
94636
|
+
break;
|
|
94637
|
+
}
|
|
94638
|
+
case Tokenizer_State.InDeclaration: {
|
|
94639
|
+
this.stateInDeclaration(c);
|
|
94640
|
+
break;
|
|
94641
|
+
}
|
|
94642
|
+
case Tokenizer_State.BeforeDeclaration: {
|
|
94643
|
+
this.stateBeforeDeclaration(c);
|
|
94644
|
+
break;
|
|
94645
|
+
}
|
|
94646
|
+
case Tokenizer_State.BeforeComment: {
|
|
94647
|
+
this.stateBeforeComment(c);
|
|
94648
|
+
break;
|
|
94649
|
+
}
|
|
94650
|
+
case Tokenizer_State.InProcessingInstruction: {
|
|
94651
|
+
this.stateInProcessingInstruction(c);
|
|
94652
|
+
break;
|
|
94653
|
+
}
|
|
94654
|
+
case Tokenizer_State.InEntity: {
|
|
94655
|
+
this.stateInEntity();
|
|
94656
|
+
break;
|
|
94657
|
+
}
|
|
94658
|
+
}
|
|
94659
|
+
this.index++;
|
|
94660
|
+
}
|
|
94661
|
+
this.cleanup();
|
|
94662
|
+
}
|
|
94663
|
+
finish() {
|
|
94664
|
+
if (this.state === Tokenizer_State.InEntity) {
|
|
94665
|
+
this.entityDecoder.end();
|
|
94666
|
+
this.state = this.baseState;
|
|
94667
|
+
}
|
|
94668
|
+
this.handleTrailingData();
|
|
94669
|
+
this.cbs.onend();
|
|
94670
|
+
}
|
|
94671
|
+
handleTrailingCommentLikeData(endIndex) {
|
|
94672
|
+
if (this.state !== Tokenizer_State.InCommentLike) {
|
|
94673
|
+
return false;
|
|
94674
|
+
}
|
|
94675
|
+
if (this.currentSequence === Sequences.CdataEnd) {
|
|
94676
|
+
if (this.xmlMode) {
|
|
94677
|
+
if (this.sectionStart < endIndex) {
|
|
94678
|
+
this.cbs.oncdata(this.sectionStart, endIndex, 0);
|
|
94679
|
+
}
|
|
94680
|
+
}
|
|
94681
|
+
else {
|
|
94682
|
+
/* In HTML mode, unclosed CDATA is a bogus comment. */
|
|
94683
|
+
const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;
|
|
94684
|
+
this.cbs.oncomment(cdataStart, endIndex, 0);
|
|
94685
|
+
}
|
|
94686
|
+
}
|
|
94687
|
+
else {
|
|
94688
|
+
const offset = this.xmlMode
|
|
94689
|
+
? 0
|
|
94690
|
+
: Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);
|
|
94691
|
+
this.cbs.oncomment(this.sectionStart, endIndex, offset);
|
|
94692
|
+
}
|
|
94693
|
+
return true;
|
|
94694
|
+
}
|
|
94695
|
+
handleTrailingMarkupDeclaration(endIndex) {
|
|
94696
|
+
if (this.xmlMode) {
|
|
94697
|
+
switch (this.state) {
|
|
94698
|
+
case Tokenizer_State.InSpecialComment:
|
|
94699
|
+
case Tokenizer_State.BeforeComment:
|
|
94700
|
+
case Tokenizer_State.CDATASequence:
|
|
94701
|
+
case Tokenizer_State.DeclarationSequence:
|
|
94702
|
+
case Tokenizer_State.InDeclaration: {
|
|
94703
|
+
this.cbs.ontext(this.sectionStart, endIndex);
|
|
94704
|
+
return true;
|
|
94705
|
+
}
|
|
94706
|
+
default: {
|
|
94707
|
+
return false;
|
|
94708
|
+
}
|
|
94709
|
+
}
|
|
94710
|
+
}
|
|
94711
|
+
switch (this.state) {
|
|
94712
|
+
case Tokenizer_State.BeforeDeclaration:
|
|
94713
|
+
case Tokenizer_State.InSpecialComment:
|
|
94714
|
+
case Tokenizer_State.BeforeComment:
|
|
94715
|
+
case Tokenizer_State.CDATASequence: {
|
|
94716
|
+
this.cbs.oncomment(this.sectionStart, endIndex, 0);
|
|
94717
|
+
return true;
|
|
94718
|
+
}
|
|
94719
|
+
case Tokenizer_State.DeclarationSequence: {
|
|
94720
|
+
if (this.sequenceIndex !== Sequences.Doctype.length) {
|
|
94721
|
+
this.cbs.oncomment(this.sectionStart, endIndex, 0);
|
|
94722
|
+
}
|
|
94723
|
+
return true;
|
|
94724
|
+
}
|
|
94725
|
+
case Tokenizer_State.InDeclaration: {
|
|
94726
|
+
return true;
|
|
94727
|
+
}
|
|
94728
|
+
default: {
|
|
94729
|
+
return false;
|
|
94730
|
+
}
|
|
94731
|
+
}
|
|
94732
|
+
}
|
|
94733
|
+
/** Handle any trailing data. */
|
|
94734
|
+
handleTrailingData() {
|
|
94735
|
+
const endIndex = this.buffer.length + this.offset;
|
|
94736
|
+
if (this.handleTrailingCommentLikeData(endIndex) ||
|
|
94737
|
+
this.handleTrailingMarkupDeclaration(endIndex)) {
|
|
94738
|
+
return;
|
|
94739
|
+
}
|
|
94740
|
+
// If there is no remaining data, we are done.
|
|
94741
|
+
if (this.sectionStart >= endIndex) {
|
|
94742
|
+
return;
|
|
94743
|
+
}
|
|
94744
|
+
switch (this.state) {
|
|
94745
|
+
case Tokenizer_State.InTagName:
|
|
94746
|
+
case Tokenizer_State.BeforeAttributeName:
|
|
94747
|
+
case Tokenizer_State.BeforeAttributeValue:
|
|
94748
|
+
case Tokenizer_State.AfterAttributeName:
|
|
94749
|
+
case Tokenizer_State.InAttributeName:
|
|
94750
|
+
case Tokenizer_State.InAttributeValueSq:
|
|
94751
|
+
case Tokenizer_State.InAttributeValueDq:
|
|
94752
|
+
case Tokenizer_State.InAttributeValueNq:
|
|
94753
|
+
case Tokenizer_State.InClosingTagName: {
|
|
94754
|
+
/*
|
|
94755
|
+
* If we are currently in an opening or closing tag, us not calling the
|
|
94756
|
+
* respective callback signals that the tag should be ignored.
|
|
94757
|
+
*/
|
|
94758
|
+
break;
|
|
94759
|
+
}
|
|
94760
|
+
default: {
|
|
94761
|
+
this.cbs.ontext(this.sectionStart, endIndex);
|
|
94762
|
+
}
|
|
94763
|
+
}
|
|
94764
|
+
}
|
|
94765
|
+
emitCodePoint(cp, consumed) {
|
|
94766
|
+
if (this.baseState !== Tokenizer_State.Text &&
|
|
94767
|
+
this.baseState !== Tokenizer_State.InSpecialTag) {
|
|
94768
|
+
if (this.sectionStart < this.entityStart) {
|
|
94769
|
+
this.cbs.onattribdata(this.sectionStart, this.entityStart);
|
|
94770
|
+
}
|
|
94771
|
+
this.sectionStart = this.entityStart + consumed;
|
|
94772
|
+
this.index = this.sectionStart - 1;
|
|
94773
|
+
this.cbs.onattribentity(cp);
|
|
94774
|
+
}
|
|
94775
|
+
else {
|
|
94776
|
+
if (this.sectionStart < this.entityStart) {
|
|
94777
|
+
this.cbs.ontext(this.sectionStart, this.entityStart);
|
|
94778
|
+
}
|
|
94779
|
+
this.sectionStart = this.entityStart + consumed;
|
|
94780
|
+
this.index = this.sectionStart - 1;
|
|
94781
|
+
this.cbs.ontextentity(cp, this.sectionStart);
|
|
94782
|
+
}
|
|
94783
|
+
}
|
|
94784
|
+
}
|
|
94785
|
+
//# sourceMappingURL=Tokenizer.js.map
|
|
94786
|
+
;// ./node_modules/htmlparser2/dist/Parser.js
|
|
94787
|
+
const { fromCodePoint: Parser_fromCodePoint } = String;
|
|
94788
|
+
|
|
94789
|
+
const formTags = new Set([
|
|
94790
|
+
"input",
|
|
94791
|
+
"option",
|
|
94792
|
+
"optgroup",
|
|
94793
|
+
"select",
|
|
94794
|
+
"button",
|
|
94795
|
+
"datalist",
|
|
94796
|
+
"textarea",
|
|
94797
|
+
]);
|
|
94798
|
+
const pTag = new Set(["p"]);
|
|
94799
|
+
const headingTags = new Set(["h1", "h2", "h3", "h4", "h5", "h6", "p"]);
|
|
94800
|
+
const tableSectionTags = new Set(["thead", "tbody"]);
|
|
94801
|
+
const ddtTags = new Set(["dd", "dt"]);
|
|
94802
|
+
const rtpTags = new Set(["rt", "rp"]);
|
|
94803
|
+
const openImpliesClose = new Map([
|
|
94804
|
+
["tr", new Set(["tr", "th", "td"])],
|
|
94805
|
+
["th", new Set(["th"])],
|
|
94806
|
+
["td", new Set(["thead", "th", "td"])],
|
|
94807
|
+
["body", new Set(["head", "link", "script"])],
|
|
94808
|
+
["a", new Set(["a"])],
|
|
94809
|
+
["li", new Set(["li"])],
|
|
94810
|
+
["p", pTag],
|
|
94811
|
+
["h1", headingTags],
|
|
94812
|
+
["h2", headingTags],
|
|
94813
|
+
["h3", headingTags],
|
|
94814
|
+
["h4", headingTags],
|
|
94815
|
+
["h5", headingTags],
|
|
94816
|
+
["h6", headingTags],
|
|
94817
|
+
["select", formTags],
|
|
94818
|
+
["input", formTags],
|
|
94819
|
+
["output", formTags],
|
|
94820
|
+
["button", formTags],
|
|
94821
|
+
["datalist", formTags],
|
|
94822
|
+
["textarea", formTags],
|
|
94823
|
+
["option", new Set(["option"])],
|
|
94824
|
+
["optgroup", new Set(["optgroup", "option"])],
|
|
94825
|
+
["dd", ddtTags],
|
|
94826
|
+
["dt", ddtTags],
|
|
94827
|
+
["address", pTag],
|
|
94828
|
+
["article", pTag],
|
|
94829
|
+
["aside", pTag],
|
|
94830
|
+
["blockquote", pTag],
|
|
94831
|
+
["details", pTag],
|
|
94832
|
+
["div", pTag],
|
|
94833
|
+
["dl", pTag],
|
|
94834
|
+
["fieldset", pTag],
|
|
94835
|
+
["figcaption", pTag],
|
|
94836
|
+
["figure", pTag],
|
|
94837
|
+
["footer", pTag],
|
|
94838
|
+
["form", pTag],
|
|
94839
|
+
["header", pTag],
|
|
94840
|
+
["hr", pTag],
|
|
94841
|
+
["main", pTag],
|
|
94842
|
+
["nav", pTag],
|
|
94843
|
+
["ol", pTag],
|
|
94844
|
+
["pre", pTag],
|
|
94845
|
+
["section", pTag],
|
|
94846
|
+
["table", pTag],
|
|
94847
|
+
["ul", pTag],
|
|
94848
|
+
["rt", rtpTags],
|
|
94849
|
+
["rp", rtpTags],
|
|
94850
|
+
["tbody", tableSectionTags],
|
|
94851
|
+
["tfoot", tableSectionTags],
|
|
94852
|
+
]);
|
|
94853
|
+
const DOCUMENT_TYPE = "doctype";
|
|
94854
|
+
const voidElements = new Set([
|
|
94855
|
+
"area",
|
|
94856
|
+
"base",
|
|
94857
|
+
"basefont",
|
|
94858
|
+
"br",
|
|
94859
|
+
"col",
|
|
94860
|
+
"command",
|
|
94861
|
+
"embed",
|
|
94862
|
+
"frame",
|
|
94863
|
+
"hr",
|
|
94864
|
+
"img",
|
|
94865
|
+
"input",
|
|
94866
|
+
"isindex",
|
|
94867
|
+
"keygen",
|
|
94868
|
+
"link",
|
|
94869
|
+
"meta",
|
|
94870
|
+
"param",
|
|
94871
|
+
"source",
|
|
94872
|
+
"track",
|
|
94873
|
+
"wbr",
|
|
94874
|
+
]);
|
|
94875
|
+
const foreignContextElements = new Set(["math", "svg"]);
|
|
94876
|
+
/**
|
|
94877
|
+
* Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).
|
|
94878
|
+
*
|
|
94879
|
+
* Entries must use the SVG-adjusted casing (e.g. "foreignObject" not
|
|
94880
|
+
* "foreignobject") since they are compared against adjusted tag names.
|
|
94881
|
+
*/
|
|
94882
|
+
const htmlIntegrationElements = new Set([
|
|
94883
|
+
"mi",
|
|
94884
|
+
"mo",
|
|
94885
|
+
"mn",
|
|
94886
|
+
"ms",
|
|
94887
|
+
"mtext",
|
|
94888
|
+
"annotation-xml",
|
|
94889
|
+
"foreignObject",
|
|
94890
|
+
"desc",
|
|
94891
|
+
"title",
|
|
94892
|
+
]);
|
|
94893
|
+
const svgTagNameAdjustments = new Map([
|
|
94894
|
+
["altglyph", "altGlyph"],
|
|
94895
|
+
["altglyphdef", "altGlyphDef"],
|
|
94896
|
+
["altglyphitem", "altGlyphItem"],
|
|
94897
|
+
["animatecolor", "animateColor"],
|
|
94898
|
+
["animatemotion", "animateMotion"],
|
|
94899
|
+
["animatetransform", "animateTransform"],
|
|
94900
|
+
["clippath", "clipPath"],
|
|
94901
|
+
["feblend", "feBlend"],
|
|
94902
|
+
["fecolormatrix", "feColorMatrix"],
|
|
94903
|
+
["fecomponenttransfer", "feComponentTransfer"],
|
|
94904
|
+
["fecomposite", "feComposite"],
|
|
94905
|
+
["feconvolvematrix", "feConvolveMatrix"],
|
|
94906
|
+
["fediffuselighting", "feDiffuseLighting"],
|
|
94907
|
+
["fedisplacementmap", "feDisplacementMap"],
|
|
94908
|
+
["fedistantlight", "feDistantLight"],
|
|
94909
|
+
["fedropshadow", "feDropShadow"],
|
|
94910
|
+
["feflood", "feFlood"],
|
|
94911
|
+
["fefunca", "feFuncA"],
|
|
94912
|
+
["fefuncb", "feFuncB"],
|
|
94913
|
+
["fefuncg", "feFuncG"],
|
|
94914
|
+
["fefuncr", "feFuncR"],
|
|
94915
|
+
["fegaussianblur", "feGaussianBlur"],
|
|
94916
|
+
["feimage", "feImage"],
|
|
94917
|
+
["femerge", "feMerge"],
|
|
94918
|
+
["femergenode", "feMergeNode"],
|
|
94919
|
+
["femorphology", "feMorphology"],
|
|
94920
|
+
["feoffset", "feOffset"],
|
|
94921
|
+
["fepointlight", "fePointLight"],
|
|
94922
|
+
["fespecularlighting", "feSpecularLighting"],
|
|
94923
|
+
["fespotlight", "feSpotLight"],
|
|
94924
|
+
["fetile", "feTile"],
|
|
94925
|
+
["feturbulence", "feTurbulence"],
|
|
94926
|
+
["foreignobject", "foreignObject"],
|
|
94927
|
+
["glyphref", "glyphRef"],
|
|
94928
|
+
["lineargradient", "linearGradient"],
|
|
94929
|
+
["radialgradient", "radialGradient"],
|
|
94930
|
+
["textpath", "textPath"],
|
|
94931
|
+
]);
|
|
94932
|
+
var ForeignContext;
|
|
94933
|
+
(function (ForeignContext) {
|
|
94934
|
+
ForeignContext[ForeignContext["None"] = 0] = "None";
|
|
94935
|
+
ForeignContext[ForeignContext["Svg"] = 1] = "Svg";
|
|
94936
|
+
ForeignContext[ForeignContext["MathML"] = 2] = "MathML";
|
|
94937
|
+
})(ForeignContext || (ForeignContext = {}));
|
|
94938
|
+
const reNameEnd = /\s|\//;
|
|
94939
|
+
/**
|
|
94940
|
+
* Incremental parser implementation.
|
|
94941
|
+
*/
|
|
94942
|
+
class Parser_Parser {
|
|
94943
|
+
options;
|
|
94944
|
+
/** The start index of the last event. */
|
|
94945
|
+
startIndex = 0;
|
|
94946
|
+
/** The end index of the last event. */
|
|
94947
|
+
endIndex = 0;
|
|
94948
|
+
/**
|
|
94949
|
+
* Store the start index of the current open tag,
|
|
94950
|
+
* so we can update the start index for attributes.
|
|
94951
|
+
*/
|
|
94952
|
+
openTagStart = 0;
|
|
94953
|
+
tagname = "";
|
|
94954
|
+
attribname = "";
|
|
94955
|
+
attribvalue = "";
|
|
94956
|
+
attribs = null;
|
|
94957
|
+
stack = [];
|
|
94958
|
+
foreignContext;
|
|
94959
|
+
cbs;
|
|
94960
|
+
lowerCaseTagNames;
|
|
94961
|
+
lowerCaseAttributeNames;
|
|
94962
|
+
recognizeSelfClosing;
|
|
94963
|
+
/** We are parsing HTML. Inverse of the `xmlMode` option. */
|
|
94964
|
+
htmlMode;
|
|
94965
|
+
tokenizer;
|
|
94966
|
+
buffers = [];
|
|
94967
|
+
bufferOffset = 0;
|
|
94968
|
+
/** The index of the last written buffer. Used when resuming after a `pause()`. */
|
|
94969
|
+
writeIndex = 0;
|
|
94970
|
+
/** Indicates whether the parser has finished running / `.end` has been called. */
|
|
94971
|
+
ended = false;
|
|
94972
|
+
constructor(cbs, options = {}) {
|
|
94973
|
+
this.options = options;
|
|
94974
|
+
this.cbs = cbs ?? {};
|
|
94975
|
+
this.htmlMode = !this.options.xmlMode;
|
|
94976
|
+
this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;
|
|
94977
|
+
this.lowerCaseAttributeNames =
|
|
94978
|
+
options.lowerCaseAttributeNames ?? this.htmlMode;
|
|
94979
|
+
this.recognizeSelfClosing =
|
|
94980
|
+
options.recognizeSelfClosing ?? !this.htmlMode;
|
|
94981
|
+
this.tokenizer = new (options.Tokenizer ?? Tokenizer_Tokenizer)(this.options, this);
|
|
94982
|
+
this.foreignContext = [ForeignContext.None];
|
|
94983
|
+
this.cbs.onparserinit?.(this);
|
|
94984
|
+
}
|
|
94985
|
+
// Tokenizer event handlers
|
|
94986
|
+
/**
|
|
94987
|
+
* @param start Start index for the current parser event.
|
|
94988
|
+
* @param endIndex End index for the current parser event.
|
|
94989
|
+
* @internal
|
|
94990
|
+
*/
|
|
94991
|
+
ontext(start, endIndex) {
|
|
94992
|
+
const data = this.getSlice(start, endIndex);
|
|
94993
|
+
this.endIndex = endIndex - 1;
|
|
94994
|
+
this.cbs.ontext?.(data);
|
|
94995
|
+
this.startIndex = endIndex;
|
|
94996
|
+
}
|
|
94997
|
+
/**
|
|
94998
|
+
* @param cp Current Unicode code point.
|
|
94999
|
+
* @param endIndex End index for the current parser event.
|
|
95000
|
+
* @internal
|
|
95001
|
+
*/
|
|
95002
|
+
ontextentity(cp, endIndex) {
|
|
95003
|
+
this.endIndex = endIndex - 1;
|
|
95004
|
+
this.cbs.ontext?.(Parser_fromCodePoint(cp));
|
|
95005
|
+
this.startIndex = endIndex;
|
|
95006
|
+
}
|
|
95007
|
+
/** @internal */
|
|
95008
|
+
isInForeignContext() {
|
|
95009
|
+
return this.foreignContext[0] !== ForeignContext.None;
|
|
95010
|
+
}
|
|
95011
|
+
/**
|
|
95012
|
+
* Checks if the current tag is a void element. Override this if you want
|
|
95013
|
+
* to specify your own additional void elements.
|
|
95014
|
+
* @param name Name of the pseudo selector.
|
|
95015
|
+
*/
|
|
95016
|
+
isVoidElement(name) {
|
|
95017
|
+
return this.htmlMode && voidElements.has(name);
|
|
95018
|
+
}
|
|
95019
|
+
/**
|
|
95020
|
+
* Read a tag name from the buffer.
|
|
95021
|
+
*
|
|
95022
|
+
* When `lowerCaseTagNames` is enabled (the default in HTML mode), the name
|
|
95023
|
+
* is lowercased and may be adjusted for SVG casing or the `image` → `img`
|
|
95024
|
+
* alias.
|
|
95025
|
+
* @param start Start index of the tag name in the buffer.
|
|
95026
|
+
* @param endIndex End index of the tag name in the buffer.
|
|
95027
|
+
*/
|
|
95028
|
+
readTagName(start, endIndex) {
|
|
95029
|
+
const name = this.lowerCaseTagNames
|
|
95030
|
+
? this.getSlice(start, endIndex).toLowerCase()
|
|
95031
|
+
: this.getSlice(start, endIndex);
|
|
95032
|
+
if (!(this.lowerCaseTagNames && this.htmlMode)) {
|
|
95033
|
+
return name;
|
|
95034
|
+
}
|
|
95035
|
+
if (this.foreignContext[0] === ForeignContext.Svg) {
|
|
95036
|
+
return svgTagNameAdjustments.get(name) ?? name;
|
|
95037
|
+
}
|
|
95038
|
+
/*
|
|
95039
|
+
* Closing tags for SVG elements inside HTML integration points
|
|
95040
|
+
* (e.g. </foreignObject> while inside its own content) need case
|
|
95041
|
+
* adjustment so the name matches what was pushed to the stack.
|
|
95042
|
+
* `foreignContext.length > 1` means a foreign ancestor exists —
|
|
95043
|
+
* the base [None] entry plus at least one pushed context.
|
|
95044
|
+
*/
|
|
95045
|
+
if (this.foreignContext.length > 1) {
|
|
95046
|
+
const adjusted = svgTagNameAdjustments.get(name);
|
|
95047
|
+
if (adjusted !== undefined && this.stack.includes(adjusted)) {
|
|
95048
|
+
return adjusted;
|
|
95049
|
+
}
|
|
95050
|
+
}
|
|
95051
|
+
if (!this.isInForeignContext()) {
|
|
95052
|
+
return name === "image" ? "img" : name;
|
|
95053
|
+
}
|
|
95054
|
+
return name;
|
|
95055
|
+
}
|
|
95056
|
+
/**
|
|
95057
|
+
* @param start Start index for the current parser event.
|
|
95058
|
+
* @param endIndex End index for the current parser event.
|
|
95059
|
+
* @internal
|
|
95060
|
+
*/
|
|
95061
|
+
onopentagname(start, endIndex) {
|
|
95062
|
+
this.endIndex = endIndex;
|
|
95063
|
+
this.emitOpenTag(this.readTagName(start, endIndex));
|
|
95064
|
+
}
|
|
95065
|
+
emitOpenTag(name) {
|
|
95066
|
+
this.openTagStart = this.startIndex;
|
|
95067
|
+
this.tagname = name;
|
|
95068
|
+
/*
|
|
95069
|
+
* The spec ignores a second <form> when one is already open.
|
|
95070
|
+
* Setting tagname to "" suppresses all downstream effects: attribs
|
|
95071
|
+
* stays null so endOpenTag is a no-op, and closeCurrentTag can't
|
|
95072
|
+
* match "" on the stack.
|
|
95073
|
+
*/
|
|
95074
|
+
if (this.htmlMode && name === "form" && this.stack.includes("form")) {
|
|
95075
|
+
this.tagname = "";
|
|
95076
|
+
return;
|
|
95077
|
+
}
|
|
95078
|
+
const impliesClose = this.htmlMode && openImpliesClose.get(name);
|
|
95079
|
+
if (impliesClose) {
|
|
95080
|
+
while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {
|
|
95081
|
+
this.popElement(true);
|
|
95082
|
+
}
|
|
95083
|
+
}
|
|
95084
|
+
if (!this.isVoidElement(name)) {
|
|
95085
|
+
this.stack.unshift(name);
|
|
95086
|
+
if (this.htmlMode) {
|
|
95087
|
+
if (name === "svg") {
|
|
95088
|
+
this.foreignContext.unshift(ForeignContext.Svg);
|
|
95089
|
+
}
|
|
95090
|
+
else if (name === "math") {
|
|
95091
|
+
this.foreignContext.unshift(ForeignContext.MathML);
|
|
95092
|
+
}
|
|
95093
|
+
else if (htmlIntegrationElements.has(name)) {
|
|
95094
|
+
this.foreignContext.unshift(ForeignContext.None);
|
|
95095
|
+
}
|
|
95096
|
+
}
|
|
95097
|
+
}
|
|
95098
|
+
this.cbs.onopentagname?.(name);
|
|
95099
|
+
if (this.cbs.onopentag)
|
|
95100
|
+
this.attribs = {};
|
|
95101
|
+
}
|
|
95102
|
+
endOpenTag(isImplied) {
|
|
95103
|
+
this.startIndex = this.openTagStart;
|
|
95104
|
+
if (this.attribs) {
|
|
95105
|
+
this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);
|
|
95106
|
+
this.attribs = null;
|
|
95107
|
+
}
|
|
95108
|
+
if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {
|
|
95109
|
+
this.cbs.onclosetag(this.tagname, true);
|
|
95110
|
+
}
|
|
95111
|
+
this.tagname = "";
|
|
95112
|
+
}
|
|
95113
|
+
/**
|
|
95114
|
+
* @param endIndex End index for the current parser event.
|
|
95115
|
+
* @internal
|
|
95116
|
+
*/
|
|
95117
|
+
onopentagend(endIndex) {
|
|
95118
|
+
this.endIndex = endIndex;
|
|
95119
|
+
this.endOpenTag(false);
|
|
95120
|
+
// Set `startIndex` for next node
|
|
95121
|
+
this.startIndex = endIndex + 1;
|
|
95122
|
+
}
|
|
95123
|
+
/**
|
|
95124
|
+
* @param start Start index for the current parser event.
|
|
95125
|
+
* @param endIndex End index for the current parser event.
|
|
95126
|
+
* @internal
|
|
95127
|
+
*/
|
|
95128
|
+
onclosetag(start, endIndex) {
|
|
95129
|
+
this.endIndex = endIndex;
|
|
95130
|
+
const name = this.readTagName(start, endIndex);
|
|
95131
|
+
if (!this.isVoidElement(name)) {
|
|
95132
|
+
const pos = this.stack.indexOf(name);
|
|
95133
|
+
if (pos !== -1) {
|
|
95134
|
+
for (let index = 0; index < pos; index++) {
|
|
95135
|
+
this.popElement(true);
|
|
95136
|
+
}
|
|
95137
|
+
this.popElement(false);
|
|
95138
|
+
}
|
|
95139
|
+
else if (this.htmlMode && name === "p") {
|
|
95140
|
+
// Implicit open before close
|
|
95141
|
+
this.emitOpenTag("p");
|
|
95142
|
+
this.closeCurrentTag(true);
|
|
95143
|
+
}
|
|
95144
|
+
}
|
|
95145
|
+
else if (this.htmlMode && name === "br") {
|
|
95146
|
+
// We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.
|
|
95147
|
+
this.cbs.onopentagname?.("br");
|
|
95148
|
+
this.cbs.onopentag?.("br", {}, true);
|
|
95149
|
+
this.cbs.onclosetag?.("br", false);
|
|
95150
|
+
}
|
|
95151
|
+
// Set `startIndex` for next node
|
|
95152
|
+
this.startIndex = endIndex + 1;
|
|
95153
|
+
}
|
|
95154
|
+
/**
|
|
95155
|
+
* @param endIndex End index for the current parser event.
|
|
95156
|
+
* @internal
|
|
95157
|
+
*/
|
|
95158
|
+
onselfclosingtag(endIndex) {
|
|
95159
|
+
this.endIndex = endIndex;
|
|
95160
|
+
if (this.recognizeSelfClosing || this.isInForeignContext()) {
|
|
95161
|
+
this.closeCurrentTag(false);
|
|
95162
|
+
// Set `startIndex` for next node
|
|
95163
|
+
this.startIndex = endIndex + 1;
|
|
95164
|
+
}
|
|
95165
|
+
else {
|
|
95166
|
+
// Ignore the fact that the tag is self-closing.
|
|
95167
|
+
this.onopentagend(endIndex);
|
|
95168
|
+
}
|
|
95169
|
+
}
|
|
95170
|
+
/**
|
|
95171
|
+
* Pop the top element off the stack, emit a close event, and maintain
|
|
95172
|
+
* the foreign context stack.
|
|
95173
|
+
* @param implied Whether this close is implied (not from an explicit end tag).
|
|
95174
|
+
*/
|
|
95175
|
+
popElement(implied) {
|
|
95176
|
+
// biome-ignore lint/style/noNonNullAssertion: The element is guaranteed to exist.
|
|
95177
|
+
const element = this.stack.shift();
|
|
95178
|
+
if (this.htmlMode &&
|
|
95179
|
+
(foreignContextElements.has(element) ||
|
|
95180
|
+
htmlIntegrationElements.has(element))) {
|
|
95181
|
+
this.foreignContext.shift();
|
|
95182
|
+
}
|
|
95183
|
+
this.cbs.onclosetag?.(element, implied);
|
|
95184
|
+
}
|
|
95185
|
+
closeCurrentTag(isOpenImplied) {
|
|
95186
|
+
const name = this.tagname;
|
|
95187
|
+
this.endOpenTag(isOpenImplied);
|
|
95188
|
+
// Self-closing tags will be on the top of the stack
|
|
95189
|
+
if (this.stack[0] === name) {
|
|
95190
|
+
this.popElement(!isOpenImplied);
|
|
95191
|
+
}
|
|
95192
|
+
}
|
|
95193
|
+
/**
|
|
95194
|
+
* @param start Start index for the current parser event.
|
|
95195
|
+
* @param endIndex End index for the current parser event.
|
|
95196
|
+
* @internal
|
|
95197
|
+
*/
|
|
95198
|
+
onattribname(start, endIndex) {
|
|
95199
|
+
this.startIndex = start;
|
|
95200
|
+
const name = this.getSlice(start, endIndex);
|
|
95201
|
+
this.attribname = this.lowerCaseAttributeNames
|
|
95202
|
+
? name.toLowerCase()
|
|
95203
|
+
: name;
|
|
95204
|
+
}
|
|
95205
|
+
/**
|
|
95206
|
+
* @param start Start index for the current parser event.
|
|
95207
|
+
* @param endIndex End index for the current parser event.
|
|
95208
|
+
* @internal
|
|
95209
|
+
*/
|
|
95210
|
+
onattribdata(start, endIndex) {
|
|
95211
|
+
this.attribvalue += this.getSlice(start, endIndex);
|
|
95212
|
+
}
|
|
95213
|
+
/**
|
|
95214
|
+
* @param cp Current Unicode code point.
|
|
95215
|
+
* @internal
|
|
95216
|
+
*/
|
|
95217
|
+
onattribentity(cp) {
|
|
95218
|
+
this.attribvalue += Parser_fromCodePoint(cp);
|
|
95219
|
+
}
|
|
95220
|
+
/**
|
|
95221
|
+
* @param quote Quote type used for the current attribute.
|
|
95222
|
+
* @param endIndex End index for the current parser event.
|
|
95223
|
+
* @internal
|
|
95224
|
+
*/
|
|
95225
|
+
onattribend(quote, endIndex) {
|
|
95226
|
+
this.endIndex = endIndex;
|
|
95227
|
+
this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double
|
|
95228
|
+
? '"'
|
|
95229
|
+
: quote === QuoteType.Single
|
|
95230
|
+
? "'"
|
|
95231
|
+
: quote === QuoteType.NoValue
|
|
95232
|
+
? undefined
|
|
95233
|
+
: null);
|
|
95234
|
+
if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) {
|
|
95235
|
+
this.attribs[this.attribname] = this.attribvalue;
|
|
95236
|
+
}
|
|
95237
|
+
this.attribvalue = "";
|
|
95238
|
+
}
|
|
95239
|
+
getInstructionName(value) {
|
|
95240
|
+
const index = value.search(reNameEnd);
|
|
95241
|
+
let name = index < 0 ? value : value.substr(0, index);
|
|
95242
|
+
if (this.lowerCaseTagNames) {
|
|
95243
|
+
name = name.toLowerCase();
|
|
95244
|
+
}
|
|
95245
|
+
return name;
|
|
95246
|
+
}
|
|
95247
|
+
/**
|
|
95248
|
+
* @param start Start index for the current parser event.
|
|
95249
|
+
* @param endIndex End index for the current parser event.
|
|
95250
|
+
* @internal
|
|
95251
|
+
*/
|
|
95252
|
+
ondeclaration(start, endIndex) {
|
|
95253
|
+
this.endIndex = endIndex;
|
|
95254
|
+
const value = this.getSlice(start, endIndex);
|
|
95255
|
+
if (this.cbs.onprocessinginstruction) {
|
|
95256
|
+
/*
|
|
95257
|
+
* In HTML mode, ondeclaration is only reached for DOCTYPE
|
|
95258
|
+
* (the tokenizer routes everything else to bogus comments).
|
|
95259
|
+
*/
|
|
95260
|
+
const name = this.htmlMode
|
|
95261
|
+
? this.lowerCaseTagNames
|
|
95262
|
+
? DOCUMENT_TYPE
|
|
95263
|
+
: value.slice(0, DOCUMENT_TYPE.length)
|
|
95264
|
+
: this.getInstructionName(value);
|
|
95265
|
+
this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
|
|
95266
|
+
}
|
|
95267
|
+
// Set `startIndex` for next node
|
|
95268
|
+
this.startIndex = endIndex + 1;
|
|
95269
|
+
}
|
|
95270
|
+
/**
|
|
95271
|
+
* @param start Start index for the current parser event.
|
|
95272
|
+
* @param endIndex End index for the current parser event.
|
|
95273
|
+
* @internal
|
|
95274
|
+
*/
|
|
95275
|
+
onprocessinginstruction(start, endIndex) {
|
|
95276
|
+
this.endIndex = endIndex;
|
|
95277
|
+
const value = this.getSlice(start, endIndex);
|
|
95278
|
+
if (this.cbs.onprocessinginstruction) {
|
|
95279
|
+
const name = this.getInstructionName(value);
|
|
95280
|
+
this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
|
|
95281
|
+
}
|
|
95282
|
+
// Set `startIndex` for next node
|
|
95283
|
+
this.startIndex = endIndex + 1;
|
|
95284
|
+
}
|
|
95285
|
+
/**
|
|
95286
|
+
* @param start Start index for the current parser event.
|
|
95287
|
+
* @param endIndex End index for the current parser event.
|
|
95288
|
+
* @param offset Offset applied when computing parser indices.
|
|
95289
|
+
* @internal
|
|
95290
|
+
*/
|
|
95291
|
+
oncomment(start, endIndex, offset) {
|
|
95292
|
+
this.endIndex = endIndex;
|
|
95293
|
+
this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));
|
|
95294
|
+
this.cbs.oncommentend?.();
|
|
95295
|
+
// Set `startIndex` for next node
|
|
95296
|
+
this.startIndex = endIndex + 1;
|
|
95297
|
+
}
|
|
95298
|
+
/**
|
|
95299
|
+
* @param start Start index for the current parser event.
|
|
95300
|
+
* @param endIndex End index for the current parser event.
|
|
95301
|
+
* @param offset Offset applied when computing parser indices.
|
|
95302
|
+
* @internal
|
|
95303
|
+
*/
|
|
95304
|
+
oncdata(start, endIndex, offset) {
|
|
95305
|
+
this.endIndex = endIndex;
|
|
95306
|
+
const value = this.getSlice(start, endIndex - offset);
|
|
95307
|
+
if (!this.htmlMode || this.options.recognizeCDATA) {
|
|
95308
|
+
this.cbs.oncdatastart?.();
|
|
95309
|
+
this.cbs.ontext?.(value);
|
|
95310
|
+
this.cbs.oncdataend?.();
|
|
95311
|
+
}
|
|
95312
|
+
else if (this.isInForeignContext()) {
|
|
95313
|
+
this.cbs.ontext?.(value);
|
|
95314
|
+
}
|
|
95315
|
+
else {
|
|
95316
|
+
this.cbs.oncomment?.(`[CDATA[${value}]]`);
|
|
95317
|
+
this.cbs.oncommentend?.();
|
|
95318
|
+
}
|
|
95319
|
+
// Set `startIndex` for next node
|
|
95320
|
+
this.startIndex = endIndex + 1;
|
|
95321
|
+
}
|
|
95322
|
+
/** @internal */
|
|
95323
|
+
onend() {
|
|
95324
|
+
if (this.cbs.onclosetag) {
|
|
95325
|
+
// Set the end index for all remaining tags
|
|
95326
|
+
this.endIndex = this.startIndex;
|
|
95327
|
+
for (let index = 0; index < this.stack.length; index++) {
|
|
95328
|
+
this.cbs.onclosetag(this.stack[index], true);
|
|
95329
|
+
}
|
|
95330
|
+
}
|
|
95331
|
+
this.cbs.onend?.();
|
|
95332
|
+
}
|
|
95333
|
+
/**
|
|
95334
|
+
* Resets the parser to a blank state, ready to parse a new HTML document
|
|
95335
|
+
*/
|
|
95336
|
+
reset() {
|
|
95337
|
+
this.cbs.onreset?.();
|
|
95338
|
+
this.tokenizer.reset();
|
|
95339
|
+
this.tagname = "";
|
|
95340
|
+
this.attribname = "";
|
|
95341
|
+
this.attribvalue = "";
|
|
95342
|
+
this.attribs = null;
|
|
95343
|
+
this.stack.length = 0;
|
|
95344
|
+
this.startIndex = 0;
|
|
95345
|
+
this.endIndex = 0;
|
|
95346
|
+
this.cbs.onparserinit?.(this);
|
|
95347
|
+
this.buffers.length = 0;
|
|
95348
|
+
this.foreignContext.length = 0;
|
|
95349
|
+
this.foreignContext.unshift(ForeignContext.None);
|
|
95350
|
+
this.bufferOffset = 0;
|
|
95351
|
+
this.writeIndex = 0;
|
|
95352
|
+
this.ended = false;
|
|
95353
|
+
}
|
|
95354
|
+
/**
|
|
95355
|
+
* Resets the parser, then parses a complete document and
|
|
95356
|
+
* pushes it to the handler.
|
|
95357
|
+
* @param data Document to parse.
|
|
95358
|
+
*/
|
|
95359
|
+
parseComplete(data) {
|
|
95360
|
+
this.reset();
|
|
95361
|
+
this.end(data);
|
|
95362
|
+
}
|
|
95363
|
+
getSlice(start, end) {
|
|
95364
|
+
if (start === end) {
|
|
95365
|
+
return "";
|
|
95366
|
+
}
|
|
95367
|
+
while (start - this.bufferOffset >= this.buffers[0].length) {
|
|
95368
|
+
this.shiftBuffer();
|
|
95369
|
+
}
|
|
95370
|
+
let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);
|
|
95371
|
+
while (end - this.bufferOffset > this.buffers[0].length) {
|
|
95372
|
+
this.shiftBuffer();
|
|
95373
|
+
slice += this.buffers[0].slice(0, end - this.bufferOffset);
|
|
95374
|
+
}
|
|
95375
|
+
return slice;
|
|
95376
|
+
}
|
|
95377
|
+
shiftBuffer() {
|
|
95378
|
+
this.bufferOffset += this.buffers[0].length;
|
|
95379
|
+
this.writeIndex--;
|
|
95380
|
+
this.buffers.shift();
|
|
95381
|
+
}
|
|
95382
|
+
/**
|
|
95383
|
+
* Parses a chunk of data and calls the corresponding callbacks.
|
|
95384
|
+
* @param chunk Chunk to parse.
|
|
95385
|
+
*/
|
|
95386
|
+
write(chunk) {
|
|
95387
|
+
if (this.ended) {
|
|
95388
|
+
this.cbs.onerror?.(new Error(".write() after done!"));
|
|
95389
|
+
return;
|
|
95390
|
+
}
|
|
95391
|
+
this.buffers.push(chunk);
|
|
95392
|
+
if (this.tokenizer.running) {
|
|
95393
|
+
this.tokenizer.write(chunk);
|
|
95394
|
+
this.writeIndex++;
|
|
95395
|
+
}
|
|
95396
|
+
}
|
|
95397
|
+
/**
|
|
95398
|
+
* Parses the end of the buffer and clears the stack, calls onend.
|
|
95399
|
+
* @param chunk Optional final chunk to parse.
|
|
95400
|
+
*/
|
|
95401
|
+
end(chunk) {
|
|
95402
|
+
if (this.ended) {
|
|
95403
|
+
this.cbs.onerror?.(new Error(".end() after done!"));
|
|
95404
|
+
return;
|
|
95405
|
+
}
|
|
95406
|
+
if (chunk)
|
|
95407
|
+
this.write(chunk);
|
|
95408
|
+
this.ended = true;
|
|
95409
|
+
this.tokenizer.end();
|
|
95410
|
+
}
|
|
95411
|
+
/**
|
|
95412
|
+
* Pauses parsing. The parser won't emit events until `resume` is called.
|
|
95413
|
+
*/
|
|
95414
|
+
pause() {
|
|
95415
|
+
this.tokenizer.pause();
|
|
95416
|
+
}
|
|
95417
|
+
/**
|
|
95418
|
+
* Resumes parsing after `pause` was called.
|
|
95419
|
+
*/
|
|
95420
|
+
resume() {
|
|
95421
|
+
this.tokenizer.resume();
|
|
95422
|
+
while (this.tokenizer.running &&
|
|
95423
|
+
this.writeIndex < this.buffers.length) {
|
|
95424
|
+
this.tokenizer.write(this.buffers[this.writeIndex++]);
|
|
95425
|
+
}
|
|
95426
|
+
if (this.ended)
|
|
95427
|
+
this.tokenizer.end();
|
|
95428
|
+
}
|
|
95429
|
+
}
|
|
95430
|
+
//# sourceMappingURL=Parser.js.map
|
|
95431
|
+
;// ./processor/transform/mdxish/tables/tag-walker.ts
|
|
95432
|
+
|
|
95433
|
+
/**
|
|
95434
|
+
* Skip certain regions / parts of the content that htmlparser2 should not handle
|
|
95435
|
+
*/
|
|
95436
|
+
const maskNonTagRegions = (html) => html
|
|
95437
|
+
.replace(/```[\s\S]*?```|``(?:[^`]|`(?!`))*``|`[^`\n]*`/g, m => ' '.repeat(m.length))
|
|
95438
|
+
// `<<NAME>>` is legacy variable syntax — without masking,
|
|
95439
|
+
// htmlparser2 sees the inner `<NAME>` as a tag. Blanking any `<<` also
|
|
95440
|
+
// covers malformed variants like `<<string>`.
|
|
95441
|
+
.replace(/<</g, ' ')
|
|
95442
|
+
// skip escaped tag openers
|
|
95443
|
+
.replace(/\\</g, ' ');
|
|
95444
|
+
/**
|
|
95445
|
+
* Drive htmlparser2 over `html` (after masking non-tag regions) and emit
|
|
95446
|
+
* tag-balance events. `start`/`end` use the original-string offsets, so
|
|
95447
|
+
* callers can splice against the input directly.
|
|
95448
|
+
*/
|
|
95449
|
+
const walkTags = (html, handlers) => {
|
|
95450
|
+
const masked = maskNonTagRegions(html);
|
|
95451
|
+
// htmlparser2's endIndex points at the `>` (inclusive); +1 lands just past
|
|
95452
|
+
// it, which is what callers want for splicing.
|
|
95453
|
+
const tagEnd = (parser) => (parser.endIndex ?? parser.startIndex) + 1;
|
|
95454
|
+
const parser = new Parser_Parser({
|
|
95455
|
+
onopentag(name) {
|
|
95456
|
+
handlers.onOpen?.({ name, start: parser.startIndex, end: tagEnd(parser) });
|
|
95457
|
+
},
|
|
95458
|
+
onclosetag(name, implicit) {
|
|
95459
|
+
handlers.onClose?.({ name, start: parser.startIndex, end: tagEnd(parser), implicit });
|
|
95460
|
+
},
|
|
95461
|
+
}, {
|
|
95462
|
+
lowerCaseAttributeNames: false,
|
|
95463
|
+
lowerCaseTags: false,
|
|
95464
|
+
recognizeSelfClosing: true,
|
|
95465
|
+
});
|
|
95466
|
+
parser.write(masked);
|
|
95467
|
+
parser.end();
|
|
95468
|
+
};
|
|
95469
|
+
|
|
93088
95470
|
;// ./processor/transform/mdxish/tables/utils.ts
|
|
93089
95471
|
const tableTags = new Set([
|
|
93090
95472
|
'thead',
|
|
93091
95473
|
'tbody',
|
|
93092
95474
|
'tfoot',
|
|
93093
95475
|
'caption',
|
|
93094
|
-
'colgroup',
|
|
95476
|
+
'colgroup',
|
|
95477
|
+
'col',
|
|
95478
|
+
'tr',
|
|
95479
|
+
'th',
|
|
95480
|
+
'td',
|
|
95481
|
+
]);
|
|
95482
|
+
/**
|
|
95483
|
+
* If the cell has exactly one paragraph child, unwrap it so its inline children sit
|
|
95484
|
+
* directly under the cell (matches GFM table cell shape and avoids stray `<p>` wrappers).
|
|
95485
|
+
*
|
|
95486
|
+
* When there are multiple paragraphs, leave them intact — they represent distinct lines
|
|
95487
|
+
* of content that need to be preserved for JSX `<Table>` serialization.
|
|
95488
|
+
*/
|
|
95489
|
+
const unwrapSoleParagraph = (children) => {
|
|
95490
|
+
const paragraphCount = children.filter(c => c.type === 'paragraph').length;
|
|
95491
|
+
if (paragraphCount !== 1)
|
|
95492
|
+
return children;
|
|
95493
|
+
return children.flatMap(child => {
|
|
95494
|
+
if (child.type === 'paragraph' && 'children' in child && Array.isArray(child.children)) {
|
|
95495
|
+
return child.children;
|
|
95496
|
+
}
|
|
95497
|
+
return [child];
|
|
95498
|
+
});
|
|
95499
|
+
};
|
|
95500
|
+
/**
|
|
95501
|
+
* Splice each text into `html` at its offset. Inserts at the same offset
|
|
95502
|
+
* are emitted in their input order (a stable sort by offset), so callers can
|
|
95503
|
+
* rely on innermost-first ordering by emitting events in stack-unwind order.
|
|
95504
|
+
*/
|
|
95505
|
+
const applyInserts = (html, inserts) => {
|
|
95506
|
+
if (inserts.length === 0)
|
|
95507
|
+
return { value: html, inserts: [] };
|
|
95508
|
+
const sorted = [...inserts].sort((a, b) => a.offset - b.offset);
|
|
95509
|
+
let out = '';
|
|
95510
|
+
let cursor = 0;
|
|
95511
|
+
sorted.forEach(({ offset, text }) => {
|
|
95512
|
+
const clamped = Math.min(Math.max(offset, cursor), html.length);
|
|
95513
|
+
if (clamped > cursor) {
|
|
95514
|
+
out += html.slice(cursor, clamped);
|
|
95515
|
+
cursor = clamped;
|
|
95516
|
+
}
|
|
95517
|
+
out += text;
|
|
95518
|
+
});
|
|
95519
|
+
return { value: out + html.slice(cursor), inserts: sorted };
|
|
95520
|
+
};
|
|
95521
|
+
|
|
95522
|
+
;// ./processor/transform/mdxish/tables/normalize-tag-spacing.ts
|
|
95523
|
+
|
|
95524
|
+
|
|
95525
|
+
/**
|
|
95526
|
+
* Returns the line bounds (start and end-exclusive offsets) containing `at`.
|
|
95527
|
+
*/
|
|
95528
|
+
const lineBoundsAt = (html, at) => {
|
|
95529
|
+
const start = html.lastIndexOf('\n', at - 1) + 1;
|
|
95530
|
+
const nl = html.indexOf('\n', at);
|
|
95531
|
+
return { start, end: nl === -1 ? html.length : nl };
|
|
95532
|
+
};
|
|
95533
|
+
/**
|
|
95534
|
+
* Compute the inserts needed to make one open/close pair line-symmetric.
|
|
95535
|
+
* Returns an empty array if the pair is already symmetric (both bare or both
|
|
95536
|
+
* attached) or shares a line.
|
|
95537
|
+
*/
|
|
95538
|
+
const symmetrizePair = (html, { openStart, openEnd, closeStart, closeEnd }) => {
|
|
95539
|
+
if (!html.slice(openEnd, closeStart).includes('\n'))
|
|
95540
|
+
return [];
|
|
95541
|
+
const openLine = lineBoundsAt(html, openStart);
|
|
95542
|
+
const closeLine = lineBoundsAt(html, closeStart);
|
|
95543
|
+
const preOpener = html.slice(openLine.start, openStart);
|
|
95544
|
+
const postOpener = html.slice(openEnd, openLine.end);
|
|
95545
|
+
const preCloser = html.slice(closeLine.start, closeStart);
|
|
95546
|
+
const postCloser = html.slice(closeEnd, closeLine.end);
|
|
95547
|
+
const openerHasExtras = preOpener.trim().length > 0 || postOpener.trim().length > 0;
|
|
95548
|
+
const closerHasExtras = preCloser.trim().length > 0 || postCloser.trim().length > 0;
|
|
95549
|
+
// Both match (both bare or both attached) — mdxjs parses this fine.
|
|
95550
|
+
if (openerHasExtras === closerHasExtras)
|
|
95551
|
+
return [];
|
|
95552
|
+
// Asymmetric. Push non-tag content on the offending side to its own line,
|
|
95553
|
+
// visually aligning the inserted line with the existing whitespace prefix.
|
|
95554
|
+
const indentFor = (linePrefix) => linePrefix.match(/^\s*/)?.[0] ?? '';
|
|
95555
|
+
const inserts = [];
|
|
95556
|
+
if (openerHasExtras) {
|
|
95557
|
+
const indent = indentFor(preOpener);
|
|
95558
|
+
if (preOpener.trim().length > 0)
|
|
95559
|
+
inserts.push({ offset: openStart, text: `\n${indent}` });
|
|
95560
|
+
if (postOpener.trim().length > 0)
|
|
95561
|
+
inserts.push({ offset: openEnd, text: `\n${indent}` });
|
|
95562
|
+
}
|
|
95563
|
+
if (closerHasExtras) {
|
|
95564
|
+
const indent = indentFor(preCloser);
|
|
95565
|
+
if (preCloser.trim().length > 0)
|
|
95566
|
+
inserts.push({ offset: closeStart, text: `\n${indent}` });
|
|
95567
|
+
if (postCloser.trim().length > 0)
|
|
95568
|
+
inserts.push({ offset: closeEnd, text: `\n${indent}` });
|
|
95569
|
+
}
|
|
95570
|
+
return inserts;
|
|
95571
|
+
};
|
|
95572
|
+
/**
|
|
95573
|
+
* mdxjs's micromark extension fails when a JSX element's opener-line and
|
|
95574
|
+
* closer-line don't match in "is the tag alone on its line?" Concretely:
|
|
95575
|
+
*
|
|
95576
|
+
* <span>X\n</span> ❌ opener-line has text, closer-line is bare
|
|
95577
|
+
* <span>\nX</span> ❌ opener-line is bare, closer-line has text
|
|
95578
|
+
* text <span>X\n</span> ❌ opener-line has leading + trailing text
|
|
95579
|
+
* <span>\nX\n</span> text ❌ closer-line has trailing text
|
|
95580
|
+
* <span>X\nY</span> ✅ both lines have adjacent text
|
|
95581
|
+
* <span>\nX\n</span> ✅ both lines are bare
|
|
95582
|
+
* <span>X</span> ✅ same line
|
|
95583
|
+
*
|
|
95584
|
+
* When the two lines disagree, mdxjs throws "Expected a closing tag…before
|
|
95585
|
+
* the end of `paragraph`" (or its mirror). This pass detects asymmetric
|
|
95586
|
+
* pairs and inserts newlines (+ matching indent) to push the offending side's
|
|
95587
|
+
* non-tag content to a separate line, restoring symmetry. Scoped to the
|
|
95588
|
+
* malformed-retry path; the happy path doesn't touch this.
|
|
95589
|
+
*/
|
|
95590
|
+
const normalizeTagSpacing = (html) => {
|
|
95591
|
+
const stack = [];
|
|
95592
|
+
const pairs = [];
|
|
95593
|
+
walkTags(html, {
|
|
95594
|
+
onOpen({ name, start, end }) {
|
|
95595
|
+
stack.push({ name, openStart: start, openEnd: end });
|
|
95596
|
+
},
|
|
95597
|
+
onClose({ name, start, end, implicit }) {
|
|
95598
|
+
if (implicit)
|
|
95599
|
+
return;
|
|
95600
|
+
// Walk the stack to find the innermost matching opener. `findLastIndex`
|
|
95601
|
+
// would be cleaner but isn't available on the current lib target.
|
|
95602
|
+
const matchIdx = stack.reduce((acc, t, i) => (t.name === name ? i : acc), -1);
|
|
95603
|
+
if (matchIdx === -1)
|
|
95604
|
+
return;
|
|
95605
|
+
const open = stack[matchIdx];
|
|
95606
|
+
pairs.push({ openStart: open.openStart, openEnd: open.openEnd, closeStart: start, closeEnd: end });
|
|
95607
|
+
stack.splice(matchIdx, 1);
|
|
95608
|
+
},
|
|
95609
|
+
});
|
|
95610
|
+
return applyInserts(html, pairs.flatMap(p => symmetrizePair(html, p)));
|
|
95611
|
+
};
|
|
95612
|
+
|
|
95613
|
+
;// ./processor/transform/mdxish/tables/remap-positions.ts
|
|
95614
|
+
|
|
95615
|
+
/**
|
|
95616
|
+
* Build a function that maps an offset in the repaired string back to the
|
|
95617
|
+
* original string's coordinate space. Inserts must be sorted by their
|
|
95618
|
+
* (original) offset.
|
|
95619
|
+
*
|
|
95620
|
+
* If a repaired offset falls *inside* synthetic text (i.e. on a character
|
|
95621
|
+
* that didn't exist in the original), it clamps to the insert's anchor
|
|
95622
|
+
* offset in the original — consumers slicing the original source get the
|
|
95623
|
+
* boundary, not garbage.
|
|
95624
|
+
*/
|
|
95625
|
+
const buildOffsetMapper = (inserts) => {
|
|
95626
|
+
// Pre-compute each insert's start in repaired-space.
|
|
95627
|
+
let acc = 0;
|
|
95628
|
+
const segments = inserts.map(ins => {
|
|
95629
|
+
const repairedStart = ins.offset + acc;
|
|
95630
|
+
acc += ins.text.length;
|
|
95631
|
+
return { origOffset: ins.offset, len: ins.text.length, repairedStart };
|
|
95632
|
+
});
|
|
95633
|
+
return (repaired) => {
|
|
95634
|
+
// Offsets inside an insert's synthetic span have no original counterpart;
|
|
95635
|
+
// clamp to the insert's anchor so consumers slice a real boundary.
|
|
95636
|
+
const hit = segments.find(seg => seg.repairedStart < repaired && repaired < seg.repairedStart + seg.len);
|
|
95637
|
+
if (hit)
|
|
95638
|
+
return hit.origOffset;
|
|
95639
|
+
const shift = segments.reduce((acc2, seg) => (seg.repairedStart < repaired ? acc2 + seg.len : acc2), 0);
|
|
95640
|
+
return repaired - shift;
|
|
95641
|
+
};
|
|
95642
|
+
};
|
|
95643
|
+
/**
|
|
95644
|
+
* Map an offset in `source` to its 1-based `{ line, column }`. `lineStarts`
|
|
95645
|
+
* is the precomputed array of offsets where each line begins.
|
|
95646
|
+
*/
|
|
95647
|
+
const offsetToLineCol = (lineStarts, offset) => {
|
|
95648
|
+
// Binary search for the greatest lineStart <= offset.
|
|
95649
|
+
let lo = 0;
|
|
95650
|
+
let hi = lineStarts.length - 1;
|
|
95651
|
+
while (lo < hi) {
|
|
95652
|
+
const mid = Math.floor((lo + hi + 1) / 2);
|
|
95653
|
+
if (lineStarts[mid] <= offset)
|
|
95654
|
+
lo = mid;
|
|
95655
|
+
else
|
|
95656
|
+
hi = mid - 1;
|
|
95657
|
+
}
|
|
95658
|
+
return { line: lo + 1, column: offset - lineStarts[lo] + 1 };
|
|
95659
|
+
};
|
|
95660
|
+
const computeLineStarts = (source) => {
|
|
95661
|
+
const starts = [0];
|
|
95662
|
+
for (let i = 0; i < source.length; i += 1) {
|
|
95663
|
+
if (source[i] === '\n')
|
|
95664
|
+
starts.push(i + 1);
|
|
95665
|
+
}
|
|
95666
|
+
return starts;
|
|
95667
|
+
};
|
|
95668
|
+
/**
|
|
95669
|
+
* Walk `tree`, translating every node's position from the repaired source's
|
|
95670
|
+
* coordinate space back to the original source. Offsets are remapped via the
|
|
95671
|
+
* insert list; line/column are recomputed from the original source so they
|
|
95672
|
+
* remain accurate even if repairs introduced newlines.
|
|
95673
|
+
*/
|
|
95674
|
+
const remapPositionsToOriginal = (tree, originalSource, inserts) => {
|
|
95675
|
+
if (inserts.length === 0)
|
|
95676
|
+
return;
|
|
95677
|
+
const mapOffset = buildOffsetMapper(inserts);
|
|
95678
|
+
const lineStarts = computeLineStarts(originalSource);
|
|
95679
|
+
visit(tree, child => {
|
|
95680
|
+
if (child.position?.start) {
|
|
95681
|
+
const origOffset = mapOffset(child.position.start.offset ?? 0);
|
|
95682
|
+
const { line, column } = offsetToLineCol(lineStarts, origOffset);
|
|
95683
|
+
child.position.start.offset = origOffset;
|
|
95684
|
+
child.position.start.line = line;
|
|
95685
|
+
child.position.start.column = column;
|
|
95686
|
+
}
|
|
95687
|
+
if (child.position?.end) {
|
|
95688
|
+
const origOffset = mapOffset(child.position.end.offset ?? 0);
|
|
95689
|
+
const { line, column } = offsetToLineCol(lineStarts, origOffset);
|
|
95690
|
+
child.position.end.offset = origOffset;
|
|
95691
|
+
child.position.end.line = line;
|
|
95692
|
+
child.position.end.column = column;
|
|
95693
|
+
}
|
|
95694
|
+
});
|
|
95695
|
+
};
|
|
95696
|
+
|
|
95697
|
+
;// ./node_modules/html-tags/html-tags.json
|
|
95698
|
+
const html_tags_namespaceObject = /*#__PURE__*/JSON.parse('["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","script","search","section","select","selectedcontent","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"]');
|
|
95699
|
+
// EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
|
|
95700
|
+
var dist = __webpack_require__(3753);
|
|
95701
|
+
var dist_default = /*#__PURE__*/__webpack_require__.n(dist);
|
|
95702
|
+
// EXTERNAL MODULE: ./node_modules/react-native-known-styling-properties/dist/index.js
|
|
95703
|
+
var react_native_known_styling_properties_dist = __webpack_require__(1734);
|
|
95704
|
+
;// ./utils/common-html-words.ts
|
|
95705
|
+
|
|
95706
|
+
|
|
95707
|
+
|
|
95708
|
+
/**
|
|
95709
|
+
* Extract word boundaries from camelCase strings (e.g., "borderWidth" -> ["border", "width"])
|
|
95710
|
+
*/
|
|
95711
|
+
function extractWordBoundaries(camelCaseStr) {
|
|
95712
|
+
return camelCaseStr
|
|
95713
|
+
.replace(/([A-Z])/g, ' $1')
|
|
95714
|
+
.toLowerCase()
|
|
95715
|
+
.trim()
|
|
95716
|
+
.split(/\s+/)
|
|
95717
|
+
.filter(word => word.length > 0);
|
|
95718
|
+
}
|
|
95719
|
+
/**
|
|
95720
|
+
* Get all unique word boundaries from an array of camelCase property names.
|
|
95721
|
+
* Filters out single-letter words to avoid false matches in smartCamelCase.
|
|
95722
|
+
*/
|
|
95723
|
+
function getWordBoundariesFromProps(props) {
|
|
95724
|
+
const boundaries = new Set();
|
|
95725
|
+
props.forEach(prop => {
|
|
95726
|
+
extractWordBoundaries(prop).forEach(word => {
|
|
95727
|
+
// Filter out single-letter words to prevent false matches (e.g., "d" matching in "data")
|
|
95728
|
+
// Keep meaningful 2+ character words
|
|
95729
|
+
if (word.length >= 2) {
|
|
95730
|
+
boundaries.add(word);
|
|
95731
|
+
}
|
|
95732
|
+
});
|
|
95733
|
+
});
|
|
95734
|
+
return Array.from(boundaries).sort();
|
|
95735
|
+
}
|
|
95736
|
+
/**
|
|
95737
|
+
* React HTML element props word boundaries (e.g., "on", "data", "aria", "accept", "auto")
|
|
95738
|
+
* Extracted from react-html-attributes package
|
|
95739
|
+
*/
|
|
95740
|
+
const REACT_HTML_PROP_BOUNDARIES = getWordBoundariesFromProps((dist_default())["*"] || []);
|
|
95741
|
+
/**
|
|
95742
|
+
* CSS style property word boundaries (e.g., "border", "margin", "padding", "flex", "align")
|
|
95743
|
+
* Extracted from react-native-known-styling-properties package
|
|
95744
|
+
*/
|
|
95745
|
+
const CSS_STYLE_PROP_BOUNDARIES = getWordBoundariesFromProps(react_native_known_styling_properties_dist/* allProps */.q9);
|
|
95746
|
+
/**
|
|
95747
|
+
* Custom component prop word boundaries not in React HTML or CSS boundaries.
|
|
95748
|
+
*/
|
|
95749
|
+
const CUSTOM_PROP_BOUNDARIES = [
|
|
95750
|
+
'alt',
|
|
95751
|
+
'attribute',
|
|
95752
|
+
'attributes',
|
|
95753
|
+
'buttons',
|
|
95754
|
+
'caption',
|
|
95755
|
+
'collection',
|
|
95756
|
+
'columns',
|
|
95757
|
+
'copy',
|
|
95758
|
+
'dark',
|
|
95759
|
+
'data',
|
|
95760
|
+
'depth',
|
|
95761
|
+
'download',
|
|
95762
|
+
'embed',
|
|
95763
|
+
'empty',
|
|
95764
|
+
'favicon',
|
|
95765
|
+
'flow',
|
|
95766
|
+
'iframe',
|
|
95767
|
+
'image',
|
|
95768
|
+
'layout',
|
|
95769
|
+
'lazy',
|
|
95770
|
+
'meta',
|
|
95771
|
+
'provider',
|
|
95772
|
+
'run',
|
|
95773
|
+
'safe',
|
|
95774
|
+
'scripts',
|
|
95775
|
+
'tag',
|
|
95776
|
+
'term',
|
|
95777
|
+
'terms',
|
|
95778
|
+
'theme',
|
|
95779
|
+
'url',
|
|
95780
|
+
'value',
|
|
95781
|
+
];
|
|
95782
|
+
/**
|
|
95783
|
+
* Tags that should be passed through and handled at runtime (not by the mdxish plugin)
|
|
95784
|
+
*/
|
|
95785
|
+
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'html-block', 'rdme-pin']);
|
|
95786
|
+
/**
|
|
95787
|
+
* Standard HTML tags that should never be treated as custom components.
|
|
95788
|
+
* Uses the html-tags package, converted to a Set<string> for efficient lookups.
|
|
95789
|
+
*/
|
|
95790
|
+
const STANDARD_HTML_TAGS = new Set(html_tags_namespaceObject);
|
|
95791
|
+
/**
|
|
95792
|
+
* HTML void elements — elements that have no closing tag and no children.
|
|
95793
|
+
*
|
|
95794
|
+
* @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
95795
|
+
*/
|
|
95796
|
+
const HTML_VOID_ELEMENTS = new Set([
|
|
95797
|
+
'area',
|
|
95798
|
+
'base',
|
|
95799
|
+
'br',
|
|
93095
95800
|
'col',
|
|
93096
|
-
'
|
|
93097
|
-
'
|
|
93098
|
-
'
|
|
95801
|
+
'embed',
|
|
95802
|
+
'hr',
|
|
95803
|
+
'img',
|
|
95804
|
+
'input',
|
|
95805
|
+
'link',
|
|
95806
|
+
'meta',
|
|
95807
|
+
'param',
|
|
95808
|
+
'source',
|
|
95809
|
+
'track',
|
|
95810
|
+
'wbr',
|
|
93099
95811
|
]);
|
|
95812
|
+
|
|
95813
|
+
;// ./processor/transform/mdxish/tables/repair-unclosed-tags.ts
|
|
95814
|
+
|
|
95815
|
+
|
|
95816
|
+
|
|
95817
|
+
const isStandardHtmlTag = (name) => STANDARD_HTML_TAGS.has(name.toLowerCase());
|
|
93100
95818
|
/**
|
|
93101
|
-
*
|
|
93102
|
-
*
|
|
95819
|
+
* MDX requires a JSX inline tag and its closer to live on the same line — not
|
|
95820
|
+
* just the same paragraph. (`<td>\nArray <object>\n</object></td>` still
|
|
95821
|
+
* throws even though there's no blank line between open and close.)
|
|
93103
95822
|
*
|
|
93104
|
-
* When
|
|
93105
|
-
*
|
|
95823
|
+
* When a pair of tags sit on different lines, return the offset of the first newline
|
|
95824
|
+
* after the open so the synthetic closer lands at the end of the open's line.
|
|
95825
|
+
* If they share a line (e.g. `<b><i>x</b>`), just use the position htmlparser2
|
|
95826
|
+
* decides the unclosed tag must be closed at by
|
|
93106
95827
|
*/
|
|
93107
|
-
const
|
|
93108
|
-
const
|
|
93109
|
-
|
|
93110
|
-
|
|
93111
|
-
|
|
93112
|
-
|
|
93113
|
-
|
|
93114
|
-
|
|
93115
|
-
|
|
95828
|
+
const findOffsetToPlaceCloser = (html, openTagEnd, forcedCloseAt) => {
|
|
95829
|
+
const newlineIdx = html.slice(openTagEnd, forcedCloseAt).indexOf('\n');
|
|
95830
|
+
return newlineIdx === -1 ? forcedCloseAt : openTagEnd + newlineIdx;
|
|
95831
|
+
};
|
|
95832
|
+
/**
|
|
95833
|
+
* Rewrites `html` so every open tag has a matching close. Returns the input
|
|
95834
|
+
* unchanged when nothing needed repair, so callers can cheaply detect no-ops.
|
|
95835
|
+
*
|
|
95836
|
+
* Detection runs through htmlparser2: any close event flagged `implicit` is
|
|
95837
|
+
* a tag the user opened but didn't explicitly close. We pair it with the
|
|
95838
|
+
* matching opener (popped from a stack we maintain) and insert `</name>` at
|
|
95839
|
+
* the end of the opener's line, or at the trigger if they're on the same line.
|
|
95840
|
+
*/
|
|
95841
|
+
const repairUnclosedTags = (html) => {
|
|
95842
|
+
const inserts = [];
|
|
95843
|
+
const openTags = [];
|
|
95844
|
+
walkTags(html, {
|
|
95845
|
+
onOpen({ name, start, end }) {
|
|
95846
|
+
// Escape non-HTML names (custom components, typos, `<arbitrary-tag>`)
|
|
95847
|
+
// so MDX treats them as literal text instead of expecting a closer
|
|
95848
|
+
if (!isStandardHtmlTag(name)) {
|
|
95849
|
+
inserts.push({ offset: start, text: '\\' });
|
|
95850
|
+
return;
|
|
95851
|
+
}
|
|
95852
|
+
if (HTML_VOID_ELEMENTS.has(name.toLowerCase())) {
|
|
95853
|
+
// MDX requires void elements to be self-closing (`<br/>`, not `<br>`).
|
|
95854
|
+
// If the source open tag doesn't end with `/`, inject one before the
|
|
95855
|
+
// `>` so it parses. `end` is one past `>`, so `end - 2` is the char
|
|
95856
|
+
// immediately before `>`.
|
|
95857
|
+
if (html[end - 2] !== '/')
|
|
95858
|
+
inserts.push({ offset: end - 1, text: '/' });
|
|
95859
|
+
return;
|
|
95860
|
+
}
|
|
95861
|
+
openTags.push({ name, start, end });
|
|
95862
|
+
},
|
|
95863
|
+
onClose({ name, start, implicit }) {
|
|
95864
|
+
if (HTML_VOID_ELEMENTS.has(name.toLowerCase()))
|
|
95865
|
+
return;
|
|
95866
|
+
if (!isStandardHtmlTag(name))
|
|
95867
|
+
return;
|
|
95868
|
+
const openTag = openTags.pop();
|
|
95869
|
+
if (!implicit || !openTag)
|
|
95870
|
+
return;
|
|
95871
|
+
inserts.push({ offset: findOffsetToPlaceCloser(html, openTag.end, start), text: `</${name}>` });
|
|
95872
|
+
},
|
|
93116
95873
|
});
|
|
95874
|
+
return applyInserts(html, inserts);
|
|
93117
95875
|
};
|
|
93118
95876
|
|
|
93119
95877
|
;// ./processor/transform/mdxish/tables/mdxish-tables.ts
|
|
@@ -93134,6 +95892,9 @@ const unwrapSoleParagraph = (children) => {
|
|
|
93134
95892
|
|
|
93135
95893
|
|
|
93136
95894
|
|
|
95895
|
+
|
|
95896
|
+
|
|
95897
|
+
|
|
93137
95898
|
const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
|
|
93138
95899
|
const tableTypes = {
|
|
93139
95900
|
tr: 'tableRow',
|
|
@@ -93157,12 +95918,13 @@ const buildTableNodeProcessor = (withMdx) => unified()
|
|
|
93157
95918
|
.use(remarkGfm);
|
|
93158
95919
|
const tableNodeProcessor = buildTableNodeProcessor(true);
|
|
93159
95920
|
const fallbackTableNodeProcessor = buildTableNodeProcessor(false);
|
|
93160
|
-
|
|
93161
|
-
|
|
93162
|
-
|
|
93163
|
-
|
|
93164
|
-
|
|
93165
|
-
|
|
95921
|
+
/**
|
|
95922
|
+
* Parse the HTML node that contains the full table substring
|
|
95923
|
+
* into the table parts (headers, rows, cells).
|
|
95924
|
+
* The plugins in the processor allows parsing markdown & special syntax inside the table cells
|
|
95925
|
+
* After parsing, we need to update the node positions
|
|
95926
|
+
*/
|
|
95927
|
+
const parseTableNode = (processor, node, repair) => {
|
|
93166
95928
|
let parsed;
|
|
93167
95929
|
try {
|
|
93168
95930
|
parsed = processor.runSync(processor.parse(node.value));
|
|
@@ -93170,6 +95932,14 @@ const parseTableNode = (processor, node) => {
|
|
|
93170
95932
|
catch {
|
|
93171
95933
|
return undefined;
|
|
93172
95934
|
}
|
|
95935
|
+
// If `node.value` was repaired before parsing, first remap positions back to
|
|
95936
|
+
// the original (unrepaired) coordinates via the insert list — otherwise the
|
|
95937
|
+
// shift would land on synthetic characters and be inaccurate
|
|
95938
|
+
if (repair) {
|
|
95939
|
+
remapPositionsToOriginal(parsed, repair.originalSource, repair.inserts);
|
|
95940
|
+
}
|
|
95941
|
+
// The subparser produces positions relative to `node.value`; shift them by
|
|
95942
|
+
// the outer node's offset/line so consumers can slice the full source.
|
|
93173
95943
|
const baseOffset = node.position?.start?.offset ?? 0;
|
|
93174
95944
|
const baseLine = (node.position?.start?.line ?? 1) - 1;
|
|
93175
95945
|
visit(parsed, child => {
|
|
@@ -93366,22 +96136,45 @@ const mdxishTables = () => tree => {
|
|
|
93366
96136
|
return;
|
|
93367
96137
|
if (!node.value.startsWith('<Table') && !node.value.startsWith('<table'))
|
|
93368
96138
|
return;
|
|
93369
|
-
|
|
96139
|
+
// Main logic to transform table node to its parts
|
|
96140
|
+
// Because the processor uses remarkMdx, it is stricter in what it accepts
|
|
96141
|
+
// and only accepts valid MDX syntax. in the table node.
|
|
96142
|
+
// To get around that, we have some fallback logics after trying to repair the table content
|
|
96143
|
+
let parsed = parseTableNode(tableNodeProcessor, node);
|
|
96144
|
+
if (!parsed) {
|
|
96145
|
+
// First common error is unclosed HTML tags
|
|
96146
|
+
const repaired = repairUnclosedTags(node.value);
|
|
96147
|
+
if (repaired.value !== node.value) {
|
|
96148
|
+
parsed = parseTableNode(tableNodeProcessor, { ...node, value: repaired.value }, { inserts: repaired.inserts, originalSource: node.value });
|
|
96149
|
+
}
|
|
96150
|
+
if (!parsed) {
|
|
96151
|
+
// Second common error is having a line with text and an opening tag
|
|
96152
|
+
// E.g. text <div> \n <div> text
|
|
96153
|
+
const normalized = normalizeTagSpacing(node.value);
|
|
96154
|
+
if (normalized.value !== node.value) {
|
|
96155
|
+
parsed = parseTableNode(tableNodeProcessor, { ...node, value: normalized.value }, { inserts: normalized.inserts, originalSource: node.value });
|
|
96156
|
+
}
|
|
96157
|
+
}
|
|
96158
|
+
}
|
|
93370
96159
|
if (parsed) {
|
|
96160
|
+
// If the table is parsed successfully, we can now process it further
|
|
96161
|
+
// to build on the markdown / JSX table
|
|
93371
96162
|
visit(parsed, isMDXElement, (tableNode) => {
|
|
93372
96163
|
if (tableNode.name !== 'Table' && tableNode.name !== 'table')
|
|
93373
96164
|
return undefined;
|
|
93374
96165
|
processTableNode(tableNode, index, parent, node.position);
|
|
93375
96166
|
return EXIT;
|
|
93376
96167
|
});
|
|
93377
|
-
return;
|
|
93378
96168
|
}
|
|
93379
|
-
|
|
93380
|
-
|
|
93381
|
-
|
|
93382
|
-
|
|
93383
|
-
|
|
93384
|
-
|
|
96169
|
+
else if (node.value.startsWith('<table')) {
|
|
96170
|
+
// If the parsing still fails, give an opportunity to the fallback parser
|
|
96171
|
+
// without remarkMdx to process lowercase tables as it's likely to not
|
|
96172
|
+
// have needed MDX parsing anyway
|
|
96173
|
+
const fallback = parseTableNode(fallbackTableNodeProcessor, node);
|
|
96174
|
+
if (!fallback || fallback.children.length <= 1)
|
|
96175
|
+
return;
|
|
96176
|
+
parent.children.splice(index, 1, ...fallback.children);
|
|
96177
|
+
}
|
|
93385
96178
|
});
|
|
93386
96179
|
return tree;
|
|
93387
96180
|
};
|
|
@@ -108713,101 +111506,6 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
108713
111506
|
/** @type {ReturnType<createH>} */
|
|
108714
111507
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
108715
111508
|
|
|
108716
|
-
;// ./node_modules/html-tags/html-tags.json
|
|
108717
|
-
const html_tags_namespaceObject = /*#__PURE__*/JSON.parse('["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","script","search","section","select","selectedcontent","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"]');
|
|
108718
|
-
// EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
|
|
108719
|
-
var dist = __webpack_require__(3753);
|
|
108720
|
-
var dist_default = /*#__PURE__*/__webpack_require__.n(dist);
|
|
108721
|
-
// EXTERNAL MODULE: ./node_modules/react-native-known-styling-properties/dist/index.js
|
|
108722
|
-
var react_native_known_styling_properties_dist = __webpack_require__(1734);
|
|
108723
|
-
;// ./utils/common-html-words.ts
|
|
108724
|
-
|
|
108725
|
-
|
|
108726
|
-
|
|
108727
|
-
/**
|
|
108728
|
-
* Extract word boundaries from camelCase strings (e.g., "borderWidth" -> ["border", "width"])
|
|
108729
|
-
*/
|
|
108730
|
-
function extractWordBoundaries(camelCaseStr) {
|
|
108731
|
-
return camelCaseStr
|
|
108732
|
-
.replace(/([A-Z])/g, ' $1')
|
|
108733
|
-
.toLowerCase()
|
|
108734
|
-
.trim()
|
|
108735
|
-
.split(/\s+/)
|
|
108736
|
-
.filter(word => word.length > 0);
|
|
108737
|
-
}
|
|
108738
|
-
/**
|
|
108739
|
-
* Get all unique word boundaries from an array of camelCase property names.
|
|
108740
|
-
* Filters out single-letter words to avoid false matches in smartCamelCase.
|
|
108741
|
-
*/
|
|
108742
|
-
function getWordBoundariesFromProps(props) {
|
|
108743
|
-
const boundaries = new Set();
|
|
108744
|
-
props.forEach(prop => {
|
|
108745
|
-
extractWordBoundaries(prop).forEach(word => {
|
|
108746
|
-
// Filter out single-letter words to prevent false matches (e.g., "d" matching in "data")
|
|
108747
|
-
// Keep meaningful 2+ character words
|
|
108748
|
-
if (word.length >= 2) {
|
|
108749
|
-
boundaries.add(word);
|
|
108750
|
-
}
|
|
108751
|
-
});
|
|
108752
|
-
});
|
|
108753
|
-
return Array.from(boundaries).sort();
|
|
108754
|
-
}
|
|
108755
|
-
/**
|
|
108756
|
-
* React HTML element props word boundaries (e.g., "on", "data", "aria", "accept", "auto")
|
|
108757
|
-
* Extracted from react-html-attributes package
|
|
108758
|
-
*/
|
|
108759
|
-
const REACT_HTML_PROP_BOUNDARIES = getWordBoundariesFromProps((dist_default())["*"] || []);
|
|
108760
|
-
/**
|
|
108761
|
-
* CSS style property word boundaries (e.g., "border", "margin", "padding", "flex", "align")
|
|
108762
|
-
* Extracted from react-native-known-styling-properties package
|
|
108763
|
-
*/
|
|
108764
|
-
const CSS_STYLE_PROP_BOUNDARIES = getWordBoundariesFromProps(react_native_known_styling_properties_dist/* allProps */.q9);
|
|
108765
|
-
/**
|
|
108766
|
-
* Custom component prop word boundaries not in React HTML or CSS boundaries.
|
|
108767
|
-
*/
|
|
108768
|
-
const CUSTOM_PROP_BOUNDARIES = [
|
|
108769
|
-
'alt',
|
|
108770
|
-
'attribute',
|
|
108771
|
-
'attributes',
|
|
108772
|
-
'buttons',
|
|
108773
|
-
'caption',
|
|
108774
|
-
'collection',
|
|
108775
|
-
'columns',
|
|
108776
|
-
'copy',
|
|
108777
|
-
'dark',
|
|
108778
|
-
'data',
|
|
108779
|
-
'depth',
|
|
108780
|
-
'download',
|
|
108781
|
-
'embed',
|
|
108782
|
-
'empty',
|
|
108783
|
-
'favicon',
|
|
108784
|
-
'flow',
|
|
108785
|
-
'iframe',
|
|
108786
|
-
'image',
|
|
108787
|
-
'layout',
|
|
108788
|
-
'lazy',
|
|
108789
|
-
'meta',
|
|
108790
|
-
'provider',
|
|
108791
|
-
'run',
|
|
108792
|
-
'safe',
|
|
108793
|
-
'scripts',
|
|
108794
|
-
'tag',
|
|
108795
|
-
'term',
|
|
108796
|
-
'terms',
|
|
108797
|
-
'theme',
|
|
108798
|
-
'url',
|
|
108799
|
-
'value',
|
|
108800
|
-
];
|
|
108801
|
-
/**
|
|
108802
|
-
* Tags that should be passed through and handled at runtime (not by the mdxish plugin)
|
|
108803
|
-
*/
|
|
108804
|
-
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'html-block', 'rdme-pin']);
|
|
108805
|
-
/**
|
|
108806
|
-
* Standard HTML tags that should never be treated as custom components.
|
|
108807
|
-
* Uses the html-tags package, converted to a Set<string> for efficient lookups.
|
|
108808
|
-
*/
|
|
108809
|
-
const STANDARD_HTML_TAGS = new Set(html_tags_namespaceObject);
|
|
108810
|
-
|
|
108811
111509
|
;// ./processor/plugin/toc.ts
|
|
108812
111510
|
|
|
108813
111511
|
|
|
@@ -115897,28 +118595,7 @@ function restoreCodeBlocks(content, protectedCode) {
|
|
|
115897
118595
|
|
|
115898
118596
|
;// ./processor/transform/mdxish/close-self-closing-html-tags.ts
|
|
115899
118597
|
|
|
115900
|
-
|
|
115901
|
-
* HTML void elements that are legitimately self-closing per the HTML spec.
|
|
115902
|
-
* These should NOT be transformed.
|
|
115903
|
-
*
|
|
115904
|
-
* @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
115905
|
-
*/
|
|
115906
|
-
const HTML_VOID_ELEMENTS = new Set([
|
|
115907
|
-
'area',
|
|
115908
|
-
'base',
|
|
115909
|
-
'br',
|
|
115910
|
-
'col',
|
|
115911
|
-
'embed',
|
|
115912
|
-
'hr',
|
|
115913
|
-
'img',
|
|
115914
|
-
'input',
|
|
115915
|
-
'link',
|
|
115916
|
-
'meta',
|
|
115917
|
-
'param',
|
|
115918
|
-
'source',
|
|
115919
|
-
'track',
|
|
115920
|
-
'wbr',
|
|
115921
|
-
]);
|
|
118598
|
+
|
|
115922
118599
|
/**
|
|
115923
118600
|
* Matches self-closing HTML tags: `<tagname/>` or `<tagname attr="val" />`
|
|
115924
118601
|
*
|
|
@@ -117749,6 +120426,14 @@ function createTokenize(mode) {
|
|
|
117749
120426
|
let fenceLength = 0;
|
|
117750
120427
|
let fenceCloseLength = 0;
|
|
117751
120428
|
let atLineStart = false;
|
|
120429
|
+
// Bail when the opener line has unmatched tag-like tokens in its body.
|
|
120430
|
+
// `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
|
|
120431
|
+
// `<Callout>x <strong>y</strong>` balance to 0. Without this,
|
|
120432
|
+
// `concrete: true` causes orphan openers to eat sibling blockquotes.
|
|
120433
|
+
let onOpenerLine = false;
|
|
120434
|
+
let openerLineHasContent = false;
|
|
120435
|
+
let openerLineOpens = 0;
|
|
120436
|
+
let openerLineCloses = 0;
|
|
117752
120437
|
// Attribute parsing state
|
|
117753
120438
|
let quoteChar = null;
|
|
117754
120439
|
let braceDepth = 0;
|
|
@@ -117837,6 +120522,7 @@ function createTokenize(mode) {
|
|
|
117837
120522
|
if (isLowercaseTag && !sawBraceAttr)
|
|
117838
120523
|
return nok(code);
|
|
117839
120524
|
effects.consume(code);
|
|
120525
|
+
onOpenerLine = isFlow;
|
|
117840
120526
|
return body;
|
|
117841
120527
|
}
|
|
117842
120528
|
// Quoted attribute value
|
|
@@ -118046,10 +120732,19 @@ function createTokenize(mode) {
|
|
|
118046
120732
|
if (markdownLineEnding(code)) {
|
|
118047
120733
|
if (!isFlow)
|
|
118048
120734
|
return nok(code);
|
|
120735
|
+
// See `onOpenerLine` declaration. Bail iff the opener line had
|
|
120736
|
+
// content AND more opener-shaped tokens than closer-shaped tokens.
|
|
120737
|
+
if (onOpenerLine && openerLineHasContent && openerLineOpens > openerLineCloses) {
|
|
120738
|
+
return nok(code);
|
|
120739
|
+
}
|
|
120740
|
+
onOpenerLine = false;
|
|
118049
120741
|
effects.exit('mdxComponentData');
|
|
118050
120742
|
atLineStart = true;
|
|
118051
120743
|
return bodyContinuationStart(code);
|
|
118052
120744
|
}
|
|
120745
|
+
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
120746
|
+
openerLineHasContent = true;
|
|
120747
|
+
}
|
|
118053
120748
|
if (code === codes.backslash) {
|
|
118054
120749
|
effects.consume(code);
|
|
118055
120750
|
return bodyEscapedChar;
|
|
@@ -118197,16 +120892,26 @@ function createTokenize(mode) {
|
|
|
118197
120892
|
// ── Tag detection inside body ──────────────────────────────────────────
|
|
118198
120893
|
function bodyLessThan(code) {
|
|
118199
120894
|
if (code === codes.slash) {
|
|
120895
|
+
if (onOpenerLine)
|
|
120896
|
+
openerLineCloses += 1;
|
|
118200
120897
|
effects.consume(code);
|
|
118201
120898
|
closingTagName = '';
|
|
118202
120899
|
return closingTagNameFirst;
|
|
118203
120900
|
}
|
|
118204
120901
|
// Potential nested opening tag (same case class as the outer tag)
|
|
118205
120902
|
if (code !== null && isAlpha(code) && isSameCaseAsTag(code)) {
|
|
120903
|
+
if (onOpenerLine)
|
|
120904
|
+
openerLineOpens += 1;
|
|
118206
120905
|
closingTagName = String.fromCharCode(code);
|
|
118207
120906
|
effects.consume(code);
|
|
118208
120907
|
return nestedOpenTagName;
|
|
118209
120908
|
}
|
|
120909
|
+
// Tag-like token but not in nested-tracking case (different case).
|
|
120910
|
+
// Count it for the opener-line bail heuristic anyway: `<strong>` in
|
|
120911
|
+
// `<Callout>x <strong>y</strong></Callout>` should pair with `</strong>`.
|
|
120912
|
+
if (code !== null && isAlpha(code) && onOpenerLine) {
|
|
120913
|
+
openerLineOpens += 1;
|
|
120914
|
+
}
|
|
118210
120915
|
atLineStart = false;
|
|
118211
120916
|
return body(code);
|
|
118212
120917
|
}
|
|
@@ -120682,14 +123387,24 @@ const transformImage = (jsx) => {
|
|
|
120682
123387
|
*/
|
|
120683
123388
|
const transformCallout = (jsx) => {
|
|
120684
123389
|
const attrs = getAttrs(jsx);
|
|
120685
|
-
const { empty = false, icon = '', theme = '' } = attrs;
|
|
123390
|
+
const { empty: explicitEmpty = false, icon = '', theme = '' } = attrs;
|
|
123391
|
+
// children[0] is the title slot. Prepend an empty-paragraph placeholder
|
|
123392
|
+
// when JSX has no leading heading, otherwise the body round-trips into it.
|
|
123393
|
+
const jsxChildren = jsx.children;
|
|
123394
|
+
const hasHeadingFirst = jsxChildren[0]?.type === 'heading';
|
|
123395
|
+
const children = hasHeadingFirst
|
|
123396
|
+
? jsxChildren
|
|
123397
|
+
: [
|
|
123398
|
+
{ type: 'paragraph', children: [{ type: 'text', value: '' }] },
|
|
123399
|
+
...jsxChildren,
|
|
123400
|
+
];
|
|
120686
123401
|
return {
|
|
120687
123402
|
type: NodeTypes.callout,
|
|
120688
|
-
children
|
|
123403
|
+
children,
|
|
120689
123404
|
data: {
|
|
120690
123405
|
hName: 'Callout',
|
|
120691
123406
|
hProperties: {
|
|
120692
|
-
empty,
|
|
123407
|
+
empty: explicitEmpty || !hasHeadingFirst,
|
|
120693
123408
|
icon,
|
|
120694
123409
|
theme,
|
|
120695
123410
|
},
|
|
@@ -120966,6 +123681,10 @@ const mdxishJsxToMdast = () => tree => {
|
|
|
120966
123681
|
return SKIP;
|
|
120967
123682
|
if (parent.type === 'paragraph')
|
|
120968
123683
|
return SKIP;
|
|
123684
|
+
// `` in any tableCell stays inline. Authors who want a captioned figure use
|
|
123685
|
+
// `<Image caption="…" />` JSX, which becomes `image-block` via `COMPONENT_MAP` above.
|
|
123686
|
+
if (parent.type === 'tableCell')
|
|
123687
|
+
return SKIP;
|
|
120969
123688
|
const newNode = transformMagicBlockImage(node);
|
|
120970
123689
|
parent.children[index] = newNode;
|
|
120971
123690
|
return SKIP;
|
|
@@ -121568,6 +124287,8 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
|
|
|
121568
124287
|
visit(tree, 'code', (node) => {
|
|
121569
124288
|
if (!node.value)
|
|
121570
124289
|
return;
|
|
124290
|
+
if (node.lang === 'mermaid')
|
|
124291
|
+
return;
|
|
121571
124292
|
const nextValue = resolveCodeVariables(node.value, resolvedVariables);
|
|
121572
124293
|
node.value = nextValue;
|
|
121573
124294
|
// Keep code-tabs/readme-components hProperties in sync with node.value
|