parse5 6.0.1 → 7.0.0

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.
Files changed (86) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/common/doctype.d.ts +5 -0
  3. package/dist/cjs/common/doctype.js +120 -0
  4. package/dist/cjs/common/error-codes.d.ts +68 -0
  5. package/dist/cjs/common/error-codes.js +67 -0
  6. package/dist/cjs/common/foreign-content.d.ts +10 -0
  7. package/dist/cjs/common/foreign-content.js +239 -0
  8. package/dist/cjs/common/html.d.ts +288 -0
  9. package/dist/cjs/common/html.js +529 -0
  10. package/dist/cjs/common/token.d.ts +85 -0
  11. package/dist/cjs/common/token.js +25 -0
  12. package/dist/cjs/common/unicode.d.ts +49 -0
  13. package/dist/cjs/common/unicode.js +77 -0
  14. package/dist/cjs/index.d.ts +60 -0
  15. package/dist/cjs/index.js +55 -0
  16. package/dist/cjs/package.json +1 -0
  17. package/dist/cjs/parser/formatting-element-list.d.ts +32 -0
  18. package/dist/cjs/parser/formatting-element-list.js +110 -0
  19. package/dist/cjs/parser/index.d.ts +157 -0
  20. package/dist/cjs/parser/index.js +3049 -0
  21. package/dist/cjs/parser/open-element-stack.d.ts +53 -0
  22. package/dist/cjs/parser/open-element-stack.js +316 -0
  23. package/dist/cjs/serializer/index.d.ts +61 -0
  24. package/dist/cjs/serializer/index.js +173 -0
  25. package/dist/cjs/tokenizer/index.d.ts +250 -0
  26. package/dist/cjs/tokenizer/index.js +2921 -0
  27. package/dist/cjs/tokenizer/preprocessor.d.ts +37 -0
  28. package/dist/cjs/tokenizer/preprocessor.js +198 -0
  29. package/dist/cjs/tree-adapters/default.d.ts +92 -0
  30. package/dist/cjs/tree-adapters/default.js +185 -0
  31. package/dist/cjs/tree-adapters/interface.d.ts +250 -0
  32. package/dist/cjs/tree-adapters/interface.js +3 -0
  33. package/dist/common/doctype.d.ts +5 -0
  34. package/{lib → dist}/common/doctype.js +25 -72
  35. package/dist/common/error-codes.d.ts +68 -0
  36. package/dist/common/error-codes.js +64 -0
  37. package/dist/common/foreign-content.d.ts +10 -0
  38. package/dist/common/foreign-content.js +230 -0
  39. package/dist/common/html.d.ts +288 -0
  40. package/dist/common/html.js +523 -0
  41. package/dist/common/token.d.ts +85 -0
  42. package/dist/common/token.js +21 -0
  43. package/dist/common/unicode.d.ts +49 -0
  44. package/dist/common/unicode.js +69 -0
  45. package/dist/index.d.ts +60 -0
  46. package/dist/index.js +44 -0
  47. package/dist/parser/formatting-element-list.d.ts +32 -0
  48. package/dist/parser/formatting-element-list.js +106 -0
  49. package/dist/parser/index.d.ts +157 -0
  50. package/dist/parser/index.js +3054 -0
  51. package/dist/parser/open-element-stack.d.ts +53 -0
  52. package/dist/parser/open-element-stack.js +312 -0
  53. package/dist/serializer/index.d.ts +61 -0
  54. package/dist/serializer/index.js +168 -0
  55. package/dist/tokenizer/index.d.ts +250 -0
  56. package/dist/tokenizer/index.js +2917 -0
  57. package/dist/tokenizer/preprocessor.d.ts +37 -0
  58. package/dist/tokenizer/preprocessor.js +194 -0
  59. package/dist/tree-adapters/default.d.ts +92 -0
  60. package/dist/tree-adapters/default.js +182 -0
  61. package/dist/tree-adapters/interface.d.ts +250 -0
  62. package/dist/tree-adapters/interface.js +2 -0
  63. package/package.json +19 -5
  64. package/lib/common/error-codes.js +0 -65
  65. package/lib/common/foreign-content.js +0 -265
  66. package/lib/common/html.js +0 -272
  67. package/lib/common/unicode.js +0 -109
  68. package/lib/extensions/error-reporting/mixin-base.js +0 -43
  69. package/lib/extensions/error-reporting/parser-mixin.js +0 -52
  70. package/lib/extensions/error-reporting/preprocessor-mixin.js +0 -24
  71. package/lib/extensions/error-reporting/tokenizer-mixin.js +0 -17
  72. package/lib/extensions/location-info/open-element-stack-mixin.js +0 -35
  73. package/lib/extensions/location-info/parser-mixin.js +0 -223
  74. package/lib/extensions/location-info/tokenizer-mixin.js +0 -146
  75. package/lib/extensions/position-tracking/preprocessor-mixin.js +0 -64
  76. package/lib/index.js +0 -29
  77. package/lib/parser/formatting-element-list.js +0 -181
  78. package/lib/parser/index.js +0 -2956
  79. package/lib/parser/open-element-stack.js +0 -482
  80. package/lib/serializer/index.js +0 -176
  81. package/lib/tokenizer/index.js +0 -2196
  82. package/lib/tokenizer/named-entity-data.js +0 -5
  83. package/lib/tokenizer/preprocessor.js +0 -159
  84. package/lib/tree-adapters/default.js +0 -221
  85. package/lib/utils/merge-options.js +0 -13
  86. package/lib/utils/mixin.js +0 -39
