@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.js
CHANGED
|
@@ -72891,35 +72891,2793 @@ const normalizeEmphasisAST = () => (tree) => {
|
|
|
72891
72891
|
};
|
|
72892
72892
|
/* harmony default export */ const normalize_malformed_md_syntax = (normalizeEmphasisAST);
|
|
72893
72893
|
|
|
72894
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/decode-codepoint.js
|
|
72895
|
+
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
|
|
72896
|
+
const dist_decode_codepoint_decodeMap = new Map([
|
|
72897
|
+
[0, 65_533],
|
|
72898
|
+
// C1 Unicode control character reference replacements
|
|
72899
|
+
[128, 8364],
|
|
72900
|
+
[130, 8218],
|
|
72901
|
+
[131, 402],
|
|
72902
|
+
[132, 8222],
|
|
72903
|
+
[133, 8230],
|
|
72904
|
+
[134, 8224],
|
|
72905
|
+
[135, 8225],
|
|
72906
|
+
[136, 710],
|
|
72907
|
+
[137, 8240],
|
|
72908
|
+
[138, 352],
|
|
72909
|
+
[139, 8249],
|
|
72910
|
+
[140, 338],
|
|
72911
|
+
[142, 381],
|
|
72912
|
+
[145, 8216],
|
|
72913
|
+
[146, 8217],
|
|
72914
|
+
[147, 8220],
|
|
72915
|
+
[148, 8221],
|
|
72916
|
+
[149, 8226],
|
|
72917
|
+
[150, 8211],
|
|
72918
|
+
[151, 8212],
|
|
72919
|
+
[152, 732],
|
|
72920
|
+
[153, 8482],
|
|
72921
|
+
[154, 353],
|
|
72922
|
+
[155, 8250],
|
|
72923
|
+
[156, 339],
|
|
72924
|
+
[158, 382],
|
|
72925
|
+
[159, 376],
|
|
72926
|
+
]);
|
|
72927
|
+
/**
|
|
72928
|
+
* Replace the given code point with a replacement character if it is a
|
|
72929
|
+
* surrogate or is outside the valid range. Otherwise return the code
|
|
72930
|
+
* point unchanged.
|
|
72931
|
+
* @param codePoint Unicode code point to convert.
|
|
72932
|
+
*/
|
|
72933
|
+
function dist_decode_codepoint_replaceCodePoint(codePoint) {
|
|
72934
|
+
if ((codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||
|
|
72935
|
+
codePoint > 0x10_ff_ff) {
|
|
72936
|
+
return 0xff_fd;
|
|
72937
|
+
}
|
|
72938
|
+
return dist_decode_codepoint_decodeMap.get(codePoint) ?? codePoint;
|
|
72939
|
+
}
|
|
72940
|
+
//# sourceMappingURL=decode-codepoint.js.map
|
|
72941
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/internal/bin-trie-flags.js
|
|
72942
|
+
/**
|
|
72943
|
+
* Bit flags & masks for the binary trie encoding used for entity decoding.
|
|
72944
|
+
*
|
|
72945
|
+
* Bit layout (16 bits total):
|
|
72946
|
+
* 15..14 VALUE_LENGTH (+1 encoding; 0 => no value)
|
|
72947
|
+
* 13 FLAG13. If valueLength>0: semicolon required flag (implicit ';').
|
|
72948
|
+
* If valueLength==0: compact run flag.
|
|
72949
|
+
* 12..7 BRANCH_LENGTH Branch length (0 => single branch in 6..0 if jumpOffset==char) OR run length (when compact run)
|
|
72950
|
+
* 6..0 JUMP_TABLE Jump offset (jump table) OR single-branch char code OR first run char
|
|
72951
|
+
*/
|
|
72952
|
+
var bin_trie_flags_BinTrieFlags;
|
|
72953
|
+
(function (BinTrieFlags) {
|
|
72954
|
+
BinTrieFlags[BinTrieFlags["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
|
|
72955
|
+
BinTrieFlags[BinTrieFlags["FLAG13"] = 8192] = "FLAG13";
|
|
72956
|
+
BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 8064] = "BRANCH_LENGTH";
|
|
72957
|
+
BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE";
|
|
72958
|
+
})(bin_trie_flags_BinTrieFlags || (bin_trie_flags_BinTrieFlags = {}));
|
|
72959
|
+
//# sourceMappingURL=bin-trie-flags.js.map
|
|
72960
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/decode.js
|
|
72961
|
+
|
|
72962
|
+
|
|
72963
|
+
|
|
72964
|
+
|
|
72965
|
+
var dist_decode_CharCodes;
|
|
72966
|
+
(function (CharCodes) {
|
|
72967
|
+
CharCodes[CharCodes["NUM"] = 35] = "NUM";
|
|
72968
|
+
CharCodes[CharCodes["SEMI"] = 59] = "SEMI";
|
|
72969
|
+
CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS";
|
|
72970
|
+
CharCodes[CharCodes["ZERO"] = 48] = "ZERO";
|
|
72971
|
+
CharCodes[CharCodes["NINE"] = 57] = "NINE";
|
|
72972
|
+
CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A";
|
|
72973
|
+
CharCodes[CharCodes["LOWER_F"] = 102] = "LOWER_F";
|
|
72974
|
+
CharCodes[CharCodes["LOWER_X"] = 120] = "LOWER_X";
|
|
72975
|
+
CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z";
|
|
72976
|
+
CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A";
|
|
72977
|
+
CharCodes[CharCodes["UPPER_F"] = 70] = "UPPER_F";
|
|
72978
|
+
CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z";
|
|
72979
|
+
})(dist_decode_CharCodes || (dist_decode_CharCodes = {}));
|
|
72980
|
+
/** Bit that needs to be set to convert an upper case ASCII character to lower case */
|
|
72981
|
+
const dist_decode_TO_LOWER_BIT = 0b10_0000;
|
|
72982
|
+
function dist_decode_isNumber(code) {
|
|
72983
|
+
return code >= dist_decode_CharCodes.ZERO && code <= dist_decode_CharCodes.NINE;
|
|
72984
|
+
}
|
|
72985
|
+
function dist_decode_isHexadecimalCharacter(code) {
|
|
72986
|
+
return ((code >= dist_decode_CharCodes.UPPER_A && code <= dist_decode_CharCodes.UPPER_F) ||
|
|
72987
|
+
(code >= dist_decode_CharCodes.LOWER_A && code <= dist_decode_CharCodes.LOWER_F));
|
|
72988
|
+
}
|
|
72989
|
+
function dist_decode_isAsciiAlphaNumeric(code) {
|
|
72990
|
+
return ((code >= dist_decode_CharCodes.UPPER_A && code <= dist_decode_CharCodes.UPPER_Z) ||
|
|
72991
|
+
(code >= dist_decode_CharCodes.LOWER_A && code <= dist_decode_CharCodes.LOWER_Z) ||
|
|
72992
|
+
dist_decode_isNumber(code));
|
|
72993
|
+
}
|
|
72994
|
+
/**
|
|
72995
|
+
* Checks if the given character is a valid end character for an entity in an attribute.
|
|
72996
|
+
*
|
|
72997
|
+
* Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.
|
|
72998
|
+
* See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
|
|
72999
|
+
* @param code Code point to decode.
|
|
73000
|
+
*/
|
|
73001
|
+
function dist_decode_isEntityInAttributeInvalidEnd(code) {
|
|
73002
|
+
return code === dist_decode_CharCodes.EQUALS || dist_decode_isAsciiAlphaNumeric(code);
|
|
73003
|
+
}
|
|
73004
|
+
var dist_decode_EntityDecoderState;
|
|
73005
|
+
(function (EntityDecoderState) {
|
|
73006
|
+
EntityDecoderState[EntityDecoderState["EntityStart"] = 0] = "EntityStart";
|
|
73007
|
+
EntityDecoderState[EntityDecoderState["NumericStart"] = 1] = "NumericStart";
|
|
73008
|
+
EntityDecoderState[EntityDecoderState["NumericDecimal"] = 2] = "NumericDecimal";
|
|
73009
|
+
EntityDecoderState[EntityDecoderState["NumericHex"] = 3] = "NumericHex";
|
|
73010
|
+
EntityDecoderState[EntityDecoderState["NamedEntity"] = 4] = "NamedEntity";
|
|
73011
|
+
})(dist_decode_EntityDecoderState || (dist_decode_EntityDecoderState = {}));
|
|
73012
|
+
/**
|
|
73013
|
+
* Decoding mode for named entities.
|
|
73014
|
+
*/
|
|
73015
|
+
var dist_decode_DecodingMode;
|
|
73016
|
+
(function (DecodingMode) {
|
|
73017
|
+
/** Entities in text nodes that can end with any character. */
|
|
73018
|
+
DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy";
|
|
73019
|
+
/** Only allow entities terminated with a semicolon. */
|
|
73020
|
+
DecodingMode[DecodingMode["Strict"] = 1] = "Strict";
|
|
73021
|
+
/** Entities in attributes have limitations on ending characters. */
|
|
73022
|
+
DecodingMode[DecodingMode["Attribute"] = 2] = "Attribute";
|
|
73023
|
+
})(dist_decode_DecodingMode || (dist_decode_DecodingMode = {}));
|
|
73024
|
+
/**
|
|
73025
|
+
* Token decoder with support of writing partial entities.
|
|
73026
|
+
*/
|
|
73027
|
+
class dist_decode_EntityDecoder {
|
|
73028
|
+
decodeTree;
|
|
73029
|
+
emitCodePoint;
|
|
73030
|
+
errors;
|
|
73031
|
+
constructor(
|
|
73032
|
+
/** The tree used to decode entities. */
|
|
73033
|
+
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: False positive
|
|
73034
|
+
decodeTree,
|
|
73035
|
+
/**
|
|
73036
|
+
* The function that is called when a codepoint is decoded.
|
|
73037
|
+
*
|
|
73038
|
+
* For multi-byte named entities, this will be called multiple times,
|
|
73039
|
+
* with the second codepoint, and the same `consumed` value.
|
|
73040
|
+
* @param codepoint The decoded codepoint.
|
|
73041
|
+
* @param consumed The number of bytes consumed by the decoder.
|
|
73042
|
+
*/
|
|
73043
|
+
emitCodePoint,
|
|
73044
|
+
/** An object that is used to produce errors. */
|
|
73045
|
+
errors) {
|
|
73046
|
+
this.decodeTree = decodeTree;
|
|
73047
|
+
this.emitCodePoint = emitCodePoint;
|
|
73048
|
+
this.errors = errors;
|
|
73049
|
+
}
|
|
73050
|
+
/** The current state of the decoder. */
|
|
73051
|
+
state = dist_decode_EntityDecoderState.EntityStart;
|
|
73052
|
+
/** Characters that were consumed while parsing an entity. */
|
|
73053
|
+
consumed = 1;
|
|
73054
|
+
/**
|
|
73055
|
+
* The result of the entity.
|
|
73056
|
+
*
|
|
73057
|
+
* Either the result index of a numeric entity, or the codepoint of a
|
|
73058
|
+
* numeric entity.
|
|
73059
|
+
*/
|
|
73060
|
+
result = 0;
|
|
73061
|
+
/** The current index in the decode tree. */
|
|
73062
|
+
treeIndex = 0;
|
|
73063
|
+
/** The number of characters that were consumed in excess. */
|
|
73064
|
+
excess = 1;
|
|
73065
|
+
/** The mode in which the decoder is operating. */
|
|
73066
|
+
decodeMode = dist_decode_DecodingMode.Strict;
|
|
73067
|
+
/** The number of characters that have been consumed in the current run. */
|
|
73068
|
+
runConsumed = 0;
|
|
73069
|
+
/**
|
|
73070
|
+
* Resets the instance to make it reusable.
|
|
73071
|
+
* @param decodeMode Entity decoding mode to use.
|
|
73072
|
+
*/
|
|
73073
|
+
startEntity(decodeMode) {
|
|
73074
|
+
this.decodeMode = decodeMode;
|
|
73075
|
+
this.state = dist_decode_EntityDecoderState.EntityStart;
|
|
73076
|
+
this.result = 0;
|
|
73077
|
+
this.treeIndex = 0;
|
|
73078
|
+
this.excess = 1;
|
|
73079
|
+
this.consumed = 1;
|
|
73080
|
+
this.runConsumed = 0;
|
|
73081
|
+
}
|
|
73082
|
+
/**
|
|
73083
|
+
* Write an entity to the decoder. This can be called multiple times with partial entities.
|
|
73084
|
+
* If the entity is incomplete, the decoder will return -1.
|
|
73085
|
+
*
|
|
73086
|
+
* Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
|
|
73087
|
+
* entity is incomplete, and resume when the next string is written.
|
|
73088
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
73089
|
+
* @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
|
|
73090
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
73091
|
+
*/
|
|
73092
|
+
write(input, offset) {
|
|
73093
|
+
switch (this.state) {
|
|
73094
|
+
case dist_decode_EntityDecoderState.EntityStart: {
|
|
73095
|
+
if (input.charCodeAt(offset) === dist_decode_CharCodes.NUM) {
|
|
73096
|
+
this.state = dist_decode_EntityDecoderState.NumericStart;
|
|
73097
|
+
this.consumed += 1;
|
|
73098
|
+
return this.stateNumericStart(input, offset + 1);
|
|
73099
|
+
}
|
|
73100
|
+
this.state = dist_decode_EntityDecoderState.NamedEntity;
|
|
73101
|
+
return this.stateNamedEntity(input, offset);
|
|
73102
|
+
}
|
|
73103
|
+
case dist_decode_EntityDecoderState.NumericStart: {
|
|
73104
|
+
return this.stateNumericStart(input, offset);
|
|
73105
|
+
}
|
|
73106
|
+
case dist_decode_EntityDecoderState.NumericDecimal: {
|
|
73107
|
+
return this.stateNumericDecimal(input, offset);
|
|
73108
|
+
}
|
|
73109
|
+
case dist_decode_EntityDecoderState.NumericHex: {
|
|
73110
|
+
return this.stateNumericHex(input, offset);
|
|
73111
|
+
}
|
|
73112
|
+
case dist_decode_EntityDecoderState.NamedEntity: {
|
|
73113
|
+
return this.stateNamedEntity(input, offset);
|
|
73114
|
+
}
|
|
73115
|
+
}
|
|
73116
|
+
}
|
|
73117
|
+
/**
|
|
73118
|
+
* Switches between the numeric decimal and hexadecimal states.
|
|
73119
|
+
*
|
|
73120
|
+
* Equivalent to the `Numeric character reference state` in the HTML spec.
|
|
73121
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
73122
|
+
* @param offset The current offset.
|
|
73123
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
73124
|
+
*/
|
|
73125
|
+
stateNumericStart(input, offset) {
|
|
73126
|
+
if (offset >= input.length) {
|
|
73127
|
+
return -1;
|
|
73128
|
+
}
|
|
73129
|
+
if ((input.charCodeAt(offset) | dist_decode_TO_LOWER_BIT) === dist_decode_CharCodes.LOWER_X) {
|
|
73130
|
+
this.state = dist_decode_EntityDecoderState.NumericHex;
|
|
73131
|
+
this.consumed += 1;
|
|
73132
|
+
return this.stateNumericHex(input, offset + 1);
|
|
73133
|
+
}
|
|
73134
|
+
this.state = dist_decode_EntityDecoderState.NumericDecimal;
|
|
73135
|
+
return this.stateNumericDecimal(input, offset);
|
|
73136
|
+
}
|
|
73137
|
+
/**
|
|
73138
|
+
* Parses a hexadecimal numeric entity.
|
|
73139
|
+
*
|
|
73140
|
+
* Equivalent to the `Hexademical character reference state` in the HTML spec.
|
|
73141
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
73142
|
+
* @param offset The current offset.
|
|
73143
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
73144
|
+
*/
|
|
73145
|
+
stateNumericHex(input, offset) {
|
|
73146
|
+
while (offset < input.length) {
|
|
73147
|
+
const char = input.charCodeAt(offset);
|
|
73148
|
+
if (dist_decode_isNumber(char) || dist_decode_isHexadecimalCharacter(char)) {
|
|
73149
|
+
// Convert hex digit to value (0-15); 'a'/'A' -> 10.
|
|
73150
|
+
const digit = char <= dist_decode_CharCodes.NINE
|
|
73151
|
+
? char - dist_decode_CharCodes.ZERO
|
|
73152
|
+
: (char | dist_decode_TO_LOWER_BIT) - dist_decode_CharCodes.LOWER_A + 10;
|
|
73153
|
+
this.result = this.result * 16 + digit;
|
|
73154
|
+
this.consumed++;
|
|
73155
|
+
offset++;
|
|
73156
|
+
}
|
|
73157
|
+
else {
|
|
73158
|
+
return this.emitNumericEntity(char, 3);
|
|
73159
|
+
}
|
|
73160
|
+
}
|
|
73161
|
+
return -1; // Incomplete entity
|
|
73162
|
+
}
|
|
73163
|
+
/**
|
|
73164
|
+
* Parses a decimal numeric entity.
|
|
73165
|
+
*
|
|
73166
|
+
* Equivalent to the `Decimal character reference state` in the HTML spec.
|
|
73167
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
73168
|
+
* @param offset The current offset.
|
|
73169
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
73170
|
+
*/
|
|
73171
|
+
stateNumericDecimal(input, offset) {
|
|
73172
|
+
while (offset < input.length) {
|
|
73173
|
+
const char = input.charCodeAt(offset);
|
|
73174
|
+
if (dist_decode_isNumber(char)) {
|
|
73175
|
+
this.result = this.result * 10 + (char - dist_decode_CharCodes.ZERO);
|
|
73176
|
+
this.consumed++;
|
|
73177
|
+
offset++;
|
|
73178
|
+
}
|
|
73179
|
+
else {
|
|
73180
|
+
return this.emitNumericEntity(char, 2);
|
|
73181
|
+
}
|
|
73182
|
+
}
|
|
73183
|
+
return -1; // Incomplete entity
|
|
73184
|
+
}
|
|
73185
|
+
/**
|
|
73186
|
+
* Validate and emit a numeric entity.
|
|
73187
|
+
*
|
|
73188
|
+
* Implements the logic from the `Hexademical character reference start
|
|
73189
|
+
* state` and `Numeric character reference end state` in the HTML spec.
|
|
73190
|
+
* @param lastCp The last code point of the entity. Used to see if the
|
|
73191
|
+
* entity was terminated with a semicolon.
|
|
73192
|
+
* @param expectedLength The minimum number of characters that should be
|
|
73193
|
+
* consumed. Used to validate that at least one digit
|
|
73194
|
+
* was consumed.
|
|
73195
|
+
* @returns The number of characters that were consumed.
|
|
73196
|
+
*/
|
|
73197
|
+
emitNumericEntity(lastCp, expectedLength) {
|
|
73198
|
+
// Ensure we consumed at least one digit.
|
|
73199
|
+
if (this.consumed <= expectedLength) {
|
|
73200
|
+
this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
|
73201
|
+
return 0;
|
|
73202
|
+
}
|
|
73203
|
+
// Figure out if this is a legit end of the entity
|
|
73204
|
+
if (lastCp === dist_decode_CharCodes.SEMI) {
|
|
73205
|
+
this.consumed += 1;
|
|
73206
|
+
}
|
|
73207
|
+
else if (this.decodeMode === dist_decode_DecodingMode.Strict) {
|
|
73208
|
+
return 0;
|
|
73209
|
+
}
|
|
73210
|
+
this.emitCodePoint(dist_decode_codepoint_replaceCodePoint(this.result), this.consumed);
|
|
73211
|
+
if (this.errors) {
|
|
73212
|
+
if (lastCp !== dist_decode_CharCodes.SEMI) {
|
|
73213
|
+
this.errors.missingSemicolonAfterCharacterReference();
|
|
73214
|
+
}
|
|
73215
|
+
this.errors.validateNumericCharacterReference(this.result);
|
|
73216
|
+
}
|
|
73217
|
+
return this.consumed;
|
|
73218
|
+
}
|
|
73219
|
+
/**
|
|
73220
|
+
* Parses a named entity.
|
|
73221
|
+
*
|
|
73222
|
+
* Equivalent to the `Named character reference state` in the HTML spec.
|
|
73223
|
+
* @param input The string containing the entity (or a continuation of the entity).
|
|
73224
|
+
* @param offset The current offset.
|
|
73225
|
+
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
|
73226
|
+
*/
|
|
73227
|
+
stateNamedEntity(input, offset) {
|
|
73228
|
+
const { decodeTree } = this;
|
|
73229
|
+
let current = decodeTree[this.treeIndex];
|
|
73230
|
+
// The length is the number of bytes of the value, including the current byte.
|
|
73231
|
+
let valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
73232
|
+
while (offset < input.length) {
|
|
73233
|
+
// Handle compact runs (possibly inline): valueLength == 0 and SEMI_REQUIRED bit set.
|
|
73234
|
+
if (valueLength === 0 && (current & bin_trie_flags_BinTrieFlags.FLAG13) !== 0) {
|
|
73235
|
+
const runLength = (current & bin_trie_flags_BinTrieFlags.BRANCH_LENGTH) >> 7; /* 2..63 */
|
|
73236
|
+
// If we are starting a run, check the first char.
|
|
73237
|
+
if (this.runConsumed === 0) {
|
|
73238
|
+
const firstChar = current & bin_trie_flags_BinTrieFlags.JUMP_TABLE;
|
|
73239
|
+
if (input.charCodeAt(offset) !== firstChar) {
|
|
73240
|
+
return this.result === 0
|
|
73241
|
+
? 0
|
|
73242
|
+
: this.emitNotTerminatedNamedEntity();
|
|
73243
|
+
}
|
|
73244
|
+
offset++;
|
|
73245
|
+
this.excess++;
|
|
73246
|
+
this.runConsumed++;
|
|
73247
|
+
}
|
|
73248
|
+
// Check remaining characters in the run.
|
|
73249
|
+
while (this.runConsumed < runLength) {
|
|
73250
|
+
if (offset >= input.length) {
|
|
73251
|
+
return -1;
|
|
73252
|
+
}
|
|
73253
|
+
const charIndexInPacked = this.runConsumed - 1;
|
|
73254
|
+
const packedWord = decodeTree[this.treeIndex + 1 + (charIndexInPacked >> 1)];
|
|
73255
|
+
const expectedChar = charIndexInPacked % 2 === 0
|
|
73256
|
+
? packedWord & 0xff
|
|
73257
|
+
: (packedWord >> 8) & 0xff;
|
|
73258
|
+
if (input.charCodeAt(offset) !== expectedChar) {
|
|
73259
|
+
this.runConsumed = 0;
|
|
73260
|
+
return this.result === 0
|
|
73261
|
+
? 0
|
|
73262
|
+
: this.emitNotTerminatedNamedEntity();
|
|
73263
|
+
}
|
|
73264
|
+
offset++;
|
|
73265
|
+
this.excess++;
|
|
73266
|
+
this.runConsumed++;
|
|
73267
|
+
}
|
|
73268
|
+
this.runConsumed = 0;
|
|
73269
|
+
this.treeIndex += 1 + (runLength >> 1);
|
|
73270
|
+
current = decodeTree[this.treeIndex];
|
|
73271
|
+
valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
73272
|
+
}
|
|
73273
|
+
if (offset >= input.length)
|
|
73274
|
+
break;
|
|
73275
|
+
const char = input.charCodeAt(offset);
|
|
73276
|
+
/*
|
|
73277
|
+
* Implicit semicolon handling for nodes that require a semicolon but
|
|
73278
|
+
* don't have an explicit ';' branch stored in the trie. If we have
|
|
73279
|
+
* a value on the current node, it requires a semicolon, and the
|
|
73280
|
+
* current input character is a semicolon, emit the entity using the
|
|
73281
|
+
* current node (without descending further).
|
|
73282
|
+
*/
|
|
73283
|
+
if (char === dist_decode_CharCodes.SEMI &&
|
|
73284
|
+
valueLength !== 0 &&
|
|
73285
|
+
(current & bin_trie_flags_BinTrieFlags.FLAG13) !== 0) {
|
|
73286
|
+
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
|
73287
|
+
}
|
|
73288
|
+
this.treeIndex = dist_decode_determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
|
|
73289
|
+
if (this.treeIndex < 0) {
|
|
73290
|
+
return this.result === 0 ||
|
|
73291
|
+
// If we are parsing an attribute
|
|
73292
|
+
(this.decodeMode === dist_decode_DecodingMode.Attribute &&
|
|
73293
|
+
// We shouldn't have consumed any characters after the entity,
|
|
73294
|
+
(valueLength === 0 ||
|
|
73295
|
+
// And there should be no invalid characters.
|
|
73296
|
+
dist_decode_isEntityInAttributeInvalidEnd(char)))
|
|
73297
|
+
? 0
|
|
73298
|
+
: this.emitNotTerminatedNamedEntity();
|
|
73299
|
+
}
|
|
73300
|
+
current = decodeTree[this.treeIndex];
|
|
73301
|
+
valueLength = (current & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
73302
|
+
// If the branch is a value, store it and continue
|
|
73303
|
+
if (valueLength !== 0) {
|
|
73304
|
+
// If the entity is terminated by a semicolon, we are done.
|
|
73305
|
+
if (char === dist_decode_CharCodes.SEMI) {
|
|
73306
|
+
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
|
73307
|
+
}
|
|
73308
|
+
// If we encounter a non-terminated (legacy) entity while parsing strictly, then ignore it.
|
|
73309
|
+
if (this.decodeMode !== dist_decode_DecodingMode.Strict &&
|
|
73310
|
+
(current & bin_trie_flags_BinTrieFlags.FLAG13) === 0) {
|
|
73311
|
+
this.result = this.treeIndex;
|
|
73312
|
+
this.consumed += this.excess;
|
|
73313
|
+
this.excess = 0;
|
|
73314
|
+
}
|
|
73315
|
+
}
|
|
73316
|
+
// Increment offset & excess for next iteration
|
|
73317
|
+
offset++;
|
|
73318
|
+
this.excess++;
|
|
73319
|
+
}
|
|
73320
|
+
return -1;
|
|
73321
|
+
}
|
|
73322
|
+
/**
|
|
73323
|
+
* Emit a named entity that was not terminated with a semicolon.
|
|
73324
|
+
* @returns The number of characters consumed.
|
|
73325
|
+
*/
|
|
73326
|
+
emitNotTerminatedNamedEntity() {
|
|
73327
|
+
const { result, decodeTree } = this;
|
|
73328
|
+
const valueLength = (decodeTree[result] & bin_trie_flags_BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
73329
|
+
this.emitNamedEntityData(result, valueLength, this.consumed);
|
|
73330
|
+
this.errors?.missingSemicolonAfterCharacterReference();
|
|
73331
|
+
return this.consumed;
|
|
73332
|
+
}
|
|
73333
|
+
/**
|
|
73334
|
+
* Emit a named entity.
|
|
73335
|
+
* @param result The index of the entity in the decode tree.
|
|
73336
|
+
* @param valueLength The number of bytes in the entity.
|
|
73337
|
+
* @param consumed The number of characters consumed.
|
|
73338
|
+
* @returns The number of characters consumed.
|
|
73339
|
+
*/
|
|
73340
|
+
emitNamedEntityData(result, valueLength, consumed) {
|
|
73341
|
+
const { decodeTree } = this;
|
|
73342
|
+
this.emitCodePoint(valueLength === 1
|
|
73343
|
+
? decodeTree[result] &
|
|
73344
|
+
~(bin_trie_flags_BinTrieFlags.VALUE_LENGTH | bin_trie_flags_BinTrieFlags.FLAG13)
|
|
73345
|
+
: decodeTree[result + 1], consumed);
|
|
73346
|
+
if (valueLength === 3) {
|
|
73347
|
+
// For multi-byte values, we need to emit the second byte.
|
|
73348
|
+
this.emitCodePoint(decodeTree[result + 2], consumed);
|
|
73349
|
+
}
|
|
73350
|
+
return consumed;
|
|
73351
|
+
}
|
|
73352
|
+
/**
|
|
73353
|
+
* Signal to the parser that the end of the input was reached.
|
|
73354
|
+
*
|
|
73355
|
+
* Remaining data will be emitted and relevant errors will be produced.
|
|
73356
|
+
* @returns The number of characters consumed.
|
|
73357
|
+
*/
|
|
73358
|
+
end() {
|
|
73359
|
+
switch (this.state) {
|
|
73360
|
+
case dist_decode_EntityDecoderState.NamedEntity: {
|
|
73361
|
+
// Emit a named entity if we have one.
|
|
73362
|
+
return this.result !== 0 &&
|
|
73363
|
+
(this.decodeMode !== dist_decode_DecodingMode.Attribute ||
|
|
73364
|
+
this.result === this.treeIndex)
|
|
73365
|
+
? this.emitNotTerminatedNamedEntity()
|
|
73366
|
+
: 0;
|
|
73367
|
+
}
|
|
73368
|
+
// Otherwise, emit a numeric entity if we have one.
|
|
73369
|
+
case dist_decode_EntityDecoderState.NumericDecimal: {
|
|
73370
|
+
return this.emitNumericEntity(0, 2);
|
|
73371
|
+
}
|
|
73372
|
+
case dist_decode_EntityDecoderState.NumericHex: {
|
|
73373
|
+
return this.emitNumericEntity(0, 3);
|
|
73374
|
+
}
|
|
73375
|
+
case dist_decode_EntityDecoderState.NumericStart: {
|
|
73376
|
+
this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
|
73377
|
+
return 0;
|
|
73378
|
+
}
|
|
73379
|
+
case dist_decode_EntityDecoderState.EntityStart: {
|
|
73380
|
+
// Return 0 if we have no entity.
|
|
73381
|
+
return 0;
|
|
73382
|
+
}
|
|
73383
|
+
}
|
|
73384
|
+
}
|
|
73385
|
+
}
|
|
73386
|
+
/**
|
|
73387
|
+
* Creates a function that decodes entities in a string.
|
|
73388
|
+
* @param decodeTree The decode tree.
|
|
73389
|
+
* @returns A function that decodes entities in a string.
|
|
73390
|
+
*/
|
|
73391
|
+
function dist_decode_getDecoder(decodeTree) {
|
|
73392
|
+
let returnValue = "";
|
|
73393
|
+
const decoder = new dist_decode_EntityDecoder(decodeTree, (data) => (returnValue += String.fromCodePoint(data)));
|
|
73394
|
+
return function decodeWithTrie(input, decodeMode) {
|
|
73395
|
+
let lastIndex = 0;
|
|
73396
|
+
let offset = 0;
|
|
73397
|
+
while ((offset = input.indexOf("&", offset)) >= 0) {
|
|
73398
|
+
returnValue += input.slice(lastIndex, offset);
|
|
73399
|
+
decoder.startEntity(decodeMode);
|
|
73400
|
+
const length = decoder.write(input,
|
|
73401
|
+
// Skip the "&"
|
|
73402
|
+
offset + 1);
|
|
73403
|
+
if (length < 0) {
|
|
73404
|
+
lastIndex = offset + decoder.end();
|
|
73405
|
+
break;
|
|
73406
|
+
}
|
|
73407
|
+
lastIndex = offset + length;
|
|
73408
|
+
// If `length` is 0, skip the current `&` and continue.
|
|
73409
|
+
offset = length === 0 ? lastIndex + 1 : lastIndex;
|
|
73410
|
+
}
|
|
73411
|
+
const result = returnValue + input.slice(lastIndex);
|
|
73412
|
+
// Make sure we don't keep a reference to the final string.
|
|
73413
|
+
returnValue = "";
|
|
73414
|
+
return result;
|
|
73415
|
+
};
|
|
73416
|
+
}
|
|
73417
|
+
/**
|
|
73418
|
+
* Determines the branch of the current node that is taken given the current
|
|
73419
|
+
* character. This function is used to traverse the trie.
|
|
73420
|
+
* @param decodeTree The trie.
|
|
73421
|
+
* @param current The current node.
|
|
73422
|
+
* @param nodeIndex Index immediately after the current node header.
|
|
73423
|
+
* @param char The current character.
|
|
73424
|
+
* @returns The index of the next node, or -1 if no branch is taken.
|
|
73425
|
+
*/
|
|
73426
|
+
function dist_decode_determineBranch(decodeTree, current, nodeIndex, char) {
|
|
73427
|
+
const branchCount = (current & bin_trie_flags_BinTrieFlags.BRANCH_LENGTH) >> 7;
|
|
73428
|
+
const jumpOffset = current & bin_trie_flags_BinTrieFlags.JUMP_TABLE;
|
|
73429
|
+
// Case 1: Single branch encoded in jump offset
|
|
73430
|
+
if (branchCount === 0) {
|
|
73431
|
+
return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;
|
|
73432
|
+
}
|
|
73433
|
+
// Case 2: Multiple branches encoded in jump table
|
|
73434
|
+
if (jumpOffset) {
|
|
73435
|
+
const value = char - jumpOffset;
|
|
73436
|
+
return value < 0 || value >= branchCount
|
|
73437
|
+
? -1
|
|
73438
|
+
: decodeTree[nodeIndex + value] - 1;
|
|
73439
|
+
}
|
|
73440
|
+
// Case 3: Multiple branches encoded in packed dictionary (two keys per uint16)
|
|
73441
|
+
const packedKeySlots = (branchCount + 1) >> 1;
|
|
73442
|
+
/*
|
|
73443
|
+
* Treat packed keys as a virtual sorted array of length `branchCount`.
|
|
73444
|
+
* Key(i) = low byte for even i, high byte for odd i in slot i>>1.
|
|
73445
|
+
*/
|
|
73446
|
+
let lo = 0;
|
|
73447
|
+
let hi = branchCount - 1;
|
|
73448
|
+
while (lo <= hi) {
|
|
73449
|
+
const mid = (lo + hi) >>> 1;
|
|
73450
|
+
const slot = mid >> 1;
|
|
73451
|
+
const packed = decodeTree[nodeIndex + slot];
|
|
73452
|
+
const midKey = (packed >> ((mid & 1) * 8)) & 0xff;
|
|
73453
|
+
if (midKey < char) {
|
|
73454
|
+
lo = mid + 1;
|
|
73455
|
+
}
|
|
73456
|
+
else if (midKey > char) {
|
|
73457
|
+
hi = mid - 1;
|
|
73458
|
+
}
|
|
73459
|
+
else {
|
|
73460
|
+
return decodeTree[nodeIndex + packedKeySlots + mid];
|
|
73461
|
+
}
|
|
73462
|
+
}
|
|
73463
|
+
return -1;
|
|
73464
|
+
}
|
|
73465
|
+
const dist_decode_htmlDecoder = /* #__PURE__ */ (/* unused pure expression or super */ null && (dist_decode_getDecoder(htmlDecodeTree)));
|
|
73466
|
+
const dist_decode_xmlDecoder = /* #__PURE__ */ (/* unused pure expression or super */ null && (dist_decode_getDecoder(xmlDecodeTree)));
|
|
73467
|
+
/**
|
|
73468
|
+
* Decodes an HTML string.
|
|
73469
|
+
* @param htmlString The string to decode.
|
|
73470
|
+
* @param mode The decoding mode.
|
|
73471
|
+
* @returns The decoded string.
|
|
73472
|
+
*/
|
|
73473
|
+
function dist_decode_decodeHTML(htmlString, mode = dist_decode_DecodingMode.Legacy) {
|
|
73474
|
+
return dist_decode_htmlDecoder(htmlString, mode);
|
|
73475
|
+
}
|
|
73476
|
+
/**
|
|
73477
|
+
* Decodes an HTML string in an attribute.
|
|
73478
|
+
* @param htmlAttribute The string to decode.
|
|
73479
|
+
* @returns The decoded string.
|
|
73480
|
+
*/
|
|
73481
|
+
function dist_decode_decodeHTMLAttribute(htmlAttribute) {
|
|
73482
|
+
return dist_decode_htmlDecoder(htmlAttribute, dist_decode_DecodingMode.Attribute);
|
|
73483
|
+
}
|
|
73484
|
+
/**
|
|
73485
|
+
* Decodes an HTML string, requiring all entities to be terminated by a semicolon.
|
|
73486
|
+
* @param htmlString The string to decode.
|
|
73487
|
+
* @returns The decoded string.
|
|
73488
|
+
*/
|
|
73489
|
+
function dist_decode_decodeHTMLStrict(htmlString) {
|
|
73490
|
+
return dist_decode_htmlDecoder(htmlString, dist_decode_DecodingMode.Strict);
|
|
73491
|
+
}
|
|
73492
|
+
/**
|
|
73493
|
+
* Decodes an XML string, requiring all entities to be terminated by a semicolon.
|
|
73494
|
+
* @param xmlString The string to decode.
|
|
73495
|
+
* @returns The decoded string.
|
|
73496
|
+
*/
|
|
73497
|
+
function dist_decode_decodeXML(xmlString) {
|
|
73498
|
+
return dist_decode_xmlDecoder(xmlString, dist_decode_DecodingMode.Strict);
|
|
73499
|
+
}
|
|
73500
|
+
|
|
73501
|
+
// Re-export for use by eg. htmlparser2
|
|
73502
|
+
|
|
73503
|
+
|
|
73504
|
+
//# sourceMappingURL=decode.js.map
|
|
73505
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/internal/decode-shared.js
|
|
73506
|
+
/**
|
|
73507
|
+
* Shared base64 decode helper for generated decode data.
|
|
73508
|
+
* Assumes global atob is available.
|
|
73509
|
+
* @param input Input string to encode or decode.
|
|
73510
|
+
*/
|
|
73511
|
+
function decodeBase64(input) {
|
|
73512
|
+
const binary = atob(input);
|
|
73513
|
+
const evenLength = binary.length & ~1; // Round down to even length
|
|
73514
|
+
const out = new Uint16Array(evenLength / 2);
|
|
73515
|
+
for (let index = 0, outIndex = 0; index < evenLength; index += 2) {
|
|
73516
|
+
const lo = binary.charCodeAt(index);
|
|
73517
|
+
const hi = binary.charCodeAt(index + 1);
|
|
73518
|
+
out[outIndex++] = lo | (hi << 8);
|
|
73519
|
+
}
|
|
73520
|
+
return out;
|
|
73521
|
+
}
|
|
73522
|
+
//# sourceMappingURL=decode-shared.js.map
|
|
73523
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/generated/decode-data-xml.js
|
|
73524
|
+
// Generated using scripts/write-decode-map.ts
|
|
73525
|
+
|
|
73526
|
+
/** Packed XML decode trie data. */
|
|
73527
|
+
const generated_decode_data_xml_xmlDecodeTree = /* #__PURE__ */ decodeBase64("AAJhZ2xxBwARABMAFQBtAg0AAAAAAA8AcAAmYG8AcwAnYHQAPmB0ADxg9SFvdCJg");
|
|
73528
|
+
//# sourceMappingURL=decode-data-xml.js.map
|
|
73529
|
+
;// ./node_modules/htmlparser2/node_modules/entities/dist/generated/decode-data-html.js
|
|
73530
|
+
// Generated using scripts/write-decode-map.ts
|
|
73531
|
+
|
|
73532
|
+
/** Packed HTML decode trie data. */
|
|
73533
|
+
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");
|
|
73534
|
+
//# sourceMappingURL=decode-data-html.js.map
|
|
73535
|
+
;// ./node_modules/htmlparser2/dist/Tokenizer.js
|
|
73536
|
+
|
|
73537
|
+
var Tokenizer_CharCodes;
|
|
73538
|
+
(function (CharCodes) {
|
|
73539
|
+
CharCodes[CharCodes["Tab"] = 9] = "Tab";
|
|
73540
|
+
CharCodes[CharCodes["NewLine"] = 10] = "NewLine";
|
|
73541
|
+
CharCodes[CharCodes["FormFeed"] = 12] = "FormFeed";
|
|
73542
|
+
CharCodes[CharCodes["CarriageReturn"] = 13] = "CarriageReturn";
|
|
73543
|
+
CharCodes[CharCodes["Space"] = 32] = "Space";
|
|
73544
|
+
CharCodes[CharCodes["ExclamationMark"] = 33] = "ExclamationMark";
|
|
73545
|
+
CharCodes[CharCodes["Number"] = 35] = "Number";
|
|
73546
|
+
CharCodes[CharCodes["Amp"] = 38] = "Amp";
|
|
73547
|
+
CharCodes[CharCodes["SingleQuote"] = 39] = "SingleQuote";
|
|
73548
|
+
CharCodes[CharCodes["DoubleQuote"] = 34] = "DoubleQuote";
|
|
73549
|
+
CharCodes[CharCodes["Dash"] = 45] = "Dash";
|
|
73550
|
+
CharCodes[CharCodes["Slash"] = 47] = "Slash";
|
|
73551
|
+
CharCodes[CharCodes["Zero"] = 48] = "Zero";
|
|
73552
|
+
CharCodes[CharCodes["Nine"] = 57] = "Nine";
|
|
73553
|
+
CharCodes[CharCodes["Semi"] = 59] = "Semi";
|
|
73554
|
+
CharCodes[CharCodes["Lt"] = 60] = "Lt";
|
|
73555
|
+
CharCodes[CharCodes["Eq"] = 61] = "Eq";
|
|
73556
|
+
CharCodes[CharCodes["Gt"] = 62] = "Gt";
|
|
73557
|
+
CharCodes[CharCodes["Questionmark"] = 63] = "Questionmark";
|
|
73558
|
+
CharCodes[CharCodes["UpperA"] = 65] = "UpperA";
|
|
73559
|
+
CharCodes[CharCodes["LowerA"] = 97] = "LowerA";
|
|
73560
|
+
CharCodes[CharCodes["UpperF"] = 70] = "UpperF";
|
|
73561
|
+
CharCodes[CharCodes["LowerF"] = 102] = "LowerF";
|
|
73562
|
+
CharCodes[CharCodes["UpperZ"] = 90] = "UpperZ";
|
|
73563
|
+
CharCodes[CharCodes["LowerZ"] = 122] = "LowerZ";
|
|
73564
|
+
CharCodes[CharCodes["LowerX"] = 120] = "LowerX";
|
|
73565
|
+
CharCodes[CharCodes["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
|
|
73566
|
+
})(Tokenizer_CharCodes || (Tokenizer_CharCodes = {}));
|
|
73567
|
+
/** All the states the tokenizer can be in. */
|
|
73568
|
+
var Tokenizer_State;
|
|
73569
|
+
(function (State) {
|
|
73570
|
+
State[State["Text"] = 1] = "Text";
|
|
73571
|
+
State[State["BeforeTagName"] = 2] = "BeforeTagName";
|
|
73572
|
+
State[State["InTagName"] = 3] = "InTagName";
|
|
73573
|
+
State[State["InSelfClosingTag"] = 4] = "InSelfClosingTag";
|
|
73574
|
+
State[State["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
|
|
73575
|
+
State[State["InClosingTagName"] = 6] = "InClosingTagName";
|
|
73576
|
+
State[State["AfterClosingTagName"] = 7] = "AfterClosingTagName";
|
|
73577
|
+
// Attributes
|
|
73578
|
+
State[State["BeforeAttributeName"] = 8] = "BeforeAttributeName";
|
|
73579
|
+
State[State["InAttributeName"] = 9] = "InAttributeName";
|
|
73580
|
+
State[State["AfterAttributeName"] = 10] = "AfterAttributeName";
|
|
73581
|
+
State[State["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
|
|
73582
|
+
State[State["InAttributeValueDq"] = 12] = "InAttributeValueDq";
|
|
73583
|
+
State[State["InAttributeValueSq"] = 13] = "InAttributeValueSq";
|
|
73584
|
+
State[State["InAttributeValueNq"] = 14] = "InAttributeValueNq";
|
|
73585
|
+
// Declarations
|
|
73586
|
+
State[State["BeforeDeclaration"] = 15] = "BeforeDeclaration";
|
|
73587
|
+
State[State["InDeclaration"] = 16] = "InDeclaration";
|
|
73588
|
+
// Processing instructions
|
|
73589
|
+
State[State["InProcessingInstruction"] = 17] = "InProcessingInstruction";
|
|
73590
|
+
// Comments & CDATA
|
|
73591
|
+
State[State["BeforeComment"] = 18] = "BeforeComment";
|
|
73592
|
+
State[State["CDATASequence"] = 19] = "CDATASequence";
|
|
73593
|
+
State[State["DeclarationSequence"] = 20] = "DeclarationSequence";
|
|
73594
|
+
State[State["InSpecialComment"] = 21] = "InSpecialComment";
|
|
73595
|
+
State[State["InCommentLike"] = 22] = "InCommentLike";
|
|
73596
|
+
// Special tags
|
|
73597
|
+
State[State["SpecialStartSequence"] = 23] = "SpecialStartSequence";
|
|
73598
|
+
State[State["InSpecialTag"] = 24] = "InSpecialTag";
|
|
73599
|
+
State[State["InPlainText"] = 25] = "InPlainText";
|
|
73600
|
+
State[State["InEntity"] = 26] = "InEntity";
|
|
73601
|
+
})(Tokenizer_State || (Tokenizer_State = {}));
|
|
73602
|
+
function Tokenizer_isWhitespace(c) {
|
|
73603
|
+
return (c === Tokenizer_CharCodes.Space ||
|
|
73604
|
+
c === Tokenizer_CharCodes.NewLine ||
|
|
73605
|
+
c === Tokenizer_CharCodes.Tab ||
|
|
73606
|
+
c === Tokenizer_CharCodes.FormFeed ||
|
|
73607
|
+
c === Tokenizer_CharCodes.CarriageReturn);
|
|
73608
|
+
}
|
|
73609
|
+
function isEndOfTagSection(c) {
|
|
73610
|
+
return c === Tokenizer_CharCodes.Slash || c === Tokenizer_CharCodes.Gt || Tokenizer_isWhitespace(c);
|
|
73611
|
+
}
|
|
73612
|
+
function isASCIIAlpha(c) {
|
|
73613
|
+
return ((c >= Tokenizer_CharCodes.LowerA && c <= Tokenizer_CharCodes.LowerZ) ||
|
|
73614
|
+
(c >= Tokenizer_CharCodes.UpperA && c <= Tokenizer_CharCodes.UpperZ));
|
|
73615
|
+
}
|
|
73616
|
+
/**
|
|
73617
|
+
* Quote style used for parsed attributes.
|
|
73618
|
+
*/
|
|
73619
|
+
var QuoteType;
|
|
73620
|
+
(function (QuoteType) {
|
|
73621
|
+
QuoteType[QuoteType["NoValue"] = 0] = "NoValue";
|
|
73622
|
+
QuoteType[QuoteType["Unquoted"] = 1] = "Unquoted";
|
|
73623
|
+
QuoteType[QuoteType["Single"] = 2] = "Single";
|
|
73624
|
+
QuoteType[QuoteType["Double"] = 3] = "Double";
|
|
73625
|
+
})(QuoteType || (QuoteType = {}));
|
|
73626
|
+
/**
|
|
73627
|
+
* Sequences used to match longer strings.
|
|
73628
|
+
*
|
|
73629
|
+
* We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End
|
|
73630
|
+
* sequences with an increased offset.
|
|
73631
|
+
*/
|
|
73632
|
+
const Sequences = {
|
|
73633
|
+
Empty: new Uint8Array(0),
|
|
73634
|
+
Cdata: new Uint8Array([0x43, 0x44, 0x41, 0x54, 0x41, 0x5b]), // CDATA[
|
|
73635
|
+
CdataEnd: new Uint8Array([0x5d, 0x5d, 0x3e]), // ]]>
|
|
73636
|
+
CommentEnd: new Uint8Array([0x2d, 0x2d, 0x21, 0x3e]), // `--!>`
|
|
73637
|
+
Doctype: new Uint8Array([0x64, 0x6f, 0x63, 0x74, 0x79, 0x70, 0x65]), // `doctype`
|
|
73638
|
+
IframeEnd: new Uint8Array([0x3c, 0x2f, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65]), // `</iframe`
|
|
73639
|
+
NoembedEnd: new Uint8Array([
|
|
73640
|
+
0x3c, 0x2f, 0x6e, 0x6f, 0x65, 0x6d, 0x62, 0x65, 0x64,
|
|
73641
|
+
]), // `</noembed`
|
|
73642
|
+
NoframesEnd: new Uint8Array([
|
|
73643
|
+
0x3c, 0x2f, 0x6e, 0x6f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73,
|
|
73644
|
+
]), // `</noframes`
|
|
73645
|
+
Plaintext: new Uint8Array([
|
|
73646
|
+
0x3c, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74,
|
|
73647
|
+
]), // `</plaintext`
|
|
73648
|
+
ScriptEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74]), // `</script`
|
|
73649
|
+
StyleEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65]), // `</style`
|
|
73650
|
+
TitleEnd: new Uint8Array([0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65]), // `</title`
|
|
73651
|
+
TextareaEnd: new Uint8Array([
|
|
73652
|
+
0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61,
|
|
73653
|
+
]), // `</textarea`
|
|
73654
|
+
XmpEnd: new Uint8Array([0x3c, 0x2f, 0x78, 0x6d, 0x70]), // `</xmp`
|
|
73655
|
+
};
|
|
73656
|
+
/**
|
|
73657
|
+
* Maps the first lowercase character of an HTML tag name to the sequence
|
|
73658
|
+
* used for special-tag detection. All sequences share a common layout
|
|
73659
|
+
* where index 2 is the first tag-name character, so matching always
|
|
73660
|
+
* continues from offset 3.
|
|
73661
|
+
*/
|
|
73662
|
+
const specialStartSequences = new Map([
|
|
73663
|
+
[Sequences.IframeEnd[2], Sequences.IframeEnd],
|
|
73664
|
+
[Sequences.NoembedEnd[2], Sequences.NoembedEnd],
|
|
73665
|
+
[Sequences.Plaintext[2], Sequences.Plaintext],
|
|
73666
|
+
[Sequences.ScriptEnd[2], Sequences.ScriptEnd],
|
|
73667
|
+
[Sequences.TitleEnd[2], Sequences.TitleEnd],
|
|
73668
|
+
[Sequences.XmpEnd[2], Sequences.XmpEnd],
|
|
73669
|
+
]);
|
|
73670
|
+
/**
|
|
73671
|
+
* Tokenizer implementation used by `Parser`.
|
|
73672
|
+
*/
|
|
73673
|
+
class Tokenizer_Tokenizer {
|
|
73674
|
+
cbs;
|
|
73675
|
+
/** The current state the tokenizer is in. */
|
|
73676
|
+
state = Tokenizer_State.Text;
|
|
73677
|
+
/** The read buffer. */
|
|
73678
|
+
buffer = "";
|
|
73679
|
+
/** The beginning of the section that is currently being read. */
|
|
73680
|
+
sectionStart = 0;
|
|
73681
|
+
/** The index within the buffer that we are currently looking at. */
|
|
73682
|
+
index = 0;
|
|
73683
|
+
/** The start of the last entity. */
|
|
73684
|
+
entityStart = 0;
|
|
73685
|
+
/** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
|
|
73686
|
+
baseState = Tokenizer_State.Text;
|
|
73687
|
+
/** For special parsing behavior inside of script and style tags. */
|
|
73688
|
+
isSpecial = false;
|
|
73689
|
+
/** Indicates whether the tokenizer has been paused. */
|
|
73690
|
+
running = true;
|
|
73691
|
+
/** The offset of the current buffer. */
|
|
73692
|
+
offset = 0;
|
|
73693
|
+
xmlMode;
|
|
73694
|
+
decodeEntities;
|
|
73695
|
+
recognizeSelfClosing;
|
|
73696
|
+
entityDecoder;
|
|
73697
|
+
constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode, }, cbs) {
|
|
73698
|
+
this.cbs = cbs;
|
|
73699
|
+
this.xmlMode = xmlMode;
|
|
73700
|
+
this.decodeEntities = decodeEntities;
|
|
73701
|
+
this.recognizeSelfClosing = recognizeSelfClosing;
|
|
73702
|
+
this.entityDecoder = new dist_decode_EntityDecoder(xmlMode ? generated_decode_data_xml_xmlDecodeTree : generated_decode_data_html_htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
|
|
73703
|
+
}
|
|
73704
|
+
reset() {
|
|
73705
|
+
this.state = Tokenizer_State.Text;
|
|
73706
|
+
this.buffer = "";
|
|
73707
|
+
this.sectionStart = 0;
|
|
73708
|
+
this.index = 0;
|
|
73709
|
+
this.baseState = Tokenizer_State.Text;
|
|
73710
|
+
this.isSpecial = false;
|
|
73711
|
+
this.currentSequence = Sequences.Empty;
|
|
73712
|
+
this.sequenceIndex = 0;
|
|
73713
|
+
this.running = true;
|
|
73714
|
+
this.offset = 0;
|
|
73715
|
+
}
|
|
73716
|
+
write(chunk) {
|
|
73717
|
+
this.offset += this.buffer.length;
|
|
73718
|
+
this.buffer = chunk;
|
|
73719
|
+
this.parse();
|
|
73720
|
+
}
|
|
73721
|
+
end() {
|
|
73722
|
+
if (this.running)
|
|
73723
|
+
this.finish();
|
|
73724
|
+
}
|
|
73725
|
+
pause() {
|
|
73726
|
+
this.running = false;
|
|
73727
|
+
}
|
|
73728
|
+
resume() {
|
|
73729
|
+
this.running = true;
|
|
73730
|
+
if (this.index < this.buffer.length + this.offset) {
|
|
73731
|
+
this.parse();
|
|
73732
|
+
}
|
|
73733
|
+
}
|
|
73734
|
+
stateText(c) {
|
|
73735
|
+
if (c === Tokenizer_CharCodes.Lt ||
|
|
73736
|
+
(!this.decodeEntities && this.fastForwardTo(Tokenizer_CharCodes.Lt))) {
|
|
73737
|
+
if (this.index > this.sectionStart) {
|
|
73738
|
+
this.cbs.ontext(this.sectionStart, this.index);
|
|
73739
|
+
}
|
|
73740
|
+
this.state = Tokenizer_State.BeforeTagName;
|
|
73741
|
+
this.sectionStart = this.index;
|
|
73742
|
+
}
|
|
73743
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
73744
|
+
this.startEntity();
|
|
73745
|
+
}
|
|
73746
|
+
}
|
|
73747
|
+
currentSequence = Sequences.Empty;
|
|
73748
|
+
sequenceIndex = 0;
|
|
73749
|
+
enterTagBody() {
|
|
73750
|
+
if (this.currentSequence === Sequences.Plaintext) {
|
|
73751
|
+
this.currentSequence = Sequences.Empty;
|
|
73752
|
+
this.state = Tokenizer_State.InPlainText;
|
|
73753
|
+
}
|
|
73754
|
+
else if (this.isSpecial) {
|
|
73755
|
+
this.state = Tokenizer_State.InSpecialTag;
|
|
73756
|
+
this.sequenceIndex = 0;
|
|
73757
|
+
}
|
|
73758
|
+
else {
|
|
73759
|
+
this.state = Tokenizer_State.Text;
|
|
73760
|
+
}
|
|
73761
|
+
}
|
|
73762
|
+
/**
|
|
73763
|
+
* Match the opening tag name against an HTML text-only tag sequence.
|
|
73764
|
+
*
|
|
73765
|
+
* Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,
|
|
73766
|
+
* `noembed`/`noframes`), so we may switch to an alternate sequence at the
|
|
73767
|
+
* first distinguishing byte. On a successful full match we fall back to
|
|
73768
|
+
* the normal tag-name state; a later `>` will enter raw-text, RCDATA, or
|
|
73769
|
+
* plaintext mode based on `currentSequence` / `isSpecial`.
|
|
73770
|
+
* @param c Current character code point.
|
|
73771
|
+
*/
|
|
73772
|
+
stateSpecialStartSequence(c) {
|
|
73773
|
+
const lower = c | 0x20;
|
|
73774
|
+
// Still matching — check for an alternate sequence at branch points.
|
|
73775
|
+
if (this.sequenceIndex < this.currentSequence.length) {
|
|
73776
|
+
if (lower === this.currentSequence[this.sequenceIndex]) {
|
|
73777
|
+
this.sequenceIndex++;
|
|
73778
|
+
return;
|
|
73779
|
+
}
|
|
73780
|
+
if (this.sequenceIndex === 3) {
|
|
73781
|
+
if (this.currentSequence === Sequences.ScriptEnd &&
|
|
73782
|
+
lower === Sequences.StyleEnd[3]) {
|
|
73783
|
+
this.currentSequence = Sequences.StyleEnd;
|
|
73784
|
+
this.sequenceIndex = 4;
|
|
73785
|
+
return;
|
|
73786
|
+
}
|
|
73787
|
+
if (this.currentSequence === Sequences.TitleEnd &&
|
|
73788
|
+
lower === Sequences.TextareaEnd[3]) {
|
|
73789
|
+
this.currentSequence = Sequences.TextareaEnd;
|
|
73790
|
+
this.sequenceIndex = 4;
|
|
73791
|
+
return;
|
|
73792
|
+
}
|
|
73793
|
+
}
|
|
73794
|
+
else if (this.sequenceIndex === 4 &&
|
|
73795
|
+
this.currentSequence === Sequences.NoembedEnd &&
|
|
73796
|
+
lower === Sequences.NoframesEnd[4]) {
|
|
73797
|
+
this.currentSequence = Sequences.NoframesEnd;
|
|
73798
|
+
this.sequenceIndex = 5;
|
|
73799
|
+
return;
|
|
73800
|
+
}
|
|
73801
|
+
}
|
|
73802
|
+
else if (isEndOfTagSection(c)) {
|
|
73803
|
+
// Full match on a valid tag boundary — keep the sequence.
|
|
73804
|
+
this.sequenceIndex = 0;
|
|
73805
|
+
this.state = Tokenizer_State.InTagName;
|
|
73806
|
+
this.stateInTagName(c);
|
|
73807
|
+
return;
|
|
73808
|
+
}
|
|
73809
|
+
// No match — abandon special-tag detection.
|
|
73810
|
+
this.isSpecial = false;
|
|
73811
|
+
this.currentSequence = Sequences.Empty;
|
|
73812
|
+
this.sequenceIndex = 0;
|
|
73813
|
+
this.state = Tokenizer_State.InTagName;
|
|
73814
|
+
this.stateInTagName(c);
|
|
73815
|
+
}
|
|
73816
|
+
stateCDATASequence(c) {
|
|
73817
|
+
if (c === Sequences.Cdata[this.sequenceIndex]) {
|
|
73818
|
+
if (++this.sequenceIndex === Sequences.Cdata.length) {
|
|
73819
|
+
this.state = Tokenizer_State.InCommentLike;
|
|
73820
|
+
this.currentSequence = Sequences.CdataEnd;
|
|
73821
|
+
this.sequenceIndex = 0;
|
|
73822
|
+
this.sectionStart = this.index + 1;
|
|
73823
|
+
}
|
|
73824
|
+
}
|
|
73825
|
+
else {
|
|
73826
|
+
this.sequenceIndex = 0;
|
|
73827
|
+
if (this.xmlMode) {
|
|
73828
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
73829
|
+
this.stateInDeclaration(c); // Reconsume the character
|
|
73830
|
+
}
|
|
73831
|
+
else {
|
|
73832
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
73833
|
+
this.stateInSpecialComment(c); // Reconsume the character
|
|
73834
|
+
}
|
|
73835
|
+
}
|
|
73836
|
+
}
|
|
73837
|
+
/**
|
|
73838
|
+
* When we wait for one specific character, we can speed things up
|
|
73839
|
+
* by skipping through the buffer until we find it.
|
|
73840
|
+
* @param c Current character code point.
|
|
73841
|
+
* @returns Whether the character was found.
|
|
73842
|
+
*/
|
|
73843
|
+
fastForwardTo(c) {
|
|
73844
|
+
while (++this.index < this.buffer.length + this.offset) {
|
|
73845
|
+
if (this.buffer.charCodeAt(this.index - this.offset) === c) {
|
|
73846
|
+
return true;
|
|
73847
|
+
}
|
|
73848
|
+
}
|
|
73849
|
+
/*
|
|
73850
|
+
* We increment the index at the end of the `parse` loop,
|
|
73851
|
+
* so set it to `buffer.length - 1` here.
|
|
73852
|
+
*
|
|
73853
|
+
* TODO: Refactor `parse` to increment index before calling states.
|
|
73854
|
+
*/
|
|
73855
|
+
this.index = this.buffer.length + this.offset - 1;
|
|
73856
|
+
return false;
|
|
73857
|
+
}
|
|
73858
|
+
/**
|
|
73859
|
+
* Emit a comment token and return to the text state.
|
|
73860
|
+
* @param offset Number of characters in the end sequence that have already been matched.
|
|
73861
|
+
*/
|
|
73862
|
+
emitComment(offset) {
|
|
73863
|
+
this.cbs.oncomment(this.sectionStart, this.index, offset);
|
|
73864
|
+
this.sequenceIndex = 0;
|
|
73865
|
+
this.sectionStart = this.index + 1;
|
|
73866
|
+
this.state = Tokenizer_State.Text;
|
|
73867
|
+
}
|
|
73868
|
+
/**
|
|
73869
|
+
* Comments and CDATA end with `-->` and `]]>`.
|
|
73870
|
+
*
|
|
73871
|
+
* Their common qualities are:
|
|
73872
|
+
* - Their end sequences have a distinct character they start with.
|
|
73873
|
+
* - That character is then repeated, so we have to check multiple repeats.
|
|
73874
|
+
* - All characters but the start character of the sequence can be skipped.
|
|
73875
|
+
* @param c Current character code point.
|
|
73876
|
+
*/
|
|
73877
|
+
stateInCommentLike(c) {
|
|
73878
|
+
if (!this.xmlMode &&
|
|
73879
|
+
this.currentSequence === Sequences.CommentEnd &&
|
|
73880
|
+
this.sequenceIndex <= 1 &&
|
|
73881
|
+
/*
|
|
73882
|
+
* We're still at the very start of the comment: the only
|
|
73883
|
+
* characters consumed since `<!--` are the dashes that
|
|
73884
|
+
* advanced sequenceIndex (0 for `<!-->`, 1 for `<!--->`).
|
|
73885
|
+
*/
|
|
73886
|
+
this.index === this.sectionStart + this.sequenceIndex &&
|
|
73887
|
+
c === Tokenizer_CharCodes.Gt) {
|
|
73888
|
+
// Abruptly closed empty HTML comment.
|
|
73889
|
+
this.emitComment(this.sequenceIndex);
|
|
73890
|
+
}
|
|
73891
|
+
else if (this.currentSequence === Sequences.CommentEnd &&
|
|
73892
|
+
this.sequenceIndex === 2 &&
|
|
73893
|
+
c === Tokenizer_CharCodes.Gt) {
|
|
73894
|
+
// `!` is optional here, so the same sequence also accepts `-->`.
|
|
73895
|
+
this.emitComment(2);
|
|
73896
|
+
}
|
|
73897
|
+
else if (this.currentSequence === Sequences.CommentEnd &&
|
|
73898
|
+
this.sequenceIndex === this.currentSequence.length - 1 &&
|
|
73899
|
+
c !== Tokenizer_CharCodes.Gt) {
|
|
73900
|
+
this.sequenceIndex = Number(c === Tokenizer_CharCodes.Dash);
|
|
73901
|
+
}
|
|
73902
|
+
else if (c === this.currentSequence[this.sequenceIndex]) {
|
|
73903
|
+
if (++this.sequenceIndex === this.currentSequence.length) {
|
|
73904
|
+
if (this.currentSequence === Sequences.CdataEnd) {
|
|
73905
|
+
this.cbs.oncdata(this.sectionStart, this.index, 2);
|
|
73906
|
+
}
|
|
73907
|
+
else {
|
|
73908
|
+
this.cbs.oncomment(this.sectionStart, this.index, 3);
|
|
73909
|
+
}
|
|
73910
|
+
this.sequenceIndex = 0;
|
|
73911
|
+
this.sectionStart = this.index + 1;
|
|
73912
|
+
this.state = Tokenizer_State.Text;
|
|
73913
|
+
}
|
|
73914
|
+
}
|
|
73915
|
+
else if (this.sequenceIndex === 0) {
|
|
73916
|
+
// Fast-forward to the first character of the sequence
|
|
73917
|
+
if (this.fastForwardTo(this.currentSequence[0])) {
|
|
73918
|
+
this.sequenceIndex = 1;
|
|
73919
|
+
}
|
|
73920
|
+
}
|
|
73921
|
+
else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
|
|
73922
|
+
// Allow long sequences, eg. --->, ]]]>
|
|
73923
|
+
this.sequenceIndex = 0;
|
|
73924
|
+
}
|
|
73925
|
+
}
|
|
73926
|
+
/**
|
|
73927
|
+
* HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
|
|
73928
|
+
*
|
|
73929
|
+
* XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
|
|
73930
|
+
* We allow anything that wouldn't end the tag.
|
|
73931
|
+
* @param c Current character code point.
|
|
73932
|
+
*/
|
|
73933
|
+
isTagStartChar(c) {
|
|
73934
|
+
return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
|
|
73935
|
+
}
|
|
73936
|
+
/**
|
|
73937
|
+
* Scan raw-text / RCDATA content for the matching end tag.
|
|
73938
|
+
*
|
|
73939
|
+
* For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.
|
|
73940
|
+
* For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.
|
|
73941
|
+
* @param c Current character code point.
|
|
73942
|
+
*/
|
|
73943
|
+
stateInSpecialTag(c) {
|
|
73944
|
+
if (this.sequenceIndex === this.currentSequence.length) {
|
|
73945
|
+
if (isEndOfTagSection(c)) {
|
|
73946
|
+
const endOfText = this.index - this.currentSequence.length;
|
|
73947
|
+
if (this.sectionStart < endOfText) {
|
|
73948
|
+
// Spoof the index so that reported locations match up.
|
|
73949
|
+
const actualIndex = this.index;
|
|
73950
|
+
this.index = endOfText;
|
|
73951
|
+
this.cbs.ontext(this.sectionStart, endOfText);
|
|
73952
|
+
this.index = actualIndex;
|
|
73953
|
+
}
|
|
73954
|
+
this.isSpecial = false;
|
|
73955
|
+
this.sectionStart = endOfText + 2; // Skip over the `</`
|
|
73956
|
+
this.stateInClosingTagName(c);
|
|
73957
|
+
return; // We are done; skip the rest of the function.
|
|
73958
|
+
}
|
|
73959
|
+
this.sequenceIndex = 0;
|
|
73960
|
+
}
|
|
73961
|
+
if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {
|
|
73962
|
+
this.sequenceIndex += 1;
|
|
73963
|
+
}
|
|
73964
|
+
else if (this.sequenceIndex === 0) {
|
|
73965
|
+
if (this.currentSequence === Sequences.TitleEnd ||
|
|
73966
|
+
this.currentSequence === Sequences.TextareaEnd) {
|
|
73967
|
+
// RCDATA tags have to parse entities while still looking for their end tag.
|
|
73968
|
+
if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
73969
|
+
this.startEntity();
|
|
73970
|
+
}
|
|
73971
|
+
}
|
|
73972
|
+
else if (this.fastForwardTo(Tokenizer_CharCodes.Lt)) {
|
|
73973
|
+
// Outside of RCDATA tags, we can fast-forward.
|
|
73974
|
+
this.sequenceIndex = 1;
|
|
73975
|
+
}
|
|
73976
|
+
}
|
|
73977
|
+
else {
|
|
73978
|
+
// If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.
|
|
73979
|
+
this.sequenceIndex = Number(c === Tokenizer_CharCodes.Lt);
|
|
73980
|
+
}
|
|
73981
|
+
}
|
|
73982
|
+
stateBeforeTagName(c) {
|
|
73983
|
+
if (c === Tokenizer_CharCodes.ExclamationMark) {
|
|
73984
|
+
this.state = Tokenizer_State.BeforeDeclaration;
|
|
73985
|
+
this.sectionStart = this.index + 1;
|
|
73986
|
+
}
|
|
73987
|
+
else if (c === Tokenizer_CharCodes.Questionmark) {
|
|
73988
|
+
if (this.xmlMode) {
|
|
73989
|
+
this.state = Tokenizer_State.InProcessingInstruction;
|
|
73990
|
+
this.sequenceIndex = 0;
|
|
73991
|
+
this.sectionStart = this.index + 1;
|
|
73992
|
+
}
|
|
73993
|
+
else {
|
|
73994
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
73995
|
+
this.sectionStart = this.index;
|
|
73996
|
+
}
|
|
73997
|
+
}
|
|
73998
|
+
else if (this.isTagStartChar(c)) {
|
|
73999
|
+
this.sectionStart = this.index;
|
|
74000
|
+
const special = this.xmlMode || this.cbs.isInForeignContext?.()
|
|
74001
|
+
? undefined
|
|
74002
|
+
: specialStartSequences.get(c | 0x20);
|
|
74003
|
+
if (special === undefined) {
|
|
74004
|
+
this.state = Tokenizer_State.InTagName;
|
|
74005
|
+
}
|
|
74006
|
+
else {
|
|
74007
|
+
this.isSpecial = true;
|
|
74008
|
+
this.currentSequence = special;
|
|
74009
|
+
this.sequenceIndex = 3;
|
|
74010
|
+
this.state = Tokenizer_State.SpecialStartSequence;
|
|
74011
|
+
}
|
|
74012
|
+
}
|
|
74013
|
+
else if (c === Tokenizer_CharCodes.Slash) {
|
|
74014
|
+
this.state = Tokenizer_State.BeforeClosingTagName;
|
|
74015
|
+
}
|
|
74016
|
+
else {
|
|
74017
|
+
this.state = Tokenizer_State.Text;
|
|
74018
|
+
this.stateText(c);
|
|
74019
|
+
}
|
|
74020
|
+
}
|
|
74021
|
+
stateInTagName(c) {
|
|
74022
|
+
if (isEndOfTagSection(c)) {
|
|
74023
|
+
this.cbs.onopentagname(this.sectionStart, this.index);
|
|
74024
|
+
this.sectionStart = -1;
|
|
74025
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
74026
|
+
this.stateBeforeAttributeName(c);
|
|
74027
|
+
}
|
|
74028
|
+
}
|
|
74029
|
+
stateBeforeClosingTagName(c) {
|
|
74030
|
+
if (Tokenizer_isWhitespace(c)) {
|
|
74031
|
+
if (this.xmlMode) {
|
|
74032
|
+
// Ignore
|
|
74033
|
+
}
|
|
74034
|
+
else {
|
|
74035
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
74036
|
+
this.sectionStart = this.index;
|
|
74037
|
+
}
|
|
74038
|
+
}
|
|
74039
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
74040
|
+
this.state = Tokenizer_State.Text;
|
|
74041
|
+
if (!this.xmlMode) {
|
|
74042
|
+
this.sectionStart = this.index + 1;
|
|
74043
|
+
}
|
|
74044
|
+
}
|
|
74045
|
+
else {
|
|
74046
|
+
this.state = this.isTagStartChar(c)
|
|
74047
|
+
? Tokenizer_State.InClosingTagName
|
|
74048
|
+
: Tokenizer_State.InSpecialComment;
|
|
74049
|
+
this.sectionStart = this.index;
|
|
74050
|
+
}
|
|
74051
|
+
}
|
|
74052
|
+
stateInClosingTagName(c) {
|
|
74053
|
+
if (isEndOfTagSection(c)) {
|
|
74054
|
+
this.cbs.onclosetag(this.sectionStart, this.index);
|
|
74055
|
+
this.sectionStart = -1;
|
|
74056
|
+
this.state = Tokenizer_State.AfterClosingTagName;
|
|
74057
|
+
this.stateAfterClosingTagName(c);
|
|
74058
|
+
}
|
|
74059
|
+
}
|
|
74060
|
+
stateAfterClosingTagName(c) {
|
|
74061
|
+
// Skip everything until ">"
|
|
74062
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
74063
|
+
this.state = Tokenizer_State.Text;
|
|
74064
|
+
this.sectionStart = this.index + 1;
|
|
74065
|
+
}
|
|
74066
|
+
}
|
|
74067
|
+
stateBeforeAttributeName(c) {
|
|
74068
|
+
if (c === Tokenizer_CharCodes.Gt) {
|
|
74069
|
+
this.cbs.onopentagend(this.index);
|
|
74070
|
+
this.enterTagBody();
|
|
74071
|
+
this.sectionStart = this.index + 1;
|
|
74072
|
+
}
|
|
74073
|
+
else if (c === Tokenizer_CharCodes.Slash) {
|
|
74074
|
+
this.state = Tokenizer_State.InSelfClosingTag;
|
|
74075
|
+
}
|
|
74076
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
74077
|
+
this.state = Tokenizer_State.InAttributeName;
|
|
74078
|
+
this.sectionStart = this.index;
|
|
74079
|
+
}
|
|
74080
|
+
}
|
|
74081
|
+
/**
|
|
74082
|
+
* Handle `/` before `>` in an opening tag.
|
|
74083
|
+
*
|
|
74084
|
+
* In HTML mode, text-only tags ignore the self-closing flag and still enter
|
|
74085
|
+
* their raw-text/RCDATA/plaintext state unless self-closing tags are being
|
|
74086
|
+
* recognized. In XML mode, or for ordinary tags, the tokenizer returns to
|
|
74087
|
+
* regular text parsing after emitting the self-closing callback.
|
|
74088
|
+
* @param c Current character code point.
|
|
74089
|
+
*/
|
|
74090
|
+
stateInSelfClosingTag(c) {
|
|
74091
|
+
if (c === Tokenizer_CharCodes.Gt) {
|
|
74092
|
+
this.cbs.onselfclosingtag(this.index);
|
|
74093
|
+
this.sectionStart = this.index + 1;
|
|
74094
|
+
if (!this.recognizeSelfClosing) {
|
|
74095
|
+
this.enterTagBody();
|
|
74096
|
+
return;
|
|
74097
|
+
}
|
|
74098
|
+
this.state = Tokenizer_State.Text;
|
|
74099
|
+
this.isSpecial = false; // Reset special state, in case of self-closing special tags
|
|
74100
|
+
this.currentSequence = Sequences.Empty;
|
|
74101
|
+
}
|
|
74102
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
74103
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
74104
|
+
this.stateBeforeAttributeName(c);
|
|
74105
|
+
}
|
|
74106
|
+
}
|
|
74107
|
+
stateInAttributeName(c) {
|
|
74108
|
+
if (c === Tokenizer_CharCodes.Eq || isEndOfTagSection(c)) {
|
|
74109
|
+
this.cbs.onattribname(this.sectionStart, this.index);
|
|
74110
|
+
this.sectionStart = this.index;
|
|
74111
|
+
this.state = Tokenizer_State.AfterAttributeName;
|
|
74112
|
+
this.stateAfterAttributeName(c);
|
|
74113
|
+
}
|
|
74114
|
+
}
|
|
74115
|
+
stateAfterAttributeName(c) {
|
|
74116
|
+
if (c === Tokenizer_CharCodes.Eq) {
|
|
74117
|
+
this.state = Tokenizer_State.BeforeAttributeValue;
|
|
74118
|
+
}
|
|
74119
|
+
else if (c === Tokenizer_CharCodes.Slash || c === Tokenizer_CharCodes.Gt) {
|
|
74120
|
+
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
|
74121
|
+
this.sectionStart = -1;
|
|
74122
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
74123
|
+
this.stateBeforeAttributeName(c);
|
|
74124
|
+
}
|
|
74125
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
74126
|
+
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
|
74127
|
+
this.state = Tokenizer_State.InAttributeName;
|
|
74128
|
+
this.sectionStart = this.index;
|
|
74129
|
+
}
|
|
74130
|
+
}
|
|
74131
|
+
stateBeforeAttributeValue(c) {
|
|
74132
|
+
if (c === Tokenizer_CharCodes.DoubleQuote) {
|
|
74133
|
+
this.state = Tokenizer_State.InAttributeValueDq;
|
|
74134
|
+
this.sectionStart = this.index + 1;
|
|
74135
|
+
}
|
|
74136
|
+
else if (c === Tokenizer_CharCodes.SingleQuote) {
|
|
74137
|
+
this.state = Tokenizer_State.InAttributeValueSq;
|
|
74138
|
+
this.sectionStart = this.index + 1;
|
|
74139
|
+
}
|
|
74140
|
+
else if (!Tokenizer_isWhitespace(c)) {
|
|
74141
|
+
this.sectionStart = this.index;
|
|
74142
|
+
this.state = Tokenizer_State.InAttributeValueNq;
|
|
74143
|
+
this.stateInAttributeValueNoQuotes(c); // Reconsume token
|
|
74144
|
+
}
|
|
74145
|
+
}
|
|
74146
|
+
handleInAttributeValue(c, quote) {
|
|
74147
|
+
if (c === quote ||
|
|
74148
|
+
(!this.decodeEntities && this.fastForwardTo(quote))) {
|
|
74149
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
74150
|
+
this.sectionStart = -1;
|
|
74151
|
+
this.cbs.onattribend(quote === Tokenizer_CharCodes.DoubleQuote
|
|
74152
|
+
? QuoteType.Double
|
|
74153
|
+
: QuoteType.Single, this.index + 1);
|
|
74154
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
74155
|
+
}
|
|
74156
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
74157
|
+
this.startEntity();
|
|
74158
|
+
}
|
|
74159
|
+
}
|
|
74160
|
+
stateInAttributeValueDoubleQuotes(c) {
|
|
74161
|
+
this.handleInAttributeValue(c, Tokenizer_CharCodes.DoubleQuote);
|
|
74162
|
+
}
|
|
74163
|
+
stateInAttributeValueSingleQuotes(c) {
|
|
74164
|
+
this.handleInAttributeValue(c, Tokenizer_CharCodes.SingleQuote);
|
|
74165
|
+
}
|
|
74166
|
+
stateInAttributeValueNoQuotes(c) {
|
|
74167
|
+
if (Tokenizer_isWhitespace(c) || c === Tokenizer_CharCodes.Gt) {
|
|
74168
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
74169
|
+
this.sectionStart = -1;
|
|
74170
|
+
this.cbs.onattribend(QuoteType.Unquoted, this.index);
|
|
74171
|
+
this.state = Tokenizer_State.BeforeAttributeName;
|
|
74172
|
+
this.stateBeforeAttributeName(c);
|
|
74173
|
+
}
|
|
74174
|
+
else if (this.decodeEntities && c === Tokenizer_CharCodes.Amp) {
|
|
74175
|
+
this.startEntity();
|
|
74176
|
+
}
|
|
74177
|
+
}
|
|
74178
|
+
/**
|
|
74179
|
+
* Distinguish between CDATA, declarations, HTML comments, and HTML bogus
|
|
74180
|
+
* comments after `<!`.
|
|
74181
|
+
*
|
|
74182
|
+
* In HTML mode, only real comments and doctypes stay on declaration paths;
|
|
74183
|
+
* everything else becomes a bogus comment terminated by the next `>`.
|
|
74184
|
+
* @param c Current character code point.
|
|
74185
|
+
*/
|
|
74186
|
+
stateBeforeDeclaration(c) {
|
|
74187
|
+
if (c === Tokenizer_CharCodes.OpeningSquareBracket) {
|
|
74188
|
+
this.state = Tokenizer_State.CDATASequence;
|
|
74189
|
+
this.sequenceIndex = 0;
|
|
74190
|
+
}
|
|
74191
|
+
else if (this.xmlMode) {
|
|
74192
|
+
this.state =
|
|
74193
|
+
c === Tokenizer_CharCodes.Dash
|
|
74194
|
+
? Tokenizer_State.BeforeComment
|
|
74195
|
+
: Tokenizer_State.InDeclaration;
|
|
74196
|
+
}
|
|
74197
|
+
else if ((c | 0x20) === Sequences.Doctype[0]) {
|
|
74198
|
+
this.state = Tokenizer_State.DeclarationSequence;
|
|
74199
|
+
this.currentSequence = Sequences.Doctype;
|
|
74200
|
+
this.sequenceIndex = 1;
|
|
74201
|
+
}
|
|
74202
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
74203
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
74204
|
+
this.state = Tokenizer_State.Text;
|
|
74205
|
+
this.sectionStart = this.index + 1;
|
|
74206
|
+
}
|
|
74207
|
+
else if (c === Tokenizer_CharCodes.Dash) {
|
|
74208
|
+
this.state = Tokenizer_State.BeforeComment;
|
|
74209
|
+
}
|
|
74210
|
+
else {
|
|
74211
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
74212
|
+
}
|
|
74213
|
+
}
|
|
74214
|
+
/**
|
|
74215
|
+
* Continue matching `doctype` after `<!d`.
|
|
74216
|
+
*
|
|
74217
|
+
* A full `doctype` match stays on the declaration path; any other name falls
|
|
74218
|
+
* back to an HTML bogus comment, which matches browser behavior for
|
|
74219
|
+
* non-doctype `<!...>` constructs.
|
|
74220
|
+
* @param c Current character code point.
|
|
74221
|
+
*/
|
|
74222
|
+
stateDeclarationSequence(c) {
|
|
74223
|
+
if (this.sequenceIndex === this.currentSequence.length) {
|
|
74224
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
74225
|
+
this.stateInDeclaration(c);
|
|
74226
|
+
}
|
|
74227
|
+
else if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {
|
|
74228
|
+
this.sequenceIndex += 1;
|
|
74229
|
+
}
|
|
74230
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
74231
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
74232
|
+
this.state = Tokenizer_State.Text;
|
|
74233
|
+
this.sectionStart = this.index + 1;
|
|
74234
|
+
}
|
|
74235
|
+
else {
|
|
74236
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
74237
|
+
}
|
|
74238
|
+
}
|
|
74239
|
+
stateInDeclaration(c) {
|
|
74240
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
74241
|
+
this.cbs.ondeclaration(this.sectionStart, this.index);
|
|
74242
|
+
this.state = Tokenizer_State.Text;
|
|
74243
|
+
this.sectionStart = this.index + 1;
|
|
74244
|
+
}
|
|
74245
|
+
}
|
|
74246
|
+
/**
|
|
74247
|
+
* XML processing instructions (`<?...?>`).
|
|
74248
|
+
*
|
|
74249
|
+
* In HTML mode `<?` is routed to `InSpecialComment` instead, so this
|
|
74250
|
+
* state is only reachable in XML mode.
|
|
74251
|
+
* @param c Current character code point.
|
|
74252
|
+
*/
|
|
74253
|
+
stateInProcessingInstruction(c) {
|
|
74254
|
+
if (c === Tokenizer_CharCodes.Questionmark) {
|
|
74255
|
+
// Remember that we just consumed `?`, so the next `>` closes the PI.
|
|
74256
|
+
this.sequenceIndex = 1;
|
|
74257
|
+
}
|
|
74258
|
+
else if (c === Tokenizer_CharCodes.Gt && this.sequenceIndex === 1) {
|
|
74259
|
+
this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);
|
|
74260
|
+
this.sequenceIndex = 0;
|
|
74261
|
+
this.state = Tokenizer_State.Text;
|
|
74262
|
+
this.sectionStart = this.index + 1;
|
|
74263
|
+
}
|
|
74264
|
+
else {
|
|
74265
|
+
// Keep scanning for the next `?`, which can start a closing `?>`.
|
|
74266
|
+
this.sequenceIndex = Number(this.fastForwardTo(Tokenizer_CharCodes.Questionmark));
|
|
74267
|
+
}
|
|
74268
|
+
}
|
|
74269
|
+
stateBeforeComment(c) {
|
|
74270
|
+
if (c === Tokenizer_CharCodes.Dash) {
|
|
74271
|
+
this.state = Tokenizer_State.InCommentLike;
|
|
74272
|
+
this.currentSequence = Sequences.CommentEnd;
|
|
74273
|
+
this.sequenceIndex = 0;
|
|
74274
|
+
this.sectionStart = this.index + 1;
|
|
74275
|
+
}
|
|
74276
|
+
else if (this.xmlMode) {
|
|
74277
|
+
this.state = Tokenizer_State.InDeclaration;
|
|
74278
|
+
}
|
|
74279
|
+
else if (c === Tokenizer_CharCodes.Gt) {
|
|
74280
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
74281
|
+
this.state = Tokenizer_State.Text;
|
|
74282
|
+
this.sectionStart = this.index + 1;
|
|
74283
|
+
}
|
|
74284
|
+
else {
|
|
74285
|
+
this.state = Tokenizer_State.InSpecialComment;
|
|
74286
|
+
}
|
|
74287
|
+
}
|
|
74288
|
+
stateInSpecialComment(c) {
|
|
74289
|
+
if (c === Tokenizer_CharCodes.Gt || this.fastForwardTo(Tokenizer_CharCodes.Gt)) {
|
|
74290
|
+
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
|
74291
|
+
this.state = Tokenizer_State.Text;
|
|
74292
|
+
this.sectionStart = this.index + 1;
|
|
74293
|
+
}
|
|
74294
|
+
}
|
|
74295
|
+
startEntity() {
|
|
74296
|
+
this.baseState = this.state;
|
|
74297
|
+
this.state = Tokenizer_State.InEntity;
|
|
74298
|
+
this.entityStart = this.index;
|
|
74299
|
+
this.entityDecoder.startEntity(this.xmlMode
|
|
74300
|
+
? dist_decode_DecodingMode.Strict
|
|
74301
|
+
: this.baseState === Tokenizer_State.Text ||
|
|
74302
|
+
this.baseState === Tokenizer_State.InSpecialTag
|
|
74303
|
+
? dist_decode_DecodingMode.Legacy
|
|
74304
|
+
: dist_decode_DecodingMode.Attribute);
|
|
74305
|
+
}
|
|
74306
|
+
stateInEntity() {
|
|
74307
|
+
const indexInBuffer = this.index - this.offset;
|
|
74308
|
+
const length = this.entityDecoder.write(this.buffer, indexInBuffer);
|
|
74309
|
+
// If `length` is positive, we are done with the entity.
|
|
74310
|
+
if (length >= 0) {
|
|
74311
|
+
this.state = this.baseState;
|
|
74312
|
+
if (length === 0) {
|
|
74313
|
+
this.index -= 1;
|
|
74314
|
+
}
|
|
74315
|
+
}
|
|
74316
|
+
else {
|
|
74317
|
+
if (indexInBuffer < this.buffer.length &&
|
|
74318
|
+
this.buffer.charCodeAt(indexInBuffer) === Tokenizer_CharCodes.Amp) {
|
|
74319
|
+
this.state = this.baseState;
|
|
74320
|
+
this.index -= 1;
|
|
74321
|
+
return;
|
|
74322
|
+
}
|
|
74323
|
+
// Mark buffer as consumed.
|
|
74324
|
+
this.index = this.offset + this.buffer.length - 1;
|
|
74325
|
+
}
|
|
74326
|
+
}
|
|
74327
|
+
/**
|
|
74328
|
+
* Remove data that has already been consumed from the buffer.
|
|
74329
|
+
*/
|
|
74330
|
+
cleanup() {
|
|
74331
|
+
// If we are inside of text or attributes, emit what we already have.
|
|
74332
|
+
if (this.running && this.sectionStart !== this.index) {
|
|
74333
|
+
if (this.state === Tokenizer_State.Text ||
|
|
74334
|
+
this.state === Tokenizer_State.InPlainText ||
|
|
74335
|
+
(this.state === Tokenizer_State.InSpecialTag && this.sequenceIndex === 0)) {
|
|
74336
|
+
this.cbs.ontext(this.sectionStart, this.index);
|
|
74337
|
+
this.sectionStart = this.index;
|
|
74338
|
+
}
|
|
74339
|
+
else if (this.state === Tokenizer_State.InAttributeValueDq ||
|
|
74340
|
+
this.state === Tokenizer_State.InAttributeValueSq ||
|
|
74341
|
+
this.state === Tokenizer_State.InAttributeValueNq) {
|
|
74342
|
+
this.cbs.onattribdata(this.sectionStart, this.index);
|
|
74343
|
+
this.sectionStart = this.index;
|
|
74344
|
+
}
|
|
74345
|
+
}
|
|
74346
|
+
}
|
|
74347
|
+
shouldContinue() {
|
|
74348
|
+
return this.index < this.buffer.length + this.offset && this.running;
|
|
74349
|
+
}
|
|
74350
|
+
/**
|
|
74351
|
+
* Iterates through the buffer, calling the function corresponding to the current state.
|
|
74352
|
+
*
|
|
74353
|
+
* States that are more likely to be hit are higher up, as a performance improvement.
|
|
74354
|
+
*/
|
|
74355
|
+
parse() {
|
|
74356
|
+
while (this.shouldContinue()) {
|
|
74357
|
+
const c = this.buffer.charCodeAt(this.index - this.offset);
|
|
74358
|
+
switch (this.state) {
|
|
74359
|
+
case Tokenizer_State.Text: {
|
|
74360
|
+
this.stateText(c);
|
|
74361
|
+
break;
|
|
74362
|
+
}
|
|
74363
|
+
case Tokenizer_State.InPlainText: {
|
|
74364
|
+
// Skip to end of buffer; cleanup() emits the text.
|
|
74365
|
+
this.index = this.buffer.length + this.offset - 1;
|
|
74366
|
+
break;
|
|
74367
|
+
}
|
|
74368
|
+
case Tokenizer_State.SpecialStartSequence: {
|
|
74369
|
+
this.stateSpecialStartSequence(c);
|
|
74370
|
+
break;
|
|
74371
|
+
}
|
|
74372
|
+
case Tokenizer_State.InSpecialTag: {
|
|
74373
|
+
this.stateInSpecialTag(c);
|
|
74374
|
+
break;
|
|
74375
|
+
}
|
|
74376
|
+
case Tokenizer_State.CDATASequence: {
|
|
74377
|
+
this.stateCDATASequence(c);
|
|
74378
|
+
break;
|
|
74379
|
+
}
|
|
74380
|
+
case Tokenizer_State.DeclarationSequence: {
|
|
74381
|
+
this.stateDeclarationSequence(c);
|
|
74382
|
+
break;
|
|
74383
|
+
}
|
|
74384
|
+
case Tokenizer_State.InAttributeValueDq: {
|
|
74385
|
+
this.stateInAttributeValueDoubleQuotes(c);
|
|
74386
|
+
break;
|
|
74387
|
+
}
|
|
74388
|
+
case Tokenizer_State.InAttributeName: {
|
|
74389
|
+
this.stateInAttributeName(c);
|
|
74390
|
+
break;
|
|
74391
|
+
}
|
|
74392
|
+
case Tokenizer_State.InCommentLike: {
|
|
74393
|
+
this.stateInCommentLike(c);
|
|
74394
|
+
break;
|
|
74395
|
+
}
|
|
74396
|
+
case Tokenizer_State.InSpecialComment: {
|
|
74397
|
+
this.stateInSpecialComment(c);
|
|
74398
|
+
break;
|
|
74399
|
+
}
|
|
74400
|
+
case Tokenizer_State.BeforeAttributeName: {
|
|
74401
|
+
this.stateBeforeAttributeName(c);
|
|
74402
|
+
break;
|
|
74403
|
+
}
|
|
74404
|
+
case Tokenizer_State.InTagName: {
|
|
74405
|
+
this.stateInTagName(c);
|
|
74406
|
+
break;
|
|
74407
|
+
}
|
|
74408
|
+
case Tokenizer_State.InClosingTagName: {
|
|
74409
|
+
this.stateInClosingTagName(c);
|
|
74410
|
+
break;
|
|
74411
|
+
}
|
|
74412
|
+
case Tokenizer_State.BeforeTagName: {
|
|
74413
|
+
this.stateBeforeTagName(c);
|
|
74414
|
+
break;
|
|
74415
|
+
}
|
|
74416
|
+
case Tokenizer_State.AfterAttributeName: {
|
|
74417
|
+
this.stateAfterAttributeName(c);
|
|
74418
|
+
break;
|
|
74419
|
+
}
|
|
74420
|
+
case Tokenizer_State.InAttributeValueSq: {
|
|
74421
|
+
this.stateInAttributeValueSingleQuotes(c);
|
|
74422
|
+
break;
|
|
74423
|
+
}
|
|
74424
|
+
case Tokenizer_State.BeforeAttributeValue: {
|
|
74425
|
+
this.stateBeforeAttributeValue(c);
|
|
74426
|
+
break;
|
|
74427
|
+
}
|
|
74428
|
+
case Tokenizer_State.BeforeClosingTagName: {
|
|
74429
|
+
this.stateBeforeClosingTagName(c);
|
|
74430
|
+
break;
|
|
74431
|
+
}
|
|
74432
|
+
case Tokenizer_State.AfterClosingTagName: {
|
|
74433
|
+
this.stateAfterClosingTagName(c);
|
|
74434
|
+
break;
|
|
74435
|
+
}
|
|
74436
|
+
case Tokenizer_State.InAttributeValueNq: {
|
|
74437
|
+
this.stateInAttributeValueNoQuotes(c);
|
|
74438
|
+
break;
|
|
74439
|
+
}
|
|
74440
|
+
case Tokenizer_State.InSelfClosingTag: {
|
|
74441
|
+
this.stateInSelfClosingTag(c);
|
|
74442
|
+
break;
|
|
74443
|
+
}
|
|
74444
|
+
case Tokenizer_State.InDeclaration: {
|
|
74445
|
+
this.stateInDeclaration(c);
|
|
74446
|
+
break;
|
|
74447
|
+
}
|
|
74448
|
+
case Tokenizer_State.BeforeDeclaration: {
|
|
74449
|
+
this.stateBeforeDeclaration(c);
|
|
74450
|
+
break;
|
|
74451
|
+
}
|
|
74452
|
+
case Tokenizer_State.BeforeComment: {
|
|
74453
|
+
this.stateBeforeComment(c);
|
|
74454
|
+
break;
|
|
74455
|
+
}
|
|
74456
|
+
case Tokenizer_State.InProcessingInstruction: {
|
|
74457
|
+
this.stateInProcessingInstruction(c);
|
|
74458
|
+
break;
|
|
74459
|
+
}
|
|
74460
|
+
case Tokenizer_State.InEntity: {
|
|
74461
|
+
this.stateInEntity();
|
|
74462
|
+
break;
|
|
74463
|
+
}
|
|
74464
|
+
}
|
|
74465
|
+
this.index++;
|
|
74466
|
+
}
|
|
74467
|
+
this.cleanup();
|
|
74468
|
+
}
|
|
74469
|
+
finish() {
|
|
74470
|
+
if (this.state === Tokenizer_State.InEntity) {
|
|
74471
|
+
this.entityDecoder.end();
|
|
74472
|
+
this.state = this.baseState;
|
|
74473
|
+
}
|
|
74474
|
+
this.handleTrailingData();
|
|
74475
|
+
this.cbs.onend();
|
|
74476
|
+
}
|
|
74477
|
+
handleTrailingCommentLikeData(endIndex) {
|
|
74478
|
+
if (this.state !== Tokenizer_State.InCommentLike) {
|
|
74479
|
+
return false;
|
|
74480
|
+
}
|
|
74481
|
+
if (this.currentSequence === Sequences.CdataEnd) {
|
|
74482
|
+
if (this.xmlMode) {
|
|
74483
|
+
if (this.sectionStart < endIndex) {
|
|
74484
|
+
this.cbs.oncdata(this.sectionStart, endIndex, 0);
|
|
74485
|
+
}
|
|
74486
|
+
}
|
|
74487
|
+
else {
|
|
74488
|
+
/* In HTML mode, unclosed CDATA is a bogus comment. */
|
|
74489
|
+
const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;
|
|
74490
|
+
this.cbs.oncomment(cdataStart, endIndex, 0);
|
|
74491
|
+
}
|
|
74492
|
+
}
|
|
74493
|
+
else {
|
|
74494
|
+
const offset = this.xmlMode
|
|
74495
|
+
? 0
|
|
74496
|
+
: Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);
|
|
74497
|
+
this.cbs.oncomment(this.sectionStart, endIndex, offset);
|
|
74498
|
+
}
|
|
74499
|
+
return true;
|
|
74500
|
+
}
|
|
74501
|
+
handleTrailingMarkupDeclaration(endIndex) {
|
|
74502
|
+
if (this.xmlMode) {
|
|
74503
|
+
switch (this.state) {
|
|
74504
|
+
case Tokenizer_State.InSpecialComment:
|
|
74505
|
+
case Tokenizer_State.BeforeComment:
|
|
74506
|
+
case Tokenizer_State.CDATASequence:
|
|
74507
|
+
case Tokenizer_State.DeclarationSequence:
|
|
74508
|
+
case Tokenizer_State.InDeclaration: {
|
|
74509
|
+
this.cbs.ontext(this.sectionStart, endIndex);
|
|
74510
|
+
return true;
|
|
74511
|
+
}
|
|
74512
|
+
default: {
|
|
74513
|
+
return false;
|
|
74514
|
+
}
|
|
74515
|
+
}
|
|
74516
|
+
}
|
|
74517
|
+
switch (this.state) {
|
|
74518
|
+
case Tokenizer_State.BeforeDeclaration:
|
|
74519
|
+
case Tokenizer_State.InSpecialComment:
|
|
74520
|
+
case Tokenizer_State.BeforeComment:
|
|
74521
|
+
case Tokenizer_State.CDATASequence: {
|
|
74522
|
+
this.cbs.oncomment(this.sectionStart, endIndex, 0);
|
|
74523
|
+
return true;
|
|
74524
|
+
}
|
|
74525
|
+
case Tokenizer_State.DeclarationSequence: {
|
|
74526
|
+
if (this.sequenceIndex !== Sequences.Doctype.length) {
|
|
74527
|
+
this.cbs.oncomment(this.sectionStart, endIndex, 0);
|
|
74528
|
+
}
|
|
74529
|
+
return true;
|
|
74530
|
+
}
|
|
74531
|
+
case Tokenizer_State.InDeclaration: {
|
|
74532
|
+
return true;
|
|
74533
|
+
}
|
|
74534
|
+
default: {
|
|
74535
|
+
return false;
|
|
74536
|
+
}
|
|
74537
|
+
}
|
|
74538
|
+
}
|
|
74539
|
+
/** Handle any trailing data. */
|
|
74540
|
+
handleTrailingData() {
|
|
74541
|
+
const endIndex = this.buffer.length + this.offset;
|
|
74542
|
+
if (this.handleTrailingCommentLikeData(endIndex) ||
|
|
74543
|
+
this.handleTrailingMarkupDeclaration(endIndex)) {
|
|
74544
|
+
return;
|
|
74545
|
+
}
|
|
74546
|
+
// If there is no remaining data, we are done.
|
|
74547
|
+
if (this.sectionStart >= endIndex) {
|
|
74548
|
+
return;
|
|
74549
|
+
}
|
|
74550
|
+
switch (this.state) {
|
|
74551
|
+
case Tokenizer_State.InTagName:
|
|
74552
|
+
case Tokenizer_State.BeforeAttributeName:
|
|
74553
|
+
case Tokenizer_State.BeforeAttributeValue:
|
|
74554
|
+
case Tokenizer_State.AfterAttributeName:
|
|
74555
|
+
case Tokenizer_State.InAttributeName:
|
|
74556
|
+
case Tokenizer_State.InAttributeValueSq:
|
|
74557
|
+
case Tokenizer_State.InAttributeValueDq:
|
|
74558
|
+
case Tokenizer_State.InAttributeValueNq:
|
|
74559
|
+
case Tokenizer_State.InClosingTagName: {
|
|
74560
|
+
/*
|
|
74561
|
+
* If we are currently in an opening or closing tag, us not calling the
|
|
74562
|
+
* respective callback signals that the tag should be ignored.
|
|
74563
|
+
*/
|
|
74564
|
+
break;
|
|
74565
|
+
}
|
|
74566
|
+
default: {
|
|
74567
|
+
this.cbs.ontext(this.sectionStart, endIndex);
|
|
74568
|
+
}
|
|
74569
|
+
}
|
|
74570
|
+
}
|
|
74571
|
+
emitCodePoint(cp, consumed) {
|
|
74572
|
+
if (this.baseState !== Tokenizer_State.Text &&
|
|
74573
|
+
this.baseState !== Tokenizer_State.InSpecialTag) {
|
|
74574
|
+
if (this.sectionStart < this.entityStart) {
|
|
74575
|
+
this.cbs.onattribdata(this.sectionStart, this.entityStart);
|
|
74576
|
+
}
|
|
74577
|
+
this.sectionStart = this.entityStart + consumed;
|
|
74578
|
+
this.index = this.sectionStart - 1;
|
|
74579
|
+
this.cbs.onattribentity(cp);
|
|
74580
|
+
}
|
|
74581
|
+
else {
|
|
74582
|
+
if (this.sectionStart < this.entityStart) {
|
|
74583
|
+
this.cbs.ontext(this.sectionStart, this.entityStart);
|
|
74584
|
+
}
|
|
74585
|
+
this.sectionStart = this.entityStart + consumed;
|
|
74586
|
+
this.index = this.sectionStart - 1;
|
|
74587
|
+
this.cbs.ontextentity(cp, this.sectionStart);
|
|
74588
|
+
}
|
|
74589
|
+
}
|
|
74590
|
+
}
|
|
74591
|
+
//# sourceMappingURL=Tokenizer.js.map
|
|
74592
|
+
;// ./node_modules/htmlparser2/dist/Parser.js
|
|
74593
|
+
const { fromCodePoint: Parser_fromCodePoint } = String;
|
|
74594
|
+
|
|
74595
|
+
const formTags = new Set([
|
|
74596
|
+
"input",
|
|
74597
|
+
"option",
|
|
74598
|
+
"optgroup",
|
|
74599
|
+
"select",
|
|
74600
|
+
"button",
|
|
74601
|
+
"datalist",
|
|
74602
|
+
"textarea",
|
|
74603
|
+
]);
|
|
74604
|
+
const pTag = new Set(["p"]);
|
|
74605
|
+
const headingTags = new Set(["h1", "h2", "h3", "h4", "h5", "h6", "p"]);
|
|
74606
|
+
const tableSectionTags = new Set(["thead", "tbody"]);
|
|
74607
|
+
const ddtTags = new Set(["dd", "dt"]);
|
|
74608
|
+
const rtpTags = new Set(["rt", "rp"]);
|
|
74609
|
+
const openImpliesClose = new Map([
|
|
74610
|
+
["tr", new Set(["tr", "th", "td"])],
|
|
74611
|
+
["th", new Set(["th"])],
|
|
74612
|
+
["td", new Set(["thead", "th", "td"])],
|
|
74613
|
+
["body", new Set(["head", "link", "script"])],
|
|
74614
|
+
["a", new Set(["a"])],
|
|
74615
|
+
["li", new Set(["li"])],
|
|
74616
|
+
["p", pTag],
|
|
74617
|
+
["h1", headingTags],
|
|
74618
|
+
["h2", headingTags],
|
|
74619
|
+
["h3", headingTags],
|
|
74620
|
+
["h4", headingTags],
|
|
74621
|
+
["h5", headingTags],
|
|
74622
|
+
["h6", headingTags],
|
|
74623
|
+
["select", formTags],
|
|
74624
|
+
["input", formTags],
|
|
74625
|
+
["output", formTags],
|
|
74626
|
+
["button", formTags],
|
|
74627
|
+
["datalist", formTags],
|
|
74628
|
+
["textarea", formTags],
|
|
74629
|
+
["option", new Set(["option"])],
|
|
74630
|
+
["optgroup", new Set(["optgroup", "option"])],
|
|
74631
|
+
["dd", ddtTags],
|
|
74632
|
+
["dt", ddtTags],
|
|
74633
|
+
["address", pTag],
|
|
74634
|
+
["article", pTag],
|
|
74635
|
+
["aside", pTag],
|
|
74636
|
+
["blockquote", pTag],
|
|
74637
|
+
["details", pTag],
|
|
74638
|
+
["div", pTag],
|
|
74639
|
+
["dl", pTag],
|
|
74640
|
+
["fieldset", pTag],
|
|
74641
|
+
["figcaption", pTag],
|
|
74642
|
+
["figure", pTag],
|
|
74643
|
+
["footer", pTag],
|
|
74644
|
+
["form", pTag],
|
|
74645
|
+
["header", pTag],
|
|
74646
|
+
["hr", pTag],
|
|
74647
|
+
["main", pTag],
|
|
74648
|
+
["nav", pTag],
|
|
74649
|
+
["ol", pTag],
|
|
74650
|
+
["pre", pTag],
|
|
74651
|
+
["section", pTag],
|
|
74652
|
+
["table", pTag],
|
|
74653
|
+
["ul", pTag],
|
|
74654
|
+
["rt", rtpTags],
|
|
74655
|
+
["rp", rtpTags],
|
|
74656
|
+
["tbody", tableSectionTags],
|
|
74657
|
+
["tfoot", tableSectionTags],
|
|
74658
|
+
]);
|
|
74659
|
+
const DOCUMENT_TYPE = "doctype";
|
|
74660
|
+
const voidElements = new Set([
|
|
74661
|
+
"area",
|
|
74662
|
+
"base",
|
|
74663
|
+
"basefont",
|
|
74664
|
+
"br",
|
|
74665
|
+
"col",
|
|
74666
|
+
"command",
|
|
74667
|
+
"embed",
|
|
74668
|
+
"frame",
|
|
74669
|
+
"hr",
|
|
74670
|
+
"img",
|
|
74671
|
+
"input",
|
|
74672
|
+
"isindex",
|
|
74673
|
+
"keygen",
|
|
74674
|
+
"link",
|
|
74675
|
+
"meta",
|
|
74676
|
+
"param",
|
|
74677
|
+
"source",
|
|
74678
|
+
"track",
|
|
74679
|
+
"wbr",
|
|
74680
|
+
]);
|
|
74681
|
+
const foreignContextElements = new Set(["math", "svg"]);
|
|
74682
|
+
/**
|
|
74683
|
+
* Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).
|
|
74684
|
+
*
|
|
74685
|
+
* Entries must use the SVG-adjusted casing (e.g. "foreignObject" not
|
|
74686
|
+
* "foreignobject") since they are compared against adjusted tag names.
|
|
74687
|
+
*/
|
|
74688
|
+
const htmlIntegrationElements = new Set([
|
|
74689
|
+
"mi",
|
|
74690
|
+
"mo",
|
|
74691
|
+
"mn",
|
|
74692
|
+
"ms",
|
|
74693
|
+
"mtext",
|
|
74694
|
+
"annotation-xml",
|
|
74695
|
+
"foreignObject",
|
|
74696
|
+
"desc",
|
|
74697
|
+
"title",
|
|
74698
|
+
]);
|
|
74699
|
+
const svgTagNameAdjustments = new Map([
|
|
74700
|
+
["altglyph", "altGlyph"],
|
|
74701
|
+
["altglyphdef", "altGlyphDef"],
|
|
74702
|
+
["altglyphitem", "altGlyphItem"],
|
|
74703
|
+
["animatecolor", "animateColor"],
|
|
74704
|
+
["animatemotion", "animateMotion"],
|
|
74705
|
+
["animatetransform", "animateTransform"],
|
|
74706
|
+
["clippath", "clipPath"],
|
|
74707
|
+
["feblend", "feBlend"],
|
|
74708
|
+
["fecolormatrix", "feColorMatrix"],
|
|
74709
|
+
["fecomponenttransfer", "feComponentTransfer"],
|
|
74710
|
+
["fecomposite", "feComposite"],
|
|
74711
|
+
["feconvolvematrix", "feConvolveMatrix"],
|
|
74712
|
+
["fediffuselighting", "feDiffuseLighting"],
|
|
74713
|
+
["fedisplacementmap", "feDisplacementMap"],
|
|
74714
|
+
["fedistantlight", "feDistantLight"],
|
|
74715
|
+
["fedropshadow", "feDropShadow"],
|
|
74716
|
+
["feflood", "feFlood"],
|
|
74717
|
+
["fefunca", "feFuncA"],
|
|
74718
|
+
["fefuncb", "feFuncB"],
|
|
74719
|
+
["fefuncg", "feFuncG"],
|
|
74720
|
+
["fefuncr", "feFuncR"],
|
|
74721
|
+
["fegaussianblur", "feGaussianBlur"],
|
|
74722
|
+
["feimage", "feImage"],
|
|
74723
|
+
["femerge", "feMerge"],
|
|
74724
|
+
["femergenode", "feMergeNode"],
|
|
74725
|
+
["femorphology", "feMorphology"],
|
|
74726
|
+
["feoffset", "feOffset"],
|
|
74727
|
+
["fepointlight", "fePointLight"],
|
|
74728
|
+
["fespecularlighting", "feSpecularLighting"],
|
|
74729
|
+
["fespotlight", "feSpotLight"],
|
|
74730
|
+
["fetile", "feTile"],
|
|
74731
|
+
["feturbulence", "feTurbulence"],
|
|
74732
|
+
["foreignobject", "foreignObject"],
|
|
74733
|
+
["glyphref", "glyphRef"],
|
|
74734
|
+
["lineargradient", "linearGradient"],
|
|
74735
|
+
["radialgradient", "radialGradient"],
|
|
74736
|
+
["textpath", "textPath"],
|
|
74737
|
+
]);
|
|
74738
|
+
var ForeignContext;
|
|
74739
|
+
(function (ForeignContext) {
|
|
74740
|
+
ForeignContext[ForeignContext["None"] = 0] = "None";
|
|
74741
|
+
ForeignContext[ForeignContext["Svg"] = 1] = "Svg";
|
|
74742
|
+
ForeignContext[ForeignContext["MathML"] = 2] = "MathML";
|
|
74743
|
+
})(ForeignContext || (ForeignContext = {}));
|
|
74744
|
+
const reNameEnd = /\s|\//;
|
|
74745
|
+
/**
|
|
74746
|
+
* Incremental parser implementation.
|
|
74747
|
+
*/
|
|
74748
|
+
class Parser_Parser {
|
|
74749
|
+
options;
|
|
74750
|
+
/** The start index of the last event. */
|
|
74751
|
+
startIndex = 0;
|
|
74752
|
+
/** The end index of the last event. */
|
|
74753
|
+
endIndex = 0;
|
|
74754
|
+
/**
|
|
74755
|
+
* Store the start index of the current open tag,
|
|
74756
|
+
* so we can update the start index for attributes.
|
|
74757
|
+
*/
|
|
74758
|
+
openTagStart = 0;
|
|
74759
|
+
tagname = "";
|
|
74760
|
+
attribname = "";
|
|
74761
|
+
attribvalue = "";
|
|
74762
|
+
attribs = null;
|
|
74763
|
+
stack = [];
|
|
74764
|
+
foreignContext;
|
|
74765
|
+
cbs;
|
|
74766
|
+
lowerCaseTagNames;
|
|
74767
|
+
lowerCaseAttributeNames;
|
|
74768
|
+
recognizeSelfClosing;
|
|
74769
|
+
/** We are parsing HTML. Inverse of the `xmlMode` option. */
|
|
74770
|
+
htmlMode;
|
|
74771
|
+
tokenizer;
|
|
74772
|
+
buffers = [];
|
|
74773
|
+
bufferOffset = 0;
|
|
74774
|
+
/** The index of the last written buffer. Used when resuming after a `pause()`. */
|
|
74775
|
+
writeIndex = 0;
|
|
74776
|
+
/** Indicates whether the parser has finished running / `.end` has been called. */
|
|
74777
|
+
ended = false;
|
|
74778
|
+
constructor(cbs, options = {}) {
|
|
74779
|
+
this.options = options;
|
|
74780
|
+
this.cbs = cbs ?? {};
|
|
74781
|
+
this.htmlMode = !this.options.xmlMode;
|
|
74782
|
+
this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;
|
|
74783
|
+
this.lowerCaseAttributeNames =
|
|
74784
|
+
options.lowerCaseAttributeNames ?? this.htmlMode;
|
|
74785
|
+
this.recognizeSelfClosing =
|
|
74786
|
+
options.recognizeSelfClosing ?? !this.htmlMode;
|
|
74787
|
+
this.tokenizer = new (options.Tokenizer ?? Tokenizer_Tokenizer)(this.options, this);
|
|
74788
|
+
this.foreignContext = [ForeignContext.None];
|
|
74789
|
+
this.cbs.onparserinit?.(this);
|
|
74790
|
+
}
|
|
74791
|
+
// Tokenizer event handlers
|
|
74792
|
+
/**
|
|
74793
|
+
* @param start Start index for the current parser event.
|
|
74794
|
+
* @param endIndex End index for the current parser event.
|
|
74795
|
+
* @internal
|
|
74796
|
+
*/
|
|
74797
|
+
ontext(start, endIndex) {
|
|
74798
|
+
const data = this.getSlice(start, endIndex);
|
|
74799
|
+
this.endIndex = endIndex - 1;
|
|
74800
|
+
this.cbs.ontext?.(data);
|
|
74801
|
+
this.startIndex = endIndex;
|
|
74802
|
+
}
|
|
74803
|
+
/**
|
|
74804
|
+
* @param cp Current Unicode code point.
|
|
74805
|
+
* @param endIndex End index for the current parser event.
|
|
74806
|
+
* @internal
|
|
74807
|
+
*/
|
|
74808
|
+
ontextentity(cp, endIndex) {
|
|
74809
|
+
this.endIndex = endIndex - 1;
|
|
74810
|
+
this.cbs.ontext?.(Parser_fromCodePoint(cp));
|
|
74811
|
+
this.startIndex = endIndex;
|
|
74812
|
+
}
|
|
74813
|
+
/** @internal */
|
|
74814
|
+
isInForeignContext() {
|
|
74815
|
+
return this.foreignContext[0] !== ForeignContext.None;
|
|
74816
|
+
}
|
|
74817
|
+
/**
|
|
74818
|
+
* Checks if the current tag is a void element. Override this if you want
|
|
74819
|
+
* to specify your own additional void elements.
|
|
74820
|
+
* @param name Name of the pseudo selector.
|
|
74821
|
+
*/
|
|
74822
|
+
isVoidElement(name) {
|
|
74823
|
+
return this.htmlMode && voidElements.has(name);
|
|
74824
|
+
}
|
|
74825
|
+
/**
|
|
74826
|
+
* Read a tag name from the buffer.
|
|
74827
|
+
*
|
|
74828
|
+
* When `lowerCaseTagNames` is enabled (the default in HTML mode), the name
|
|
74829
|
+
* is lowercased and may be adjusted for SVG casing or the `image` → `img`
|
|
74830
|
+
* alias.
|
|
74831
|
+
* @param start Start index of the tag name in the buffer.
|
|
74832
|
+
* @param endIndex End index of the tag name in the buffer.
|
|
74833
|
+
*/
|
|
74834
|
+
readTagName(start, endIndex) {
|
|
74835
|
+
const name = this.lowerCaseTagNames
|
|
74836
|
+
? this.getSlice(start, endIndex).toLowerCase()
|
|
74837
|
+
: this.getSlice(start, endIndex);
|
|
74838
|
+
if (!(this.lowerCaseTagNames && this.htmlMode)) {
|
|
74839
|
+
return name;
|
|
74840
|
+
}
|
|
74841
|
+
if (this.foreignContext[0] === ForeignContext.Svg) {
|
|
74842
|
+
return svgTagNameAdjustments.get(name) ?? name;
|
|
74843
|
+
}
|
|
74844
|
+
/*
|
|
74845
|
+
* Closing tags for SVG elements inside HTML integration points
|
|
74846
|
+
* (e.g. </foreignObject> while inside its own content) need case
|
|
74847
|
+
* adjustment so the name matches what was pushed to the stack.
|
|
74848
|
+
* `foreignContext.length > 1` means a foreign ancestor exists —
|
|
74849
|
+
* the base [None] entry plus at least one pushed context.
|
|
74850
|
+
*/
|
|
74851
|
+
if (this.foreignContext.length > 1) {
|
|
74852
|
+
const adjusted = svgTagNameAdjustments.get(name);
|
|
74853
|
+
if (adjusted !== undefined && this.stack.includes(adjusted)) {
|
|
74854
|
+
return adjusted;
|
|
74855
|
+
}
|
|
74856
|
+
}
|
|
74857
|
+
if (!this.isInForeignContext()) {
|
|
74858
|
+
return name === "image" ? "img" : name;
|
|
74859
|
+
}
|
|
74860
|
+
return name;
|
|
74861
|
+
}
|
|
74862
|
+
/**
|
|
74863
|
+
* @param start Start index for the current parser event.
|
|
74864
|
+
* @param endIndex End index for the current parser event.
|
|
74865
|
+
* @internal
|
|
74866
|
+
*/
|
|
74867
|
+
onopentagname(start, endIndex) {
|
|
74868
|
+
this.endIndex = endIndex;
|
|
74869
|
+
this.emitOpenTag(this.readTagName(start, endIndex));
|
|
74870
|
+
}
|
|
74871
|
+
emitOpenTag(name) {
|
|
74872
|
+
this.openTagStart = this.startIndex;
|
|
74873
|
+
this.tagname = name;
|
|
74874
|
+
/*
|
|
74875
|
+
* The spec ignores a second <form> when one is already open.
|
|
74876
|
+
* Setting tagname to "" suppresses all downstream effects: attribs
|
|
74877
|
+
* stays null so endOpenTag is a no-op, and closeCurrentTag can't
|
|
74878
|
+
* match "" on the stack.
|
|
74879
|
+
*/
|
|
74880
|
+
if (this.htmlMode && name === "form" && this.stack.includes("form")) {
|
|
74881
|
+
this.tagname = "";
|
|
74882
|
+
return;
|
|
74883
|
+
}
|
|
74884
|
+
const impliesClose = this.htmlMode && openImpliesClose.get(name);
|
|
74885
|
+
if (impliesClose) {
|
|
74886
|
+
while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {
|
|
74887
|
+
this.popElement(true);
|
|
74888
|
+
}
|
|
74889
|
+
}
|
|
74890
|
+
if (!this.isVoidElement(name)) {
|
|
74891
|
+
this.stack.unshift(name);
|
|
74892
|
+
if (this.htmlMode) {
|
|
74893
|
+
if (name === "svg") {
|
|
74894
|
+
this.foreignContext.unshift(ForeignContext.Svg);
|
|
74895
|
+
}
|
|
74896
|
+
else if (name === "math") {
|
|
74897
|
+
this.foreignContext.unshift(ForeignContext.MathML);
|
|
74898
|
+
}
|
|
74899
|
+
else if (htmlIntegrationElements.has(name)) {
|
|
74900
|
+
this.foreignContext.unshift(ForeignContext.None);
|
|
74901
|
+
}
|
|
74902
|
+
}
|
|
74903
|
+
}
|
|
74904
|
+
this.cbs.onopentagname?.(name);
|
|
74905
|
+
if (this.cbs.onopentag)
|
|
74906
|
+
this.attribs = {};
|
|
74907
|
+
}
|
|
74908
|
+
endOpenTag(isImplied) {
|
|
74909
|
+
this.startIndex = this.openTagStart;
|
|
74910
|
+
if (this.attribs) {
|
|
74911
|
+
this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);
|
|
74912
|
+
this.attribs = null;
|
|
74913
|
+
}
|
|
74914
|
+
if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {
|
|
74915
|
+
this.cbs.onclosetag(this.tagname, true);
|
|
74916
|
+
}
|
|
74917
|
+
this.tagname = "";
|
|
74918
|
+
}
|
|
74919
|
+
/**
|
|
74920
|
+
* @param endIndex End index for the current parser event.
|
|
74921
|
+
* @internal
|
|
74922
|
+
*/
|
|
74923
|
+
onopentagend(endIndex) {
|
|
74924
|
+
this.endIndex = endIndex;
|
|
74925
|
+
this.endOpenTag(false);
|
|
74926
|
+
// Set `startIndex` for next node
|
|
74927
|
+
this.startIndex = endIndex + 1;
|
|
74928
|
+
}
|
|
74929
|
+
/**
|
|
74930
|
+
* @param start Start index for the current parser event.
|
|
74931
|
+
* @param endIndex End index for the current parser event.
|
|
74932
|
+
* @internal
|
|
74933
|
+
*/
|
|
74934
|
+
onclosetag(start, endIndex) {
|
|
74935
|
+
this.endIndex = endIndex;
|
|
74936
|
+
const name = this.readTagName(start, endIndex);
|
|
74937
|
+
if (!this.isVoidElement(name)) {
|
|
74938
|
+
const pos = this.stack.indexOf(name);
|
|
74939
|
+
if (pos !== -1) {
|
|
74940
|
+
for (let index = 0; index < pos; index++) {
|
|
74941
|
+
this.popElement(true);
|
|
74942
|
+
}
|
|
74943
|
+
this.popElement(false);
|
|
74944
|
+
}
|
|
74945
|
+
else if (this.htmlMode && name === "p") {
|
|
74946
|
+
// Implicit open before close
|
|
74947
|
+
this.emitOpenTag("p");
|
|
74948
|
+
this.closeCurrentTag(true);
|
|
74949
|
+
}
|
|
74950
|
+
}
|
|
74951
|
+
else if (this.htmlMode && name === "br") {
|
|
74952
|
+
// We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.
|
|
74953
|
+
this.cbs.onopentagname?.("br");
|
|
74954
|
+
this.cbs.onopentag?.("br", {}, true);
|
|
74955
|
+
this.cbs.onclosetag?.("br", false);
|
|
74956
|
+
}
|
|
74957
|
+
// Set `startIndex` for next node
|
|
74958
|
+
this.startIndex = endIndex + 1;
|
|
74959
|
+
}
|
|
74960
|
+
/**
|
|
74961
|
+
* @param endIndex End index for the current parser event.
|
|
74962
|
+
* @internal
|
|
74963
|
+
*/
|
|
74964
|
+
onselfclosingtag(endIndex) {
|
|
74965
|
+
this.endIndex = endIndex;
|
|
74966
|
+
if (this.recognizeSelfClosing || this.isInForeignContext()) {
|
|
74967
|
+
this.closeCurrentTag(false);
|
|
74968
|
+
// Set `startIndex` for next node
|
|
74969
|
+
this.startIndex = endIndex + 1;
|
|
74970
|
+
}
|
|
74971
|
+
else {
|
|
74972
|
+
// Ignore the fact that the tag is self-closing.
|
|
74973
|
+
this.onopentagend(endIndex);
|
|
74974
|
+
}
|
|
74975
|
+
}
|
|
74976
|
+
/**
|
|
74977
|
+
* Pop the top element off the stack, emit a close event, and maintain
|
|
74978
|
+
* the foreign context stack.
|
|
74979
|
+
* @param implied Whether this close is implied (not from an explicit end tag).
|
|
74980
|
+
*/
|
|
74981
|
+
popElement(implied) {
|
|
74982
|
+
// biome-ignore lint/style/noNonNullAssertion: The element is guaranteed to exist.
|
|
74983
|
+
const element = this.stack.shift();
|
|
74984
|
+
if (this.htmlMode &&
|
|
74985
|
+
(foreignContextElements.has(element) ||
|
|
74986
|
+
htmlIntegrationElements.has(element))) {
|
|
74987
|
+
this.foreignContext.shift();
|
|
74988
|
+
}
|
|
74989
|
+
this.cbs.onclosetag?.(element, implied);
|
|
74990
|
+
}
|
|
74991
|
+
closeCurrentTag(isOpenImplied) {
|
|
74992
|
+
const name = this.tagname;
|
|
74993
|
+
this.endOpenTag(isOpenImplied);
|
|
74994
|
+
// Self-closing tags will be on the top of the stack
|
|
74995
|
+
if (this.stack[0] === name) {
|
|
74996
|
+
this.popElement(!isOpenImplied);
|
|
74997
|
+
}
|
|
74998
|
+
}
|
|
74999
|
+
/**
|
|
75000
|
+
* @param start Start index for the current parser event.
|
|
75001
|
+
* @param endIndex End index for the current parser event.
|
|
75002
|
+
* @internal
|
|
75003
|
+
*/
|
|
75004
|
+
onattribname(start, endIndex) {
|
|
75005
|
+
this.startIndex = start;
|
|
75006
|
+
const name = this.getSlice(start, endIndex);
|
|
75007
|
+
this.attribname = this.lowerCaseAttributeNames
|
|
75008
|
+
? name.toLowerCase()
|
|
75009
|
+
: name;
|
|
75010
|
+
}
|
|
75011
|
+
/**
|
|
75012
|
+
* @param start Start index for the current parser event.
|
|
75013
|
+
* @param endIndex End index for the current parser event.
|
|
75014
|
+
* @internal
|
|
75015
|
+
*/
|
|
75016
|
+
onattribdata(start, endIndex) {
|
|
75017
|
+
this.attribvalue += this.getSlice(start, endIndex);
|
|
75018
|
+
}
|
|
75019
|
+
/**
|
|
75020
|
+
* @param cp Current Unicode code point.
|
|
75021
|
+
* @internal
|
|
75022
|
+
*/
|
|
75023
|
+
onattribentity(cp) {
|
|
75024
|
+
this.attribvalue += Parser_fromCodePoint(cp);
|
|
75025
|
+
}
|
|
75026
|
+
/**
|
|
75027
|
+
* @param quote Quote type used for the current attribute.
|
|
75028
|
+
* @param endIndex End index for the current parser event.
|
|
75029
|
+
* @internal
|
|
75030
|
+
*/
|
|
75031
|
+
onattribend(quote, endIndex) {
|
|
75032
|
+
this.endIndex = endIndex;
|
|
75033
|
+
this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double
|
|
75034
|
+
? '"'
|
|
75035
|
+
: quote === QuoteType.Single
|
|
75036
|
+
? "'"
|
|
75037
|
+
: quote === QuoteType.NoValue
|
|
75038
|
+
? undefined
|
|
75039
|
+
: null);
|
|
75040
|
+
if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) {
|
|
75041
|
+
this.attribs[this.attribname] = this.attribvalue;
|
|
75042
|
+
}
|
|
75043
|
+
this.attribvalue = "";
|
|
75044
|
+
}
|
|
75045
|
+
getInstructionName(value) {
|
|
75046
|
+
const index = value.search(reNameEnd);
|
|
75047
|
+
let name = index < 0 ? value : value.substr(0, index);
|
|
75048
|
+
if (this.lowerCaseTagNames) {
|
|
75049
|
+
name = name.toLowerCase();
|
|
75050
|
+
}
|
|
75051
|
+
return name;
|
|
75052
|
+
}
|
|
75053
|
+
/**
|
|
75054
|
+
* @param start Start index for the current parser event.
|
|
75055
|
+
* @param endIndex End index for the current parser event.
|
|
75056
|
+
* @internal
|
|
75057
|
+
*/
|
|
75058
|
+
ondeclaration(start, endIndex) {
|
|
75059
|
+
this.endIndex = endIndex;
|
|
75060
|
+
const value = this.getSlice(start, endIndex);
|
|
75061
|
+
if (this.cbs.onprocessinginstruction) {
|
|
75062
|
+
/*
|
|
75063
|
+
* In HTML mode, ondeclaration is only reached for DOCTYPE
|
|
75064
|
+
* (the tokenizer routes everything else to bogus comments).
|
|
75065
|
+
*/
|
|
75066
|
+
const name = this.htmlMode
|
|
75067
|
+
? this.lowerCaseTagNames
|
|
75068
|
+
? DOCUMENT_TYPE
|
|
75069
|
+
: value.slice(0, DOCUMENT_TYPE.length)
|
|
75070
|
+
: this.getInstructionName(value);
|
|
75071
|
+
this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
|
|
75072
|
+
}
|
|
75073
|
+
// Set `startIndex` for next node
|
|
75074
|
+
this.startIndex = endIndex + 1;
|
|
75075
|
+
}
|
|
75076
|
+
/**
|
|
75077
|
+
* @param start Start index for the current parser event.
|
|
75078
|
+
* @param endIndex End index for the current parser event.
|
|
75079
|
+
* @internal
|
|
75080
|
+
*/
|
|
75081
|
+
onprocessinginstruction(start, endIndex) {
|
|
75082
|
+
this.endIndex = endIndex;
|
|
75083
|
+
const value = this.getSlice(start, endIndex);
|
|
75084
|
+
if (this.cbs.onprocessinginstruction) {
|
|
75085
|
+
const name = this.getInstructionName(value);
|
|
75086
|
+
this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
|
|
75087
|
+
}
|
|
75088
|
+
// Set `startIndex` for next node
|
|
75089
|
+
this.startIndex = endIndex + 1;
|
|
75090
|
+
}
|
|
75091
|
+
/**
|
|
75092
|
+
* @param start Start index for the current parser event.
|
|
75093
|
+
* @param endIndex End index for the current parser event.
|
|
75094
|
+
* @param offset Offset applied when computing parser indices.
|
|
75095
|
+
* @internal
|
|
75096
|
+
*/
|
|
75097
|
+
oncomment(start, endIndex, offset) {
|
|
75098
|
+
this.endIndex = endIndex;
|
|
75099
|
+
this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));
|
|
75100
|
+
this.cbs.oncommentend?.();
|
|
75101
|
+
// Set `startIndex` for next node
|
|
75102
|
+
this.startIndex = endIndex + 1;
|
|
75103
|
+
}
|
|
75104
|
+
/**
|
|
75105
|
+
* @param start Start index for the current parser event.
|
|
75106
|
+
* @param endIndex End index for the current parser event.
|
|
75107
|
+
* @param offset Offset applied when computing parser indices.
|
|
75108
|
+
* @internal
|
|
75109
|
+
*/
|
|
75110
|
+
oncdata(start, endIndex, offset) {
|
|
75111
|
+
this.endIndex = endIndex;
|
|
75112
|
+
const value = this.getSlice(start, endIndex - offset);
|
|
75113
|
+
if (!this.htmlMode || this.options.recognizeCDATA) {
|
|
75114
|
+
this.cbs.oncdatastart?.();
|
|
75115
|
+
this.cbs.ontext?.(value);
|
|
75116
|
+
this.cbs.oncdataend?.();
|
|
75117
|
+
}
|
|
75118
|
+
else if (this.isInForeignContext()) {
|
|
75119
|
+
this.cbs.ontext?.(value);
|
|
75120
|
+
}
|
|
75121
|
+
else {
|
|
75122
|
+
this.cbs.oncomment?.(`[CDATA[${value}]]`);
|
|
75123
|
+
this.cbs.oncommentend?.();
|
|
75124
|
+
}
|
|
75125
|
+
// Set `startIndex` for next node
|
|
75126
|
+
this.startIndex = endIndex + 1;
|
|
75127
|
+
}
|
|
75128
|
+
/** @internal */
|
|
75129
|
+
onend() {
|
|
75130
|
+
if (this.cbs.onclosetag) {
|
|
75131
|
+
// Set the end index for all remaining tags
|
|
75132
|
+
this.endIndex = this.startIndex;
|
|
75133
|
+
for (let index = 0; index < this.stack.length; index++) {
|
|
75134
|
+
this.cbs.onclosetag(this.stack[index], true);
|
|
75135
|
+
}
|
|
75136
|
+
}
|
|
75137
|
+
this.cbs.onend?.();
|
|
75138
|
+
}
|
|
75139
|
+
/**
|
|
75140
|
+
* Resets the parser to a blank state, ready to parse a new HTML document
|
|
75141
|
+
*/
|
|
75142
|
+
reset() {
|
|
75143
|
+
this.cbs.onreset?.();
|
|
75144
|
+
this.tokenizer.reset();
|
|
75145
|
+
this.tagname = "";
|
|
75146
|
+
this.attribname = "";
|
|
75147
|
+
this.attribvalue = "";
|
|
75148
|
+
this.attribs = null;
|
|
75149
|
+
this.stack.length = 0;
|
|
75150
|
+
this.startIndex = 0;
|
|
75151
|
+
this.endIndex = 0;
|
|
75152
|
+
this.cbs.onparserinit?.(this);
|
|
75153
|
+
this.buffers.length = 0;
|
|
75154
|
+
this.foreignContext.length = 0;
|
|
75155
|
+
this.foreignContext.unshift(ForeignContext.None);
|
|
75156
|
+
this.bufferOffset = 0;
|
|
75157
|
+
this.writeIndex = 0;
|
|
75158
|
+
this.ended = false;
|
|
75159
|
+
}
|
|
75160
|
+
/**
|
|
75161
|
+
* Resets the parser, then parses a complete document and
|
|
75162
|
+
* pushes it to the handler.
|
|
75163
|
+
* @param data Document to parse.
|
|
75164
|
+
*/
|
|
75165
|
+
parseComplete(data) {
|
|
75166
|
+
this.reset();
|
|
75167
|
+
this.end(data);
|
|
75168
|
+
}
|
|
75169
|
+
getSlice(start, end) {
|
|
75170
|
+
if (start === end) {
|
|
75171
|
+
return "";
|
|
75172
|
+
}
|
|
75173
|
+
while (start - this.bufferOffset >= this.buffers[0].length) {
|
|
75174
|
+
this.shiftBuffer();
|
|
75175
|
+
}
|
|
75176
|
+
let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);
|
|
75177
|
+
while (end - this.bufferOffset > this.buffers[0].length) {
|
|
75178
|
+
this.shiftBuffer();
|
|
75179
|
+
slice += this.buffers[0].slice(0, end - this.bufferOffset);
|
|
75180
|
+
}
|
|
75181
|
+
return slice;
|
|
75182
|
+
}
|
|
75183
|
+
shiftBuffer() {
|
|
75184
|
+
this.bufferOffset += this.buffers[0].length;
|
|
75185
|
+
this.writeIndex--;
|
|
75186
|
+
this.buffers.shift();
|
|
75187
|
+
}
|
|
75188
|
+
/**
|
|
75189
|
+
* Parses a chunk of data and calls the corresponding callbacks.
|
|
75190
|
+
* @param chunk Chunk to parse.
|
|
75191
|
+
*/
|
|
75192
|
+
write(chunk) {
|
|
75193
|
+
if (this.ended) {
|
|
75194
|
+
this.cbs.onerror?.(new Error(".write() after done!"));
|
|
75195
|
+
return;
|
|
75196
|
+
}
|
|
75197
|
+
this.buffers.push(chunk);
|
|
75198
|
+
if (this.tokenizer.running) {
|
|
75199
|
+
this.tokenizer.write(chunk);
|
|
75200
|
+
this.writeIndex++;
|
|
75201
|
+
}
|
|
75202
|
+
}
|
|
75203
|
+
/**
|
|
75204
|
+
* Parses the end of the buffer and clears the stack, calls onend.
|
|
75205
|
+
* @param chunk Optional final chunk to parse.
|
|
75206
|
+
*/
|
|
75207
|
+
end(chunk) {
|
|
75208
|
+
if (this.ended) {
|
|
75209
|
+
this.cbs.onerror?.(new Error(".end() after done!"));
|
|
75210
|
+
return;
|
|
75211
|
+
}
|
|
75212
|
+
if (chunk)
|
|
75213
|
+
this.write(chunk);
|
|
75214
|
+
this.ended = true;
|
|
75215
|
+
this.tokenizer.end();
|
|
75216
|
+
}
|
|
75217
|
+
/**
|
|
75218
|
+
* Pauses parsing. The parser won't emit events until `resume` is called.
|
|
75219
|
+
*/
|
|
75220
|
+
pause() {
|
|
75221
|
+
this.tokenizer.pause();
|
|
75222
|
+
}
|
|
75223
|
+
/**
|
|
75224
|
+
* Resumes parsing after `pause` was called.
|
|
75225
|
+
*/
|
|
75226
|
+
resume() {
|
|
75227
|
+
this.tokenizer.resume();
|
|
75228
|
+
while (this.tokenizer.running &&
|
|
75229
|
+
this.writeIndex < this.buffers.length) {
|
|
75230
|
+
this.tokenizer.write(this.buffers[this.writeIndex++]);
|
|
75231
|
+
}
|
|
75232
|
+
if (this.ended)
|
|
75233
|
+
this.tokenizer.end();
|
|
75234
|
+
}
|
|
75235
|
+
}
|
|
75236
|
+
//# sourceMappingURL=Parser.js.map
|
|
75237
|
+
;// ./processor/transform/mdxish/tables/tag-walker.ts
|
|
75238
|
+
|
|
75239
|
+
/**
|
|
75240
|
+
* Skip certain regions / parts of the content that htmlparser2 should not handle
|
|
75241
|
+
*/
|
|
75242
|
+
const maskNonTagRegions = (html) => html
|
|
75243
|
+
.replace(/```[\s\S]*?```|``(?:[^`]|`(?!`))*``|`[^`\n]*`/g, m => ' '.repeat(m.length))
|
|
75244
|
+
// `<<NAME>>` is legacy variable syntax — without masking,
|
|
75245
|
+
// htmlparser2 sees the inner `<NAME>` as a tag. Blanking any `<<` also
|
|
75246
|
+
// covers malformed variants like `<<string>`.
|
|
75247
|
+
.replace(/<</g, ' ')
|
|
75248
|
+
// skip escaped tag openers
|
|
75249
|
+
.replace(/\\</g, ' ');
|
|
75250
|
+
/**
|
|
75251
|
+
* Drive htmlparser2 over `html` (after masking non-tag regions) and emit
|
|
75252
|
+
* tag-balance events. `start`/`end` use the original-string offsets, so
|
|
75253
|
+
* callers can splice against the input directly.
|
|
75254
|
+
*/
|
|
75255
|
+
const walkTags = (html, handlers) => {
|
|
75256
|
+
const masked = maskNonTagRegions(html);
|
|
75257
|
+
// htmlparser2's endIndex points at the `>` (inclusive); +1 lands just past
|
|
75258
|
+
// it, which is what callers want for splicing.
|
|
75259
|
+
const tagEnd = (parser) => (parser.endIndex ?? parser.startIndex) + 1;
|
|
75260
|
+
const parser = new Parser_Parser({
|
|
75261
|
+
onopentag(name) {
|
|
75262
|
+
handlers.onOpen?.({ name, start: parser.startIndex, end: tagEnd(parser) });
|
|
75263
|
+
},
|
|
75264
|
+
onclosetag(name, implicit) {
|
|
75265
|
+
handlers.onClose?.({ name, start: parser.startIndex, end: tagEnd(parser), implicit });
|
|
75266
|
+
},
|
|
75267
|
+
}, {
|
|
75268
|
+
lowerCaseAttributeNames: false,
|
|
75269
|
+
lowerCaseTags: false,
|
|
75270
|
+
recognizeSelfClosing: true,
|
|
75271
|
+
});
|
|
75272
|
+
parser.write(masked);
|
|
75273
|
+
parser.end();
|
|
75274
|
+
};
|
|
75275
|
+
|
|
72894
75276
|
;// ./processor/transform/mdxish/tables/utils.ts
|
|
72895
75277
|
const tableTags = new Set([
|
|
72896
75278
|
'thead',
|
|
72897
75279
|
'tbody',
|
|
72898
75280
|
'tfoot',
|
|
72899
75281
|
'caption',
|
|
72900
|
-
'colgroup',
|
|
75282
|
+
'colgroup',
|
|
75283
|
+
'col',
|
|
75284
|
+
'tr',
|
|
75285
|
+
'th',
|
|
75286
|
+
'td',
|
|
75287
|
+
]);
|
|
75288
|
+
/**
|
|
75289
|
+
* If the cell has exactly one paragraph child, unwrap it so its inline children sit
|
|
75290
|
+
* directly under the cell (matches GFM table cell shape and avoids stray `<p>` wrappers).
|
|
75291
|
+
*
|
|
75292
|
+
* When there are multiple paragraphs, leave them intact — they represent distinct lines
|
|
75293
|
+
* of content that need to be preserved for JSX `<Table>` serialization.
|
|
75294
|
+
*/
|
|
75295
|
+
const unwrapSoleParagraph = (children) => {
|
|
75296
|
+
const paragraphCount = children.filter(c => c.type === 'paragraph').length;
|
|
75297
|
+
if (paragraphCount !== 1)
|
|
75298
|
+
return children;
|
|
75299
|
+
return children.flatMap(child => {
|
|
75300
|
+
if (child.type === 'paragraph' && 'children' in child && Array.isArray(child.children)) {
|
|
75301
|
+
return child.children;
|
|
75302
|
+
}
|
|
75303
|
+
return [child];
|
|
75304
|
+
});
|
|
75305
|
+
};
|
|
75306
|
+
/**
|
|
75307
|
+
* Splice each text into `html` at its offset. Inserts at the same offset
|
|
75308
|
+
* are emitted in their input order (a stable sort by offset), so callers can
|
|
75309
|
+
* rely on innermost-first ordering by emitting events in stack-unwind order.
|
|
75310
|
+
*/
|
|
75311
|
+
const applyInserts = (html, inserts) => {
|
|
75312
|
+
if (inserts.length === 0)
|
|
75313
|
+
return { value: html, inserts: [] };
|
|
75314
|
+
const sorted = [...inserts].sort((a, b) => a.offset - b.offset);
|
|
75315
|
+
let out = '';
|
|
75316
|
+
let cursor = 0;
|
|
75317
|
+
sorted.forEach(({ offset, text }) => {
|
|
75318
|
+
const clamped = Math.min(Math.max(offset, cursor), html.length);
|
|
75319
|
+
if (clamped > cursor) {
|
|
75320
|
+
out += html.slice(cursor, clamped);
|
|
75321
|
+
cursor = clamped;
|
|
75322
|
+
}
|
|
75323
|
+
out += text;
|
|
75324
|
+
});
|
|
75325
|
+
return { value: out + html.slice(cursor), inserts: sorted };
|
|
75326
|
+
};
|
|
75327
|
+
|
|
75328
|
+
;// ./processor/transform/mdxish/tables/normalize-tag-spacing.ts
|
|
75329
|
+
|
|
75330
|
+
|
|
75331
|
+
/**
|
|
75332
|
+
* Returns the line bounds (start and end-exclusive offsets) containing `at`.
|
|
75333
|
+
*/
|
|
75334
|
+
const lineBoundsAt = (html, at) => {
|
|
75335
|
+
const start = html.lastIndexOf('\n', at - 1) + 1;
|
|
75336
|
+
const nl = html.indexOf('\n', at);
|
|
75337
|
+
return { start, end: nl === -1 ? html.length : nl };
|
|
75338
|
+
};
|
|
75339
|
+
/**
|
|
75340
|
+
* Compute the inserts needed to make one open/close pair line-symmetric.
|
|
75341
|
+
* Returns an empty array if the pair is already symmetric (both bare or both
|
|
75342
|
+
* attached) or shares a line.
|
|
75343
|
+
*/
|
|
75344
|
+
const symmetrizePair = (html, { openStart, openEnd, closeStart, closeEnd }) => {
|
|
75345
|
+
if (!html.slice(openEnd, closeStart).includes('\n'))
|
|
75346
|
+
return [];
|
|
75347
|
+
const openLine = lineBoundsAt(html, openStart);
|
|
75348
|
+
const closeLine = lineBoundsAt(html, closeStart);
|
|
75349
|
+
const preOpener = html.slice(openLine.start, openStart);
|
|
75350
|
+
const postOpener = html.slice(openEnd, openLine.end);
|
|
75351
|
+
const preCloser = html.slice(closeLine.start, closeStart);
|
|
75352
|
+
const postCloser = html.slice(closeEnd, closeLine.end);
|
|
75353
|
+
const openerHasExtras = preOpener.trim().length > 0 || postOpener.trim().length > 0;
|
|
75354
|
+
const closerHasExtras = preCloser.trim().length > 0 || postCloser.trim().length > 0;
|
|
75355
|
+
// Both match (both bare or both attached) — mdxjs parses this fine.
|
|
75356
|
+
if (openerHasExtras === closerHasExtras)
|
|
75357
|
+
return [];
|
|
75358
|
+
// Asymmetric. Push non-tag content on the offending side to its own line,
|
|
75359
|
+
// visually aligning the inserted line with the existing whitespace prefix.
|
|
75360
|
+
const indentFor = (linePrefix) => linePrefix.match(/^\s*/)?.[0] ?? '';
|
|
75361
|
+
const inserts = [];
|
|
75362
|
+
if (openerHasExtras) {
|
|
75363
|
+
const indent = indentFor(preOpener);
|
|
75364
|
+
if (preOpener.trim().length > 0)
|
|
75365
|
+
inserts.push({ offset: openStart, text: `\n${indent}` });
|
|
75366
|
+
if (postOpener.trim().length > 0)
|
|
75367
|
+
inserts.push({ offset: openEnd, text: `\n${indent}` });
|
|
75368
|
+
}
|
|
75369
|
+
if (closerHasExtras) {
|
|
75370
|
+
const indent = indentFor(preCloser);
|
|
75371
|
+
if (preCloser.trim().length > 0)
|
|
75372
|
+
inserts.push({ offset: closeStart, text: `\n${indent}` });
|
|
75373
|
+
if (postCloser.trim().length > 0)
|
|
75374
|
+
inserts.push({ offset: closeEnd, text: `\n${indent}` });
|
|
75375
|
+
}
|
|
75376
|
+
return inserts;
|
|
75377
|
+
};
|
|
75378
|
+
/**
|
|
75379
|
+
* mdxjs's micromark extension fails when a JSX element's opener-line and
|
|
75380
|
+
* closer-line don't match in "is the tag alone on its line?" Concretely:
|
|
75381
|
+
*
|
|
75382
|
+
* <span>X\n</span> ❌ opener-line has text, closer-line is bare
|
|
75383
|
+
* <span>\nX</span> ❌ opener-line is bare, closer-line has text
|
|
75384
|
+
* text <span>X\n</span> ❌ opener-line has leading + trailing text
|
|
75385
|
+
* <span>\nX\n</span> text ❌ closer-line has trailing text
|
|
75386
|
+
* <span>X\nY</span> ✅ both lines have adjacent text
|
|
75387
|
+
* <span>\nX\n</span> ✅ both lines are bare
|
|
75388
|
+
* <span>X</span> ✅ same line
|
|
75389
|
+
*
|
|
75390
|
+
* When the two lines disagree, mdxjs throws "Expected a closing tag…before
|
|
75391
|
+
* the end of `paragraph`" (or its mirror). This pass detects asymmetric
|
|
75392
|
+
* pairs and inserts newlines (+ matching indent) to push the offending side's
|
|
75393
|
+
* non-tag content to a separate line, restoring symmetry. Scoped to the
|
|
75394
|
+
* malformed-retry path; the happy path doesn't touch this.
|
|
75395
|
+
*/
|
|
75396
|
+
const normalizeTagSpacing = (html) => {
|
|
75397
|
+
const stack = [];
|
|
75398
|
+
const pairs = [];
|
|
75399
|
+
walkTags(html, {
|
|
75400
|
+
onOpen({ name, start, end }) {
|
|
75401
|
+
stack.push({ name, openStart: start, openEnd: end });
|
|
75402
|
+
},
|
|
75403
|
+
onClose({ name, start, end, implicit }) {
|
|
75404
|
+
if (implicit)
|
|
75405
|
+
return;
|
|
75406
|
+
// Walk the stack to find the innermost matching opener. `findLastIndex`
|
|
75407
|
+
// would be cleaner but isn't available on the current lib target.
|
|
75408
|
+
const matchIdx = stack.reduce((acc, t, i) => (t.name === name ? i : acc), -1);
|
|
75409
|
+
if (matchIdx === -1)
|
|
75410
|
+
return;
|
|
75411
|
+
const open = stack[matchIdx];
|
|
75412
|
+
pairs.push({ openStart: open.openStart, openEnd: open.openEnd, closeStart: start, closeEnd: end });
|
|
75413
|
+
stack.splice(matchIdx, 1);
|
|
75414
|
+
},
|
|
75415
|
+
});
|
|
75416
|
+
return applyInserts(html, pairs.flatMap(p => symmetrizePair(html, p)));
|
|
75417
|
+
};
|
|
75418
|
+
|
|
75419
|
+
;// ./processor/transform/mdxish/tables/remap-positions.ts
|
|
75420
|
+
|
|
75421
|
+
/**
|
|
75422
|
+
* Build a function that maps an offset in the repaired string back to the
|
|
75423
|
+
* original string's coordinate space. Inserts must be sorted by their
|
|
75424
|
+
* (original) offset.
|
|
75425
|
+
*
|
|
75426
|
+
* If a repaired offset falls *inside* synthetic text (i.e. on a character
|
|
75427
|
+
* that didn't exist in the original), it clamps to the insert's anchor
|
|
75428
|
+
* offset in the original — consumers slicing the original source get the
|
|
75429
|
+
* boundary, not garbage.
|
|
75430
|
+
*/
|
|
75431
|
+
const buildOffsetMapper = (inserts) => {
|
|
75432
|
+
// Pre-compute each insert's start in repaired-space.
|
|
75433
|
+
let acc = 0;
|
|
75434
|
+
const segments = inserts.map(ins => {
|
|
75435
|
+
const repairedStart = ins.offset + acc;
|
|
75436
|
+
acc += ins.text.length;
|
|
75437
|
+
return { origOffset: ins.offset, len: ins.text.length, repairedStart };
|
|
75438
|
+
});
|
|
75439
|
+
return (repaired) => {
|
|
75440
|
+
// Offsets inside an insert's synthetic span have no original counterpart;
|
|
75441
|
+
// clamp to the insert's anchor so consumers slice a real boundary.
|
|
75442
|
+
const hit = segments.find(seg => seg.repairedStart < repaired && repaired < seg.repairedStart + seg.len);
|
|
75443
|
+
if (hit)
|
|
75444
|
+
return hit.origOffset;
|
|
75445
|
+
const shift = segments.reduce((acc2, seg) => (seg.repairedStart < repaired ? acc2 + seg.len : acc2), 0);
|
|
75446
|
+
return repaired - shift;
|
|
75447
|
+
};
|
|
75448
|
+
};
|
|
75449
|
+
/**
|
|
75450
|
+
* Map an offset in `source` to its 1-based `{ line, column }`. `lineStarts`
|
|
75451
|
+
* is the precomputed array of offsets where each line begins.
|
|
75452
|
+
*/
|
|
75453
|
+
const offsetToLineCol = (lineStarts, offset) => {
|
|
75454
|
+
// Binary search for the greatest lineStart <= offset.
|
|
75455
|
+
let lo = 0;
|
|
75456
|
+
let hi = lineStarts.length - 1;
|
|
75457
|
+
while (lo < hi) {
|
|
75458
|
+
const mid = Math.floor((lo + hi + 1) / 2);
|
|
75459
|
+
if (lineStarts[mid] <= offset)
|
|
75460
|
+
lo = mid;
|
|
75461
|
+
else
|
|
75462
|
+
hi = mid - 1;
|
|
75463
|
+
}
|
|
75464
|
+
return { line: lo + 1, column: offset - lineStarts[lo] + 1 };
|
|
75465
|
+
};
|
|
75466
|
+
const computeLineStarts = (source) => {
|
|
75467
|
+
const starts = [0];
|
|
75468
|
+
for (let i = 0; i < source.length; i += 1) {
|
|
75469
|
+
if (source[i] === '\n')
|
|
75470
|
+
starts.push(i + 1);
|
|
75471
|
+
}
|
|
75472
|
+
return starts;
|
|
75473
|
+
};
|
|
75474
|
+
/**
|
|
75475
|
+
* Walk `tree`, translating every node's position from the repaired source's
|
|
75476
|
+
* coordinate space back to the original source. Offsets are remapped via the
|
|
75477
|
+
* insert list; line/column are recomputed from the original source so they
|
|
75478
|
+
* remain accurate even if repairs introduced newlines.
|
|
75479
|
+
*/
|
|
75480
|
+
const remapPositionsToOriginal = (tree, originalSource, inserts) => {
|
|
75481
|
+
if (inserts.length === 0)
|
|
75482
|
+
return;
|
|
75483
|
+
const mapOffset = buildOffsetMapper(inserts);
|
|
75484
|
+
const lineStarts = computeLineStarts(originalSource);
|
|
75485
|
+
visit(tree, child => {
|
|
75486
|
+
if (child.position?.start) {
|
|
75487
|
+
const origOffset = mapOffset(child.position.start.offset ?? 0);
|
|
75488
|
+
const { line, column } = offsetToLineCol(lineStarts, origOffset);
|
|
75489
|
+
child.position.start.offset = origOffset;
|
|
75490
|
+
child.position.start.line = line;
|
|
75491
|
+
child.position.start.column = column;
|
|
75492
|
+
}
|
|
75493
|
+
if (child.position?.end) {
|
|
75494
|
+
const origOffset = mapOffset(child.position.end.offset ?? 0);
|
|
75495
|
+
const { line, column } = offsetToLineCol(lineStarts, origOffset);
|
|
75496
|
+
child.position.end.offset = origOffset;
|
|
75497
|
+
child.position.end.line = line;
|
|
75498
|
+
child.position.end.column = column;
|
|
75499
|
+
}
|
|
75500
|
+
});
|
|
75501
|
+
};
|
|
75502
|
+
|
|
75503
|
+
;// ./node_modules/html-tags/html-tags.json
|
|
75504
|
+
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"]');
|
|
75505
|
+
// EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
|
|
75506
|
+
var dist = __webpack_require__(3753);
|
|
75507
|
+
var dist_default = /*#__PURE__*/__webpack_require__.n(dist);
|
|
75508
|
+
// EXTERNAL MODULE: ./node_modules/react-native-known-styling-properties/dist/index.js
|
|
75509
|
+
var react_native_known_styling_properties_dist = __webpack_require__(1734);
|
|
75510
|
+
;// ./utils/common-html-words.ts
|
|
75511
|
+
|
|
75512
|
+
|
|
75513
|
+
|
|
75514
|
+
/**
|
|
75515
|
+
* Extract word boundaries from camelCase strings (e.g., "borderWidth" -> ["border", "width"])
|
|
75516
|
+
*/
|
|
75517
|
+
function extractWordBoundaries(camelCaseStr) {
|
|
75518
|
+
return camelCaseStr
|
|
75519
|
+
.replace(/([A-Z])/g, ' $1')
|
|
75520
|
+
.toLowerCase()
|
|
75521
|
+
.trim()
|
|
75522
|
+
.split(/\s+/)
|
|
75523
|
+
.filter(word => word.length > 0);
|
|
75524
|
+
}
|
|
75525
|
+
/**
|
|
75526
|
+
* Get all unique word boundaries from an array of camelCase property names.
|
|
75527
|
+
* Filters out single-letter words to avoid false matches in smartCamelCase.
|
|
75528
|
+
*/
|
|
75529
|
+
function getWordBoundariesFromProps(props) {
|
|
75530
|
+
const boundaries = new Set();
|
|
75531
|
+
props.forEach(prop => {
|
|
75532
|
+
extractWordBoundaries(prop).forEach(word => {
|
|
75533
|
+
// Filter out single-letter words to prevent false matches (e.g., "d" matching in "data")
|
|
75534
|
+
// Keep meaningful 2+ character words
|
|
75535
|
+
if (word.length >= 2) {
|
|
75536
|
+
boundaries.add(word);
|
|
75537
|
+
}
|
|
75538
|
+
});
|
|
75539
|
+
});
|
|
75540
|
+
return Array.from(boundaries).sort();
|
|
75541
|
+
}
|
|
75542
|
+
/**
|
|
75543
|
+
* React HTML element props word boundaries (e.g., "on", "data", "aria", "accept", "auto")
|
|
75544
|
+
* Extracted from react-html-attributes package
|
|
75545
|
+
*/
|
|
75546
|
+
const REACT_HTML_PROP_BOUNDARIES = getWordBoundariesFromProps((dist_default())["*"] || []);
|
|
75547
|
+
/**
|
|
75548
|
+
* CSS style property word boundaries (e.g., "border", "margin", "padding", "flex", "align")
|
|
75549
|
+
* Extracted from react-native-known-styling-properties package
|
|
75550
|
+
*/
|
|
75551
|
+
const CSS_STYLE_PROP_BOUNDARIES = getWordBoundariesFromProps(react_native_known_styling_properties_dist/* allProps */.q9);
|
|
75552
|
+
/**
|
|
75553
|
+
* Custom component prop word boundaries not in React HTML or CSS boundaries.
|
|
75554
|
+
*/
|
|
75555
|
+
const CUSTOM_PROP_BOUNDARIES = [
|
|
75556
|
+
'alt',
|
|
75557
|
+
'attribute',
|
|
75558
|
+
'attributes',
|
|
75559
|
+
'buttons',
|
|
75560
|
+
'caption',
|
|
75561
|
+
'collection',
|
|
75562
|
+
'columns',
|
|
75563
|
+
'copy',
|
|
75564
|
+
'dark',
|
|
75565
|
+
'data',
|
|
75566
|
+
'depth',
|
|
75567
|
+
'download',
|
|
75568
|
+
'embed',
|
|
75569
|
+
'empty',
|
|
75570
|
+
'favicon',
|
|
75571
|
+
'flow',
|
|
75572
|
+
'iframe',
|
|
75573
|
+
'image',
|
|
75574
|
+
'layout',
|
|
75575
|
+
'lazy',
|
|
75576
|
+
'meta',
|
|
75577
|
+
'provider',
|
|
75578
|
+
'run',
|
|
75579
|
+
'safe',
|
|
75580
|
+
'scripts',
|
|
75581
|
+
'tag',
|
|
75582
|
+
'term',
|
|
75583
|
+
'terms',
|
|
75584
|
+
'theme',
|
|
75585
|
+
'url',
|
|
75586
|
+
'value',
|
|
75587
|
+
];
|
|
75588
|
+
/**
|
|
75589
|
+
* Tags that should be passed through and handled at runtime (not by the mdxish plugin)
|
|
75590
|
+
*/
|
|
75591
|
+
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'html-block', 'rdme-pin']);
|
|
75592
|
+
/**
|
|
75593
|
+
* Standard HTML tags that should never be treated as custom components.
|
|
75594
|
+
* Uses the html-tags package, converted to a Set<string> for efficient lookups.
|
|
75595
|
+
*/
|
|
75596
|
+
const STANDARD_HTML_TAGS = new Set(html_tags_namespaceObject);
|
|
75597
|
+
/**
|
|
75598
|
+
* HTML void elements — elements that have no closing tag and no children.
|
|
75599
|
+
*
|
|
75600
|
+
* @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
75601
|
+
*/
|
|
75602
|
+
const HTML_VOID_ELEMENTS = new Set([
|
|
75603
|
+
'area',
|
|
75604
|
+
'base',
|
|
75605
|
+
'br',
|
|
72901
75606
|
'col',
|
|
72902
|
-
'
|
|
72903
|
-
'
|
|
72904
|
-
'
|
|
75607
|
+
'embed',
|
|
75608
|
+
'hr',
|
|
75609
|
+
'img',
|
|
75610
|
+
'input',
|
|
75611
|
+
'link',
|
|
75612
|
+
'meta',
|
|
75613
|
+
'param',
|
|
75614
|
+
'source',
|
|
75615
|
+
'track',
|
|
75616
|
+
'wbr',
|
|
72905
75617
|
]);
|
|
75618
|
+
|
|
75619
|
+
;// ./processor/transform/mdxish/tables/repair-unclosed-tags.ts
|
|
75620
|
+
|
|
75621
|
+
|
|
75622
|
+
|
|
75623
|
+
const isStandardHtmlTag = (name) => STANDARD_HTML_TAGS.has(name.toLowerCase());
|
|
72906
75624
|
/**
|
|
72907
|
-
*
|
|
72908
|
-
*
|
|
75625
|
+
* MDX requires a JSX inline tag and its closer to live on the same line — not
|
|
75626
|
+
* just the same paragraph. (`<td>\nArray <object>\n</object></td>` still
|
|
75627
|
+
* throws even though there's no blank line between open and close.)
|
|
72909
75628
|
*
|
|
72910
|
-
* When
|
|
72911
|
-
*
|
|
75629
|
+
* When a pair of tags sit on different lines, return the offset of the first newline
|
|
75630
|
+
* after the open so the synthetic closer lands at the end of the open's line.
|
|
75631
|
+
* If they share a line (e.g. `<b><i>x</b>`), just use the position htmlparser2
|
|
75632
|
+
* decides the unclosed tag must be closed at by
|
|
72912
75633
|
*/
|
|
72913
|
-
const
|
|
72914
|
-
const
|
|
72915
|
-
|
|
72916
|
-
|
|
72917
|
-
|
|
72918
|
-
|
|
72919
|
-
|
|
72920
|
-
|
|
72921
|
-
|
|
75634
|
+
const findOffsetToPlaceCloser = (html, openTagEnd, forcedCloseAt) => {
|
|
75635
|
+
const newlineIdx = html.slice(openTagEnd, forcedCloseAt).indexOf('\n');
|
|
75636
|
+
return newlineIdx === -1 ? forcedCloseAt : openTagEnd + newlineIdx;
|
|
75637
|
+
};
|
|
75638
|
+
/**
|
|
75639
|
+
* Rewrites `html` so every open tag has a matching close. Returns the input
|
|
75640
|
+
* unchanged when nothing needed repair, so callers can cheaply detect no-ops.
|
|
75641
|
+
*
|
|
75642
|
+
* Detection runs through htmlparser2: any close event flagged `implicit` is
|
|
75643
|
+
* a tag the user opened but didn't explicitly close. We pair it with the
|
|
75644
|
+
* matching opener (popped from a stack we maintain) and insert `</name>` at
|
|
75645
|
+
* the end of the opener's line, or at the trigger if they're on the same line.
|
|
75646
|
+
*/
|
|
75647
|
+
const repairUnclosedTags = (html) => {
|
|
75648
|
+
const inserts = [];
|
|
75649
|
+
const openTags = [];
|
|
75650
|
+
walkTags(html, {
|
|
75651
|
+
onOpen({ name, start, end }) {
|
|
75652
|
+
// Escape non-HTML names (custom components, typos, `<arbitrary-tag>`)
|
|
75653
|
+
// so MDX treats them as literal text instead of expecting a closer
|
|
75654
|
+
if (!isStandardHtmlTag(name)) {
|
|
75655
|
+
inserts.push({ offset: start, text: '\\' });
|
|
75656
|
+
return;
|
|
75657
|
+
}
|
|
75658
|
+
if (HTML_VOID_ELEMENTS.has(name.toLowerCase())) {
|
|
75659
|
+
// MDX requires void elements to be self-closing (`<br/>`, not `<br>`).
|
|
75660
|
+
// If the source open tag doesn't end with `/`, inject one before the
|
|
75661
|
+
// `>` so it parses. `end` is one past `>`, so `end - 2` is the char
|
|
75662
|
+
// immediately before `>`.
|
|
75663
|
+
if (html[end - 2] !== '/')
|
|
75664
|
+
inserts.push({ offset: end - 1, text: '/' });
|
|
75665
|
+
return;
|
|
75666
|
+
}
|
|
75667
|
+
openTags.push({ name, start, end });
|
|
75668
|
+
},
|
|
75669
|
+
onClose({ name, start, implicit }) {
|
|
75670
|
+
if (HTML_VOID_ELEMENTS.has(name.toLowerCase()))
|
|
75671
|
+
return;
|
|
75672
|
+
if (!isStandardHtmlTag(name))
|
|
75673
|
+
return;
|
|
75674
|
+
const openTag = openTags.pop();
|
|
75675
|
+
if (!implicit || !openTag)
|
|
75676
|
+
return;
|
|
75677
|
+
inserts.push({ offset: findOffsetToPlaceCloser(html, openTag.end, start), text: `</${name}>` });
|
|
75678
|
+
},
|
|
72922
75679
|
});
|
|
75680
|
+
return applyInserts(html, inserts);
|
|
72923
75681
|
};
|
|
72924
75682
|
|
|
72925
75683
|
;// ./processor/transform/mdxish/tables/mdxish-tables.ts
|
|
@@ -72940,6 +75698,9 @@ const unwrapSoleParagraph = (children) => {
|
|
|
72940
75698
|
|
|
72941
75699
|
|
|
72942
75700
|
|
|
75701
|
+
|
|
75702
|
+
|
|
75703
|
+
|
|
72943
75704
|
const isTableCell = (node) => isMDXElement(node) && ['th', 'td'].includes(node.name);
|
|
72944
75705
|
const tableTypes = {
|
|
72945
75706
|
tr: 'tableRow',
|
|
@@ -72963,12 +75724,13 @@ const buildTableNodeProcessor = (withMdx) => unified()
|
|
|
72963
75724
|
.use(remarkGfm);
|
|
72964
75725
|
const tableNodeProcessor = buildTableNodeProcessor(true);
|
|
72965
75726
|
const fallbackTableNodeProcessor = buildTableNodeProcessor(false);
|
|
72966
|
-
|
|
72967
|
-
|
|
72968
|
-
|
|
72969
|
-
|
|
72970
|
-
|
|
72971
|
-
|
|
75727
|
+
/**
|
|
75728
|
+
* Parse the HTML node that contains the full table substring
|
|
75729
|
+
* into the table parts (headers, rows, cells).
|
|
75730
|
+
* The plugins in the processor allows parsing markdown & special syntax inside the table cells
|
|
75731
|
+
* After parsing, we need to update the node positions
|
|
75732
|
+
*/
|
|
75733
|
+
const parseTableNode = (processor, node, repair) => {
|
|
72972
75734
|
let parsed;
|
|
72973
75735
|
try {
|
|
72974
75736
|
parsed = processor.runSync(processor.parse(node.value));
|
|
@@ -72976,6 +75738,14 @@ const parseTableNode = (processor, node) => {
|
|
|
72976
75738
|
catch {
|
|
72977
75739
|
return undefined;
|
|
72978
75740
|
}
|
|
75741
|
+
// If `node.value` was repaired before parsing, first remap positions back to
|
|
75742
|
+
// the original (unrepaired) coordinates via the insert list — otherwise the
|
|
75743
|
+
// shift would land on synthetic characters and be inaccurate
|
|
75744
|
+
if (repair) {
|
|
75745
|
+
remapPositionsToOriginal(parsed, repair.originalSource, repair.inserts);
|
|
75746
|
+
}
|
|
75747
|
+
// The subparser produces positions relative to `node.value`; shift them by
|
|
75748
|
+
// the outer node's offset/line so consumers can slice the full source.
|
|
72979
75749
|
const baseOffset = node.position?.start?.offset ?? 0;
|
|
72980
75750
|
const baseLine = (node.position?.start?.line ?? 1) - 1;
|
|
72981
75751
|
visit(parsed, child => {
|
|
@@ -73172,22 +75942,45 @@ const mdxishTables = () => tree => {
|
|
|
73172
75942
|
return;
|
|
73173
75943
|
if (!node.value.startsWith('<Table') && !node.value.startsWith('<table'))
|
|
73174
75944
|
return;
|
|
73175
|
-
|
|
75945
|
+
// Main logic to transform table node to its parts
|
|
75946
|
+
// Because the processor uses remarkMdx, it is stricter in what it accepts
|
|
75947
|
+
// and only accepts valid MDX syntax. in the table node.
|
|
75948
|
+
// To get around that, we have some fallback logics after trying to repair the table content
|
|
75949
|
+
let parsed = parseTableNode(tableNodeProcessor, node);
|
|
75950
|
+
if (!parsed) {
|
|
75951
|
+
// First common error is unclosed HTML tags
|
|
75952
|
+
const repaired = repairUnclosedTags(node.value);
|
|
75953
|
+
if (repaired.value !== node.value) {
|
|
75954
|
+
parsed = parseTableNode(tableNodeProcessor, { ...node, value: repaired.value }, { inserts: repaired.inserts, originalSource: node.value });
|
|
75955
|
+
}
|
|
75956
|
+
if (!parsed) {
|
|
75957
|
+
// Second common error is having a line with text and an opening tag
|
|
75958
|
+
// E.g. text <div> \n <div> text
|
|
75959
|
+
const normalized = normalizeTagSpacing(node.value);
|
|
75960
|
+
if (normalized.value !== node.value) {
|
|
75961
|
+
parsed = parseTableNode(tableNodeProcessor, { ...node, value: normalized.value }, { inserts: normalized.inserts, originalSource: node.value });
|
|
75962
|
+
}
|
|
75963
|
+
}
|
|
75964
|
+
}
|
|
73176
75965
|
if (parsed) {
|
|
75966
|
+
// If the table is parsed successfully, we can now process it further
|
|
75967
|
+
// to build on the markdown / JSX table
|
|
73177
75968
|
visit(parsed, isMDXElement, (tableNode) => {
|
|
73178
75969
|
if (tableNode.name !== 'Table' && tableNode.name !== 'table')
|
|
73179
75970
|
return undefined;
|
|
73180
75971
|
processTableNode(tableNode, index, parent, node.position);
|
|
73181
75972
|
return EXIT;
|
|
73182
75973
|
});
|
|
73183
|
-
return;
|
|
73184
75974
|
}
|
|
73185
|
-
|
|
73186
|
-
|
|
73187
|
-
|
|
73188
|
-
|
|
73189
|
-
|
|
73190
|
-
|
|
75975
|
+
else if (node.value.startsWith('<table')) {
|
|
75976
|
+
// If the parsing still fails, give an opportunity to the fallback parser
|
|
75977
|
+
// without remarkMdx to process lowercase tables as it's likely to not
|
|
75978
|
+
// have needed MDX parsing anyway
|
|
75979
|
+
const fallback = parseTableNode(fallbackTableNodeProcessor, node);
|
|
75980
|
+
if (!fallback || fallback.children.length <= 1)
|
|
75981
|
+
return;
|
|
75982
|
+
parent.children.splice(index, 1, ...fallback.children);
|
|
75983
|
+
}
|
|
73191
75984
|
});
|
|
73192
75985
|
return tree;
|
|
73193
75986
|
};
|
|
@@ -88519,101 +91312,6 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
88519
91312
|
/** @type {ReturnType<createH>} */
|
|
88520
91313
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
88521
91314
|
|
|
88522
|
-
;// ./node_modules/html-tags/html-tags.json
|
|
88523
|
-
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"]');
|
|
88524
|
-
// EXTERNAL MODULE: ./node_modules/react-html-attributes/dist/index.js
|
|
88525
|
-
var dist = __webpack_require__(3753);
|
|
88526
|
-
var dist_default = /*#__PURE__*/__webpack_require__.n(dist);
|
|
88527
|
-
// EXTERNAL MODULE: ./node_modules/react-native-known-styling-properties/dist/index.js
|
|
88528
|
-
var react_native_known_styling_properties_dist = __webpack_require__(1734);
|
|
88529
|
-
;// ./utils/common-html-words.ts
|
|
88530
|
-
|
|
88531
|
-
|
|
88532
|
-
|
|
88533
|
-
/**
|
|
88534
|
-
* Extract word boundaries from camelCase strings (e.g., "borderWidth" -> ["border", "width"])
|
|
88535
|
-
*/
|
|
88536
|
-
function extractWordBoundaries(camelCaseStr) {
|
|
88537
|
-
return camelCaseStr
|
|
88538
|
-
.replace(/([A-Z])/g, ' $1')
|
|
88539
|
-
.toLowerCase()
|
|
88540
|
-
.trim()
|
|
88541
|
-
.split(/\s+/)
|
|
88542
|
-
.filter(word => word.length > 0);
|
|
88543
|
-
}
|
|
88544
|
-
/**
|
|
88545
|
-
* Get all unique word boundaries from an array of camelCase property names.
|
|
88546
|
-
* Filters out single-letter words to avoid false matches in smartCamelCase.
|
|
88547
|
-
*/
|
|
88548
|
-
function getWordBoundariesFromProps(props) {
|
|
88549
|
-
const boundaries = new Set();
|
|
88550
|
-
props.forEach(prop => {
|
|
88551
|
-
extractWordBoundaries(prop).forEach(word => {
|
|
88552
|
-
// Filter out single-letter words to prevent false matches (e.g., "d" matching in "data")
|
|
88553
|
-
// Keep meaningful 2+ character words
|
|
88554
|
-
if (word.length >= 2) {
|
|
88555
|
-
boundaries.add(word);
|
|
88556
|
-
}
|
|
88557
|
-
});
|
|
88558
|
-
});
|
|
88559
|
-
return Array.from(boundaries).sort();
|
|
88560
|
-
}
|
|
88561
|
-
/**
|
|
88562
|
-
* React HTML element props word boundaries (e.g., "on", "data", "aria", "accept", "auto")
|
|
88563
|
-
* Extracted from react-html-attributes package
|
|
88564
|
-
*/
|
|
88565
|
-
const REACT_HTML_PROP_BOUNDARIES = getWordBoundariesFromProps((dist_default())["*"] || []);
|
|
88566
|
-
/**
|
|
88567
|
-
* CSS style property word boundaries (e.g., "border", "margin", "padding", "flex", "align")
|
|
88568
|
-
* Extracted from react-native-known-styling-properties package
|
|
88569
|
-
*/
|
|
88570
|
-
const CSS_STYLE_PROP_BOUNDARIES = getWordBoundariesFromProps(react_native_known_styling_properties_dist/* allProps */.q9);
|
|
88571
|
-
/**
|
|
88572
|
-
* Custom component prop word boundaries not in React HTML or CSS boundaries.
|
|
88573
|
-
*/
|
|
88574
|
-
const CUSTOM_PROP_BOUNDARIES = [
|
|
88575
|
-
'alt',
|
|
88576
|
-
'attribute',
|
|
88577
|
-
'attributes',
|
|
88578
|
-
'buttons',
|
|
88579
|
-
'caption',
|
|
88580
|
-
'collection',
|
|
88581
|
-
'columns',
|
|
88582
|
-
'copy',
|
|
88583
|
-
'dark',
|
|
88584
|
-
'data',
|
|
88585
|
-
'depth',
|
|
88586
|
-
'download',
|
|
88587
|
-
'embed',
|
|
88588
|
-
'empty',
|
|
88589
|
-
'favicon',
|
|
88590
|
-
'flow',
|
|
88591
|
-
'iframe',
|
|
88592
|
-
'image',
|
|
88593
|
-
'layout',
|
|
88594
|
-
'lazy',
|
|
88595
|
-
'meta',
|
|
88596
|
-
'provider',
|
|
88597
|
-
'run',
|
|
88598
|
-
'safe',
|
|
88599
|
-
'scripts',
|
|
88600
|
-
'tag',
|
|
88601
|
-
'term',
|
|
88602
|
-
'terms',
|
|
88603
|
-
'theme',
|
|
88604
|
-
'url',
|
|
88605
|
-
'value',
|
|
88606
|
-
];
|
|
88607
|
-
/**
|
|
88608
|
-
* Tags that should be passed through and handled at runtime (not by the mdxish plugin)
|
|
88609
|
-
*/
|
|
88610
|
-
const RUNTIME_COMPONENT_TAGS = new Set(['Variable', 'variable', 'html-block', 'rdme-pin']);
|
|
88611
|
-
/**
|
|
88612
|
-
* Standard HTML tags that should never be treated as custom components.
|
|
88613
|
-
* Uses the html-tags package, converted to a Set<string> for efficient lookups.
|
|
88614
|
-
*/
|
|
88615
|
-
const STANDARD_HTML_TAGS = new Set(html_tags_namespaceObject);
|
|
88616
|
-
|
|
88617
91315
|
;// ./processor/plugin/toc.ts
|
|
88618
91316
|
|
|
88619
91317
|
|
|
@@ -95703,28 +98401,7 @@ function restoreCodeBlocks(content, protectedCode) {
|
|
|
95703
98401
|
|
|
95704
98402
|
;// ./processor/transform/mdxish/close-self-closing-html-tags.ts
|
|
95705
98403
|
|
|
95706
|
-
|
|
95707
|
-
* HTML void elements that are legitimately self-closing per the HTML spec.
|
|
95708
|
-
* These should NOT be transformed.
|
|
95709
|
-
*
|
|
95710
|
-
* @see https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
95711
|
-
*/
|
|
95712
|
-
const HTML_VOID_ELEMENTS = new Set([
|
|
95713
|
-
'area',
|
|
95714
|
-
'base',
|
|
95715
|
-
'br',
|
|
95716
|
-
'col',
|
|
95717
|
-
'embed',
|
|
95718
|
-
'hr',
|
|
95719
|
-
'img',
|
|
95720
|
-
'input',
|
|
95721
|
-
'link',
|
|
95722
|
-
'meta',
|
|
95723
|
-
'param',
|
|
95724
|
-
'source',
|
|
95725
|
-
'track',
|
|
95726
|
-
'wbr',
|
|
95727
|
-
]);
|
|
98404
|
+
|
|
95728
98405
|
/**
|
|
95729
98406
|
* Matches self-closing HTML tags: `<tagname/>` or `<tagname attr="val" />`
|
|
95730
98407
|
*
|
|
@@ -97555,6 +100232,14 @@ function createTokenize(mode) {
|
|
|
97555
100232
|
let fenceLength = 0;
|
|
97556
100233
|
let fenceCloseLength = 0;
|
|
97557
100234
|
let atLineStart = false;
|
|
100235
|
+
// Bail when the opener line has unmatched tag-like tokens in its body.
|
|
100236
|
+
// `<Foo>_<Bar>.csv` leaves opens > closes; matched shapes like
|
|
100237
|
+
// `<Callout>x <strong>y</strong>` balance to 0. Without this,
|
|
100238
|
+
// `concrete: true` causes orphan openers to eat sibling blockquotes.
|
|
100239
|
+
let onOpenerLine = false;
|
|
100240
|
+
let openerLineHasContent = false;
|
|
100241
|
+
let openerLineOpens = 0;
|
|
100242
|
+
let openerLineCloses = 0;
|
|
97558
100243
|
// Attribute parsing state
|
|
97559
100244
|
let quoteChar = null;
|
|
97560
100245
|
let braceDepth = 0;
|
|
@@ -97643,6 +100328,7 @@ function createTokenize(mode) {
|
|
|
97643
100328
|
if (isLowercaseTag && !sawBraceAttr)
|
|
97644
100329
|
return nok(code);
|
|
97645
100330
|
effects.consume(code);
|
|
100331
|
+
onOpenerLine = isFlow;
|
|
97646
100332
|
return body;
|
|
97647
100333
|
}
|
|
97648
100334
|
// Quoted attribute value
|
|
@@ -97852,10 +100538,19 @@ function createTokenize(mode) {
|
|
|
97852
100538
|
if (markdownLineEnding(code)) {
|
|
97853
100539
|
if (!isFlow)
|
|
97854
100540
|
return nok(code);
|
|
100541
|
+
// See `onOpenerLine` declaration. Bail iff the opener line had
|
|
100542
|
+
// content AND more opener-shaped tokens than closer-shaped tokens.
|
|
100543
|
+
if (onOpenerLine && openerLineHasContent && openerLineOpens > openerLineCloses) {
|
|
100544
|
+
return nok(code);
|
|
100545
|
+
}
|
|
100546
|
+
onOpenerLine = false;
|
|
97855
100547
|
effects.exit('mdxComponentData');
|
|
97856
100548
|
atLineStart = true;
|
|
97857
100549
|
return bodyContinuationStart(code);
|
|
97858
100550
|
}
|
|
100551
|
+
if (code !== codes.space && code !== codes.horizontalTab) {
|
|
100552
|
+
openerLineHasContent = true;
|
|
100553
|
+
}
|
|
97859
100554
|
if (code === codes.backslash) {
|
|
97860
100555
|
effects.consume(code);
|
|
97861
100556
|
return bodyEscapedChar;
|
|
@@ -98003,16 +100698,26 @@ function createTokenize(mode) {
|
|
|
98003
100698
|
// ── Tag detection inside body ──────────────────────────────────────────
|
|
98004
100699
|
function bodyLessThan(code) {
|
|
98005
100700
|
if (code === codes.slash) {
|
|
100701
|
+
if (onOpenerLine)
|
|
100702
|
+
openerLineCloses += 1;
|
|
98006
100703
|
effects.consume(code);
|
|
98007
100704
|
closingTagName = '';
|
|
98008
100705
|
return closingTagNameFirst;
|
|
98009
100706
|
}
|
|
98010
100707
|
// Potential nested opening tag (same case class as the outer tag)
|
|
98011
100708
|
if (code !== null && isAlpha(code) && isSameCaseAsTag(code)) {
|
|
100709
|
+
if (onOpenerLine)
|
|
100710
|
+
openerLineOpens += 1;
|
|
98012
100711
|
closingTagName = String.fromCharCode(code);
|
|
98013
100712
|
effects.consume(code);
|
|
98014
100713
|
return nestedOpenTagName;
|
|
98015
100714
|
}
|
|
100715
|
+
// Tag-like token but not in nested-tracking case (different case).
|
|
100716
|
+
// Count it for the opener-line bail heuristic anyway: `<strong>` in
|
|
100717
|
+
// `<Callout>x <strong>y</strong></Callout>` should pair with `</strong>`.
|
|
100718
|
+
if (code !== null && isAlpha(code) && onOpenerLine) {
|
|
100719
|
+
openerLineOpens += 1;
|
|
100720
|
+
}
|
|
98016
100721
|
atLineStart = false;
|
|
98017
100722
|
return body(code);
|
|
98018
100723
|
}
|
|
@@ -100488,14 +103193,24 @@ const transformImage = (jsx) => {
|
|
|
100488
103193
|
*/
|
|
100489
103194
|
const transformCallout = (jsx) => {
|
|
100490
103195
|
const attrs = getAttrs(jsx);
|
|
100491
|
-
const { empty = false, icon = '', theme = '' } = attrs;
|
|
103196
|
+
const { empty: explicitEmpty = false, icon = '', theme = '' } = attrs;
|
|
103197
|
+
// children[0] is the title slot. Prepend an empty-paragraph placeholder
|
|
103198
|
+
// when JSX has no leading heading, otherwise the body round-trips into it.
|
|
103199
|
+
const jsxChildren = jsx.children;
|
|
103200
|
+
const hasHeadingFirst = jsxChildren[0]?.type === 'heading';
|
|
103201
|
+
const children = hasHeadingFirst
|
|
103202
|
+
? jsxChildren
|
|
103203
|
+
: [
|
|
103204
|
+
{ type: 'paragraph', children: [{ type: 'text', value: '' }] },
|
|
103205
|
+
...jsxChildren,
|
|
103206
|
+
];
|
|
100492
103207
|
return {
|
|
100493
103208
|
type: NodeTypes.callout,
|
|
100494
|
-
children
|
|
103209
|
+
children,
|
|
100495
103210
|
data: {
|
|
100496
103211
|
hName: 'Callout',
|
|
100497
103212
|
hProperties: {
|
|
100498
|
-
empty,
|
|
103213
|
+
empty: explicitEmpty || !hasHeadingFirst,
|
|
100499
103214
|
icon,
|
|
100500
103215
|
theme,
|
|
100501
103216
|
},
|
|
@@ -100772,6 +103487,10 @@ const mdxishJsxToMdast = () => tree => {
|
|
|
100772
103487
|
return SKIP;
|
|
100773
103488
|
if (parent.type === 'paragraph')
|
|
100774
103489
|
return SKIP;
|
|
103490
|
+
// `` in any tableCell stays inline. Authors who want a captioned figure use
|
|
103491
|
+
// `<Image caption="…" />` JSX, which becomes `image-block` via `COMPONENT_MAP` above.
|
|
103492
|
+
if (parent.type === 'tableCell')
|
|
103493
|
+
return SKIP;
|
|
100775
103494
|
const newNode = transformMagicBlockImage(node);
|
|
100776
103495
|
parent.children[index] = newNode;
|
|
100777
103496
|
return SKIP;
|
|
@@ -101374,6 +104093,8 @@ const variablesCodeResolver = ({ variables } = {}) => tree => {
|
|
|
101374
104093
|
visit(tree, 'code', (node) => {
|
|
101375
104094
|
if (!node.value)
|
|
101376
104095
|
return;
|
|
104096
|
+
if (node.lang === 'mermaid')
|
|
104097
|
+
return;
|
|
101377
104098
|
const nextValue = resolveCodeVariables(node.value, resolvedVariables);
|
|
101378
104099
|
node.value = nextValue;
|
|
101379
104100
|
// Keep code-tabs/readme-components hProperties in sync with node.value
|