@@ -0,0 +1,2921 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tokenizer = exports.TokenizerMode = void 0;
4
+ const preprocessor_js_1 = require("./preprocessor.js");
5
+ const unicode_js_1 = require("../common/unicode.js");
6
+ const token_js_1 = require("../common/token.js");
7
+ const decode_js_1 = require("entities/lib/decode.js");
8
+ const error_codes_js_1 = require("../common/error-codes.js");
9
+ const html_js_1 = require("../common/html.js");
10
+ //C1 Unicode control character reference replacements
11
+ const C1_CONTROLS_REFERENCE_REPLACEMENTS = new Map([
12
+ [0x80, 8364],
13
+ [0x82, 8218],
14
+ [0x83, 402],
15
+ [0x84, 8222],
16
+ [0x85, 8230],
17
+ [0x86, 8224],
18
+ [0x87, 8225],
19
+ [0x88, 710],
20
+ [0x89, 8240],
21
+ [0x8a, 352],
22
+ [0x8b, 8249],
23
+ [0x8c, 338],
24
+ [0x8e, 381],
25
+ [0x91, 8216],
26
+ [0x92, 8217],
27
+ [0x93, 8220],
28
+ [0x94, 8221],
29
+ [0x95, 8226],
30
+ [0x96, 8211],
31
+ [0x97, 8212],
32
+ [0x98, 732],
33
+ [0x99, 8482],
34
+ [0x9a, 353],
35
+ [0x9b, 8250],
36
+ [0x9c, 339],
37
+ [0x9e, 382],
38
+ [0x9f, 376],
39
+ ]);
40
+ //States
41
+ var State;
42
+ (function (State) {
43
+ State[State["DATA"] = 0] = "DATA";
44
+ State[State["RCDATA"] = 1] = "RCDATA";
45
+ State[State["RAWTEXT"] = 2] = "RAWTEXT";
46
+ State[State["SCRIPT_DATA"] = 3] = "SCRIPT_DATA";
47
+ State[State["PLAINTEXT"] = 4] = "PLAINTEXT";
48
+ State[State["TAG_OPEN"] = 5] = "TAG_OPEN";
49
+ State[State["END_TAG_OPEN"] = 6] = "END_TAG_OPEN";
50
+ State[State["TAG_NAME"] = 7] = "TAG_NAME";
51
+ State[State["RCDATA_LESS_THAN_SIGN"] = 8] = "RCDATA_LESS_THAN_SIGN";
52
+ State[State["RCDATA_END_TAG_OPEN"] = 9] = "RCDATA_END_TAG_OPEN";
53
+ State[State["RCDATA_END_TAG_NAME"] = 10] = "RCDATA_END_TAG_NAME";
54
+ State[State["RAWTEXT_LESS_THAN_SIGN"] = 11] = "RAWTEXT_LESS_THAN_SIGN";
55
+ State[State["RAWTEXT_END_TAG_OPEN"] = 12] = "RAWTEXT_END_TAG_OPEN";
56
+ State[State["RAWTEXT_END_TAG_NAME"] = 13] = "RAWTEXT_END_TAG_NAME";
57
+ State[State["SCRIPT_DATA_LESS_THAN_SIGN"] = 14] = "SCRIPT_DATA_LESS_THAN_SIGN";
58
+ State[State["SCRIPT_DATA_END_TAG_OPEN"] = 15] = "SCRIPT_DATA_END_TAG_OPEN";
59
+ State[State["SCRIPT_DATA_END_TAG_NAME"] = 16] = "SCRIPT_DATA_END_TAG_NAME";
60
+ State[State["SCRIPT_DATA_ESCAPE_START"] = 17] = "SCRIPT_DATA_ESCAPE_START";
61
+ State[State["SCRIPT_DATA_ESCAPE_START_DASH"] = 18] = "SCRIPT_DATA_ESCAPE_START_DASH";
62
+ State[State["SCRIPT_DATA_ESCAPED"] = 19] = "SCRIPT_DATA_ESCAPED";
63
+ State[State["SCRIPT_DATA_ESCAPED_DASH"] = 20] = "SCRIPT_DATA_ESCAPED_DASH";
64
+ State[State["SCRIPT_DATA_ESCAPED_DASH_DASH"] = 21] = "SCRIPT_DATA_ESCAPED_DASH_DASH";
65
+ State[State["SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN"] = 22] = "SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN";
66
+ State[State["SCRIPT_DATA_ESCAPED_END_TAG_OPEN"] = 23] = "SCRIPT_DATA_ESCAPED_END_TAG_OPEN";
67
+ State[State["SCRIPT_DATA_ESCAPED_END_TAG_NAME"] = 24] = "SCRIPT_DATA_ESCAPED_END_TAG_NAME";
68
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPE_START"] = 25] = "SCRIPT_DATA_DOUBLE_ESCAPE_START";
69
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPED"] = 26] = "SCRIPT_DATA_DOUBLE_ESCAPED";
70
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPED_DASH"] = 27] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH";
71
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH"] = 28] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH";
72
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN"] = 29] = "SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN";
73
+ State[State["SCRIPT_DATA_DOUBLE_ESCAPE_END"] = 30] = "SCRIPT_DATA_DOUBLE_ESCAPE_END";
74
+ State[State["BEFORE_ATTRIBUTE_NAME"] = 31] = "BEFORE_ATTRIBUTE_NAME";
75
+ State[State["ATTRIBUTE_NAME"] = 32] = "ATTRIBUTE_NAME";
76
+ State[State["AFTER_ATTRIBUTE_NAME"] = 33] = "AFTER_ATTRIBUTE_NAME";
77
+ State[State["BEFORE_ATTRIBUTE_VALUE"] = 34] = "BEFORE_ATTRIBUTE_VALUE";
78
+ State[State["ATTRIBUTE_VALUE_DOUBLE_QUOTED"] = 35] = "ATTRIBUTE_VALUE_DOUBLE_QUOTED";
79
+ State[State["ATTRIBUTE_VALUE_SINGLE_QUOTED"] = 36] = "ATTRIBUTE_VALUE_SINGLE_QUOTED";
80
+ State[State["ATTRIBUTE_VALUE_UNQUOTED"] = 37] = "ATTRIBUTE_VALUE_UNQUOTED";
81
+ State[State["AFTER_ATTRIBUTE_VALUE_QUOTED"] = 38] = "AFTER_ATTRIBUTE_VALUE_QUOTED";
82
+ State[State["SELF_CLOSING_START_TAG"] = 39] = "SELF_CLOSING_START_TAG";
83
+ State[State["BOGUS_COMMENT"] = 40] = "BOGUS_COMMENT";
84
+ State[State["MARKUP_DECLARATION_OPEN"] = 41] = "MARKUP_DECLARATION_OPEN";
85
+ State[State["COMMENT_START"] = 42] = "COMMENT_START";
86
+ State[State["COMMENT_START_DASH"] = 43] = "COMMENT_START_DASH";
87
+ State[State["COMMENT"] = 44] = "COMMENT";
88
+ State[State["COMMENT_LESS_THAN_SIGN"] = 45] = "COMMENT_LESS_THAN_SIGN";
89
+ State[State["COMMENT_LESS_THAN_SIGN_BANG"] = 46] = "COMMENT_LESS_THAN_SIGN_BANG";
90
+ State[State["COMMENT_LESS_THAN_SIGN_BANG_DASH"] = 47] = "COMMENT_LESS_THAN_SIGN_BANG_DASH";
91
+ State[State["COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH"] = 48] = "COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH";
92
+ State[State["COMMENT_END_DASH"] = 49] = "COMMENT_END_DASH";
93
+ State[State["COMMENT_END"] = 50] = "COMMENT_END";
94
+ State[State["COMMENT_END_BANG"] = 51] = "COMMENT_END_BANG";
95
+ State[State["DOCTYPE"] = 52] = "DOCTYPE";
96
+ State[State["BEFORE_DOCTYPE_NAME"] = 53] = "BEFORE_DOCTYPE_NAME";
97
+ State[State["DOCTYPE_NAME"] = 54] = "DOCTYPE_NAME";
98
+ State[State["AFTER_DOCTYPE_NAME"] = 55] = "AFTER_DOCTYPE_NAME";
99
+ State[State["AFTER_DOCTYPE_PUBLIC_KEYWORD"] = 56] = "AFTER_DOCTYPE_PUBLIC_KEYWORD";
100
+ State[State["BEFORE_DOCTYPE_PUBLIC_IDENTIFIER"] = 57] = "BEFORE_DOCTYPE_PUBLIC_IDENTIFIER";
101
+ State[State["DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED"] = 58] = "DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED";
102
+ State[State["DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED"] = 59] = "DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED";
103
+ State[State["AFTER_DOCTYPE_PUBLIC_IDENTIFIER"] = 60] = "AFTER_DOCTYPE_PUBLIC_IDENTIFIER";
104
+ State[State["BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS"] = 61] = "BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS";
105
+ State[State["AFTER_DOCTYPE_SYSTEM_KEYWORD"] = 62] = "AFTER_DOCTYPE_SYSTEM_KEYWORD";
106
+ State[State["BEFORE_DOCTYPE_SYSTEM_IDENTIFIER"] = 63] = "BEFORE_DOCTYPE_SYSTEM_IDENTIFIER";
107
+ State[State["DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED"] = 64] = "DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED";
108
+ State[State["DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED"] = 65] = "DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED";
109
+ State[State["AFTER_DOCTYPE_SYSTEM_IDENTIFIER"] = 66] = "AFTER_DOCTYPE_SYSTEM_IDENTIFIER";
110
+ State[State["BOGUS_DOCTYPE"] = 67] = "BOGUS_DOCTYPE";
111
+ State[State["CDATA_SECTION"] = 68] = "CDATA_SECTION";
112
+ State[State["CDATA_SECTION_BRACKET"] = 69] = "CDATA_SECTION_BRACKET";
113
+ State[State["CDATA_SECTION_END"] = 70] = "CDATA_SECTION_END";
114
+ State[State["CHARACTER_REFERENCE"] = 71] = "CHARACTER_REFERENCE";
115
+ State[State["NAMED_CHARACTER_REFERENCE"] = 72] = "NAMED_CHARACTER_REFERENCE";
116
+ State[State["AMBIGUOUS_AMPERSAND"] = 73] = "AMBIGUOUS_AMPERSAND";
117
+ State[State["NUMERIC_CHARACTER_REFERENCE"] = 74] = "NUMERIC_CHARACTER_REFERENCE";
118
+ State[State["HEXADEMICAL_CHARACTER_REFERENCE_START"] = 75] = "HEXADEMICAL_CHARACTER_REFERENCE_START";
119
+ State[State["DECIMAL_CHARACTER_REFERENCE_START"] = 76] = "DECIMAL_CHARACTER_REFERENCE_START";
120
+ State[State["HEXADEMICAL_CHARACTER_REFERENCE"] = 77] = "HEXADEMICAL_CHARACTER_REFERENCE";
121
+ State[State["DECIMAL_CHARACTER_REFERENCE"] = 78] = "DECIMAL_CHARACTER_REFERENCE";
122
+ State[State["NUMERIC_CHARACTER_REFERENCE_END"] = 79] = "NUMERIC_CHARACTER_REFERENCE_END";
123
+ })(State || (State = {}));
124
+ //Tokenizer initial states for different modes
125
+ exports.TokenizerMode = {
126
+ DATA: State.DATA,
127
+ RCDATA: State.RCDATA,
128
+ RAWTEXT: State.RAWTEXT,
129
+ SCRIPT_DATA: State.SCRIPT_DATA,
130
+ PLAINTEXT: State.PLAINTEXT,
131
+ CDATA_SECTION: State.CDATA_SECTION,
132
+ };
133
+ //Utils
134
+ //OPTIMIZATION: these utility functions should not be moved out of this module. V8 Crankshaft will not inline
135
+ //this functions if they will be situated in another module due to context switch.
136
+ //Always perform inlining check before modifying this functions ('node --trace-inlining').
137
+ function isAsciiDigit(cp) {
138
+ return cp >= unicode_js_1.CODE_POINTS.DIGIT_0 && cp <= unicode_js_1.CODE_POINTS.DIGIT_9;
139
+ }
140
+ function isAsciiUpper(cp) {
141
+ return cp >= unicode_js_1.CODE_POINTS.LATIN_CAPITAL_A && cp <= unicode_js_1.CODE_POINTS.LATIN_CAPITAL_Z;
142
+ }
143
+ function isAsciiLower(cp) {
144
+ return cp >= unicode_js_1.CODE_POINTS.LATIN_SMALL_A && cp <= unicode_js_1.CODE_POINTS.LATIN_SMALL_Z;
145
+ }
146
+ function isAsciiLetter(cp) {
147
+ return isAsciiLower(cp) || isAsciiUpper(cp);
148
+ }
149
+ function isAsciiAlphaNumeric(cp) {
150
+ return isAsciiLetter(cp) || isAsciiDigit(cp);
151
+ }
152
+ function isAsciiUpperHexDigit(cp) {
153
+ return cp >= unicode_js_1.CODE_POINTS.LATIN_CAPITAL_A && cp <= unicode_js_1.CODE_POINTS.LATIN_CAPITAL_F;
154
+ }
155
+ function isAsciiLowerHexDigit(cp) {
156
+ return cp >= unicode_js_1.CODE_POINTS.LATIN_SMALL_A && cp <= unicode_js_1.CODE_POINTS.LATIN_SMALL_F;
157
+ }
158
+ function isAsciiHexDigit(cp) {
159
+ return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
160
+ }
161
+ function toAsciiLower(cp) {
162
+ return cp + 32;
163
+ }
164
+ function isWhitespace(cp) {
165
+ return cp === unicode_js_1.CODE_POINTS.SPACE || cp === unicode_js_1.CODE_POINTS.LINE_FEED || cp === unicode_js_1.CODE_POINTS.TABULATION || cp === unicode_js_1.CODE_POINTS.FORM_FEED;
166
+ }
167
+ function isEntityInAttributeInvalidEnd(nextCp) {
168
+ return nextCp === unicode_js_1.CODE_POINTS.EQUALS_SIGN || isAsciiAlphaNumeric(nextCp);
169
+ }
170
+ function isScriptDataDoubleEscapeSequenceEnd(cp) {
171
+ return isWhitespace(cp) || cp === unicode_js_1.CODE_POINTS.SOLIDUS || cp === unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN;
172
+ }
173
+ //Tokenizer
174
+ class Tokenizer {
175
+ constructor(options, handler) {
176
+ this.options = options;
177
+ this.handler = handler;
178
+ this.paused = false;
179
+ /** Ensures that the parsing loop isn't run multiple times at once. */
180
+ this.inLoop = false;
181
+ /**
182
+ * Indicates that the current adjusted node exists, is not an element in the HTML namespace,
183
+ * and that it is not an integration point for either MathML or HTML.
184
+ *
185
+ * @see {@link https://html.spec.whatwg.org/multipage/parsing.html#tree-construction}
186
+ */
187
+ this.inForeignNode = false;
188
+ this.lastStartTagName = '';
189
+ this.active = false;
190
+ this.state = State.DATA;
191
+ this.returnState = State.DATA;
192
+ this.charRefCode = -1;
193
+ this.consumedAfterSnapshot = -1;
194
+ this.currentCharacterToken = null;
195
+ this.currentToken = null;
196
+ this.currentAttr = { name: '', value: '' };
197
+ this.preprocessor = new preprocessor_js_1.Preprocessor(handler);
198
+ this.currentLocation = this.getCurrentLocation(-1);
199
+ }
200
+ //Errors
201
+ _err(code) {
202
+ var _a, _b;
203
+ (_b = (_a = this.handler).onParseError) === null || _b === void 0 ? void 0 : _b.call(_a, this.preprocessor.getError(code));
204
+ }
205
+ // NOTE: `offset` may never run across line boundaries.
206
+ getCurrentLocation(offset) {
207
+ if (!this.options.sourceCodeLocationInfo) {
208
+ return null;
209
+ }
210
+ return {
211
+ startLine: this.preprocessor.line,
212
+ startCol: this.preprocessor.col - offset,
213
+ startOffset: this.preprocessor.offset - offset,
214
+ endLine: -1,
215
+ endCol: -1,
216
+ endOffset: -1,
217
+ };
218
+ }
219
+ _runParsingLoop() {
220
+ if (this.inLoop)
221
+ return;
222
+ this.inLoop = true;
223
+ while (this.active && !this.paused) {
224
+ this.consumedAfterSnapshot = 0;
225
+ const cp = this._consume();
226
+ if (!this._ensureHibernation()) {
227
+ this._callState(cp);
228
+ }
229
+ }
230
+ this.inLoop = false;
231
+ }
232
+ //API
233
+ pause() {
234
+ this.paused = true;
235
+ }
236
+ resume(writeCallback) {
237
+ if (!this.paused) {
238
+ throw new Error('Parser was already resumed');
239
+ }
240
+ this.paused = false;
241
+ // Necessary for synchronous resume.
242
+ if (this.inLoop)
243
+ return;
244
+ this._runParsingLoop();
245
+ if (!this.paused) {
246
+ writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
247
+ }
248
+ }
249
+ write(chunk, isLastChunk, writeCallback) {
250
+ this.active = true;
251
+ this.preprocessor.write(chunk, isLastChunk);
252
+ this._runParsingLoop();
253
+ if (!this.paused) {
254
+ writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
255
+ }
256
+ }
257
+ insertHtmlAtCurrentPos(chunk) {
258
+ this.active = true;
259
+ this.preprocessor.insertHtmlAtCurrentPos(chunk);
260
+ this._runParsingLoop();
261
+ }
262
+ //Hibernation
263
+ _ensureHibernation() {
264
+ if (this.preprocessor.endOfChunkHit) {
265
+ this._unconsume(this.consumedAfterSnapshot);
266
+ this.active = false;
267
+ return true;
268
+ }
269
+ return false;
270
+ }
271
+ //Consumption
272
+ _consume() {
273
+ this.consumedAfterSnapshot++;
274
+ return this.preprocessor.advance();
275
+ }
276
+ _unconsume(count) {
277
+ this.consumedAfterSnapshot -= count;
278
+ this.preprocessor.retreat(count);
279
+ }
280
+ _reconsumeInState(state) {
281
+ this.state = state;
282
+ this._unconsume(1);
283
+ }
284
+ _advanceBy(count) {
285
+ this.consumedAfterSnapshot += count;
286
+ for (let i = 0; i < count; i++) {
287
+ this.preprocessor.advance();
288
+ }
289
+ }
290
+ _consumeSequenceIfMatch(pattern, caseSensitive) {
291
+ if (this.preprocessor.startsWith(pattern, caseSensitive)) {
292
+ // We will already have consumed one character before calling this method.
293
+ this._advanceBy(pattern.length - 1);
294
+ return true;
295
+ }
296
+ return false;
297
+ }
298
+ //Token creation
299
+ _createStartTagToken() {
300
+ this.currentToken = {
301
+ type: token_js_1.TokenType.START_TAG,
302
+ tagName: '',
303
+ tagID: html_js_1.TAG_ID.UNKNOWN,
304
+ selfClosing: false,
305
+ ackSelfClosing: false,
306
+ attrs: [],
307
+ location: this.getCurrentLocation(1),
308
+ };
309
+ }
310
+ _createEndTagToken() {
311
+ this.currentToken = {
312
+ type: token_js_1.TokenType.END_TAG,
313
+ tagName: '',
314
+ tagID: html_js_1.TAG_ID.UNKNOWN,
315
+ selfClosing: false,
316
+ ackSelfClosing: false,
317
+ attrs: [],
318
+ location: this.getCurrentLocation(2),
319
+ };
320
+ }
321
+ _createCommentToken(offset) {
322
+ this.currentToken = {
323
+ type: token_js_1.TokenType.COMMENT,
324
+ data: '',
325
+ location: this.getCurrentLocation(offset),
326
+ };
327
+ }
328
+ _createDoctypeToken(initialName) {
329
+ this.currentToken = {
330
+ type: token_js_1.TokenType.DOCTYPE,
331
+ name: initialName,
332
+ forceQuirks: false,
333
+ publicId: null,
334
+ systemId: null,
335
+ location: this.currentLocation,
336
+ };
337
+ }
338
+ _createCharacterToken(type, chars) {
339
+ this.currentCharacterToken = {
340
+ type,
341
+ chars,
342
+ location: this.currentLocation,
343
+ };
344
+ }
345
+ //Tag attributes
346
+ _createAttr(attrNameFirstCh) {
347
+ this.currentAttr = {
348
+ name: attrNameFirstCh,
349
+ value: '',
350
+ };
351
+ this.currentLocation = this.getCurrentLocation(0);
352
+ }
353
+ _leaveAttrName() {
354
+ var _a;
355
+ var _b;
356
+ const token = this.currentToken;
357
+ if ((0, token_js_1.getTokenAttr)(token, this.currentAttr.name) === null) {
358
+ token.attrs.push(this.currentAttr);
359
+ if (token.location && this.currentLocation) {
360
+ const attrLocations = ((_a = (_b = token.location).attrs) !== null && _a !== void 0 ? _a : (_b.attrs = Object.create(null)));
361
+ attrLocations[this.currentAttr.name] = this.currentLocation;
362
+ // Set end location
363
+ this._leaveAttrValue();
364
+ }
365
+ }
366
+ else {
367
+ this._err(error_codes_js_1.ERR.duplicateAttribute);
368
+ }
369
+ }
370
+ _leaveAttrValue() {
371
+ if (this.currentLocation) {
372
+ this.currentLocation.endLine = this.preprocessor.line;
373
+ this.currentLocation.endCol = this.preprocessor.col;
374
+ this.currentLocation.endOffset = this.preprocessor.offset;
375
+ }
376
+ }
377
+ //Token emission
378
+ prepareToken(ct) {
379
+ this._emitCurrentCharacterToken(ct.location);
380
+ this.currentToken = null;
381
+ if (ct.location) {
382
+ ct.location.endLine = this.preprocessor.line;
383
+ ct.location.endCol = this.preprocessor.col + 1;
384
+ ct.location.endOffset = this.preprocessor.offset + 1;
385
+ }
386
+ this.currentLocation = this.getCurrentLocation(-1);
387
+ }
388
+ emitCurrentTagToken() {
389
+ const ct = this.currentToken;
390
+ this.prepareToken(ct);
391
+ ct.tagID = (0, html_js_1.getTagID)(ct.tagName);
392
+ if (ct.type === token_js_1.TokenType.START_TAG) {
393
+ this.lastStartTagName = ct.tagName;
394
+ this.handler.onStartTag(ct);
395
+ }
396
+ else {
397
+ if (ct.attrs.length > 0) {
398
+ this._err(error_codes_js_1.ERR.endTagWithAttributes);
399
+ }
400
+ if (ct.selfClosing) {
401
+ this._err(error_codes_js_1.ERR.endTagWithTrailingSolidus);
402
+ }
403
+ this.handler.onEndTag(ct);
404
+ }
405
+ this.preprocessor.dropParsedChunk();
406
+ }
407
+ emitCurrentComment(ct) {
408
+ this.prepareToken(ct);
409
+ this.handler.onComment(ct);
410
+ this.preprocessor.dropParsedChunk();
411
+ }
412
+ emitCurrentDoctype(ct) {
413
+ this.prepareToken(ct);
414
+ this.handler.onDoctype(ct);
415
+ this.preprocessor.dropParsedChunk();
416
+ }
417
+ _emitCurrentCharacterToken(nextLocation) {
418
+ if (this.currentCharacterToken) {
419
+ //NOTE: if we have a pending character token, make it's end location equal to the
420
+ //current token's start location.
421
+ if (nextLocation && this.currentCharacterToken.location) {
422
+ this.currentCharacterToken.location.endLine = nextLocation.startLine;
423
+ this.currentCharacterToken.location.endCol = nextLocation.startCol;
424
+ this.currentCharacterToken.location.endOffset = nextLocation.startOffset;
425
+ }
426
+ switch (this.currentCharacterToken.type) {
427
+ case token_js_1.TokenType.CHARACTER: {
428
+ this.handler.onCharacter(this.currentCharacterToken);
429
+ break;
430
+ }
431
+ case token_js_1.TokenType.NULL_CHARACTER: {
432
+ this.handler.onNullCharacter(this.currentCharacterToken);
433
+ break;
434
+ }
435
+ case token_js_1.TokenType.WHITESPACE_CHARACTER: {
436
+ this.handler.onWhitespaceCharacter(this.currentCharacterToken);
437
+ break;
438
+ }
439
+ }
440
+ this.currentCharacterToken = null;
441
+ }
442
+ }
443
+ _emitEOFToken() {
444
+ const location = this.getCurrentLocation(0);
445
+ if (location) {
446
+ location.endLine = location.startLine;
447
+ location.endCol = location.startCol;
448
+ location.endOffset = location.startOffset;
449
+ }
450
+ this._emitCurrentCharacterToken(location);
451
+ this.handler.onEof({ type: token_js_1.TokenType.EOF, location });
452
+ this.active = false;
453
+ }
454
+ //Characters emission
455
+ //OPTIMIZATION: specification uses only one type of character tokens (one token per character).
456
+ //This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
457
+ //If we have a sequence of characters that belong to the same group, the parser can process it
458
+ //as a single solid character token.
459
+ //So, there are 3 types of character tokens in parse5:
460
+ //1)TokenType.NULL_CHARACTER - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
461
+ //2)TokenType.WHITESPACE_CHARACTER - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
462
+ //3)TokenType.CHARACTER - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
463
+ _appendCharToCurrentCharacterToken(type, ch) {
464
+ if (this.currentCharacterToken) {
465
+ if (this.currentCharacterToken.type !== type) {
466
+ this.currentLocation = this.getCurrentLocation(0);
467
+ this._emitCurrentCharacterToken(this.currentLocation);
468
+ this.preprocessor.dropParsedChunk();
469
+ }
470
+ else {
471
+ this.currentCharacterToken.chars += ch;
472
+ return;
473
+ }
474
+ }
475
+ this._createCharacterToken(type, ch);
476
+ }
477
+ _emitCodePoint(cp) {
478
+ let type = token_js_1.TokenType.CHARACTER;
479
+ if (isWhitespace(cp)) {
480
+ type = token_js_1.TokenType.WHITESPACE_CHARACTER;
481
+ }
482
+ else if (cp === unicode_js_1.CODE_POINTS.NULL) {
483
+ type = token_js_1.TokenType.NULL_CHARACTER;
484
+ }
485
+ this._appendCharToCurrentCharacterToken(type, String.fromCodePoint(cp));
486
+ }
487
+ //NOTE: used when we emit characters explicitly.
488
+ //This is always for non-whitespace and non-null characters, which allows us to avoid additional checks.
489
+ _emitChars(ch) {
490
+ this._appendCharToCurrentCharacterToken(token_js_1.TokenType.CHARACTER, ch);
491
+ }
492
+ // Character reference helpers
493
+ _matchNamedCharacterReference(cp) {
494
+ let result = null;
495
+ let excess = 0;
496
+ let withoutSemicolon = false;
497
+ for (let i = 0, current = decode_js_1.htmlDecodeTree[0]; i >= 0; cp = this._consume()) {
498
+ i = (0, decode_js_1.determineBranch)(decode_js_1.htmlDecodeTree, current, i + 1, cp);
499
+ if (i < 0)
500
+ break;
501
+ excess += 1;
502
+ current = decode_js_1.htmlDecodeTree[i];
503
+ const masked = current & decode_js_1.BinTrieFlags.VALUE_LENGTH;
504
+ // If the branch is a value, store it and continue
505
+ if (masked) {
506
+ // The mask is the number of bytes of the value, including the current byte.
507
+ const valueLength = (masked >> 14) - 1;
508
+ // Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.
509
+ // See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
510
+ if (cp !== unicode_js_1.CODE_POINTS.SEMICOLON &&
511
+ this._isCharacterReferenceInAttribute() &&
512
+ isEntityInAttributeInvalidEnd(this.preprocessor.peek(1))) {
513
+ //NOTE: we don't flush all consumed code points here, and instead switch back to the original state after
514
+ //emitting an ampersand. This is fine, as alphanumeric characters won't be parsed differently in attributes.
515
+ result = [unicode_js_1.CODE_POINTS.AMPERSAND];
516
+ // Skip over the value.
517
+ i += valueLength;
518
+ }
519
+ else {
520
+ // If this is a surrogate pair, consume the next two bytes.
521
+ result =
522
+ valueLength === 0
523
+ ? [decode_js_1.htmlDecodeTree[i] & ~decode_js_1.BinTrieFlags.VALUE_LENGTH]
524
+ : valueLength === 1
525
+ ? [decode_js_1.htmlDecodeTree[++i]]
526
+ : [decode_js_1.htmlDecodeTree[++i], decode_js_1.htmlDecodeTree[++i]];
527
+ excess = 0;
528
+ withoutSemicolon = cp !== unicode_js_1.CODE_POINTS.SEMICOLON;
529
+ }
530
+ if (valueLength === 0) {
531
+ // If the value is zero-length, we're done.
532
+ this._consume();
533
+ break;
534
+ }
535
+ }
536
+ }
537
+ this._unconsume(excess);
538
+ if (withoutSemicolon && !this.preprocessor.endOfChunkHit) {
539
+ this._err(error_codes_js_1.ERR.missingSemicolonAfterCharacterReference);
540
+ }
541
+ // We want to emit the error above on the code point after the entity.
542
+ // We always consume one code point too many in the loop, and we wait to
543
+ // unconsume it until after the error is emitted.
544
+ this._unconsume(1);
545
+ return result;
546
+ }
547
+ _isCharacterReferenceInAttribute() {
548
+ return (this.returnState === State.ATTRIBUTE_VALUE_DOUBLE_QUOTED ||
549
+ this.returnState === State.ATTRIBUTE_VALUE_SINGLE_QUOTED ||
550
+ this.returnState === State.ATTRIBUTE_VALUE_UNQUOTED);
551
+ }
552
+ _flushCodePointConsumedAsCharacterReference(cp) {
553
+ if (this._isCharacterReferenceInAttribute()) {
554
+ this.currentAttr.value += String.fromCodePoint(cp);
555
+ }
556
+ else {
557
+ this._emitCodePoint(cp);
558
+ }
559
+ }
560
+ // Calling states this way turns out to be much faster than any other approach.
561
+ _callState(cp) {
562
+ switch (this.state) {
563
+ case State.DATA: {
564
+ this._stateData(cp);
565
+ break;
566
+ }
567
+ case State.RCDATA: {
568
+ this._stateRcdata(cp);
569
+ break;
570
+ }
571
+ case State.RAWTEXT: {
572
+ this._stateRawtext(cp);
573
+ break;
574
+ }
575
+ case State.SCRIPT_DATA: {
576
+ this._stateScriptData(cp);
577
+ break;
578
+ }
579
+ case State.PLAINTEXT: {
580
+ this._statePlaintext(cp);
581
+ break;
582
+ }
583
+ case State.TAG_OPEN: {
584
+ this._stateTagOpen(cp);
585
+ break;
586
+ }
587
+ case State.END_TAG_OPEN: {
588
+ this._stateEndTagOpen(cp);
589
+ break;
590
+ }
591
+ case State.TAG_NAME: {
592
+ this._stateTagName(cp);
593
+ break;
594
+ }
595
+ case State.RCDATA_LESS_THAN_SIGN: {
596
+ this._stateRcdataLessThanSign(cp);
597
+ break;
598
+ }
599
+ case State.RCDATA_END_TAG_OPEN: {
600
+ this._stateRcdataEndTagOpen(cp);
601
+ break;
602
+ }
603
+ case State.RCDATA_END_TAG_NAME: {
604
+ this._stateRcdataEndTagName(cp);
605
+ break;
606
+ }
607
+ case State.RAWTEXT_LESS_THAN_SIGN: {
608
+ this._stateRawtextLessThanSign(cp);
609
+ break;
610
+ }
611
+ case State.RAWTEXT_END_TAG_OPEN: {
612
+ this._stateRawtextEndTagOpen(cp);
613
+ break;
614
+ }
615
+ case State.RAWTEXT_END_TAG_NAME: {
616
+ this._stateRawtextEndTagName(cp);
617
+ break;
618
+ }
619
+ case State.SCRIPT_DATA_LESS_THAN_SIGN: {
620
+ this._stateScriptDataLessThanSign(cp);
621
+ break;
622
+ }
623
+ case State.SCRIPT_DATA_END_TAG_OPEN: {
624
+ this._stateScriptDataEndTagOpen(cp);
625
+ break;
626
+ }
627
+ case State.SCRIPT_DATA_END_TAG_NAME: {
628
+ this._stateScriptDataEndTagName(cp);
629
+ break;
630
+ }
631
+ case State.SCRIPT_DATA_ESCAPE_START: {
632
+ this._stateScriptDataEscapeStart(cp);
633
+ break;
634
+ }
635
+ case State.SCRIPT_DATA_ESCAPE_START_DASH: {
636
+ this._stateScriptDataEscapeStartDash(cp);
637
+ break;
638
+ }
639
+ case State.SCRIPT_DATA_ESCAPED: {
640
+ this._stateScriptDataEscaped(cp);
641
+ break;
642
+ }
643
+ case State.SCRIPT_DATA_ESCAPED_DASH: {
644
+ this._stateScriptDataEscapedDash(cp);
645
+ break;
646
+ }
647
+ case State.SCRIPT_DATA_ESCAPED_DASH_DASH: {
648
+ this._stateScriptDataEscapedDashDash(cp);
649
+ break;
650
+ }
651
+ case State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
652
+ this._stateScriptDataEscapedLessThanSign(cp);
653
+ break;
654
+ }
655
+ case State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN: {
656
+ this._stateScriptDataEscapedEndTagOpen(cp);
657
+ break;
658
+ }
659
+ case State.SCRIPT_DATA_ESCAPED_END_TAG_NAME: {
660
+ this._stateScriptDataEscapedEndTagName(cp);
661
+ break;
662
+ }
663
+ case State.SCRIPT_DATA_DOUBLE_ESCAPE_START: {
664
+ this._stateScriptDataDoubleEscapeStart(cp);
665
+ break;
666
+ }
667
+ case State.SCRIPT_DATA_DOUBLE_ESCAPED: {
668
+ this._stateScriptDataDoubleEscaped(cp);
669
+ break;
670
+ }
671
+ case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
672
+ this._stateScriptDataDoubleEscapedDash(cp);
673
+ break;
674
+ }
675
+ case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
676
+ this._stateScriptDataDoubleEscapedDashDash(cp);
677
+ break;
678
+ }
679
+ case State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
680
+ this._stateScriptDataDoubleEscapedLessThanSign(cp);
681
+ break;
682
+ }
683
+ case State.SCRIPT_DATA_DOUBLE_ESCAPE_END: {
684
+ this._stateScriptDataDoubleEscapeEnd(cp);
685
+ break;
686
+ }
687
+ case State.BEFORE_ATTRIBUTE_NAME: {
688
+ this._stateBeforeAttributeName(cp);
689
+ break;
690
+ }
691
+ case State.ATTRIBUTE_NAME: {
692
+ this._stateAttributeName(cp);
693
+ break;
694
+ }
695
+ case State.AFTER_ATTRIBUTE_NAME: {
696
+ this._stateAfterAttributeName(cp);
697
+ break;
698
+ }
699
+ case State.BEFORE_ATTRIBUTE_VALUE: {
700
+ this._stateBeforeAttributeValue(cp);
701
+ break;
702
+ }
703
+ case State.ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
704
+ this._stateAttributeValueDoubleQuoted(cp);
705
+ break;
706
+ }
707
+ case State.ATTRIBUTE_VALUE_SINGLE_QUOTED: {
708
+ this._stateAttributeValueSingleQuoted(cp);
709
+ break;
710
+ }
711
+ case State.ATTRIBUTE_VALUE_UNQUOTED: {
712
+ this._stateAttributeValueUnquoted(cp);
713
+ break;
714
+ }
715
+ case State.AFTER_ATTRIBUTE_VALUE_QUOTED: {
716
+ this._stateAfterAttributeValueQuoted(cp);
717
+ break;
718
+ }
719
+ case State.SELF_CLOSING_START_TAG: {
720
+ this._stateSelfClosingStartTag(cp);
721
+ break;
722
+ }
723
+ case State.BOGUS_COMMENT: {
724
+ this._stateBogusComment(cp);
725
+ break;
726
+ }
727
+ case State.MARKUP_DECLARATION_OPEN: {
728
+ this._stateMarkupDeclarationOpen(cp);
729
+ break;
730
+ }
731
+ case State.COMMENT_START: {
732
+ this._stateCommentStart(cp);
733
+ break;
734
+ }
735
+ case State.COMMENT_START_DASH: {
736
+ this._stateCommentStartDash(cp);
737
+ break;
738
+ }
739
+ case State.COMMENT: {
740
+ this._stateComment(cp);
741
+ break;
742
+ }
743
+ case State.COMMENT_LESS_THAN_SIGN: {
744
+ this._stateCommentLessThanSign(cp);
745
+ break;
746
+ }
747
+ case State.COMMENT_LESS_THAN_SIGN_BANG: {
748
+ this._stateCommentLessThanSignBang(cp);
749
+ break;
750
+ }
751
+ case State.COMMENT_LESS_THAN_SIGN_BANG_DASH: {
752
+ this._stateCommentLessThanSignBangDash(cp);
753
+ break;
754
+ }
755
+ case State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: {
756
+ this._stateCommentLessThanSignBangDashDash(cp);
757
+ break;
758
+ }
759
+ case State.COMMENT_END_DASH: {
760
+ this._stateCommentEndDash(cp);
761
+ break;
762
+ }
763
+ case State.COMMENT_END: {
764
+ this._stateCommentEnd(cp);
765
+ break;
766
+ }
767
+ case State.COMMENT_END_BANG: {
768
+ this._stateCommentEndBang(cp);
769
+ break;
770
+ }
771
+ case State.DOCTYPE: {
772
+ this._stateDoctype(cp);
773
+ break;
774
+ }
775
+ case State.BEFORE_DOCTYPE_NAME: {
776
+ this._stateBeforeDoctypeName(cp);
777
+ break;
778
+ }
779
+ case State.DOCTYPE_NAME: {
780
+ this._stateDoctypeName(cp);
781
+ break;
782
+ }
783
+ case State.AFTER_DOCTYPE_NAME: {
784
+ this._stateAfterDoctypeName(cp);
785
+ break;
786
+ }
787
+ case State.AFTER_DOCTYPE_PUBLIC_KEYWORD: {
788
+ this._stateAfterDoctypePublicKeyword(cp);
789
+ break;
790
+ }
791
+ case State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
792
+ this._stateBeforeDoctypePublicIdentifier(cp);
793
+ break;
794
+ }
795
+ case State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
796
+ this._stateDoctypePublicIdentifierDoubleQuoted(cp);
797
+ break;
798
+ }
799
+ case State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
800
+ this._stateDoctypePublicIdentifierSingleQuoted(cp);
801
+ break;
802
+ }
803
+ case State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
804
+ this._stateAfterDoctypePublicIdentifier(cp);
805
+ break;
806
+ }
807
+ case State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
808
+ this._stateBetweenDoctypePublicAndSystemIdentifiers(cp);
809
+ break;
810
+ }
811
+ case State.AFTER_DOCTYPE_SYSTEM_KEYWORD: {
812
+ this._stateAfterDoctypeSystemKeyword(cp);
813
+ break;
814
+ }
815
+ case State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
816
+ this._stateBeforeDoctypeSystemIdentifier(cp);
817
+ break;
818
+ }
819
+ case State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
820
+ this._stateDoctypeSystemIdentifierDoubleQuoted(cp);
821
+ break;
822
+ }
823
+ case State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
824
+ this._stateDoctypeSystemIdentifierSingleQuoted(cp);
825
+ break;
826
+ }
827
+ case State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
828
+ this._stateAfterDoctypeSystemIdentifier(cp);
829
+ break;
830
+ }
831
+ case State.BOGUS_DOCTYPE: {
832
+ this._stateBogusDoctype(cp);
833
+ break;
834
+ }
835
+ case State.CDATA_SECTION: {
836
+ this._stateCdataSection(cp);
837
+ break;
838
+ }
839
+ case State.CDATA_SECTION_BRACKET: {
840
+ this._stateCdataSectionBracket(cp);
841
+ break;
842
+ }
843
+ case State.CDATA_SECTION_END: {
844
+ this._stateCdataSectionEnd(cp);
845
+ break;
846
+ }
847
+ case State.CHARACTER_REFERENCE: {
848
+ this._stateCharacterReference(cp);
849
+ break;
850
+ }
851
+ case State.NAMED_CHARACTER_REFERENCE: {
852
+ this._stateNamedCharacterReference(cp);
853
+ break;
854
+ }
855
+ case State.AMBIGUOUS_AMPERSAND: {
856
+ this._stateAmbiguousAmpersand(cp);
857
+ break;
858
+ }
859
+ case State.NUMERIC_CHARACTER_REFERENCE: {
860
+ this._stateNumericCharacterReference(cp);
861
+ break;
862
+ }
863
+ case State.HEXADEMICAL_CHARACTER_REFERENCE_START: {
864
+ this._stateHexademicalCharacterReferenceStart(cp);
865
+ break;
866
+ }
867
+ case State.DECIMAL_CHARACTER_REFERENCE_START: {
868
+ this._stateDecimalCharacterReferenceStart(cp);
869
+ break;
870
+ }
871
+ case State.HEXADEMICAL_CHARACTER_REFERENCE: {
872
+ this._stateHexademicalCharacterReference(cp);
873
+ break;
874
+ }
875
+ case State.DECIMAL_CHARACTER_REFERENCE: {
876
+ this._stateDecimalCharacterReference(cp);
877
+ break;
878
+ }
879
+ case State.NUMERIC_CHARACTER_REFERENCE_END: {
880
+ this._stateNumericCharacterReferenceEnd();
881
+ break;
882
+ }
883
+ default: {
884
+ throw new Error('Unknown state');
885
+ }
886
+ }
887
+ }
888
+ // State machine
889
+ // Data state
890
+ //------------------------------------------------------------------
891
+ _stateData(cp) {
892
+ switch (cp) {
893
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
894
+ this.state = State.TAG_OPEN;
895
+ break;
896
+ }
897
+ case unicode_js_1.CODE_POINTS.AMPERSAND: {
898
+ this.returnState = State.DATA;
899
+ this.state = State.CHARACTER_REFERENCE;
900
+ break;
901
+ }
902
+ case unicode_js_1.CODE_POINTS.NULL: {
903
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
904
+ this._emitCodePoint(cp);
905
+ break;
906
+ }
907
+ case unicode_js_1.CODE_POINTS.EOF: {
908
+ this._emitEOFToken();
909
+ break;
910
+ }
911
+ default: {
912
+ this._emitCodePoint(cp);
913
+ }
914
+ }
915
+ }
916
+ // RCDATA state
917
+ //------------------------------------------------------------------
918
+ _stateRcdata(cp) {
919
+ switch (cp) {
920
+ case unicode_js_1.CODE_POINTS.AMPERSAND: {
921
+ this.returnState = State.RCDATA;
922
+ this.state = State.CHARACTER_REFERENCE;
923
+ break;
924
+ }
925
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
926
+ this.state = State.RCDATA_LESS_THAN_SIGN;
927
+ break;
928
+ }
929
+ case unicode_js_1.CODE_POINTS.NULL: {
930
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
931
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
932
+ break;
933
+ }
934
+ case unicode_js_1.CODE_POINTS.EOF: {
935
+ this._emitEOFToken();
936
+ break;
937
+ }
938
+ default: {
939
+ this._emitCodePoint(cp);
940
+ }
941
+ }
942
+ }
943
+ // RAWTEXT state
944
+ //------------------------------------------------------------------
945
+ _stateRawtext(cp) {
946
+ switch (cp) {
947
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
948
+ this.state = State.RAWTEXT_LESS_THAN_SIGN;
949
+ break;
950
+ }
951
+ case unicode_js_1.CODE_POINTS.NULL: {
952
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
953
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
954
+ break;
955
+ }
956
+ case unicode_js_1.CODE_POINTS.EOF: {
957
+ this._emitEOFToken();
958
+ break;
959
+ }
960
+ default: {
961
+ this._emitCodePoint(cp);
962
+ }
963
+ }
964
+ }
965
+ // Script data state
966
+ //------------------------------------------------------------------
967
+ _stateScriptData(cp) {
968
+ switch (cp) {
969
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
970
+ this.state = State.SCRIPT_DATA_LESS_THAN_SIGN;
971
+ break;
972
+ }
973
+ case unicode_js_1.CODE_POINTS.NULL: {
974
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
975
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
976
+ break;
977
+ }
978
+ case unicode_js_1.CODE_POINTS.EOF: {
979
+ this._emitEOFToken();
980
+ break;
981
+ }
982
+ default: {
983
+ this._emitCodePoint(cp);
984
+ }
985
+ }
986
+ }
987
+ // PLAINTEXT state
988
+ //------------------------------------------------------------------
989
+ _statePlaintext(cp) {
990
+ switch (cp) {
991
+ case unicode_js_1.CODE_POINTS.NULL: {
992
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
993
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
994
+ break;
995
+ }
996
+ case unicode_js_1.CODE_POINTS.EOF: {
997
+ this._emitEOFToken();
998
+ break;
999
+ }
1000
+ default: {
1001
+ this._emitCodePoint(cp);
1002
+ }
1003
+ }
1004
+ }
1005
+ // Tag open state
1006
+ //------------------------------------------------------------------
1007
+ _stateTagOpen(cp) {
1008
+ if (isAsciiLetter(cp)) {
1009
+ this._createStartTagToken();
1010
+ this.state = State.TAG_NAME;
1011
+ this._stateTagName(cp);
1012
+ }
1013
+ else
1014
+ switch (cp) {
1015
+ case unicode_js_1.CODE_POINTS.EXCLAMATION_MARK: {
1016
+ this.state = State.MARKUP_DECLARATION_OPEN;
1017
+ break;
1018
+ }
1019
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1020
+ this.state = State.END_TAG_OPEN;
1021
+ break;
1022
+ }
1023
+ case unicode_js_1.CODE_POINTS.QUESTION_MARK: {
1024
+ this._err(error_codes_js_1.ERR.unexpectedQuestionMarkInsteadOfTagName);
1025
+ this._createCommentToken(1);
1026
+ this.state = State.BOGUS_COMMENT;
1027
+ this._stateBogusComment(cp);
1028
+ break;
1029
+ }
1030
+ case unicode_js_1.CODE_POINTS.EOF: {
1031
+ this._err(error_codes_js_1.ERR.eofBeforeTagName);
1032
+ this._emitChars('<');
1033
+ this._emitEOFToken();
1034
+ break;
1035
+ }
1036
+ default: {
1037
+ this._err(error_codes_js_1.ERR.invalidFirstCharacterOfTagName);
1038
+ this._emitChars('<');
1039
+ this.state = State.DATA;
1040
+ this._stateData(cp);
1041
+ }
1042
+ }
1043
+ }
1044
+ // End tag open state
1045
+ //------------------------------------------------------------------
1046
+ _stateEndTagOpen(cp) {
1047
+ if (isAsciiLetter(cp)) {
1048
+ this._createEndTagToken();
1049
+ this.state = State.TAG_NAME;
1050
+ this._stateTagName(cp);
1051
+ }
1052
+ else
1053
+ switch (cp) {
1054
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1055
+ this._err(error_codes_js_1.ERR.missingEndTagName);
1056
+ this.state = State.DATA;
1057
+ break;
1058
+ }
1059
+ case unicode_js_1.CODE_POINTS.EOF: {
1060
+ this._err(error_codes_js_1.ERR.eofBeforeTagName);
1061
+ this._emitChars('</');
1062
+ this._emitEOFToken();
1063
+ break;
1064
+ }
1065
+ default: {
1066
+ this._err(error_codes_js_1.ERR.invalidFirstCharacterOfTagName);
1067
+ this._createCommentToken(2);
1068
+ this.state = State.BOGUS_COMMENT;
1069
+ this._stateBogusComment(cp);
1070
+ }
1071
+ }
1072
+ }
1073
+ // Tag name state
1074
+ //------------------------------------------------------------------
1075
+ _stateTagName(cp) {
1076
+ const token = this.currentToken;
1077
+ switch (cp) {
1078
+ case unicode_js_1.CODE_POINTS.SPACE:
1079
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1080
+ case unicode_js_1.CODE_POINTS.TABULATION:
1081
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1082
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1083
+ break;
1084
+ }
1085
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1086
+ this.state = State.SELF_CLOSING_START_TAG;
1087
+ break;
1088
+ }
1089
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1090
+ this.state = State.DATA;
1091
+ this.emitCurrentTagToken();
1092
+ break;
1093
+ }
1094
+ case unicode_js_1.CODE_POINTS.NULL: {
1095
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1096
+ token.tagName += unicode_js_1.REPLACEMENT_CHARACTER;
1097
+ break;
1098
+ }
1099
+ case unicode_js_1.CODE_POINTS.EOF: {
1100
+ this._err(error_codes_js_1.ERR.eofInTag);
1101
+ this._emitEOFToken();
1102
+ break;
1103
+ }
1104
+ default: {
1105
+ token.tagName += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
1106
+ }
1107
+ }
1108
+ }
1109
+ // RCDATA less-than sign state
1110
+ //------------------------------------------------------------------
1111
+ _stateRcdataLessThanSign(cp) {
1112
+ if (cp === unicode_js_1.CODE_POINTS.SOLIDUS) {
1113
+ this.state = State.RCDATA_END_TAG_OPEN;
1114
+ }
1115
+ else {
1116
+ this._emitChars('<');
1117
+ this.state = State.RCDATA;
1118
+ this._stateRcdata(cp);
1119
+ }
1120
+ }
1121
+ // RCDATA end tag open state
1122
+ //------------------------------------------------------------------
1123
+ _stateRcdataEndTagOpen(cp) {
1124
+ if (isAsciiLetter(cp)) {
1125
+ this.state = State.RCDATA_END_TAG_NAME;
1126
+ this._stateRcdataEndTagName(cp);
1127
+ }
1128
+ else {
1129
+ this._emitChars('</');
1130
+ this.state = State.RCDATA;
1131
+ this._stateRcdata(cp);
1132
+ }
1133
+ }
1134
+ handleSpecialEndTag(_cp) {
1135
+ if (!this.preprocessor.startsWith(this.lastStartTagName, false)) {
1136
+ return !this._ensureHibernation();
1137
+ }
1138
+ this._createEndTagToken();
1139
+ const token = this.currentToken;
1140
+ token.tagName = this.lastStartTagName;
1141
+ const cp = this.preprocessor.peek(this.lastStartTagName.length);
1142
+ switch (cp) {
1143
+ case unicode_js_1.CODE_POINTS.SPACE:
1144
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1145
+ case unicode_js_1.CODE_POINTS.TABULATION:
1146
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1147
+ this._advanceBy(this.lastStartTagName.length);
1148
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1149
+ return false;
1150
+ }
1151
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1152
+ this._advanceBy(this.lastStartTagName.length);
1153
+ this.state = State.SELF_CLOSING_START_TAG;
1154
+ return false;
1155
+ }
1156
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1157
+ this._advanceBy(this.lastStartTagName.length);
1158
+ this.emitCurrentTagToken();
1159
+ this.state = State.DATA;
1160
+ return false;
1161
+ }
1162
+ default: {
1163
+ return !this._ensureHibernation();
1164
+ }
1165
+ }
1166
+ }
1167
+ // RCDATA end tag name state
1168
+ //------------------------------------------------------------------
1169
+ _stateRcdataEndTagName(cp) {
1170
+ if (this.handleSpecialEndTag(cp)) {
1171
+ this._emitChars('</');
1172
+ this.state = State.RCDATA;
1173
+ this._stateRcdata(cp);
1174
+ }
1175
+ }
1176
+ // RAWTEXT less-than sign state
1177
+ //------------------------------------------------------------------
1178
+ _stateRawtextLessThanSign(cp) {
1179
+ if (cp === unicode_js_1.CODE_POINTS.SOLIDUS) {
1180
+ this.state = State.RAWTEXT_END_TAG_OPEN;
1181
+ }
1182
+ else {
1183
+ this._emitChars('<');
1184
+ this.state = State.RAWTEXT;
1185
+ this._stateRawtext(cp);
1186
+ }
1187
+ }
1188
+ // RAWTEXT end tag open state
1189
+ //------------------------------------------------------------------
1190
+ _stateRawtextEndTagOpen(cp) {
1191
+ if (isAsciiLetter(cp)) {
1192
+ this.state = State.RAWTEXT_END_TAG_NAME;
1193
+ this._stateRawtextEndTagName(cp);
1194
+ }
1195
+ else {
1196
+ this._emitChars('</');
1197
+ this.state = State.RAWTEXT;
1198
+ this._stateRawtext(cp);
1199
+ }
1200
+ }
1201
+ // RAWTEXT end tag name state
1202
+ //------------------------------------------------------------------
1203
+ _stateRawtextEndTagName(cp) {
1204
+ if (this.handleSpecialEndTag(cp)) {
1205
+ this._emitChars('</');
1206
+ this.state = State.RAWTEXT;
1207
+ this._stateRawtext(cp);
1208
+ }
1209
+ }
1210
+ // Script data less-than sign state
1211
+ //------------------------------------------------------------------
1212
+ _stateScriptDataLessThanSign(cp) {
1213
+ switch (cp) {
1214
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1215
+ this.state = State.SCRIPT_DATA_END_TAG_OPEN;
1216
+ break;
1217
+ }
1218
+ case unicode_js_1.CODE_POINTS.EXCLAMATION_MARK: {
1219
+ this.state = State.SCRIPT_DATA_ESCAPE_START;
1220
+ this._emitChars('<!');
1221
+ break;
1222
+ }
1223
+ default: {
1224
+ this._emitChars('<');
1225
+ this.state = State.SCRIPT_DATA;
1226
+ this._stateScriptData(cp);
1227
+ }
1228
+ }
1229
+ }
1230
+ // Script data end tag open state
1231
+ //------------------------------------------------------------------
1232
+ _stateScriptDataEndTagOpen(cp) {
1233
+ if (isAsciiLetter(cp)) {
1234
+ this.state = State.SCRIPT_DATA_END_TAG_NAME;
1235
+ this._stateScriptDataEndTagName(cp);
1236
+ }
1237
+ else {
1238
+ this._emitChars('</');
1239
+ this.state = State.SCRIPT_DATA;
1240
+ this._stateScriptData(cp);
1241
+ }
1242
+ }
1243
+ // Script data end tag name state
1244
+ //------------------------------------------------------------------
1245
+ _stateScriptDataEndTagName(cp) {
1246
+ if (this.handleSpecialEndTag(cp)) {
1247
+ this._emitChars('</');
1248
+ this.state = State.SCRIPT_DATA;
1249
+ this._stateScriptData(cp);
1250
+ }
1251
+ }
1252
+ // Script data escape start state
1253
+ //------------------------------------------------------------------
1254
+ _stateScriptDataEscapeStart(cp) {
1255
+ if (cp === unicode_js_1.CODE_POINTS.HYPHEN_MINUS) {
1256
+ this.state = State.SCRIPT_DATA_ESCAPE_START_DASH;
1257
+ this._emitChars('-');
1258
+ }
1259
+ else {
1260
+ this.state = State.SCRIPT_DATA;
1261
+ this._stateScriptData(cp);
1262
+ }
1263
+ }
1264
+ // Script data escape start dash state
1265
+ //------------------------------------------------------------------
1266
+ _stateScriptDataEscapeStartDash(cp) {
1267
+ if (cp === unicode_js_1.CODE_POINTS.HYPHEN_MINUS) {
1268
+ this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
1269
+ this._emitChars('-');
1270
+ }
1271
+ else {
1272
+ this.state = State.SCRIPT_DATA;
1273
+ this._stateScriptData(cp);
1274
+ }
1275
+ }
1276
+ // Script data escaped state
1277
+ //------------------------------------------------------------------
1278
+ _stateScriptDataEscaped(cp) {
1279
+ switch (cp) {
1280
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1281
+ this.state = State.SCRIPT_DATA_ESCAPED_DASH;
1282
+ this._emitChars('-');
1283
+ break;
1284
+ }
1285
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1286
+ this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
1287
+ break;
1288
+ }
1289
+ case unicode_js_1.CODE_POINTS.NULL: {
1290
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1291
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1292
+ break;
1293
+ }
1294
+ case unicode_js_1.CODE_POINTS.EOF: {
1295
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1296
+ this._emitEOFToken();
1297
+ break;
1298
+ }
1299
+ default: {
1300
+ this._emitCodePoint(cp);
1301
+ }
1302
+ }
1303
+ }
1304
+ // Script data escaped dash state
1305
+ //------------------------------------------------------------------
1306
+ _stateScriptDataEscapedDash(cp) {
1307
+ switch (cp) {
1308
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1309
+ this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
1310
+ this._emitChars('-');
1311
+ break;
1312
+ }
1313
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1314
+ this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
1315
+ break;
1316
+ }
1317
+ case unicode_js_1.CODE_POINTS.NULL: {
1318
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1319
+ this.state = State.SCRIPT_DATA_ESCAPED;
1320
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1321
+ break;
1322
+ }
1323
+ case unicode_js_1.CODE_POINTS.EOF: {
1324
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1325
+ this._emitEOFToken();
1326
+ break;
1327
+ }
1328
+ default: {
1329
+ this.state = State.SCRIPT_DATA_ESCAPED;
1330
+ this._emitCodePoint(cp);
1331
+ }
1332
+ }
1333
+ }
1334
+ // Script data escaped dash dash state
1335
+ //------------------------------------------------------------------
1336
+ _stateScriptDataEscapedDashDash(cp) {
1337
+ switch (cp) {
1338
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1339
+ this._emitChars('-');
1340
+ break;
1341
+ }
1342
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1343
+ this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
1344
+ break;
1345
+ }
1346
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1347
+ this.state = State.SCRIPT_DATA;
1348
+ this._emitChars('>');
1349
+ break;
1350
+ }
1351
+ case unicode_js_1.CODE_POINTS.NULL: {
1352
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1353
+ this.state = State.SCRIPT_DATA_ESCAPED;
1354
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1355
+ break;
1356
+ }
1357
+ case unicode_js_1.CODE_POINTS.EOF: {
1358
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1359
+ this._emitEOFToken();
1360
+ break;
1361
+ }
1362
+ default: {
1363
+ this.state = State.SCRIPT_DATA_ESCAPED;
1364
+ this._emitCodePoint(cp);
1365
+ }
1366
+ }
1367
+ }
1368
+ // Script data escaped less-than sign state
1369
+ //------------------------------------------------------------------
1370
+ _stateScriptDataEscapedLessThanSign(cp) {
1371
+ if (cp === unicode_js_1.CODE_POINTS.SOLIDUS) {
1372
+ this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN;
1373
+ }
1374
+ else if (isAsciiLetter(cp)) {
1375
+ this._emitChars('<');
1376
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_START;
1377
+ this._stateScriptDataDoubleEscapeStart(cp);
1378
+ }
1379
+ else {
1380
+ this._emitChars('<');
1381
+ this.state = State.SCRIPT_DATA_ESCAPED;
1382
+ this._stateScriptDataEscaped(cp);
1383
+ }
1384
+ }
1385
+ // Script data escaped end tag open state
1386
+ //------------------------------------------------------------------
1387
+ _stateScriptDataEscapedEndTagOpen(cp) {
1388
+ if (isAsciiLetter(cp)) {
1389
+ this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_NAME;
1390
+ this._stateScriptDataEscapedEndTagName(cp);
1391
+ }
1392
+ else {
1393
+ this._emitChars('</');
1394
+ this.state = State.SCRIPT_DATA_ESCAPED;
1395
+ this._stateScriptDataEscaped(cp);
1396
+ }
1397
+ }
1398
+ // Script data escaped end tag name state
1399
+ //------------------------------------------------------------------
1400
+ _stateScriptDataEscapedEndTagName(cp) {
1401
+ if (this.handleSpecialEndTag(cp)) {
1402
+ this._emitChars('</');
1403
+ this.state = State.SCRIPT_DATA_ESCAPED;
1404
+ this._stateScriptDataEscaped(cp);
1405
+ }
1406
+ }
1407
+ // Script data double escape start state
1408
+ //------------------------------------------------------------------
1409
+ _stateScriptDataDoubleEscapeStart(cp) {
1410
+ if (this.preprocessor.startsWith(unicode_js_1.SEQUENCES.SCRIPT, false) &&
1411
+ isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(unicode_js_1.SEQUENCES.SCRIPT.length))) {
1412
+ this._emitCodePoint(cp);
1413
+ for (let i = 0; i < unicode_js_1.SEQUENCES.SCRIPT.length; i++) {
1414
+ this._emitCodePoint(this._consume());
1415
+ }
1416
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1417
+ }
1418
+ else if (!this._ensureHibernation()) {
1419
+ this.state = State.SCRIPT_DATA_ESCAPED;
1420
+ this._stateScriptDataEscaped(cp);
1421
+ }
1422
+ }
1423
+ // Script data double escaped state
1424
+ //------------------------------------------------------------------
1425
+ _stateScriptDataDoubleEscaped(cp) {
1426
+ switch (cp) {
1427
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1428
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH;
1429
+ this._emitChars('-');
1430
+ break;
1431
+ }
1432
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1433
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
1434
+ this._emitChars('<');
1435
+ break;
1436
+ }
1437
+ case unicode_js_1.CODE_POINTS.NULL: {
1438
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1439
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1440
+ break;
1441
+ }
1442
+ case unicode_js_1.CODE_POINTS.EOF: {
1443
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1444
+ this._emitEOFToken();
1445
+ break;
1446
+ }
1447
+ default: {
1448
+ this._emitCodePoint(cp);
1449
+ }
1450
+ }
1451
+ }
1452
+ // Script data double escaped dash state
1453
+ //------------------------------------------------------------------
1454
+ _stateScriptDataDoubleEscapedDash(cp) {
1455
+ switch (cp) {
1456
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1457
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH;
1458
+ this._emitChars('-');
1459
+ break;
1460
+ }
1461
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1462
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
1463
+ this._emitChars('<');
1464
+ break;
1465
+ }
1466
+ case unicode_js_1.CODE_POINTS.NULL: {
1467
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1468
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1469
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1470
+ break;
1471
+ }
1472
+ case unicode_js_1.CODE_POINTS.EOF: {
1473
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1474
+ this._emitEOFToken();
1475
+ break;
1476
+ }
1477
+ default: {
1478
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1479
+ this._emitCodePoint(cp);
1480
+ }
1481
+ }
1482
+ }
1483
+ // Script data double escaped dash dash state
1484
+ //------------------------------------------------------------------
1485
+ _stateScriptDataDoubleEscapedDashDash(cp) {
1486
+ switch (cp) {
1487
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1488
+ this._emitChars('-');
1489
+ break;
1490
+ }
1491
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1492
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
1493
+ this._emitChars('<');
1494
+ break;
1495
+ }
1496
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1497
+ this.state = State.SCRIPT_DATA;
1498
+ this._emitChars('>');
1499
+ break;
1500
+ }
1501
+ case unicode_js_1.CODE_POINTS.NULL: {
1502
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1503
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1504
+ this._emitChars(unicode_js_1.REPLACEMENT_CHARACTER);
1505
+ break;
1506
+ }
1507
+ case unicode_js_1.CODE_POINTS.EOF: {
1508
+ this._err(error_codes_js_1.ERR.eofInScriptHtmlCommentLikeText);
1509
+ this._emitEOFToken();
1510
+ break;
1511
+ }
1512
+ default: {
1513
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1514
+ this._emitCodePoint(cp);
1515
+ }
1516
+ }
1517
+ }
1518
+ // Script data double escaped less-than sign state
1519
+ //------------------------------------------------------------------
1520
+ _stateScriptDataDoubleEscapedLessThanSign(cp) {
1521
+ if (cp === unicode_js_1.CODE_POINTS.SOLIDUS) {
1522
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_END;
1523
+ this._emitChars('/');
1524
+ }
1525
+ else {
1526
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1527
+ this._stateScriptDataDoubleEscaped(cp);
1528
+ }
1529
+ }
1530
+ // Script data double escape end state
1531
+ //------------------------------------------------------------------
1532
+ _stateScriptDataDoubleEscapeEnd(cp) {
1533
+ if (this.preprocessor.startsWith(unicode_js_1.SEQUENCES.SCRIPT, false) &&
1534
+ isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(unicode_js_1.SEQUENCES.SCRIPT.length))) {
1535
+ this._emitCodePoint(cp);
1536
+ for (let i = 0; i < unicode_js_1.SEQUENCES.SCRIPT.length; i++) {
1537
+ this._emitCodePoint(this._consume());
1538
+ }
1539
+ this.state = State.SCRIPT_DATA_ESCAPED;
1540
+ }
1541
+ else if (!this._ensureHibernation()) {
1542
+ this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
1543
+ this._stateScriptDataDoubleEscaped(cp);
1544
+ }
1545
+ }
1546
+ // Before attribute name state
1547
+ //------------------------------------------------------------------
1548
+ _stateBeforeAttributeName(cp) {
1549
+ switch (cp) {
1550
+ case unicode_js_1.CODE_POINTS.SPACE:
1551
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1552
+ case unicode_js_1.CODE_POINTS.TABULATION:
1553
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1554
+ // Ignore whitespace
1555
+ break;
1556
+ }
1557
+ case unicode_js_1.CODE_POINTS.SOLIDUS:
1558
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN:
1559
+ case unicode_js_1.CODE_POINTS.EOF: {
1560
+ this.state = State.AFTER_ATTRIBUTE_NAME;
1561
+ this._stateAfterAttributeName(cp);
1562
+ break;
1563
+ }
1564
+ case unicode_js_1.CODE_POINTS.EQUALS_SIGN: {
1565
+ this._err(error_codes_js_1.ERR.unexpectedEqualsSignBeforeAttributeName);
1566
+ this._createAttr('=');
1567
+ this.state = State.ATTRIBUTE_NAME;
1568
+ break;
1569
+ }
1570
+ default: {
1571
+ this._createAttr('');
1572
+ this.state = State.ATTRIBUTE_NAME;
1573
+ this._stateAttributeName(cp);
1574
+ }
1575
+ }
1576
+ }
1577
+ // Attribute name state
1578
+ //------------------------------------------------------------------
1579
+ _stateAttributeName(cp) {
1580
+ switch (cp) {
1581
+ case unicode_js_1.CODE_POINTS.SPACE:
1582
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1583
+ case unicode_js_1.CODE_POINTS.TABULATION:
1584
+ case unicode_js_1.CODE_POINTS.FORM_FEED:
1585
+ case unicode_js_1.CODE_POINTS.SOLIDUS:
1586
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN:
1587
+ case unicode_js_1.CODE_POINTS.EOF: {
1588
+ this._leaveAttrName();
1589
+ this.state = State.AFTER_ATTRIBUTE_NAME;
1590
+ this._stateAfterAttributeName(cp);
1591
+ break;
1592
+ }
1593
+ case unicode_js_1.CODE_POINTS.EQUALS_SIGN: {
1594
+ this._leaveAttrName();
1595
+ this.state = State.BEFORE_ATTRIBUTE_VALUE;
1596
+ break;
1597
+ }
1598
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK:
1599
+ case unicode_js_1.CODE_POINTS.APOSTROPHE:
1600
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1601
+ this._err(error_codes_js_1.ERR.unexpectedCharacterInAttributeName);
1602
+ this.currentAttr.name += String.fromCodePoint(cp);
1603
+ break;
1604
+ }
1605
+ case unicode_js_1.CODE_POINTS.NULL: {
1606
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1607
+ this.currentAttr.name += unicode_js_1.REPLACEMENT_CHARACTER;
1608
+ break;
1609
+ }
1610
+ default: {
1611
+ this.currentAttr.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
1612
+ }
1613
+ }
1614
+ }
1615
+ // After attribute name state
1616
+ //------------------------------------------------------------------
1617
+ _stateAfterAttributeName(cp) {
1618
+ switch (cp) {
1619
+ case unicode_js_1.CODE_POINTS.SPACE:
1620
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1621
+ case unicode_js_1.CODE_POINTS.TABULATION:
1622
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1623
+ // Ignore whitespace
1624
+ break;
1625
+ }
1626
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1627
+ this.state = State.SELF_CLOSING_START_TAG;
1628
+ break;
1629
+ }
1630
+ case unicode_js_1.CODE_POINTS.EQUALS_SIGN: {
1631
+ this.state = State.BEFORE_ATTRIBUTE_VALUE;
1632
+ break;
1633
+ }
1634
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1635
+ this.state = State.DATA;
1636
+ this.emitCurrentTagToken();
1637
+ break;
1638
+ }
1639
+ case unicode_js_1.CODE_POINTS.EOF: {
1640
+ this._err(error_codes_js_1.ERR.eofInTag);
1641
+ this._emitEOFToken();
1642
+ break;
1643
+ }
1644
+ default: {
1645
+ this._createAttr('');
1646
+ this.state = State.ATTRIBUTE_NAME;
1647
+ this._stateAttributeName(cp);
1648
+ }
1649
+ }
1650
+ }
1651
+ // Before attribute value state
1652
+ //------------------------------------------------------------------
1653
+ _stateBeforeAttributeValue(cp) {
1654
+ switch (cp) {
1655
+ case unicode_js_1.CODE_POINTS.SPACE:
1656
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1657
+ case unicode_js_1.CODE_POINTS.TABULATION:
1658
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1659
+ // Ignore whitespace
1660
+ break;
1661
+ }
1662
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
1663
+ this.state = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
1664
+ break;
1665
+ }
1666
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
1667
+ this.state = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
1668
+ break;
1669
+ }
1670
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1671
+ this._err(error_codes_js_1.ERR.missingAttributeValue);
1672
+ this.state = State.DATA;
1673
+ this.emitCurrentTagToken();
1674
+ break;
1675
+ }
1676
+ default: {
1677
+ this.state = State.ATTRIBUTE_VALUE_UNQUOTED;
1678
+ this._stateAttributeValueUnquoted(cp);
1679
+ }
1680
+ }
1681
+ }
1682
+ // Attribute value (double-quoted) state
1683
+ //------------------------------------------------------------------
1684
+ _stateAttributeValueDoubleQuoted(cp) {
1685
+ switch (cp) {
1686
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
1687
+ this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
1688
+ break;
1689
+ }
1690
+ case unicode_js_1.CODE_POINTS.AMPERSAND: {
1691
+ this.returnState = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
1692
+ this.state = State.CHARACTER_REFERENCE;
1693
+ break;
1694
+ }
1695
+ case unicode_js_1.CODE_POINTS.NULL: {
1696
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1697
+ this.currentAttr.value += unicode_js_1.REPLACEMENT_CHARACTER;
1698
+ break;
1699
+ }
1700
+ case unicode_js_1.CODE_POINTS.EOF: {
1701
+ this._err(error_codes_js_1.ERR.eofInTag);
1702
+ this._emitEOFToken();
1703
+ break;
1704
+ }
1705
+ default: {
1706
+ this.currentAttr.value += String.fromCodePoint(cp);
1707
+ }
1708
+ }
1709
+ }
1710
+ // Attribute value (single-quoted) state
1711
+ //------------------------------------------------------------------
1712
+ _stateAttributeValueSingleQuoted(cp) {
1713
+ switch (cp) {
1714
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
1715
+ this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
1716
+ break;
1717
+ }
1718
+ case unicode_js_1.CODE_POINTS.AMPERSAND: {
1719
+ this.returnState = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
1720
+ this.state = State.CHARACTER_REFERENCE;
1721
+ break;
1722
+ }
1723
+ case unicode_js_1.CODE_POINTS.NULL: {
1724
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1725
+ this.currentAttr.value += unicode_js_1.REPLACEMENT_CHARACTER;
1726
+ break;
1727
+ }
1728
+ case unicode_js_1.CODE_POINTS.EOF: {
1729
+ this._err(error_codes_js_1.ERR.eofInTag);
1730
+ this._emitEOFToken();
1731
+ break;
1732
+ }
1733
+ default: {
1734
+ this.currentAttr.value += String.fromCodePoint(cp);
1735
+ }
1736
+ }
1737
+ }
1738
+ // Attribute value (unquoted) state
1739
+ //------------------------------------------------------------------
1740
+ _stateAttributeValueUnquoted(cp) {
1741
+ switch (cp) {
1742
+ case unicode_js_1.CODE_POINTS.SPACE:
1743
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1744
+ case unicode_js_1.CODE_POINTS.TABULATION:
1745
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1746
+ this._leaveAttrValue();
1747
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1748
+ break;
1749
+ }
1750
+ case unicode_js_1.CODE_POINTS.AMPERSAND: {
1751
+ this.returnState = State.ATTRIBUTE_VALUE_UNQUOTED;
1752
+ this.state = State.CHARACTER_REFERENCE;
1753
+ break;
1754
+ }
1755
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1756
+ this._leaveAttrValue();
1757
+ this.state = State.DATA;
1758
+ this.emitCurrentTagToken();
1759
+ break;
1760
+ }
1761
+ case unicode_js_1.CODE_POINTS.NULL: {
1762
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1763
+ this.currentAttr.value += unicode_js_1.REPLACEMENT_CHARACTER;
1764
+ break;
1765
+ }
1766
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK:
1767
+ case unicode_js_1.CODE_POINTS.APOSTROPHE:
1768
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN:
1769
+ case unicode_js_1.CODE_POINTS.EQUALS_SIGN:
1770
+ case unicode_js_1.CODE_POINTS.GRAVE_ACCENT: {
1771
+ this._err(error_codes_js_1.ERR.unexpectedCharacterInUnquotedAttributeValue);
1772
+ this.currentAttr.value += String.fromCodePoint(cp);
1773
+ break;
1774
+ }
1775
+ case unicode_js_1.CODE_POINTS.EOF: {
1776
+ this._err(error_codes_js_1.ERR.eofInTag);
1777
+ this._emitEOFToken();
1778
+ break;
1779
+ }
1780
+ default: {
1781
+ this.currentAttr.value += String.fromCodePoint(cp);
1782
+ }
1783
+ }
1784
+ }
1785
+ // After attribute value (quoted) state
1786
+ //------------------------------------------------------------------
1787
+ _stateAfterAttributeValueQuoted(cp) {
1788
+ switch (cp) {
1789
+ case unicode_js_1.CODE_POINTS.SPACE:
1790
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
1791
+ case unicode_js_1.CODE_POINTS.TABULATION:
1792
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
1793
+ this._leaveAttrValue();
1794
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1795
+ break;
1796
+ }
1797
+ case unicode_js_1.CODE_POINTS.SOLIDUS: {
1798
+ this._leaveAttrValue();
1799
+ this.state = State.SELF_CLOSING_START_TAG;
1800
+ break;
1801
+ }
1802
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1803
+ this._leaveAttrValue();
1804
+ this.state = State.DATA;
1805
+ this.emitCurrentTagToken();
1806
+ break;
1807
+ }
1808
+ case unicode_js_1.CODE_POINTS.EOF: {
1809
+ this._err(error_codes_js_1.ERR.eofInTag);
1810
+ this._emitEOFToken();
1811
+ break;
1812
+ }
1813
+ default: {
1814
+ this._err(error_codes_js_1.ERR.missingWhitespaceBetweenAttributes);
1815
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1816
+ this._stateBeforeAttributeName(cp);
1817
+ }
1818
+ }
1819
+ }
1820
+ // Self-closing start tag state
1821
+ //------------------------------------------------------------------
1822
+ _stateSelfClosingStartTag(cp) {
1823
+ switch (cp) {
1824
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1825
+ const token = this.currentToken;
1826
+ token.selfClosing = true;
1827
+ this.state = State.DATA;
1828
+ this.emitCurrentTagToken();
1829
+ break;
1830
+ }
1831
+ case unicode_js_1.CODE_POINTS.EOF: {
1832
+ this._err(error_codes_js_1.ERR.eofInTag);
1833
+ this._emitEOFToken();
1834
+ break;
1835
+ }
1836
+ default: {
1837
+ this._err(error_codes_js_1.ERR.unexpectedSolidusInTag);
1838
+ this.state = State.BEFORE_ATTRIBUTE_NAME;
1839
+ this._stateBeforeAttributeName(cp);
1840
+ }
1841
+ }
1842
+ }
1843
+ // Bogus comment state
1844
+ //------------------------------------------------------------------
1845
+ _stateBogusComment(cp) {
1846
+ const token = this.currentToken;
1847
+ switch (cp) {
1848
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1849
+ this.state = State.DATA;
1850
+ this.emitCurrentComment(token);
1851
+ break;
1852
+ }
1853
+ case unicode_js_1.CODE_POINTS.EOF: {
1854
+ this.emitCurrentComment(token);
1855
+ this._emitEOFToken();
1856
+ break;
1857
+ }
1858
+ case unicode_js_1.CODE_POINTS.NULL: {
1859
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1860
+ token.data += unicode_js_1.REPLACEMENT_CHARACTER;
1861
+ break;
1862
+ }
1863
+ default: {
1864
+ token.data += String.fromCodePoint(cp);
1865
+ }
1866
+ }
1867
+ }
1868
+ // Markup declaration open state
1869
+ //------------------------------------------------------------------
1870
+ _stateMarkupDeclarationOpen(cp) {
1871
+ if (this._consumeSequenceIfMatch(unicode_js_1.SEQUENCES.DASH_DASH, true)) {
1872
+ this._createCommentToken(unicode_js_1.SEQUENCES.DASH_DASH.length + 1);
1873
+ this.state = State.COMMENT_START;
1874
+ }
1875
+ else if (this._consumeSequenceIfMatch(unicode_js_1.SEQUENCES.DOCTYPE, false)) {
1876
+ // NOTE: Doctypes tokens are created without fixed offsets. We keep track of the moment a doctype *might* start here.
1877
+ this.currentLocation = this.getCurrentLocation(unicode_js_1.SEQUENCES.DOCTYPE.length + 1);
1878
+ this.state = State.DOCTYPE;
1879
+ }
1880
+ else if (this._consumeSequenceIfMatch(unicode_js_1.SEQUENCES.CDATA_START, true)) {
1881
+ if (this.inForeignNode) {
1882
+ this.state = State.CDATA_SECTION;
1883
+ }
1884
+ else {
1885
+ this._err(error_codes_js_1.ERR.cdataInHtmlContent);
1886
+ this._createCommentToken(unicode_js_1.SEQUENCES.CDATA_START.length + 1);
1887
+ this.currentToken.data = '[CDATA[';
1888
+ this.state = State.BOGUS_COMMENT;
1889
+ }
1890
+ }
1891
+ //NOTE: Sequence lookups can be abrupted by hibernation. In that case, lookup
1892
+ //results are no longer valid and we will need to start over.
1893
+ else if (!this._ensureHibernation()) {
1894
+ this._err(error_codes_js_1.ERR.incorrectlyOpenedComment);
1895
+ this._createCommentToken(2);
1896
+ this.state = State.BOGUS_COMMENT;
1897
+ this._stateBogusComment(cp);
1898
+ }
1899
+ }
1900
+ // Comment start state
1901
+ //------------------------------------------------------------------
1902
+ _stateCommentStart(cp) {
1903
+ switch (cp) {
1904
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1905
+ this.state = State.COMMENT_START_DASH;
1906
+ break;
1907
+ }
1908
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1909
+ this._err(error_codes_js_1.ERR.abruptClosingOfEmptyComment);
1910
+ this.state = State.DATA;
1911
+ const token = this.currentToken;
1912
+ this.emitCurrentComment(token);
1913
+ break;
1914
+ }
1915
+ default: {
1916
+ this.state = State.COMMENT;
1917
+ this._stateComment(cp);
1918
+ }
1919
+ }
1920
+ }
1921
+ // Comment start dash state
1922
+ //------------------------------------------------------------------
1923
+ _stateCommentStartDash(cp) {
1924
+ const token = this.currentToken;
1925
+ switch (cp) {
1926
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1927
+ this.state = State.COMMENT_END;
1928
+ break;
1929
+ }
1930
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
1931
+ this._err(error_codes_js_1.ERR.abruptClosingOfEmptyComment);
1932
+ this.state = State.DATA;
1933
+ this.emitCurrentComment(token);
1934
+ break;
1935
+ }
1936
+ case unicode_js_1.CODE_POINTS.EOF: {
1937
+ this._err(error_codes_js_1.ERR.eofInComment);
1938
+ this.emitCurrentComment(token);
1939
+ this._emitEOFToken();
1940
+ break;
1941
+ }
1942
+ default: {
1943
+ token.data += '-';
1944
+ this.state = State.COMMENT;
1945
+ this._stateComment(cp);
1946
+ }
1947
+ }
1948
+ }
1949
+ // Comment state
1950
+ //------------------------------------------------------------------
1951
+ _stateComment(cp) {
1952
+ const token = this.currentToken;
1953
+ switch (cp) {
1954
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
1955
+ this.state = State.COMMENT_END_DASH;
1956
+ break;
1957
+ }
1958
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1959
+ token.data += '<';
1960
+ this.state = State.COMMENT_LESS_THAN_SIGN;
1961
+ break;
1962
+ }
1963
+ case unicode_js_1.CODE_POINTS.NULL: {
1964
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
1965
+ token.data += unicode_js_1.REPLACEMENT_CHARACTER;
1966
+ break;
1967
+ }
1968
+ case unicode_js_1.CODE_POINTS.EOF: {
1969
+ this._err(error_codes_js_1.ERR.eofInComment);
1970
+ this.emitCurrentComment(token);
1971
+ this._emitEOFToken();
1972
+ break;
1973
+ }
1974
+ default: {
1975
+ token.data += String.fromCodePoint(cp);
1976
+ }
1977
+ }
1978
+ }
1979
+ // Comment less-than sign state
1980
+ //------------------------------------------------------------------
1981
+ _stateCommentLessThanSign(cp) {
1982
+ const token = this.currentToken;
1983
+ switch (cp) {
1984
+ case unicode_js_1.CODE_POINTS.EXCLAMATION_MARK: {
1985
+ token.data += '!';
1986
+ this.state = State.COMMENT_LESS_THAN_SIGN_BANG;
1987
+ break;
1988
+ }
1989
+ case unicode_js_1.CODE_POINTS.LESS_THAN_SIGN: {
1990
+ token.data += '<';
1991
+ break;
1992
+ }
1993
+ default: {
1994
+ this.state = State.COMMENT;
1995
+ this._stateComment(cp);
1996
+ }
1997
+ }
1998
+ }
1999
+ // Comment less-than sign bang state
2000
+ //------------------------------------------------------------------
2001
+ _stateCommentLessThanSignBang(cp) {
2002
+ if (cp === unicode_js_1.CODE_POINTS.HYPHEN_MINUS) {
2003
+ this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH;
2004
+ }
2005
+ else {
2006
+ this.state = State.COMMENT;
2007
+ this._stateComment(cp);
2008
+ }
2009
+ }
2010
+ // Comment less-than sign bang dash state
2011
+ //------------------------------------------------------------------
2012
+ _stateCommentLessThanSignBangDash(cp) {
2013
+ if (cp === unicode_js_1.CODE_POINTS.HYPHEN_MINUS) {
2014
+ this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
2015
+ }
2016
+ else {
2017
+ this.state = State.COMMENT_END_DASH;
2018
+ this._stateCommentEndDash(cp);
2019
+ }
2020
+ }
2021
+ // Comment less-than sign bang dash dash state
2022
+ //------------------------------------------------------------------
2023
+ _stateCommentLessThanSignBangDashDash(cp) {
2024
+ if (cp !== unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN && cp !== unicode_js_1.CODE_POINTS.EOF) {
2025
+ this._err(error_codes_js_1.ERR.nestedComment);
2026
+ }
2027
+ this.state = State.COMMENT_END;
2028
+ this._stateCommentEnd(cp);
2029
+ }
2030
+ // Comment end dash state
2031
+ //------------------------------------------------------------------
2032
+ _stateCommentEndDash(cp) {
2033
+ const token = this.currentToken;
2034
+ switch (cp) {
2035
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
2036
+ this.state = State.COMMENT_END;
2037
+ break;
2038
+ }
2039
+ case unicode_js_1.CODE_POINTS.EOF: {
2040
+ this._err(error_codes_js_1.ERR.eofInComment);
2041
+ this.emitCurrentComment(token);
2042
+ this._emitEOFToken();
2043
+ break;
2044
+ }
2045
+ default: {
2046
+ token.data += '-';
2047
+ this.state = State.COMMENT;
2048
+ this._stateComment(cp);
2049
+ }
2050
+ }
2051
+ }
2052
+ // Comment end state
2053
+ //------------------------------------------------------------------
2054
+ _stateCommentEnd(cp) {
2055
+ const token = this.currentToken;
2056
+ switch (cp) {
2057
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2058
+ this.state = State.DATA;
2059
+ this.emitCurrentComment(token);
2060
+ break;
2061
+ }
2062
+ case unicode_js_1.CODE_POINTS.EXCLAMATION_MARK: {
2063
+ this.state = State.COMMENT_END_BANG;
2064
+ break;
2065
+ }
2066
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
2067
+ token.data += '-';
2068
+ break;
2069
+ }
2070
+ case unicode_js_1.CODE_POINTS.EOF: {
2071
+ this._err(error_codes_js_1.ERR.eofInComment);
2072
+ this.emitCurrentComment(token);
2073
+ this._emitEOFToken();
2074
+ break;
2075
+ }
2076
+ default: {
2077
+ token.data += '--';
2078
+ this.state = State.COMMENT;
2079
+ this._stateComment(cp);
2080
+ }
2081
+ }
2082
+ }
2083
+ // Comment end bang state
2084
+ //------------------------------------------------------------------
2085
+ _stateCommentEndBang(cp) {
2086
+ const token = this.currentToken;
2087
+ switch (cp) {
2088
+ case unicode_js_1.CODE_POINTS.HYPHEN_MINUS: {
2089
+ token.data += '--!';
2090
+ this.state = State.COMMENT_END_DASH;
2091
+ break;
2092
+ }
2093
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2094
+ this._err(error_codes_js_1.ERR.incorrectlyClosedComment);
2095
+ this.state = State.DATA;
2096
+ this.emitCurrentComment(token);
2097
+ break;
2098
+ }
2099
+ case unicode_js_1.CODE_POINTS.EOF: {
2100
+ this._err(error_codes_js_1.ERR.eofInComment);
2101
+ this.emitCurrentComment(token);
2102
+ this._emitEOFToken();
2103
+ break;
2104
+ }
2105
+ default: {
2106
+ token.data += '--!';
2107
+ this.state = State.COMMENT;
2108
+ this._stateComment(cp);
2109
+ }
2110
+ }
2111
+ }
2112
+ // DOCTYPE state
2113
+ //------------------------------------------------------------------
2114
+ _stateDoctype(cp) {
2115
+ switch (cp) {
2116
+ case unicode_js_1.CODE_POINTS.SPACE:
2117
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2118
+ case unicode_js_1.CODE_POINTS.TABULATION:
2119
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2120
+ this.state = State.BEFORE_DOCTYPE_NAME;
2121
+ break;
2122
+ }
2123
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2124
+ this.state = State.BEFORE_DOCTYPE_NAME;
2125
+ this._stateBeforeDoctypeName(cp);
2126
+ break;
2127
+ }
2128
+ case unicode_js_1.CODE_POINTS.EOF: {
2129
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2130
+ this._createDoctypeToken(null);
2131
+ const token = this.currentToken;
2132
+ token.forceQuirks = true;
2133
+ this.emitCurrentDoctype(token);
2134
+ this._emitEOFToken();
2135
+ break;
2136
+ }
2137
+ default: {
2138
+ this._err(error_codes_js_1.ERR.missingWhitespaceBeforeDoctypeName);
2139
+ this.state = State.BEFORE_DOCTYPE_NAME;
2140
+ this._stateBeforeDoctypeName(cp);
2141
+ }
2142
+ }
2143
+ }
2144
+ // Before DOCTYPE name state
2145
+ //------------------------------------------------------------------
2146
+ _stateBeforeDoctypeName(cp) {
2147
+ if (isAsciiUpper(cp)) {
2148
+ this._createDoctypeToken(String.fromCharCode(toAsciiLower(cp)));
2149
+ this.state = State.DOCTYPE_NAME;
2150
+ }
2151
+ else
2152
+ switch (cp) {
2153
+ case unicode_js_1.CODE_POINTS.SPACE:
2154
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2155
+ case unicode_js_1.CODE_POINTS.TABULATION:
2156
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2157
+ // Ignore whitespace
2158
+ break;
2159
+ }
2160
+ case unicode_js_1.CODE_POINTS.NULL: {
2161
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2162
+ this._createDoctypeToken(unicode_js_1.REPLACEMENT_CHARACTER);
2163
+ this.state = State.DOCTYPE_NAME;
2164
+ break;
2165
+ }
2166
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2167
+ this._err(error_codes_js_1.ERR.missingDoctypeName);
2168
+ this._createDoctypeToken(null);
2169
+ const token = this.currentToken;
2170
+ token.forceQuirks = true;
2171
+ this.emitCurrentDoctype(token);
2172
+ this.state = State.DATA;
2173
+ break;
2174
+ }
2175
+ case unicode_js_1.CODE_POINTS.EOF: {
2176
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2177
+ this._createDoctypeToken(null);
2178
+ const token = this.currentToken;
2179
+ token.forceQuirks = true;
2180
+ this.emitCurrentDoctype(token);
2181
+ this._emitEOFToken();
2182
+ break;
2183
+ }
2184
+ default: {
2185
+ this._createDoctypeToken(String.fromCodePoint(cp));
2186
+ this.state = State.DOCTYPE_NAME;
2187
+ }
2188
+ }
2189
+ }
2190
+ // DOCTYPE name state
2191
+ //------------------------------------------------------------------
2192
+ _stateDoctypeName(cp) {
2193
+ const token = this.currentToken;
2194
+ switch (cp) {
2195
+ case unicode_js_1.CODE_POINTS.SPACE:
2196
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2197
+ case unicode_js_1.CODE_POINTS.TABULATION:
2198
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2199
+ this.state = State.AFTER_DOCTYPE_NAME;
2200
+ break;
2201
+ }
2202
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2203
+ this.state = State.DATA;
2204
+ this.emitCurrentDoctype(token);
2205
+ break;
2206
+ }
2207
+ case unicode_js_1.CODE_POINTS.NULL: {
2208
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2209
+ token.name += unicode_js_1.REPLACEMENT_CHARACTER;
2210
+ break;
2211
+ }
2212
+ case unicode_js_1.CODE_POINTS.EOF: {
2213
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2214
+ token.forceQuirks = true;
2215
+ this.emitCurrentDoctype(token);
2216
+ this._emitEOFToken();
2217
+ break;
2218
+ }
2219
+ default: {
2220
+ token.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
2221
+ }
2222
+ }
2223
+ }
2224
+ // After DOCTYPE name state
2225
+ //------------------------------------------------------------------
2226
+ _stateAfterDoctypeName(cp) {
2227
+ const token = this.currentToken;
2228
+ switch (cp) {
2229
+ case unicode_js_1.CODE_POINTS.SPACE:
2230
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2231
+ case unicode_js_1.CODE_POINTS.TABULATION:
2232
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2233
+ // Ignore whitespace
2234
+ break;
2235
+ }
2236
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2237
+ this.state = State.DATA;
2238
+ this.emitCurrentDoctype(token);
2239
+ break;
2240
+ }
2241
+ case unicode_js_1.CODE_POINTS.EOF: {
2242
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2243
+ token.forceQuirks = true;
2244
+ this.emitCurrentDoctype(token);
2245
+ this._emitEOFToken();
2246
+ break;
2247
+ }
2248
+ default:
2249
+ if (this._consumeSequenceIfMatch(unicode_js_1.SEQUENCES.PUBLIC, false)) {
2250
+ this.state = State.AFTER_DOCTYPE_PUBLIC_KEYWORD;
2251
+ }
2252
+ else if (this._consumeSequenceIfMatch(unicode_js_1.SEQUENCES.SYSTEM, false)) {
2253
+ this.state = State.AFTER_DOCTYPE_SYSTEM_KEYWORD;
2254
+ }
2255
+ //NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
2256
+ //results are no longer valid and we will need to start over.
2257
+ else if (!this._ensureHibernation()) {
2258
+ this._err(error_codes_js_1.ERR.invalidCharacterSequenceAfterDoctypeName);
2259
+ token.forceQuirks = true;
2260
+ this.state = State.BOGUS_DOCTYPE;
2261
+ this._stateBogusDoctype(cp);
2262
+ }
2263
+ }
2264
+ }
2265
+ // After DOCTYPE public keyword state
2266
+ //------------------------------------------------------------------
2267
+ _stateAfterDoctypePublicKeyword(cp) {
2268
+ const token = this.currentToken;
2269
+ switch (cp) {
2270
+ case unicode_js_1.CODE_POINTS.SPACE:
2271
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2272
+ case unicode_js_1.CODE_POINTS.TABULATION:
2273
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2274
+ this.state = State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
2275
+ break;
2276
+ }
2277
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2278
+ this._err(error_codes_js_1.ERR.missingWhitespaceAfterDoctypePublicKeyword);
2279
+ token.publicId = '';
2280
+ this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
2281
+ break;
2282
+ }
2283
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2284
+ this._err(error_codes_js_1.ERR.missingWhitespaceAfterDoctypePublicKeyword);
2285
+ token.publicId = '';
2286
+ this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
2287
+ break;
2288
+ }
2289
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2290
+ this._err(error_codes_js_1.ERR.missingDoctypePublicIdentifier);
2291
+ token.forceQuirks = true;
2292
+ this.state = State.DATA;
2293
+ this.emitCurrentDoctype(token);
2294
+ break;
2295
+ }
2296
+ case unicode_js_1.CODE_POINTS.EOF: {
2297
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2298
+ token.forceQuirks = true;
2299
+ this.emitCurrentDoctype(token);
2300
+ this._emitEOFToken();
2301
+ break;
2302
+ }
2303
+ default: {
2304
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypePublicIdentifier);
2305
+ token.forceQuirks = true;
2306
+ this.state = State.BOGUS_DOCTYPE;
2307
+ this._stateBogusDoctype(cp);
2308
+ }
2309
+ }
2310
+ }
2311
+ // Before DOCTYPE public identifier state
2312
+ //------------------------------------------------------------------
2313
+ _stateBeforeDoctypePublicIdentifier(cp) {
2314
+ const token = this.currentToken;
2315
+ switch (cp) {
2316
+ case unicode_js_1.CODE_POINTS.SPACE:
2317
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2318
+ case unicode_js_1.CODE_POINTS.TABULATION:
2319
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2320
+ // Ignore whitespace
2321
+ break;
2322
+ }
2323
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2324
+ token.publicId = '';
2325
+ this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
2326
+ break;
2327
+ }
2328
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2329
+ token.publicId = '';
2330
+ this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
2331
+ break;
2332
+ }
2333
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2334
+ this._err(error_codes_js_1.ERR.missingDoctypePublicIdentifier);
2335
+ token.forceQuirks = true;
2336
+ this.state = State.DATA;
2337
+ this.emitCurrentDoctype(token);
2338
+ break;
2339
+ }
2340
+ case unicode_js_1.CODE_POINTS.EOF: {
2341
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2342
+ token.forceQuirks = true;
2343
+ this.emitCurrentDoctype(token);
2344
+ this._emitEOFToken();
2345
+ break;
2346
+ }
2347
+ default: {
2348
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypePublicIdentifier);
2349
+ token.forceQuirks = true;
2350
+ this.state = State.BOGUS_DOCTYPE;
2351
+ this._stateBogusDoctype(cp);
2352
+ }
2353
+ }
2354
+ }
2355
+ // DOCTYPE public identifier (double-quoted) state
2356
+ //------------------------------------------------------------------
2357
+ _stateDoctypePublicIdentifierDoubleQuoted(cp) {
2358
+ const token = this.currentToken;
2359
+ switch (cp) {
2360
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2361
+ this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
2362
+ break;
2363
+ }
2364
+ case unicode_js_1.CODE_POINTS.NULL: {
2365
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2366
+ token.publicId += unicode_js_1.REPLACEMENT_CHARACTER;
2367
+ break;
2368
+ }
2369
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2370
+ this._err(error_codes_js_1.ERR.abruptDoctypePublicIdentifier);
2371
+ token.forceQuirks = true;
2372
+ this.emitCurrentDoctype(token);
2373
+ this.state = State.DATA;
2374
+ break;
2375
+ }
2376
+ case unicode_js_1.CODE_POINTS.EOF: {
2377
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2378
+ token.forceQuirks = true;
2379
+ this.emitCurrentDoctype(token);
2380
+ this._emitEOFToken();
2381
+ break;
2382
+ }
2383
+ default: {
2384
+ token.publicId += String.fromCodePoint(cp);
2385
+ }
2386
+ }
2387
+ }
2388
+ // DOCTYPE public identifier (single-quoted) state
2389
+ //------------------------------------------------------------------
2390
+ _stateDoctypePublicIdentifierSingleQuoted(cp) {
2391
+ const token = this.currentToken;
2392
+ switch (cp) {
2393
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2394
+ this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
2395
+ break;
2396
+ }
2397
+ case unicode_js_1.CODE_POINTS.NULL: {
2398
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2399
+ token.publicId += unicode_js_1.REPLACEMENT_CHARACTER;
2400
+ break;
2401
+ }
2402
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2403
+ this._err(error_codes_js_1.ERR.abruptDoctypePublicIdentifier);
2404
+ token.forceQuirks = true;
2405
+ this.emitCurrentDoctype(token);
2406
+ this.state = State.DATA;
2407
+ break;
2408
+ }
2409
+ case unicode_js_1.CODE_POINTS.EOF: {
2410
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2411
+ token.forceQuirks = true;
2412
+ this.emitCurrentDoctype(token);
2413
+ this._emitEOFToken();
2414
+ break;
2415
+ }
2416
+ default: {
2417
+ token.publicId += String.fromCodePoint(cp);
2418
+ }
2419
+ }
2420
+ }
2421
+ // After DOCTYPE public identifier state
2422
+ //------------------------------------------------------------------
2423
+ _stateAfterDoctypePublicIdentifier(cp) {
2424
+ const token = this.currentToken;
2425
+ switch (cp) {
2426
+ case unicode_js_1.CODE_POINTS.SPACE:
2427
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2428
+ case unicode_js_1.CODE_POINTS.TABULATION:
2429
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2430
+ this.state = State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
2431
+ break;
2432
+ }
2433
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2434
+ this.state = State.DATA;
2435
+ this.emitCurrentDoctype(token);
2436
+ break;
2437
+ }
2438
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2439
+ this._err(error_codes_js_1.ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
2440
+ token.systemId = '';
2441
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
2442
+ break;
2443
+ }
2444
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2445
+ this._err(error_codes_js_1.ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
2446
+ token.systemId = '';
2447
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
2448
+ break;
2449
+ }
2450
+ case unicode_js_1.CODE_POINTS.EOF: {
2451
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2452
+ token.forceQuirks = true;
2453
+ this.emitCurrentDoctype(token);
2454
+ this._emitEOFToken();
2455
+ break;
2456
+ }
2457
+ default: {
2458
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypeSystemIdentifier);
2459
+ token.forceQuirks = true;
2460
+ this.state = State.BOGUS_DOCTYPE;
2461
+ this._stateBogusDoctype(cp);
2462
+ }
2463
+ }
2464
+ }
2465
+ // Between DOCTYPE public and system identifiers state
2466
+ //------------------------------------------------------------------
2467
+ _stateBetweenDoctypePublicAndSystemIdentifiers(cp) {
2468
+ const token = this.currentToken;
2469
+ switch (cp) {
2470
+ case unicode_js_1.CODE_POINTS.SPACE:
2471
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2472
+ case unicode_js_1.CODE_POINTS.TABULATION:
2473
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2474
+ // Ignore whitespace
2475
+ break;
2476
+ }
2477
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2478
+ this.emitCurrentDoctype(token);
2479
+ this.state = State.DATA;
2480
+ break;
2481
+ }
2482
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2483
+ token.systemId = '';
2484
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
2485
+ break;
2486
+ }
2487
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2488
+ token.systemId = '';
2489
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
2490
+ break;
2491
+ }
2492
+ case unicode_js_1.CODE_POINTS.EOF: {
2493
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2494
+ token.forceQuirks = true;
2495
+ this.emitCurrentDoctype(token);
2496
+ this._emitEOFToken();
2497
+ break;
2498
+ }
2499
+ default: {
2500
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypeSystemIdentifier);
2501
+ token.forceQuirks = true;
2502
+ this.state = State.BOGUS_DOCTYPE;
2503
+ this._stateBogusDoctype(cp);
2504
+ }
2505
+ }
2506
+ }
2507
+ // After DOCTYPE system keyword state
2508
+ //------------------------------------------------------------------
2509
+ _stateAfterDoctypeSystemKeyword(cp) {
2510
+ const token = this.currentToken;
2511
+ switch (cp) {
2512
+ case unicode_js_1.CODE_POINTS.SPACE:
2513
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2514
+ case unicode_js_1.CODE_POINTS.TABULATION:
2515
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2516
+ this.state = State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
2517
+ break;
2518
+ }
2519
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2520
+ this._err(error_codes_js_1.ERR.missingWhitespaceAfterDoctypeSystemKeyword);
2521
+ token.systemId = '';
2522
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
2523
+ break;
2524
+ }
2525
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2526
+ this._err(error_codes_js_1.ERR.missingWhitespaceAfterDoctypeSystemKeyword);
2527
+ token.systemId = '';
2528
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
2529
+ break;
2530
+ }
2531
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2532
+ this._err(error_codes_js_1.ERR.missingDoctypeSystemIdentifier);
2533
+ token.forceQuirks = true;
2534
+ this.state = State.DATA;
2535
+ this.emitCurrentDoctype(token);
2536
+ break;
2537
+ }
2538
+ case unicode_js_1.CODE_POINTS.EOF: {
2539
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2540
+ token.forceQuirks = true;
2541
+ this.emitCurrentDoctype(token);
2542
+ this._emitEOFToken();
2543
+ break;
2544
+ }
2545
+ default: {
2546
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypeSystemIdentifier);
2547
+ token.forceQuirks = true;
2548
+ this.state = State.BOGUS_DOCTYPE;
2549
+ this._stateBogusDoctype(cp);
2550
+ }
2551
+ }
2552
+ }
2553
+ // Before DOCTYPE system identifier state
2554
+ //------------------------------------------------------------------
2555
+ _stateBeforeDoctypeSystemIdentifier(cp) {
2556
+ const token = this.currentToken;
2557
+ switch (cp) {
2558
+ case unicode_js_1.CODE_POINTS.SPACE:
2559
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2560
+ case unicode_js_1.CODE_POINTS.TABULATION:
2561
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2562
+ // Ignore whitespace
2563
+ break;
2564
+ }
2565
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2566
+ token.systemId = '';
2567
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
2568
+ break;
2569
+ }
2570
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2571
+ token.systemId = '';
2572
+ this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
2573
+ break;
2574
+ }
2575
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2576
+ this._err(error_codes_js_1.ERR.missingDoctypeSystemIdentifier);
2577
+ token.forceQuirks = true;
2578
+ this.state = State.DATA;
2579
+ this.emitCurrentDoctype(token);
2580
+ break;
2581
+ }
2582
+ case unicode_js_1.CODE_POINTS.EOF: {
2583
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2584
+ token.forceQuirks = true;
2585
+ this.emitCurrentDoctype(token);
2586
+ this._emitEOFToken();
2587
+ break;
2588
+ }
2589
+ default: {
2590
+ this._err(error_codes_js_1.ERR.missingQuoteBeforeDoctypeSystemIdentifier);
2591
+ token.forceQuirks = true;
2592
+ this.state = State.BOGUS_DOCTYPE;
2593
+ this._stateBogusDoctype(cp);
2594
+ }
2595
+ }
2596
+ }
2597
+ // DOCTYPE system identifier (double-quoted) state
2598
+ //------------------------------------------------------------------
2599
+ _stateDoctypeSystemIdentifierDoubleQuoted(cp) {
2600
+ const token = this.currentToken;
2601
+ switch (cp) {
2602
+ case unicode_js_1.CODE_POINTS.QUOTATION_MARK: {
2603
+ this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
2604
+ break;
2605
+ }
2606
+ case unicode_js_1.CODE_POINTS.NULL: {
2607
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2608
+ token.systemId += unicode_js_1.REPLACEMENT_CHARACTER;
2609
+ break;
2610
+ }
2611
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2612
+ this._err(error_codes_js_1.ERR.abruptDoctypeSystemIdentifier);
2613
+ token.forceQuirks = true;
2614
+ this.emitCurrentDoctype(token);
2615
+ this.state = State.DATA;
2616
+ break;
2617
+ }
2618
+ case unicode_js_1.CODE_POINTS.EOF: {
2619
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2620
+ token.forceQuirks = true;
2621
+ this.emitCurrentDoctype(token);
2622
+ this._emitEOFToken();
2623
+ break;
2624
+ }
2625
+ default: {
2626
+ token.systemId += String.fromCodePoint(cp);
2627
+ }
2628
+ }
2629
+ }
2630
+ // DOCTYPE system identifier (single-quoted) state
2631
+ //------------------------------------------------------------------
2632
+ _stateDoctypeSystemIdentifierSingleQuoted(cp) {
2633
+ const token = this.currentToken;
2634
+ switch (cp) {
2635
+ case unicode_js_1.CODE_POINTS.APOSTROPHE: {
2636
+ this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
2637
+ break;
2638
+ }
2639
+ case unicode_js_1.CODE_POINTS.NULL: {
2640
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2641
+ token.systemId += unicode_js_1.REPLACEMENT_CHARACTER;
2642
+ break;
2643
+ }
2644
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2645
+ this._err(error_codes_js_1.ERR.abruptDoctypeSystemIdentifier);
2646
+ token.forceQuirks = true;
2647
+ this.emitCurrentDoctype(token);
2648
+ this.state = State.DATA;
2649
+ break;
2650
+ }
2651
+ case unicode_js_1.CODE_POINTS.EOF: {
2652
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2653
+ token.forceQuirks = true;
2654
+ this.emitCurrentDoctype(token);
2655
+ this._emitEOFToken();
2656
+ break;
2657
+ }
2658
+ default: {
2659
+ token.systemId += String.fromCodePoint(cp);
2660
+ }
2661
+ }
2662
+ }
2663
+ // After DOCTYPE system identifier state
2664
+ //------------------------------------------------------------------
2665
+ _stateAfterDoctypeSystemIdentifier(cp) {
2666
+ const token = this.currentToken;
2667
+ switch (cp) {
2668
+ case unicode_js_1.CODE_POINTS.SPACE:
2669
+ case unicode_js_1.CODE_POINTS.LINE_FEED:
2670
+ case unicode_js_1.CODE_POINTS.TABULATION:
2671
+ case unicode_js_1.CODE_POINTS.FORM_FEED: {
2672
+ // Ignore whitespace
2673
+ break;
2674
+ }
2675
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2676
+ this.emitCurrentDoctype(token);
2677
+ this.state = State.DATA;
2678
+ break;
2679
+ }
2680
+ case unicode_js_1.CODE_POINTS.EOF: {
2681
+ this._err(error_codes_js_1.ERR.eofInDoctype);
2682
+ token.forceQuirks = true;
2683
+ this.emitCurrentDoctype(token);
2684
+ this._emitEOFToken();
2685
+ break;
2686
+ }
2687
+ default: {
2688
+ this._err(error_codes_js_1.ERR.unexpectedCharacterAfterDoctypeSystemIdentifier);
2689
+ this.state = State.BOGUS_DOCTYPE;
2690
+ this._stateBogusDoctype(cp);
2691
+ }
2692
+ }
2693
+ }
2694
+ // Bogus DOCTYPE state
2695
+ //------------------------------------------------------------------
2696
+ _stateBogusDoctype(cp) {
2697
+ const token = this.currentToken;
2698
+ switch (cp) {
2699
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2700
+ this.emitCurrentDoctype(token);
2701
+ this.state = State.DATA;
2702
+ break;
2703
+ }
2704
+ case unicode_js_1.CODE_POINTS.NULL: {
2705
+ this._err(error_codes_js_1.ERR.unexpectedNullCharacter);
2706
+ break;
2707
+ }
2708
+ case unicode_js_1.CODE_POINTS.EOF: {
2709
+ this.emitCurrentDoctype(token);
2710
+ this._emitEOFToken();
2711
+ break;
2712
+ }
2713
+ default:
2714
+ // Do nothing
2715
+ }
2716
+ }
2717
+ // CDATA section state
2718
+ //------------------------------------------------------------------
2719
+ _stateCdataSection(cp) {
2720
+ switch (cp) {
2721
+ case unicode_js_1.CODE_POINTS.RIGHT_SQUARE_BRACKET: {
2722
+ this.state = State.CDATA_SECTION_BRACKET;
2723
+ break;
2724
+ }
2725
+ case unicode_js_1.CODE_POINTS.EOF: {
2726
+ this._err(error_codes_js_1.ERR.eofInCdata);
2727
+ this._emitEOFToken();
2728
+ break;
2729
+ }
2730
+ default: {
2731
+ this._emitCodePoint(cp);
2732
+ }
2733
+ }
2734
+ }
2735
+ // CDATA section bracket state
2736
+ //------------------------------------------------------------------
2737
+ _stateCdataSectionBracket(cp) {
2738
+ if (cp === unicode_js_1.CODE_POINTS.RIGHT_SQUARE_BRACKET) {
2739
+ this.state = State.CDATA_SECTION_END;
2740
+ }
2741
+ else {
2742
+ this._emitChars(']');
2743
+ this.state = State.CDATA_SECTION;
2744
+ this._stateCdataSection(cp);
2745
+ }
2746
+ }
2747
+ // CDATA section end state
2748
+ //------------------------------------------------------------------
2749
+ _stateCdataSectionEnd(cp) {
2750
+ switch (cp) {
2751
+ case unicode_js_1.CODE_POINTS.GREATER_THAN_SIGN: {
2752
+ this.state = State.DATA;
2753
+ break;
2754
+ }
2755
+ case unicode_js_1.CODE_POINTS.RIGHT_SQUARE_BRACKET: {
2756
+ this._emitChars(']');
2757
+ break;
2758
+ }
2759
+ default: {
2760
+ this._emitChars(']]');
2761
+ this.state = State.CDATA_SECTION;
2762
+ this._stateCdataSection(cp);
2763
+ }
2764
+ }
2765
+ }
2766
+ // Character reference state
2767
+ //------------------------------------------------------------------
2768
+ _stateCharacterReference(cp) {
2769
+ if (cp === unicode_js_1.CODE_POINTS.NUMBER_SIGN) {
2770
+ this.state = State.NUMERIC_CHARACTER_REFERENCE;
2771
+ }
2772
+ else if (isAsciiAlphaNumeric(cp)) {
2773
+ this.state = State.NAMED_CHARACTER_REFERENCE;
2774
+ this._stateNamedCharacterReference(cp);
2775
+ }
2776
+ else {
2777
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.AMPERSAND);
2778
+ this._reconsumeInState(this.returnState);
2779
+ }
2780
+ }
2781
+ // Named character reference state
2782
+ //------------------------------------------------------------------
2783
+ _stateNamedCharacterReference(cp) {
2784
+ const matchResult = this._matchNamedCharacterReference(cp);
2785
+ //NOTE: Matching can be abrupted by hibernation. In that case, match
2786
+ //results are no longer valid and we will need to start over.
2787
+ if (this._ensureHibernation()) {
2788
+ // Stay in the state, try again.
2789
+ }
2790
+ else if (matchResult) {
2791
+ for (let i = 0; i < matchResult.length; i++) {
2792
+ this._flushCodePointConsumedAsCharacterReference(matchResult[i]);
2793
+ }
2794
+ this.state = this.returnState;
2795
+ }
2796
+ else {
2797
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.AMPERSAND);
2798
+ this.state = State.AMBIGUOUS_AMPERSAND;
2799
+ }
2800
+ }
2801
+ // Ambiguos ampersand state
2802
+ //------------------------------------------------------------------
2803
+ _stateAmbiguousAmpersand(cp) {
2804
+ if (isAsciiAlphaNumeric(cp)) {
2805
+ this._flushCodePointConsumedAsCharacterReference(cp);
2806
+ }
2807
+ else {
2808
+ if (cp === unicode_js_1.CODE_POINTS.SEMICOLON) {
2809
+ this._err(error_codes_js_1.ERR.unknownNamedCharacterReference);
2810
+ }
2811
+ this._reconsumeInState(this.returnState);
2812
+ }
2813
+ }
2814
+ // Numeric character reference state
2815
+ //------------------------------------------------------------------
2816
+ _stateNumericCharacterReference(cp) {
2817
+ this.charRefCode = 0;
2818
+ if (cp === unicode_js_1.CODE_POINTS.LATIN_SMALL_X || cp === unicode_js_1.CODE_POINTS.LATIN_CAPITAL_X) {
2819
+ this.state = State.HEXADEMICAL_CHARACTER_REFERENCE_START;
2820
+ }
2821
+ else {
2822
+ this.state = State.DECIMAL_CHARACTER_REFERENCE_START;
2823
+ this._stateDecimalCharacterReferenceStart(cp);
2824
+ }
2825
+ }
2826
+ // Hexademical character reference start state
2827
+ //------------------------------------------------------------------
2828
+ _stateHexademicalCharacterReferenceStart(cp) {
2829
+ if (isAsciiHexDigit(cp)) {
2830
+ this.state = State.HEXADEMICAL_CHARACTER_REFERENCE;
2831
+ this._stateHexademicalCharacterReference(cp);
2832
+ }
2833
+ else {
2834
+ this._err(error_codes_js_1.ERR.absenceOfDigitsInNumericCharacterReference);
2835
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.AMPERSAND);
2836
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.NUMBER_SIGN);
2837
+ this._unconsume(2);
2838
+ this.state = this.returnState;
2839
+ }
2840
+ }
2841
+ // Decimal character reference start state
2842
+ //------------------------------------------------------------------
2843
+ _stateDecimalCharacterReferenceStart(cp) {
2844
+ if (isAsciiDigit(cp)) {
2845
+ this.state = State.DECIMAL_CHARACTER_REFERENCE;
2846
+ this._stateDecimalCharacterReference(cp);
2847
+ }
2848
+ else {
2849
+ this._err(error_codes_js_1.ERR.absenceOfDigitsInNumericCharacterReference);
2850
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.AMPERSAND);
2851
+ this._flushCodePointConsumedAsCharacterReference(unicode_js_1.CODE_POINTS.NUMBER_SIGN);
2852
+ this._reconsumeInState(this.returnState);
2853
+ }
2854
+ }
2855
+ // Hexademical character reference state
2856
+ //------------------------------------------------------------------
2857
+ _stateHexademicalCharacterReference(cp) {
2858
+ if (isAsciiUpperHexDigit(cp)) {
2859
+ this.charRefCode = this.charRefCode * 16 + cp - 0x37;
2860
+ }
2861
+ else if (isAsciiLowerHexDigit(cp)) {
2862
+ this.charRefCode = this.charRefCode * 16 + cp - 0x57;
2863
+ }
2864
+ else if (isAsciiDigit(cp)) {
2865
+ this.charRefCode = this.charRefCode * 16 + cp - 0x30;
2866
+ }
2867
+ else if (cp === unicode_js_1.CODE_POINTS.SEMICOLON) {
2868
+ this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
2869
+ }
2870
+ else {
2871
+ this._err(error_codes_js_1.ERR.missingSemicolonAfterCharacterReference);
2872
+ this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
2873
+ this._stateNumericCharacterReferenceEnd();
2874
+ }
2875
+ }
2876
+ // Decimal character reference state
2877
+ //------------------------------------------------------------------
2878
+ _stateDecimalCharacterReference(cp) {
2879
+ if (isAsciiDigit(cp)) {
2880
+ this.charRefCode = this.charRefCode * 10 + cp - 0x30;
2881
+ }
2882
+ else if (cp === unicode_js_1.CODE_POINTS.SEMICOLON) {
2883
+ this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
2884
+ }
2885
+ else {
2886
+ this._err(error_codes_js_1.ERR.missingSemicolonAfterCharacterReference);
2887
+ this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
2888
+ this._stateNumericCharacterReferenceEnd();
2889
+ }
2890
+ }
2891
+ // Numeric character reference end state
2892
+ //------------------------------------------------------------------
2893
+ _stateNumericCharacterReferenceEnd() {
2894
+ if (this.charRefCode === unicode_js_1.CODE_POINTS.NULL) {
2895
+ this._err(error_codes_js_1.ERR.nullCharacterReference);
2896
+ this.charRefCode = unicode_js_1.CODE_POINTS.REPLACEMENT_CHARACTER;
2897
+ }
2898
+ else if (this.charRefCode > 1114111) {
2899
+ this._err(error_codes_js_1.ERR.characterReferenceOutsideUnicodeRange);
2900
+ this.charRefCode = unicode_js_1.CODE_POINTS.REPLACEMENT_CHARACTER;
2901
+ }
2902
+ else if ((0, unicode_js_1.isSurrogate)(this.charRefCode)) {
2903
+ this._err(error_codes_js_1.ERR.surrogateCharacterReference);
2904
+ this.charRefCode = unicode_js_1.CODE_POINTS.REPLACEMENT_CHARACTER;
2905
+ }
2906
+ else if ((0, unicode_js_1.isUndefinedCodePoint)(this.charRefCode)) {
2907
+ this._err(error_codes_js_1.ERR.noncharacterCharacterReference);
2908
+ }
2909
+ else if ((0, unicode_js_1.isControlCodePoint)(this.charRefCode) || this.charRefCode === unicode_js_1.CODE_POINTS.CARRIAGE_RETURN) {
2910
+ this._err(error_codes_js_1.ERR.controlCharacterReference);
2911
+ const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS.get(this.charRefCode);
2912
+ if (replacement !== undefined) {
2913
+ this.charRefCode = replacement;
2914
+ }
2915
+ }
2916
+ this._flushCodePointConsumedAsCharacterReference(this.charRefCode);
2917
+ this._reconsumeInState(this.returnState);
2918
+ }
2919
+ }
2920
+ exports.Tokenizer = Tokenizer;
2921
+ //# sourceMappingURL=index.js.map