parse5 3.0.3 → 5.1.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.
- package/README.md +14 -16
- package/lib/common/doctype.js +125 -108
- package/lib/common/error-codes.js +65 -0
- package/lib/common/foreign-content.js +265 -0
- package/lib/common/html.js +102 -102
- package/lib/common/unicode.js +81 -19
- package/lib/extensions/error-reporting/mixin-base.js +43 -0
- package/lib/extensions/error-reporting/parser-mixin.js +52 -0
- package/lib/extensions/error-reporting/preprocessor-mixin.js +24 -0
- package/lib/extensions/error-reporting/tokenizer-mixin.js +17 -0
- package/lib/extensions/location-info/open-element-stack-mixin.js +35 -0
- package/lib/extensions/location-info/parser-mixin.js +222 -0
- package/lib/extensions/location-info/tokenizer-mixin.js +146 -0
- package/lib/extensions/position-tracking/preprocessor-mixin.js +64 -0
- package/lib/index.js +6 -21
- package/lib/parser/formatting-element-list.js +181 -0
- package/lib/parser/index.js +1469 -1332
- package/lib/parser/open-element-stack.js +482 -0
- package/lib/serializer/index.js +136 -122
- package/lib/tokenizer/index.js +1856 -1804
- package/lib/tokenizer/{named_entity_data.js → named-entity-data.js} +1 -1
- package/lib/tokenizer/preprocessor.js +115 -103
- package/lib/tree-adapters/default.js +217 -0
- package/lib/utils/{merge_options.js → merge-options.js} +2 -2
- package/lib/utils/mixin.js +33 -12
- package/package.json +32 -61
- package/LICENSE +0 -19
- package/lib/common/foreign_content.js +0 -260
- package/lib/extensions/location_info/open_element_stack_mixin.js +0 -34
- package/lib/extensions/location_info/parser_mixin.js +0 -213
- package/lib/extensions/location_info/tokenizer_mixin.js +0 -117
- package/lib/extensions/position_tracking/preprocessor_mixin.js +0 -72
- package/lib/index.d.ts +0 -1077
- package/lib/parser/formatting_element_list.js +0 -167
- package/lib/parser/open_element_stack.js +0 -395
- package/lib/parser/parser_stream.js +0 -76
- package/lib/parser/plain_text_conversion_stream.js +0 -20
- package/lib/sax/dev_null_stream.js +0 -14
- package/lib/sax/index.js +0 -118
- package/lib/sax/parser_feedback_simulator.js +0 -153
- package/lib/serializer/serializer_stream.js +0 -28
- package/lib/tree_adapters/default.js +0 -209
- package/lib/tree_adapters/htmlparser2.js +0 -338
package/lib/tokenizer/index.js
CHANGED
|
@@ -1,95 +1,132 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const Preprocessor = require('./preprocessor');
|
|
4
|
+
const unicode = require('../common/unicode');
|
|
5
|
+
const neTree = require('./named-entity-data');
|
|
6
|
+
const ERR = require('../common/error-codes');
|
|
6
7
|
|
|
7
8
|
//Aliases
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
const $ = unicode.CODE_POINTS;
|
|
10
|
+
const $$ = unicode.CODE_POINT_SEQUENCES;
|
|
11
|
+
|
|
12
|
+
//C1 Unicode control character reference replacements
|
|
13
|
+
const C1_CONTROLS_REFERENCE_REPLACEMENTS = {
|
|
14
|
+
0x80: 0x20ac,
|
|
15
|
+
0x82: 0x201a,
|
|
16
|
+
0x83: 0x0192,
|
|
17
|
+
0x84: 0x201e,
|
|
18
|
+
0x85: 0x2026,
|
|
19
|
+
0x86: 0x2020,
|
|
20
|
+
0x87: 0x2021,
|
|
21
|
+
0x88: 0x02c6,
|
|
22
|
+
0x89: 0x2030,
|
|
23
|
+
0x8a: 0x0160,
|
|
24
|
+
0x8b: 0x2039,
|
|
25
|
+
0x8c: 0x0152,
|
|
26
|
+
0x8e: 0x017d,
|
|
27
|
+
0x91: 0x2018,
|
|
28
|
+
0x92: 0x2019,
|
|
29
|
+
0x93: 0x201c,
|
|
30
|
+
0x94: 0x201d,
|
|
31
|
+
0x95: 0x2022,
|
|
32
|
+
0x96: 0x2013,
|
|
33
|
+
0x97: 0x2014,
|
|
34
|
+
0x98: 0x02dc,
|
|
35
|
+
0x99: 0x2122,
|
|
36
|
+
0x9a: 0x0161,
|
|
37
|
+
0x9b: 0x203a,
|
|
38
|
+
0x9c: 0x0153,
|
|
39
|
+
0x9e: 0x017e,
|
|
40
|
+
0x9f: 0x0178
|
|
18
41
|
};
|
|
19
42
|
|
|
20
43
|
// Named entity tree flags
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
44
|
+
const HAS_DATA_FLAG = 1 << 0;
|
|
45
|
+
const DATA_DUPLET_FLAG = 1 << 1;
|
|
46
|
+
const HAS_BRANCHES_FLAG = 1 << 2;
|
|
47
|
+
const MAX_BRANCH_MARKER_VALUE = HAS_DATA_FLAG | DATA_DUPLET_FLAG | HAS_BRANCHES_FLAG;
|
|
26
48
|
|
|
27
49
|
//States
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
50
|
+
const DATA_STATE = 'DATA_STATE';
|
|
51
|
+
const RCDATA_STATE = 'RCDATA_STATE';
|
|
52
|
+
const RAWTEXT_STATE = 'RAWTEXT_STATE';
|
|
53
|
+
const SCRIPT_DATA_STATE = 'SCRIPT_DATA_STATE';
|
|
54
|
+
const PLAINTEXT_STATE = 'PLAINTEXT_STATE';
|
|
55
|
+
const TAG_OPEN_STATE = 'TAG_OPEN_STATE';
|
|
56
|
+
const END_TAG_OPEN_STATE = 'END_TAG_OPEN_STATE';
|
|
57
|
+
const TAG_NAME_STATE = 'TAG_NAME_STATE';
|
|
58
|
+
const RCDATA_LESS_THAN_SIGN_STATE = 'RCDATA_LESS_THAN_SIGN_STATE';
|
|
59
|
+
const RCDATA_END_TAG_OPEN_STATE = 'RCDATA_END_TAG_OPEN_STATE';
|
|
60
|
+
const RCDATA_END_TAG_NAME_STATE = 'RCDATA_END_TAG_NAME_STATE';
|
|
61
|
+
const RAWTEXT_LESS_THAN_SIGN_STATE = 'RAWTEXT_LESS_THAN_SIGN_STATE';
|
|
62
|
+
const RAWTEXT_END_TAG_OPEN_STATE = 'RAWTEXT_END_TAG_OPEN_STATE';
|
|
63
|
+
const RAWTEXT_END_TAG_NAME_STATE = 'RAWTEXT_END_TAG_NAME_STATE';
|
|
64
|
+
const SCRIPT_DATA_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_LESS_THAN_SIGN_STATE';
|
|
65
|
+
const SCRIPT_DATA_END_TAG_OPEN_STATE = 'SCRIPT_DATA_END_TAG_OPEN_STATE';
|
|
66
|
+
const SCRIPT_DATA_END_TAG_NAME_STATE = 'SCRIPT_DATA_END_TAG_NAME_STATE';
|
|
67
|
+
const SCRIPT_DATA_ESCAPE_START_STATE = 'SCRIPT_DATA_ESCAPE_START_STATE';
|
|
68
|
+
const SCRIPT_DATA_ESCAPE_START_DASH_STATE = 'SCRIPT_DATA_ESCAPE_START_DASH_STATE';
|
|
69
|
+
const SCRIPT_DATA_ESCAPED_STATE = 'SCRIPT_DATA_ESCAPED_STATE';
|
|
70
|
+
const SCRIPT_DATA_ESCAPED_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_STATE';
|
|
71
|
+
const SCRIPT_DATA_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_DASH_STATE';
|
|
72
|
+
const SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE';
|
|
73
|
+
const SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE';
|
|
74
|
+
const SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE';
|
|
75
|
+
const SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE';
|
|
76
|
+
const SCRIPT_DATA_DOUBLE_ESCAPED_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_STATE';
|
|
77
|
+
const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE';
|
|
78
|
+
const SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE';
|
|
79
|
+
const SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE';
|
|
80
|
+
const SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE';
|
|
81
|
+
const BEFORE_ATTRIBUTE_NAME_STATE = 'BEFORE_ATTRIBUTE_NAME_STATE';
|
|
82
|
+
const ATTRIBUTE_NAME_STATE = 'ATTRIBUTE_NAME_STATE';
|
|
83
|
+
const AFTER_ATTRIBUTE_NAME_STATE = 'AFTER_ATTRIBUTE_NAME_STATE';
|
|
84
|
+
const BEFORE_ATTRIBUTE_VALUE_STATE = 'BEFORE_ATTRIBUTE_VALUE_STATE';
|
|
85
|
+
const ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE';
|
|
86
|
+
const ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE';
|
|
87
|
+
const ATTRIBUTE_VALUE_UNQUOTED_STATE = 'ATTRIBUTE_VALUE_UNQUOTED_STATE';
|
|
88
|
+
const AFTER_ATTRIBUTE_VALUE_QUOTED_STATE = 'AFTER_ATTRIBUTE_VALUE_QUOTED_STATE';
|
|
89
|
+
const SELF_CLOSING_START_TAG_STATE = 'SELF_CLOSING_START_TAG_STATE';
|
|
90
|
+
const BOGUS_COMMENT_STATE = 'BOGUS_COMMENT_STATE';
|
|
91
|
+
const MARKUP_DECLARATION_OPEN_STATE = 'MARKUP_DECLARATION_OPEN_STATE';
|
|
92
|
+
const COMMENT_START_STATE = 'COMMENT_START_STATE';
|
|
93
|
+
const COMMENT_START_DASH_STATE = 'COMMENT_START_DASH_STATE';
|
|
94
|
+
const COMMENT_STATE = 'COMMENT_STATE';
|
|
95
|
+
const COMMENT_LESS_THAN_SIGN_STATE = 'COMMENT_LESS_THAN_SIGN_STATE';
|
|
96
|
+
const COMMENT_LESS_THAN_SIGN_BANG_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_STATE';
|
|
97
|
+
const COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE';
|
|
98
|
+
const COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE = 'COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE';
|
|
99
|
+
const COMMENT_END_DASH_STATE = 'COMMENT_END_DASH_STATE';
|
|
100
|
+
const COMMENT_END_STATE = 'COMMENT_END_STATE';
|
|
101
|
+
const COMMENT_END_BANG_STATE = 'COMMENT_END_BANG_STATE';
|
|
102
|
+
const DOCTYPE_STATE = 'DOCTYPE_STATE';
|
|
103
|
+
const BEFORE_DOCTYPE_NAME_STATE = 'BEFORE_DOCTYPE_NAME_STATE';
|
|
104
|
+
const DOCTYPE_NAME_STATE = 'DOCTYPE_NAME_STATE';
|
|
105
|
+
const AFTER_DOCTYPE_NAME_STATE = 'AFTER_DOCTYPE_NAME_STATE';
|
|
106
|
+
const AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE = 'AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE';
|
|
107
|
+
const BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
|
|
108
|
+
const DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE';
|
|
109
|
+
const DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE';
|
|
110
|
+
const AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE';
|
|
111
|
+
const BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE = 'BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE';
|
|
112
|
+
const AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE = 'AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE';
|
|
113
|
+
const BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
|
|
114
|
+
const DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE';
|
|
115
|
+
const DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE';
|
|
116
|
+
const AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE';
|
|
117
|
+
const BOGUS_DOCTYPE_STATE = 'BOGUS_DOCTYPE_STATE';
|
|
118
|
+
const CDATA_SECTION_STATE = 'CDATA_SECTION_STATE';
|
|
119
|
+
const CDATA_SECTION_BRACKET_STATE = 'CDATA_SECTION_BRACKET_STATE';
|
|
120
|
+
const CDATA_SECTION_END_STATE = 'CDATA_SECTION_END_STATE';
|
|
121
|
+
const CHARACTER_REFERENCE_STATE = 'CHARACTER_REFERENCE_STATE';
|
|
122
|
+
const NAMED_CHARACTER_REFERENCE_STATE = 'NAMED_CHARACTER_REFERENCE_STATE';
|
|
123
|
+
const AMBIGUOUS_AMPERSAND_STATE = 'AMBIGUOS_AMPERSAND_STATE';
|
|
124
|
+
const NUMERIC_CHARACTER_REFERENCE_STATE = 'NUMERIC_CHARACTER_REFERENCE_STATE';
|
|
125
|
+
const HEXADEMICAL_CHARACTER_REFERENCE_START_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_START_STATE';
|
|
126
|
+
const DECIMAL_CHARACTER_REFERENCE_START_STATE = 'DECIMAL_CHARACTER_REFERENCE_START_STATE';
|
|
127
|
+
const HEXADEMICAL_CHARACTER_REFERENCE_STATE = 'HEXADEMICAL_CHARACTER_REFERENCE_STATE';
|
|
128
|
+
const DECIMAL_CHARACTER_REFERENCE_STATE = 'DECIMAL_CHARACTER_REFERENCE_STATE';
|
|
129
|
+
const NUMERIC_CHARACTER_REFERENCE_END_STATE = 'NUMERIC_CHARACTER_REFERENCE_END_STATE';
|
|
93
130
|
|
|
94
131
|
//Utils
|
|
95
132
|
|
|
@@ -120,13 +157,16 @@ function isAsciiAlphaNumeric(cp) {
|
|
|
120
157
|
return isAsciiLetter(cp) || isAsciiDigit(cp);
|
|
121
158
|
}
|
|
122
159
|
|
|
123
|
-
function
|
|
124
|
-
return
|
|
125
|
-
|
|
160
|
+
function isAsciiUpperHexDigit(cp) {
|
|
161
|
+
return cp >= $.LATIN_CAPITAL_A && cp <= $.LATIN_CAPITAL_F;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function isAsciiLowerHexDigit(cp) {
|
|
165
|
+
return cp >= $.LATIN_SMALL_A && cp <= $.LATIN_SMALL_F;
|
|
126
166
|
}
|
|
127
167
|
|
|
128
|
-
function
|
|
129
|
-
return cp
|
|
168
|
+
function isAsciiHexDigit(cp) {
|
|
169
|
+
return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
|
|
130
170
|
}
|
|
131
171
|
|
|
132
172
|
function toAsciiLowerCodePoint(cp) {
|
|
@@ -137,11 +177,12 @@ function toAsciiLowerCodePoint(cp) {
|
|
|
137
177
|
//So, we need to workaround this manually.
|
|
138
178
|
//(see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode#Getting_it_to_work_with_higher_values)
|
|
139
179
|
function toChar(cp) {
|
|
140
|
-
if (cp <=
|
|
180
|
+
if (cp <= 0xffff) {
|
|
141
181
|
return String.fromCharCode(cp);
|
|
182
|
+
}
|
|
142
183
|
|
|
143
184
|
cp -= 0x10000;
|
|
144
|
-
return String.fromCharCode(cp >>> 10 &
|
|
185
|
+
return String.fromCharCode(((cp >>> 10) & 0x3ff) | 0xd800) + String.fromCharCode(0xdc00 | (cp & 0x3ff));
|
|
145
186
|
}
|
|
146
187
|
|
|
147
188
|
function toAsciiLowerChar(cp) {
|
|
@@ -149,1996 +190,2007 @@ function toAsciiLowerChar(cp) {
|
|
|
149
190
|
}
|
|
150
191
|
|
|
151
192
|
function findNamedEntityTreeBranch(nodeIx, cp) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
193
|
+
const branchCount = neTree[++nodeIx];
|
|
194
|
+
let lo = ++nodeIx;
|
|
195
|
+
let hi = lo + branchCount - 1;
|
|
155
196
|
|
|
156
197
|
while (lo <= hi) {
|
|
157
|
-
|
|
158
|
-
|
|
198
|
+
const mid = (lo + hi) >>> 1;
|
|
199
|
+
const midCp = neTree[mid];
|
|
159
200
|
|
|
160
|
-
if (midCp < cp)
|
|
201
|
+
if (midCp < cp) {
|
|
161
202
|
lo = mid + 1;
|
|
162
|
-
|
|
163
|
-
else if (midCp > cp)
|
|
203
|
+
} else if (midCp > cp) {
|
|
164
204
|
hi = mid - 1;
|
|
165
|
-
|
|
166
|
-
else
|
|
205
|
+
} else {
|
|
167
206
|
return neTree[mid + branchCount];
|
|
207
|
+
}
|
|
168
208
|
}
|
|
169
209
|
|
|
170
210
|
return -1;
|
|
171
211
|
}
|
|
172
212
|
|
|
173
|
-
|
|
174
213
|
//Tokenizer
|
|
175
|
-
|
|
176
|
-
|
|
214
|
+
class Tokenizer {
|
|
215
|
+
constructor() {
|
|
216
|
+
this.preprocessor = new Preprocessor();
|
|
177
217
|
|
|
178
|
-
|
|
218
|
+
this.tokenQueue = [];
|
|
179
219
|
|
|
180
|
-
|
|
220
|
+
this.allowCDATA = false;
|
|
181
221
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.tempBuff = [];
|
|
186
|
-
this.additionalAllowedCp = void 0;
|
|
187
|
-
this.lastStartTagName = '';
|
|
222
|
+
this.state = DATA_STATE;
|
|
223
|
+
this.returnState = '';
|
|
188
224
|
|
|
189
|
-
|
|
190
|
-
|
|
225
|
+
this.charRefCode = -1;
|
|
226
|
+
this.tempBuff = [];
|
|
227
|
+
this.lastStartTagName = '';
|
|
191
228
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
this.currentAttr = null;
|
|
195
|
-
};
|
|
229
|
+
this.consumedAfterSnapshot = -1;
|
|
230
|
+
this.active = false;
|
|
196
231
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Tokenizer.START_TAG_TOKEN = 'START_TAG_TOKEN';
|
|
202
|
-
Tokenizer.END_TAG_TOKEN = 'END_TAG_TOKEN';
|
|
203
|
-
Tokenizer.COMMENT_TOKEN = 'COMMENT_TOKEN';
|
|
204
|
-
Tokenizer.DOCTYPE_TOKEN = 'DOCTYPE_TOKEN';
|
|
205
|
-
Tokenizer.EOF_TOKEN = 'EOF_TOKEN';
|
|
206
|
-
Tokenizer.HIBERNATION_TOKEN = 'HIBERNATION_TOKEN';
|
|
232
|
+
this.currentCharacterToken = null;
|
|
233
|
+
this.currentToken = null;
|
|
234
|
+
this.currentAttr = null;
|
|
235
|
+
}
|
|
207
236
|
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
RAWTEXT: RAWTEXT_STATE,
|
|
213
|
-
SCRIPT_DATA: SCRIPT_DATA_STATE,
|
|
214
|
-
PLAINTEXT: PLAINTEXT_STATE
|
|
215
|
-
};
|
|
237
|
+
//Errors
|
|
238
|
+
_err() {
|
|
239
|
+
// NOTE: err reporting is noop by default. Enabled by mixin.
|
|
240
|
+
}
|
|
216
241
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return token.attrs[i].value;
|
|
242
|
+
_errOnNextCodePoint(err) {
|
|
243
|
+
this._consume();
|
|
244
|
+
this._err(err);
|
|
245
|
+
this._unconsume();
|
|
222
246
|
}
|
|
223
247
|
|
|
224
|
-
|
|
225
|
-
|
|
248
|
+
//API
|
|
249
|
+
getNextToken() {
|
|
250
|
+
while (!this.tokenQueue.length && this.active) {
|
|
251
|
+
this.consumedAfterSnapshot = 0;
|
|
226
252
|
|
|
227
|
-
|
|
228
|
-
Tokenizer.prototype.getNextToken = function () {
|
|
229
|
-
while (!this.tokenQueue.length && this.active) {
|
|
230
|
-
this._hibernationSnapshot();
|
|
253
|
+
const cp = this._consume();
|
|
231
254
|
|
|
232
|
-
|
|
255
|
+
if (!this._ensureHibernation()) {
|
|
256
|
+
this[this.state](cp);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
233
259
|
|
|
234
|
-
|
|
235
|
-
this[this.state](cp);
|
|
260
|
+
return this.tokenQueue.shift();
|
|
236
261
|
}
|
|
237
262
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
this.active = true;
|
|
243
|
-
this.preprocessor.write(chunk, isLastChunk);
|
|
244
|
-
};
|
|
263
|
+
write(chunk, isLastChunk) {
|
|
264
|
+
this.active = true;
|
|
265
|
+
this.preprocessor.write(chunk, isLastChunk);
|
|
266
|
+
}
|
|
245
267
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
268
|
+
insertHtmlAtCurrentPos(chunk) {
|
|
269
|
+
this.active = true;
|
|
270
|
+
this.preprocessor.insertHtmlAtCurrentPos(chunk);
|
|
271
|
+
}
|
|
250
272
|
|
|
251
|
-
//Hibernation
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
273
|
+
//Hibernation
|
|
274
|
+
_ensureHibernation() {
|
|
275
|
+
if (this.preprocessor.endOfChunkHit) {
|
|
276
|
+
for (; this.consumedAfterSnapshot > 0; this.consumedAfterSnapshot--) {
|
|
277
|
+
this.preprocessor.retreat();
|
|
278
|
+
}
|
|
255
279
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
for (; this.consumedAfterSnapshot > 0; this.consumedAfterSnapshot--)
|
|
259
|
-
this.preprocessor.retreat();
|
|
280
|
+
this.active = false;
|
|
281
|
+
this.tokenQueue.push({ type: Tokenizer.HIBERNATION_TOKEN });
|
|
260
282
|
|
|
261
|
-
|
|
262
|
-
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
263
285
|
|
|
264
|
-
return
|
|
286
|
+
return false;
|
|
265
287
|
}
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
|
|
289
|
+
//Consumption
|
|
290
|
+
_consume() {
|
|
291
|
+
this.consumedAfterSnapshot++;
|
|
292
|
+
return this.preprocessor.advance();
|
|
293
|
+
}
|
|
269
294
|
|
|
295
|
+
_unconsume() {
|
|
296
|
+
this.consumedAfterSnapshot--;
|
|
297
|
+
this.preprocessor.retreat();
|
|
298
|
+
}
|
|
270
299
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
};
|
|
300
|
+
_reconsumeInState(state) {
|
|
301
|
+
this.state = state;
|
|
302
|
+
this._unconsume();
|
|
303
|
+
}
|
|
276
304
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
305
|
+
_consumeSequenceIfMatch(pattern, startCp, caseSensitive) {
|
|
306
|
+
let consumedCount = 0;
|
|
307
|
+
let isMatch = true;
|
|
308
|
+
const patternLength = pattern.length;
|
|
309
|
+
let patternPos = 0;
|
|
310
|
+
let cp = startCp;
|
|
311
|
+
let patternCp = void 0;
|
|
281
312
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
313
|
+
for (; patternPos < patternLength; patternPos++) {
|
|
314
|
+
if (patternPos > 0) {
|
|
315
|
+
cp = this._consume();
|
|
316
|
+
consumedCount++;
|
|
317
|
+
}
|
|
286
318
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
319
|
+
if (cp === $.EOF) {
|
|
320
|
+
isMatch = false;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
291
323
|
|
|
292
|
-
|
|
293
|
-
var consumedCount = 0,
|
|
294
|
-
isMatch = true,
|
|
295
|
-
patternLength = pattern.length,
|
|
296
|
-
patternPos = 0,
|
|
297
|
-
cp = startCp,
|
|
298
|
-
patternCp = void 0;
|
|
324
|
+
patternCp = pattern[patternPos];
|
|
299
325
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
326
|
+
if (cp !== patternCp && (caseSensitive || cp !== toAsciiLowerCodePoint(patternCp))) {
|
|
327
|
+
isMatch = false;
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
304
330
|
}
|
|
305
331
|
|
|
306
|
-
if (
|
|
307
|
-
|
|
308
|
-
|
|
332
|
+
if (!isMatch) {
|
|
333
|
+
while (consumedCount--) {
|
|
334
|
+
this._unconsume();
|
|
335
|
+
}
|
|
309
336
|
}
|
|
310
337
|
|
|
311
|
-
|
|
338
|
+
return isMatch;
|
|
339
|
+
}
|
|
312
340
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
341
|
+
//Temp buffer
|
|
342
|
+
_isTempBufferEqualToScriptString() {
|
|
343
|
+
if (this.tempBuff.length !== $$.SCRIPT_STRING.length) {
|
|
344
|
+
return false;
|
|
316
345
|
}
|
|
317
|
-
}
|
|
318
346
|
|
|
319
|
-
|
|
320
|
-
|
|
347
|
+
for (let i = 0; i < this.tempBuff.length; i++) {
|
|
348
|
+
if (this.tempBuff[i] !== $$.SCRIPT_STRING[i]) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
321
352
|
|
|
322
|
-
|
|
323
|
-
}
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
324
355
|
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
|
|
356
|
+
//Token creation
|
|
357
|
+
_createStartTagToken() {
|
|
358
|
+
this.currentToken = {
|
|
359
|
+
type: Tokenizer.START_TAG_TOKEN,
|
|
360
|
+
tagName: '',
|
|
361
|
+
selfClosing: false,
|
|
362
|
+
ackSelfClosing: false,
|
|
363
|
+
attrs: []
|
|
364
|
+
};
|
|
365
|
+
}
|
|
328
366
|
|
|
329
|
-
|
|
367
|
+
_createEndTagToken() {
|
|
368
|
+
this.currentToken = {
|
|
369
|
+
type: Tokenizer.END_TAG_TOKEN,
|
|
370
|
+
tagName: '',
|
|
371
|
+
selfClosing: false,
|
|
372
|
+
attrs: []
|
|
373
|
+
};
|
|
374
|
+
}
|
|
330
375
|
|
|
331
|
-
|
|
332
|
-
|
|
376
|
+
_createCommentToken() {
|
|
377
|
+
this.currentToken = {
|
|
378
|
+
type: Tokenizer.COMMENT_TOKEN,
|
|
379
|
+
data: ''
|
|
380
|
+
};
|
|
381
|
+
}
|
|
333
382
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
383
|
+
_createDoctypeToken(initialName) {
|
|
384
|
+
this.currentToken = {
|
|
385
|
+
type: Tokenizer.DOCTYPE_TOKEN,
|
|
386
|
+
name: initialName,
|
|
387
|
+
forceQuirks: false,
|
|
388
|
+
publicId: null,
|
|
389
|
+
systemId: null
|
|
390
|
+
};
|
|
391
|
+
}
|
|
338
392
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
393
|
+
_createCharacterToken(type, ch) {
|
|
394
|
+
this.currentCharacterToken = {
|
|
395
|
+
type: type,
|
|
396
|
+
chars: ch
|
|
397
|
+
};
|
|
342
398
|
}
|
|
343
399
|
|
|
344
|
-
|
|
345
|
-
};
|
|
400
|
+
_createEOFToken() {
|
|
401
|
+
this.currentToken = { type: Tokenizer.EOF_TOKEN };
|
|
402
|
+
}
|
|
346
403
|
|
|
347
|
-
//
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
};
|
|
355
|
-
};
|
|
404
|
+
//Tag attributes
|
|
405
|
+
_createAttr(attrNameFirstCh) {
|
|
406
|
+
this.currentAttr = {
|
|
407
|
+
name: attrNameFirstCh,
|
|
408
|
+
value: ''
|
|
409
|
+
};
|
|
410
|
+
}
|
|
356
411
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
};
|
|
412
|
+
_leaveAttrName(toState) {
|
|
413
|
+
if (Tokenizer.getTokenAttr(this.currentToken, this.currentAttr.name) === null) {
|
|
414
|
+
this.currentToken.attrs.push(this.currentAttr);
|
|
415
|
+
} else {
|
|
416
|
+
this._err(ERR.duplicateAttribute);
|
|
417
|
+
}
|
|
364
418
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
type: Tokenizer.COMMENT_TOKEN,
|
|
368
|
-
data: ''
|
|
369
|
-
};
|
|
370
|
-
};
|
|
419
|
+
this.state = toState;
|
|
420
|
+
}
|
|
371
421
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
name: initialName,
|
|
376
|
-
forceQuirks: false,
|
|
377
|
-
publicId: null,
|
|
378
|
-
systemId: null
|
|
379
|
-
};
|
|
380
|
-
};
|
|
422
|
+
_leaveAttrValue(toState) {
|
|
423
|
+
this.state = toState;
|
|
424
|
+
}
|
|
381
425
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
chars: ch
|
|
386
|
-
};
|
|
387
|
-
};
|
|
426
|
+
//Token emission
|
|
427
|
+
_emitCurrentToken() {
|
|
428
|
+
this._emitCurrentCharacterToken();
|
|
388
429
|
|
|
389
|
-
|
|
390
|
-
Tokenizer.prototype._createAttr = function (attrNameFirstCh) {
|
|
391
|
-
this.currentAttr = {
|
|
392
|
-
name: attrNameFirstCh,
|
|
393
|
-
value: ''
|
|
394
|
-
};
|
|
395
|
-
};
|
|
430
|
+
const ct = this.currentToken;
|
|
396
431
|
|
|
397
|
-
|
|
398
|
-
return Tokenizer.getTokenAttr(this.currentToken, this.currentAttr.name) !== null;
|
|
399
|
-
};
|
|
432
|
+
this.currentToken = null;
|
|
400
433
|
|
|
401
|
-
|
|
402
|
-
|
|
434
|
+
//NOTE: store emited start tag's tagName to determine is the following end tag token is appropriate.
|
|
435
|
+
if (ct.type === Tokenizer.START_TAG_TOKEN) {
|
|
436
|
+
this.lastStartTagName = ct.tagName;
|
|
437
|
+
} else if (ct.type === Tokenizer.END_TAG_TOKEN) {
|
|
438
|
+
if (ct.attrs.length > 0) {
|
|
439
|
+
this._err(ERR.endTagWithAttributes);
|
|
440
|
+
}
|
|
403
441
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
442
|
+
if (ct.selfClosing) {
|
|
443
|
+
this._err(ERR.endTagWithTrailingSolidus);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
407
446
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
};
|
|
447
|
+
this.tokenQueue.push(ct);
|
|
448
|
+
}
|
|
411
449
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}
|
|
450
|
+
_emitCurrentCharacterToken() {
|
|
451
|
+
if (this.currentCharacterToken) {
|
|
452
|
+
this.tokenQueue.push(this.currentCharacterToken);
|
|
453
|
+
this.currentCharacterToken = null;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
417
456
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
457
|
+
_emitEOFToken() {
|
|
458
|
+
this._createEOFToken();
|
|
459
|
+
this._emitCurrentToken();
|
|
460
|
+
}
|
|
421
461
|
|
|
422
|
-
//
|
|
423
|
-
if (this.currentToken.type === Tokenizer.START_TAG_TOKEN)
|
|
424
|
-
this.lastStartTagName = this.currentToken.tagName;
|
|
462
|
+
//Characters emission
|
|
425
463
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
464
|
+
//OPTIMIZATION: specification uses only one type of character tokens (one token per character).
|
|
465
|
+
//This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
|
|
466
|
+
//If we have a sequence of characters that belong to the same group, parser can process it
|
|
467
|
+
//as a single solid character token.
|
|
468
|
+
//So, there are 3 types of character tokens in parse5:
|
|
469
|
+
//1)NULL_CHARACTER_TOKEN - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
|
|
470
|
+
//2)WHITESPACE_CHARACTER_TOKEN - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
|
|
471
|
+
//3)CHARACTER_TOKEN - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
|
|
472
|
+
_appendCharToCurrentCharacterToken(type, ch) {
|
|
473
|
+
if (this.currentCharacterToken && this.currentCharacterToken.type !== type) {
|
|
474
|
+
this._emitCurrentCharacterToken();
|
|
475
|
+
}
|
|
429
476
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
477
|
+
if (this.currentCharacterToken) {
|
|
478
|
+
this.currentCharacterToken.chars += ch;
|
|
479
|
+
} else {
|
|
480
|
+
this._createCharacterToken(type, ch);
|
|
481
|
+
}
|
|
434
482
|
}
|
|
435
|
-
};
|
|
436
483
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
this.tokenQueue.push({type: Tokenizer.EOF_TOKEN});
|
|
440
|
-
};
|
|
484
|
+
_emitCodePoint(cp) {
|
|
485
|
+
let type = Tokenizer.CHARACTER_TOKEN;
|
|
441
486
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
//as a single solid character token.
|
|
448
|
-
//So, there are 3 types of character tokens in parse5:
|
|
449
|
-
//1)NULL_CHARACTER_TOKEN - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
|
|
450
|
-
//2)WHITESPACE_CHARACTER_TOKEN - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
|
|
451
|
-
//3)CHARACTER_TOKEN - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
|
|
452
|
-
Tokenizer.prototype._appendCharToCurrentCharacterToken = function (type, ch) {
|
|
453
|
-
if (this.currentCharacterToken && this.currentCharacterToken.type !== type)
|
|
454
|
-
this._emitCurrentCharacterToken();
|
|
487
|
+
if (isWhitespace(cp)) {
|
|
488
|
+
type = Tokenizer.WHITESPACE_CHARACTER_TOKEN;
|
|
489
|
+
} else if (cp === $.NULL) {
|
|
490
|
+
type = Tokenizer.NULL_CHARACTER_TOKEN;
|
|
491
|
+
}
|
|
455
492
|
|
|
456
|
-
|
|
457
|
-
|
|
493
|
+
this._appendCharToCurrentCharacterToken(type, toChar(cp));
|
|
494
|
+
}
|
|
458
495
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
496
|
+
_emitSeveralCodePoints(codePoints) {
|
|
497
|
+
for (let i = 0; i < codePoints.length; i++) {
|
|
498
|
+
this._emitCodePoint(codePoints[i]);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
462
501
|
|
|
463
|
-
|
|
464
|
-
|
|
502
|
+
//NOTE: used then we emit character explicitly. This is always a non-whitespace and a non-null character.
|
|
503
|
+
//So we can avoid additional checks here.
|
|
504
|
+
_emitChars(ch) {
|
|
505
|
+
this._appendCharToCurrentCharacterToken(Tokenizer.CHARACTER_TOKEN, ch);
|
|
506
|
+
}
|
|
465
507
|
|
|
466
|
-
|
|
467
|
-
|
|
508
|
+
// Character reference helpers
|
|
509
|
+
_matchNamedCharacterReference(startCp) {
|
|
510
|
+
let result = null;
|
|
511
|
+
let excess = 1;
|
|
512
|
+
let i = findNamedEntityTreeBranch(0, startCp);
|
|
468
513
|
|
|
469
|
-
|
|
470
|
-
type = Tokenizer.NULL_CHARACTER_TOKEN;
|
|
514
|
+
this.tempBuff.push(startCp);
|
|
471
515
|
|
|
472
|
-
|
|
473
|
-
|
|
516
|
+
while (i > -1) {
|
|
517
|
+
const current = neTree[i];
|
|
518
|
+
const inNode = current < MAX_BRANCH_MARKER_VALUE;
|
|
519
|
+
const nodeWithData = inNode && current & HAS_DATA_FLAG;
|
|
474
520
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
521
|
+
if (nodeWithData) {
|
|
522
|
+
//NOTE: we use greedy search, so we continue lookup at this point
|
|
523
|
+
result = current & DATA_DUPLET_FLAG ? [neTree[++i], neTree[++i]] : [neTree[++i]];
|
|
524
|
+
excess = 0;
|
|
525
|
+
}
|
|
479
526
|
|
|
480
|
-
|
|
481
|
-
//So we can avoid additional checks here.
|
|
482
|
-
Tokenizer.prototype._emitChar = function (ch) {
|
|
483
|
-
this._appendCharToCurrentCharacterToken(Tokenizer.CHARACTER_TOKEN, ch);
|
|
484
|
-
};
|
|
527
|
+
const cp = this._consume();
|
|
485
528
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
var digits = '',
|
|
489
|
-
nextCp = void 0;
|
|
529
|
+
this.tempBuff.push(cp);
|
|
530
|
+
excess++;
|
|
490
531
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
} while (nextCp !== $.EOF && isDigit(nextCp, isHex));
|
|
532
|
+
if (cp === $.EOF) {
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
495
535
|
|
|
496
|
-
|
|
497
|
-
|
|
536
|
+
if (inNode) {
|
|
537
|
+
i = current & HAS_BRANCHES_FLAG ? findNamedEntityTreeBranch(i, cp) : -1;
|
|
538
|
+
} else {
|
|
539
|
+
i = cp === current ? ++i : -1;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
498
542
|
|
|
499
|
-
|
|
500
|
-
|
|
543
|
+
while (excess--) {
|
|
544
|
+
this.tempBuff.pop();
|
|
545
|
+
this._unconsume();
|
|
546
|
+
}
|
|
501
547
|
|
|
502
|
-
|
|
503
|
-
|
|
548
|
+
return result;
|
|
549
|
+
}
|
|
504
550
|
|
|
505
|
-
|
|
506
|
-
return
|
|
551
|
+
_isCharacterReferenceInAttribute() {
|
|
552
|
+
return (
|
|
553
|
+
this.returnState === ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE ||
|
|
554
|
+
this.returnState === ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE ||
|
|
555
|
+
this.returnState === ATTRIBUTE_VALUE_UNQUOTED_STATE
|
|
556
|
+
);
|
|
557
|
+
}
|
|
507
558
|
|
|
508
|
-
|
|
509
|
-
|
|
559
|
+
_isCharacterReferenceAttributeQuirk(withSemicolon) {
|
|
560
|
+
if (!withSemicolon && this._isCharacterReferenceInAttribute()) {
|
|
561
|
+
const nextCp = this._consume();
|
|
510
562
|
|
|
511
|
-
|
|
512
|
-
// https://github.com/inikulin/parse5/tree/master/scripts/generate_named_entity_data/README.md
|
|
513
|
-
Tokenizer.prototype._consumeNamedEntity = function (inAttr) {
|
|
514
|
-
var referencedCodePoints = null,
|
|
515
|
-
referenceSize = 0,
|
|
516
|
-
cp = null,
|
|
517
|
-
consumedCount = 0,
|
|
518
|
-
semicolonTerminated = false;
|
|
563
|
+
this._unconsume();
|
|
519
564
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
inNode = current < MAX_BRANCH_MARKER_VALUE,
|
|
523
|
-
nodeWithData = inNode && current & HAS_DATA_FLAG;
|
|
565
|
+
return nextCp === $.EQUALS_SIGN || isAsciiAlphaNumeric(nextCp);
|
|
566
|
+
}
|
|
524
567
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
referenceSize = consumedCount;
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
528
570
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
571
|
+
_flushCodePointsConsumedAsCharacterReference() {
|
|
572
|
+
if (this._isCharacterReferenceInAttribute()) {
|
|
573
|
+
for (let i = 0; i < this.tempBuff.length; i++) {
|
|
574
|
+
this.currentAttr.value += toChar(this.tempBuff[i]);
|
|
532
575
|
}
|
|
576
|
+
} else {
|
|
577
|
+
this._emitSeveralCodePoints(this.tempBuff);
|
|
533
578
|
}
|
|
534
579
|
|
|
535
|
-
|
|
536
|
-
|
|
580
|
+
this.tempBuff = [];
|
|
581
|
+
}
|
|
537
582
|
|
|
538
|
-
|
|
539
|
-
break;
|
|
583
|
+
// State machine
|
|
540
584
|
|
|
541
|
-
|
|
542
|
-
|
|
585
|
+
// Data state
|
|
586
|
+
//------------------------------------------------------------------
|
|
587
|
+
[DATA_STATE](cp) {
|
|
588
|
+
this.preprocessor.dropParsedChunk();
|
|
543
589
|
|
|
544
|
-
|
|
545
|
-
|
|
590
|
+
if (cp === $.LESS_THAN_SIGN) {
|
|
591
|
+
this.state = TAG_OPEN_STATE;
|
|
592
|
+
} else if (cp === $.AMPERSAND) {
|
|
593
|
+
this.returnState = DATA_STATE;
|
|
594
|
+
this.state = CHARACTER_REFERENCE_STATE;
|
|
595
|
+
} else if (cp === $.NULL) {
|
|
596
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
597
|
+
this._emitCodePoint(cp);
|
|
598
|
+
} else if (cp === $.EOF) {
|
|
599
|
+
this._emitEOFToken();
|
|
600
|
+
} else {
|
|
601
|
+
this._emitCodePoint(cp);
|
|
602
|
+
}
|
|
546
603
|
}
|
|
547
604
|
|
|
605
|
+
// RCDATA state
|
|
606
|
+
//------------------------------------------------------------------
|
|
607
|
+
[RCDATA_STATE](cp) {
|
|
608
|
+
this.preprocessor.dropParsedChunk();
|
|
609
|
+
|
|
610
|
+
if (cp === $.AMPERSAND) {
|
|
611
|
+
this.returnState = RCDATA_STATE;
|
|
612
|
+
this.state = CHARACTER_REFERENCE_STATE;
|
|
613
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
614
|
+
this.state = RCDATA_LESS_THAN_SIGN_STATE;
|
|
615
|
+
} else if (cp === $.NULL) {
|
|
616
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
617
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
618
|
+
} else if (cp === $.EOF) {
|
|
619
|
+
this._emitEOFToken();
|
|
620
|
+
} else {
|
|
621
|
+
this._emitCodePoint(cp);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
548
624
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
//NOTE: If the character reference is being consumed as part of an attribute and the next character
|
|
555
|
-
//is either a U+003D EQUALS SIGN character (=) or an alphanumeric ASCII character, then, for historical
|
|
556
|
-
//reasons, all the characters that were matched after the U+0026 AMPERSAND character (&) must be
|
|
557
|
-
//unconsumed, and nothing is returned.
|
|
558
|
-
//However, if this next character is in fact a U+003D EQUALS SIGN character (=), then this is a
|
|
559
|
-
//parse error, because some legacy user agents will misinterpret the markup in those cases.
|
|
560
|
-
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#tokenizing-character-references)
|
|
561
|
-
if (inAttr) {
|
|
562
|
-
var nextCp = this._lookahead();
|
|
625
|
+
// RAWTEXT state
|
|
626
|
+
//------------------------------------------------------------------
|
|
627
|
+
[RAWTEXT_STATE](cp) {
|
|
628
|
+
this.preprocessor.dropParsedChunk();
|
|
563
629
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
630
|
+
if (cp === $.LESS_THAN_SIGN) {
|
|
631
|
+
this.state = RAWTEXT_LESS_THAN_SIGN_STATE;
|
|
632
|
+
} else if (cp === $.NULL) {
|
|
633
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
634
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
635
|
+
} else if (cp === $.EOF) {
|
|
636
|
+
this._emitEOFToken();
|
|
637
|
+
} else {
|
|
638
|
+
this._emitCodePoint(cp);
|
|
569
639
|
}
|
|
570
|
-
|
|
571
|
-
return referencedCodePoints;
|
|
572
640
|
}
|
|
573
641
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
642
|
+
// Script data state
|
|
643
|
+
//------------------------------------------------------------------
|
|
644
|
+
[SCRIPT_DATA_STATE](cp) {
|
|
645
|
+
this.preprocessor.dropParsedChunk();
|
|
578
646
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
647
|
+
if (cp === $.LESS_THAN_SIGN) {
|
|
648
|
+
this.state = SCRIPT_DATA_LESS_THAN_SIGN_STATE;
|
|
649
|
+
} else if (cp === $.NULL) {
|
|
650
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
651
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
652
|
+
} else if (cp === $.EOF) {
|
|
653
|
+
this._emitEOFToken();
|
|
654
|
+
} else {
|
|
655
|
+
this._emitCodePoint(cp);
|
|
656
|
+
}
|
|
585
657
|
}
|
|
586
658
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
659
|
+
// PLAINTEXT state
|
|
660
|
+
//------------------------------------------------------------------
|
|
661
|
+
[PLAINTEXT_STATE](cp) {
|
|
662
|
+
this.preprocessor.dropParsedChunk();
|
|
591
663
|
|
|
592
|
-
if (
|
|
593
|
-
this.
|
|
594
|
-
|
|
664
|
+
if (cp === $.NULL) {
|
|
665
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
666
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
667
|
+
} else if (cp === $.EOF) {
|
|
668
|
+
this._emitEOFToken();
|
|
669
|
+
} else {
|
|
670
|
+
this._emitCodePoint(cp);
|
|
595
671
|
}
|
|
672
|
+
}
|
|
596
673
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if (
|
|
601
|
-
|
|
674
|
+
// Tag open state
|
|
675
|
+
//------------------------------------------------------------------
|
|
676
|
+
[TAG_OPEN_STATE](cp) {
|
|
677
|
+
if (cp === $.EXCLAMATION_MARK) {
|
|
678
|
+
this.state = MARKUP_DECLARATION_OPEN_STATE;
|
|
679
|
+
} else if (cp === $.SOLIDUS) {
|
|
680
|
+
this.state = END_TAG_OPEN_STATE;
|
|
681
|
+
} else if (isAsciiLetter(cp)) {
|
|
682
|
+
this._createStartTagToken();
|
|
683
|
+
this._reconsumeInState(TAG_NAME_STATE);
|
|
684
|
+
} else if (cp === $.QUESTION_MARK) {
|
|
685
|
+
this._err(ERR.unexpectedQuestionMarkInsteadOfTagName);
|
|
686
|
+
this._createCommentToken();
|
|
687
|
+
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
688
|
+
} else if (cp === $.EOF) {
|
|
689
|
+
this._err(ERR.eofBeforeTagName);
|
|
690
|
+
this._emitChars('<');
|
|
691
|
+
this._emitEOFToken();
|
|
692
|
+
} else {
|
|
693
|
+
this._err(ERR.invalidFirstCharacterOfTagName);
|
|
694
|
+
this._emitChars('<');
|
|
695
|
+
this._reconsumeInState(DATA_STATE);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
602
698
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
699
|
+
// End tag open state
|
|
700
|
+
//------------------------------------------------------------------
|
|
701
|
+
[END_TAG_OPEN_STATE](cp) {
|
|
702
|
+
if (isAsciiLetter(cp)) {
|
|
703
|
+
this._createEndTagToken();
|
|
704
|
+
this._reconsumeInState(TAG_NAME_STATE);
|
|
705
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
706
|
+
this._err(ERR.missingEndTagName);
|
|
707
|
+
this.state = DATA_STATE;
|
|
708
|
+
} else if (cp === $.EOF) {
|
|
709
|
+
this._err(ERR.eofBeforeTagName);
|
|
710
|
+
this._emitChars('</');
|
|
711
|
+
this._emitEOFToken();
|
|
712
|
+
} else {
|
|
713
|
+
this._err(ERR.invalidFirstCharacterOfTagName);
|
|
714
|
+
this._createCommentToken();
|
|
715
|
+
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
716
|
+
}
|
|
607
717
|
}
|
|
608
718
|
|
|
609
|
-
|
|
719
|
+
// Tag name state
|
|
720
|
+
//------------------------------------------------------------------
|
|
721
|
+
[TAG_NAME_STATE](cp) {
|
|
722
|
+
if (isWhitespace(cp)) {
|
|
723
|
+
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
724
|
+
} else if (cp === $.SOLIDUS) {
|
|
725
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
726
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
727
|
+
this.state = DATA_STATE;
|
|
728
|
+
this._emitCurrentToken();
|
|
729
|
+
} else if (isAsciiUpper(cp)) {
|
|
730
|
+
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
731
|
+
} else if (cp === $.NULL) {
|
|
732
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
733
|
+
this.currentToken.tagName += unicode.REPLACEMENT_CHARACTER;
|
|
734
|
+
} else if (cp === $.EOF) {
|
|
735
|
+
this._err(ERR.eofInTag);
|
|
736
|
+
this._emitEOFToken();
|
|
737
|
+
} else {
|
|
738
|
+
this.currentToken.tagName += toChar(cp);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
610
741
|
|
|
611
|
-
|
|
612
|
-
|
|
742
|
+
// RCDATA less-than sign state
|
|
743
|
+
//------------------------------------------------------------------
|
|
744
|
+
[RCDATA_LESS_THAN_SIGN_STATE](cp) {
|
|
745
|
+
if (cp === $.SOLIDUS) {
|
|
746
|
+
this.tempBuff = [];
|
|
747
|
+
this.state = RCDATA_END_TAG_OPEN_STATE;
|
|
748
|
+
} else {
|
|
749
|
+
this._emitChars('<');
|
|
750
|
+
this._reconsumeInState(RCDATA_STATE);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
613
753
|
|
|
614
|
-
//
|
|
615
|
-
|
|
754
|
+
// RCDATA end tag open state
|
|
755
|
+
//------------------------------------------------------------------
|
|
756
|
+
[RCDATA_END_TAG_OPEN_STATE](cp) {
|
|
757
|
+
if (isAsciiLetter(cp)) {
|
|
758
|
+
this._createEndTagToken();
|
|
759
|
+
this._reconsumeInState(RCDATA_END_TAG_NAME_STATE);
|
|
760
|
+
} else {
|
|
761
|
+
this._emitChars('</');
|
|
762
|
+
this._reconsumeInState(RCDATA_STATE);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
616
765
|
|
|
617
|
-
//
|
|
618
|
-
//------------------------------------------------------------------
|
|
619
|
-
|
|
620
|
-
|
|
766
|
+
// RCDATA end tag name state
|
|
767
|
+
//------------------------------------------------------------------
|
|
768
|
+
[RCDATA_END_TAG_NAME_STATE](cp) {
|
|
769
|
+
if (isAsciiUpper(cp)) {
|
|
770
|
+
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
771
|
+
this.tempBuff.push(cp);
|
|
772
|
+
} else if (isAsciiLower(cp)) {
|
|
773
|
+
this.currentToken.tagName += toChar(cp);
|
|
774
|
+
this.tempBuff.push(cp);
|
|
775
|
+
} else {
|
|
776
|
+
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
777
|
+
if (isWhitespace(cp)) {
|
|
778
|
+
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
621
781
|
|
|
622
|
-
|
|
623
|
-
|
|
782
|
+
if (cp === $.SOLIDUS) {
|
|
783
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
624
786
|
|
|
625
|
-
|
|
626
|
-
|
|
787
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
788
|
+
this.state = DATA_STATE;
|
|
789
|
+
this._emitCurrentToken();
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
627
793
|
|
|
628
|
-
|
|
629
|
-
|
|
794
|
+
this._emitChars('</');
|
|
795
|
+
this._emitSeveralCodePoints(this.tempBuff);
|
|
796
|
+
this._reconsumeInState(RCDATA_STATE);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
630
799
|
|
|
631
|
-
|
|
632
|
-
|
|
800
|
+
// RAWTEXT less-than sign state
|
|
801
|
+
//------------------------------------------------------------------
|
|
802
|
+
[RAWTEXT_LESS_THAN_SIGN_STATE](cp) {
|
|
803
|
+
if (cp === $.SOLIDUS) {
|
|
804
|
+
this.tempBuff = [];
|
|
805
|
+
this.state = RAWTEXT_END_TAG_OPEN_STATE;
|
|
806
|
+
} else {
|
|
807
|
+
this._emitChars('<');
|
|
808
|
+
this._reconsumeInState(RAWTEXT_STATE);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
633
811
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
812
|
+
// RAWTEXT end tag open state
|
|
813
|
+
//------------------------------------------------------------------
|
|
814
|
+
[RAWTEXT_END_TAG_OPEN_STATE](cp) {
|
|
815
|
+
if (isAsciiLetter(cp)) {
|
|
816
|
+
this._createEndTagToken();
|
|
817
|
+
this._reconsumeInState(RAWTEXT_END_TAG_NAME_STATE);
|
|
818
|
+
} else {
|
|
819
|
+
this._emitChars('</');
|
|
820
|
+
this._reconsumeInState(RAWTEXT_STATE);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
637
823
|
|
|
824
|
+
// RAWTEXT end tag name state
|
|
825
|
+
//------------------------------------------------------------------
|
|
826
|
+
[RAWTEXT_END_TAG_NAME_STATE](cp) {
|
|
827
|
+
if (isAsciiUpper(cp)) {
|
|
828
|
+
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
829
|
+
this.tempBuff.push(cp);
|
|
830
|
+
} else if (isAsciiLower(cp)) {
|
|
831
|
+
this.currentToken.tagName += toChar(cp);
|
|
832
|
+
this.tempBuff.push(cp);
|
|
833
|
+
} else {
|
|
834
|
+
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
835
|
+
if (isWhitespace(cp)) {
|
|
836
|
+
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
638
839
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
840
|
+
if (cp === $.SOLIDUS) {
|
|
841
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
643
844
|
|
|
644
|
-
|
|
845
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
846
|
+
this._emitCurrentToken();
|
|
847
|
+
this.state = DATA_STATE;
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
645
851
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
this.
|
|
852
|
+
this._emitChars('</');
|
|
853
|
+
this._emitSeveralCodePoints(this.tempBuff);
|
|
854
|
+
this._reconsumeInState(RAWTEXT_STATE);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
649
857
|
|
|
650
|
-
|
|
651
|
-
|
|
858
|
+
// Script data less-than sign state
|
|
859
|
+
//------------------------------------------------------------------
|
|
860
|
+
[SCRIPT_DATA_LESS_THAN_SIGN_STATE](cp) {
|
|
861
|
+
if (cp === $.SOLIDUS) {
|
|
862
|
+
this.tempBuff = [];
|
|
863
|
+
this.state = SCRIPT_DATA_END_TAG_OPEN_STATE;
|
|
864
|
+
} else if (cp === $.EXCLAMATION_MARK) {
|
|
865
|
+
this.state = SCRIPT_DATA_ESCAPE_START_STATE;
|
|
866
|
+
this._emitChars('<!');
|
|
867
|
+
} else {
|
|
868
|
+
this._emitChars('<');
|
|
869
|
+
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
652
872
|
|
|
653
|
-
|
|
873
|
+
// Script data end tag open state
|
|
874
|
+
//------------------------------------------------------------------
|
|
875
|
+
[SCRIPT_DATA_END_TAG_OPEN_STATE](cp) {
|
|
876
|
+
if (isAsciiLetter(cp)) {
|
|
877
|
+
this._createEndTagToken();
|
|
878
|
+
this._reconsumeInState(SCRIPT_DATA_END_TAG_NAME_STATE);
|
|
879
|
+
} else {
|
|
880
|
+
this._emitChars('</');
|
|
881
|
+
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
882
|
+
}
|
|
654
883
|
}
|
|
655
|
-
};
|
|
656
884
|
|
|
885
|
+
// Script data end tag name state
|
|
886
|
+
//------------------------------------------------------------------
|
|
887
|
+
[SCRIPT_DATA_END_TAG_NAME_STATE](cp) {
|
|
888
|
+
if (isAsciiUpper(cp)) {
|
|
889
|
+
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
890
|
+
this.tempBuff.push(cp);
|
|
891
|
+
} else if (isAsciiLower(cp)) {
|
|
892
|
+
this.currentToken.tagName += toChar(cp);
|
|
893
|
+
this.tempBuff.push(cp);
|
|
894
|
+
} else {
|
|
895
|
+
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
896
|
+
if (isWhitespace(cp)) {
|
|
897
|
+
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
898
|
+
return;
|
|
899
|
+
} else if (cp === $.SOLIDUS) {
|
|
900
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
901
|
+
return;
|
|
902
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
903
|
+
this._emitCurrentToken();
|
|
904
|
+
this.state = DATA_STATE;
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
657
908
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
909
|
+
this._emitChars('</');
|
|
910
|
+
this._emitSeveralCodePoints(this.tempBuff);
|
|
911
|
+
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
662
914
|
|
|
663
|
-
|
|
664
|
-
|
|
915
|
+
// Script data escape start state
|
|
916
|
+
//------------------------------------------------------------------
|
|
917
|
+
[SCRIPT_DATA_ESCAPE_START_STATE](cp) {
|
|
918
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
919
|
+
this.state = SCRIPT_DATA_ESCAPE_START_DASH_STATE;
|
|
920
|
+
this._emitChars('-');
|
|
921
|
+
} else {
|
|
922
|
+
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
665
925
|
|
|
666
|
-
|
|
667
|
-
|
|
926
|
+
// Script data escape start dash state
|
|
927
|
+
//------------------------------------------------------------------
|
|
928
|
+
[SCRIPT_DATA_ESCAPE_START_DASH_STATE](cp) {
|
|
929
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
930
|
+
this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
|
|
931
|
+
this._emitChars('-');
|
|
932
|
+
} else {
|
|
933
|
+
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
668
936
|
|
|
669
|
-
|
|
670
|
-
|
|
937
|
+
// Script data escaped state
|
|
938
|
+
//------------------------------------------------------------------
|
|
939
|
+
[SCRIPT_DATA_ESCAPED_STATE](cp) {
|
|
940
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
941
|
+
this.state = SCRIPT_DATA_ESCAPED_DASH_STATE;
|
|
942
|
+
this._emitChars('-');
|
|
943
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
944
|
+
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
945
|
+
} else if (cp === $.NULL) {
|
|
946
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
947
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
948
|
+
} else if (cp === $.EOF) {
|
|
949
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
950
|
+
this._emitEOFToken();
|
|
951
|
+
} else {
|
|
952
|
+
this._emitCodePoint(cp);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
671
955
|
|
|
672
|
-
|
|
673
|
-
|
|
956
|
+
// Script data escaped dash state
|
|
957
|
+
//------------------------------------------------------------------
|
|
958
|
+
[SCRIPT_DATA_ESCAPED_DASH_STATE](cp) {
|
|
959
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
960
|
+
this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
|
|
961
|
+
this._emitChars('-');
|
|
962
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
963
|
+
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
964
|
+
} else if (cp === $.NULL) {
|
|
965
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
966
|
+
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
967
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
968
|
+
} else if (cp === $.EOF) {
|
|
969
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
970
|
+
this._emitEOFToken();
|
|
971
|
+
} else {
|
|
972
|
+
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
973
|
+
this._emitCodePoint(cp);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
674
976
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
977
|
+
// Script data escaped dash dash state
|
|
978
|
+
//------------------------------------------------------------------
|
|
979
|
+
[SCRIPT_DATA_ESCAPED_DASH_DASH_STATE](cp) {
|
|
980
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
981
|
+
this._emitChars('-');
|
|
982
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
983
|
+
this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
984
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
985
|
+
this.state = SCRIPT_DATA_STATE;
|
|
986
|
+
this._emitChars('>');
|
|
987
|
+
} else if (cp === $.NULL) {
|
|
988
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
989
|
+
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
990
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
991
|
+
} else if (cp === $.EOF) {
|
|
992
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
993
|
+
this._emitEOFToken();
|
|
994
|
+
} else {
|
|
995
|
+
this.state = SCRIPT_DATA_ESCAPED_STATE;
|
|
996
|
+
this._emitCodePoint(cp);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
678
999
|
|
|
1000
|
+
// Script data escaped less-than sign state
|
|
1001
|
+
//------------------------------------------------------------------
|
|
1002
|
+
[SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
|
|
1003
|
+
if (cp === $.SOLIDUS) {
|
|
1004
|
+
this.tempBuff = [];
|
|
1005
|
+
this.state = SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE;
|
|
1006
|
+
} else if (isAsciiLetter(cp)) {
|
|
1007
|
+
this.tempBuff = [];
|
|
1008
|
+
this._emitChars('<');
|
|
1009
|
+
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE);
|
|
1010
|
+
} else {
|
|
1011
|
+
this._emitChars('<');
|
|
1012
|
+
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
679
1015
|
|
|
680
|
-
//
|
|
681
|
-
//------------------------------------------------------------------
|
|
682
|
-
|
|
683
|
-
|
|
1016
|
+
// Script data escaped end tag open state
|
|
1017
|
+
//------------------------------------------------------------------
|
|
1018
|
+
[SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE](cp) {
|
|
1019
|
+
if (isAsciiLetter(cp)) {
|
|
1020
|
+
this._createEndTagToken();
|
|
1021
|
+
this._reconsumeInState(SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE);
|
|
1022
|
+
} else {
|
|
1023
|
+
this._emitChars('</');
|
|
1024
|
+
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
684
1027
|
|
|
685
|
-
|
|
1028
|
+
// Script data escaped end tag name state
|
|
1029
|
+
//------------------------------------------------------------------
|
|
1030
|
+
[SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE](cp) {
|
|
1031
|
+
if (isAsciiUpper(cp)) {
|
|
1032
|
+
this.currentToken.tagName += toAsciiLowerChar(cp);
|
|
1033
|
+
this.tempBuff.push(cp);
|
|
1034
|
+
} else if (isAsciiLower(cp)) {
|
|
1035
|
+
this.currentToken.tagName += toChar(cp);
|
|
1036
|
+
this.tempBuff.push(cp);
|
|
1037
|
+
} else {
|
|
1038
|
+
if (this.lastStartTagName === this.currentToken.tagName) {
|
|
1039
|
+
if (isWhitespace(cp)) {
|
|
1040
|
+
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
686
1043
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
1044
|
+
if (cp === $.SOLIDUS) {
|
|
1045
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
690
1048
|
|
|
691
|
-
|
|
692
|
-
|
|
1049
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1050
|
+
this._emitCurrentToken();
|
|
1051
|
+
this.state = DATA_STATE;
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
693
1055
|
|
|
694
|
-
|
|
1056
|
+
this._emitChars('</');
|
|
1057
|
+
this._emitSeveralCodePoints(this.tempBuff);
|
|
1058
|
+
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
1059
|
+
}
|
|
695
1060
|
}
|
|
696
|
-
};
|
|
697
1061
|
|
|
1062
|
+
// Script data double escape start state
|
|
1063
|
+
//------------------------------------------------------------------
|
|
1064
|
+
[SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE](cp) {
|
|
1065
|
+
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
|
|
1066
|
+
this.state = this._isTempBufferEqualToScriptString()
|
|
1067
|
+
? SCRIPT_DATA_DOUBLE_ESCAPED_STATE
|
|
1068
|
+
: SCRIPT_DATA_ESCAPED_STATE;
|
|
1069
|
+
this._emitCodePoint(cp);
|
|
1070
|
+
} else if (isAsciiUpper(cp)) {
|
|
1071
|
+
this.tempBuff.push(toAsciiLowerCodePoint(cp));
|
|
1072
|
+
this._emitCodePoint(cp);
|
|
1073
|
+
} else if (isAsciiLower(cp)) {
|
|
1074
|
+
this.tempBuff.push(cp);
|
|
1075
|
+
this._emitCodePoint(cp);
|
|
1076
|
+
} else {
|
|
1077
|
+
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
698
1080
|
|
|
699
|
-
//
|
|
700
|
-
//------------------------------------------------------------------
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
1081
|
+
// Script data double escaped state
|
|
1082
|
+
//------------------------------------------------------------------
|
|
1083
|
+
[SCRIPT_DATA_DOUBLE_ESCAPED_STATE](cp) {
|
|
1084
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1085
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE;
|
|
1086
|
+
this._emitChars('-');
|
|
1087
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
1088
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
1089
|
+
this._emitChars('<');
|
|
1090
|
+
} else if (cp === $.NULL) {
|
|
1091
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1092
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
1093
|
+
} else if (cp === $.EOF) {
|
|
1094
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
1095
|
+
this._emitEOFToken();
|
|
1096
|
+
} else {
|
|
1097
|
+
this._emitCodePoint(cp);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
706
1100
|
|
|
707
|
-
|
|
708
|
-
|
|
1101
|
+
// Script data double escaped dash state
|
|
1102
|
+
//------------------------------------------------------------------
|
|
1103
|
+
[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE](cp) {
|
|
1104
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1105
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE;
|
|
1106
|
+
this._emitChars('-');
|
|
1107
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
1108
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
1109
|
+
this._emitChars('<');
|
|
1110
|
+
} else if (cp === $.NULL) {
|
|
1111
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1112
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
1113
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
1114
|
+
} else if (cp === $.EOF) {
|
|
1115
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
1116
|
+
this._emitEOFToken();
|
|
1117
|
+
} else {
|
|
1118
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
1119
|
+
this._emitCodePoint(cp);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
709
1122
|
|
|
710
|
-
|
|
711
|
-
|
|
1123
|
+
// Script data double escaped dash dash state
|
|
1124
|
+
//------------------------------------------------------------------
|
|
1125
|
+
[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE](cp) {
|
|
1126
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1127
|
+
this._emitChars('-');
|
|
1128
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
1129
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
1130
|
+
this._emitChars('<');
|
|
1131
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1132
|
+
this.state = SCRIPT_DATA_STATE;
|
|
1133
|
+
this._emitChars('>');
|
|
1134
|
+
} else if (cp === $.NULL) {
|
|
1135
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1136
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
1137
|
+
this._emitChars(unicode.REPLACEMENT_CHARACTER);
|
|
1138
|
+
} else if (cp === $.EOF) {
|
|
1139
|
+
this._err(ERR.eofInScriptHtmlCommentLikeText);
|
|
1140
|
+
this._emitEOFToken();
|
|
1141
|
+
} else {
|
|
1142
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
1143
|
+
this._emitCodePoint(cp);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
712
1146
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
1147
|
+
// Script data double escaped less-than sign state
|
|
1148
|
+
//------------------------------------------------------------------
|
|
1149
|
+
[SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE](cp) {
|
|
1150
|
+
if (cp === $.SOLIDUS) {
|
|
1151
|
+
this.tempBuff = [];
|
|
1152
|
+
this.state = SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE;
|
|
1153
|
+
this._emitChars('/');
|
|
1154
|
+
} else {
|
|
1155
|
+
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
716
1158
|
|
|
1159
|
+
// Script data double escape end state
|
|
1160
|
+
//------------------------------------------------------------------
|
|
1161
|
+
[SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE](cp) {
|
|
1162
|
+
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
|
|
1163
|
+
this.state = this._isTempBufferEqualToScriptString()
|
|
1164
|
+
? SCRIPT_DATA_ESCAPED_STATE
|
|
1165
|
+
: SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
|
|
717
1166
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1167
|
+
this._emitCodePoint(cp);
|
|
1168
|
+
} else if (isAsciiUpper(cp)) {
|
|
1169
|
+
this.tempBuff.push(toAsciiLowerCodePoint(cp));
|
|
1170
|
+
this._emitCodePoint(cp);
|
|
1171
|
+
} else if (isAsciiLower(cp)) {
|
|
1172
|
+
this.tempBuff.push(cp);
|
|
1173
|
+
this._emitCodePoint(cp);
|
|
1174
|
+
} else {
|
|
1175
|
+
this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
722
1178
|
|
|
723
|
-
|
|
724
|
-
|
|
1179
|
+
// Before attribute name state
|
|
1180
|
+
//------------------------------------------------------------------
|
|
1181
|
+
[BEFORE_ATTRIBUTE_NAME_STATE](cp) {
|
|
1182
|
+
if (isWhitespace(cp)) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
725
1185
|
|
|
726
|
-
|
|
727
|
-
|
|
1186
|
+
if (cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF) {
|
|
1187
|
+
this._reconsumeInState(AFTER_ATTRIBUTE_NAME_STATE);
|
|
1188
|
+
} else if (cp === $.EQUALS_SIGN) {
|
|
1189
|
+
this._err(ERR.unexpectedEqualsSignBeforeAttributeName);
|
|
1190
|
+
this._createAttr('=');
|
|
1191
|
+
this.state = ATTRIBUTE_NAME_STATE;
|
|
1192
|
+
} else {
|
|
1193
|
+
this._createAttr('');
|
|
1194
|
+
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
728
1197
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
else
|
|
749
|
-
this._emitCodePoint(cp);
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
//12.2.4.8 Tag open state
|
|
754
|
-
//------------------------------------------------------------------
|
|
755
|
-
_[TAG_OPEN_STATE] = function tagOpenState(cp) {
|
|
756
|
-
if (cp === $.EXCLAMATION_MARK)
|
|
757
|
-
this.state = MARKUP_DECLARATION_OPEN_STATE;
|
|
758
|
-
|
|
759
|
-
else if (cp === $.SOLIDUS)
|
|
760
|
-
this.state = END_TAG_OPEN_STATE;
|
|
761
|
-
|
|
762
|
-
else if (isAsciiLetter(cp)) {
|
|
763
|
-
this._createStartTagToken();
|
|
764
|
-
this._reconsumeInState(TAG_NAME_STATE);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
else if (cp === $.QUESTION_MARK)
|
|
768
|
-
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
769
|
-
|
|
770
|
-
else {
|
|
771
|
-
this._emitChar('<');
|
|
772
|
-
this._reconsumeInState(DATA_STATE);
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
//12.2.4.9 End tag open state
|
|
778
|
-
//------------------------------------------------------------------
|
|
779
|
-
_[END_TAG_OPEN_STATE] = function endTagOpenState(cp) {
|
|
780
|
-
if (isAsciiLetter(cp)) {
|
|
781
|
-
this._createEndTagToken();
|
|
782
|
-
this._reconsumeInState(TAG_NAME_STATE);
|
|
1198
|
+
// Attribute name state
|
|
1199
|
+
//------------------------------------------------------------------
|
|
1200
|
+
[ATTRIBUTE_NAME_STATE](cp) {
|
|
1201
|
+
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF) {
|
|
1202
|
+
this._leaveAttrName(AFTER_ATTRIBUTE_NAME_STATE);
|
|
1203
|
+
this._unconsume();
|
|
1204
|
+
} else if (cp === $.EQUALS_SIGN) {
|
|
1205
|
+
this._leaveAttrName(BEFORE_ATTRIBUTE_VALUE_STATE);
|
|
1206
|
+
} else if (isAsciiUpper(cp)) {
|
|
1207
|
+
this.currentAttr.name += toAsciiLowerChar(cp);
|
|
1208
|
+
} else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN) {
|
|
1209
|
+
this._err(ERR.unexpectedCharacterInAttributeName);
|
|
1210
|
+
this.currentAttr.name += toChar(cp);
|
|
1211
|
+
} else if (cp === $.NULL) {
|
|
1212
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1213
|
+
this.currentAttr.name += unicode.REPLACEMENT_CHARACTER;
|
|
1214
|
+
} else {
|
|
1215
|
+
this.currentAttr.name += toChar(cp);
|
|
1216
|
+
}
|
|
783
1217
|
}
|
|
784
1218
|
|
|
785
|
-
|
|
786
|
-
|
|
1219
|
+
// After attribute name state
|
|
1220
|
+
//------------------------------------------------------------------
|
|
1221
|
+
[AFTER_ATTRIBUTE_NAME_STATE](cp) {
|
|
1222
|
+
if (isWhitespace(cp)) {
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
787
1225
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
1226
|
+
if (cp === $.SOLIDUS) {
|
|
1227
|
+
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
1228
|
+
} else if (cp === $.EQUALS_SIGN) {
|
|
1229
|
+
this.state = BEFORE_ATTRIBUTE_VALUE_STATE;
|
|
1230
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1231
|
+
this.state = DATA_STATE;
|
|
1232
|
+
this._emitCurrentToken();
|
|
1233
|
+
} else if (cp === $.EOF) {
|
|
1234
|
+
this._err(ERR.eofInTag);
|
|
1235
|
+
this._emitEOFToken();
|
|
1236
|
+
} else {
|
|
1237
|
+
this._createAttr('');
|
|
1238
|
+
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
1239
|
+
}
|
|
792
1240
|
}
|
|
793
1241
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
//------------------------------------------------------------------
|
|
801
|
-
_[TAG_NAME_STATE] = function tagNameState(cp) {
|
|
802
|
-
if (isWhitespace(cp))
|
|
803
|
-
this.state = BEFORE_ATTRIBUTE_NAME_STATE;
|
|
804
|
-
|
|
805
|
-
else if (cp === $.SOLIDUS)
|
|
806
|
-
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
1242
|
+
// Before attribute value state
|
|
1243
|
+
//------------------------------------------------------------------
|
|
1244
|
+
[BEFORE_ATTRIBUTE_VALUE_STATE](cp) {
|
|
1245
|
+
if (isWhitespace(cp)) {
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
807
1248
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1249
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1250
|
+
this.state = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
|
|
1251
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1252
|
+
this.state = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
|
|
1253
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1254
|
+
this._err(ERR.missingAttributeValue);
|
|
1255
|
+
this.state = DATA_STATE;
|
|
1256
|
+
this._emitCurrentToken();
|
|
1257
|
+
} else {
|
|
1258
|
+
this._reconsumeInState(ATTRIBUTE_VALUE_UNQUOTED_STATE);
|
|
1259
|
+
}
|
|
811
1260
|
}
|
|
812
1261
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
if (cp === $.SOLIDUS) {
|
|
831
|
-
this.tempBuff = [];
|
|
832
|
-
this.state = RCDATA_END_TAG_OPEN_STATE;
|
|
1262
|
+
// Attribute value (double-quoted) state
|
|
1263
|
+
//------------------------------------------------------------------
|
|
1264
|
+
[ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE](cp) {
|
|
1265
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1266
|
+
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
1267
|
+
} else if (cp === $.AMPERSAND) {
|
|
1268
|
+
this.returnState = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
|
|
1269
|
+
this.state = CHARACTER_REFERENCE_STATE;
|
|
1270
|
+
} else if (cp === $.NULL) {
|
|
1271
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1272
|
+
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
1273
|
+
} else if (cp === $.EOF) {
|
|
1274
|
+
this._err(ERR.eofInTag);
|
|
1275
|
+
this._emitEOFToken();
|
|
1276
|
+
} else {
|
|
1277
|
+
this.currentAttr.value += toChar(cp);
|
|
1278
|
+
}
|
|
833
1279
|
}
|
|
834
1280
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1281
|
+
// Attribute value (single-quoted) state
|
|
1282
|
+
//------------------------------------------------------------------
|
|
1283
|
+
[ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE](cp) {
|
|
1284
|
+
if (cp === $.APOSTROPHE) {
|
|
1285
|
+
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
1286
|
+
} else if (cp === $.AMPERSAND) {
|
|
1287
|
+
this.returnState = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
|
|
1288
|
+
this.state = CHARACTER_REFERENCE_STATE;
|
|
1289
|
+
} else if (cp === $.NULL) {
|
|
1290
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1291
|
+
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
1292
|
+
} else if (cp === $.EOF) {
|
|
1293
|
+
this._err(ERR.eofInTag);
|
|
1294
|
+
this._emitEOFToken();
|
|
1295
|
+
} else {
|
|
1296
|
+
this.currentAttr.value += toChar(cp);
|
|
1297
|
+
}
|
|
838
1298
|
}
|
|
839
|
-
};
|
|
840
|
-
|
|
841
1299
|
|
|
842
|
-
//
|
|
843
|
-
//------------------------------------------------------------------
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1300
|
+
// Attribute value (unquoted) state
|
|
1301
|
+
//------------------------------------------------------------------
|
|
1302
|
+
[ATTRIBUTE_VALUE_UNQUOTED_STATE](cp) {
|
|
1303
|
+
if (isWhitespace(cp)) {
|
|
1304
|
+
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1305
|
+
} else if (cp === $.AMPERSAND) {
|
|
1306
|
+
this.returnState = ATTRIBUTE_VALUE_UNQUOTED_STATE;
|
|
1307
|
+
this.state = CHARACTER_REFERENCE_STATE;
|
|
1308
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1309
|
+
this._leaveAttrValue(DATA_STATE);
|
|
1310
|
+
this._emitCurrentToken();
|
|
1311
|
+
} else if (cp === $.NULL) {
|
|
1312
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1313
|
+
this.currentAttr.value += unicode.REPLACEMENT_CHARACTER;
|
|
1314
|
+
} else if (
|
|
1315
|
+
cp === $.QUOTATION_MARK ||
|
|
1316
|
+
cp === $.APOSTROPHE ||
|
|
1317
|
+
cp === $.LESS_THAN_SIGN ||
|
|
1318
|
+
cp === $.EQUALS_SIGN ||
|
|
1319
|
+
cp === $.GRAVE_ACCENT
|
|
1320
|
+
) {
|
|
1321
|
+
this._err(ERR.unexpectedCharacterInUnquotedAttributeValue);
|
|
1322
|
+
this.currentAttr.value += toChar(cp);
|
|
1323
|
+
} else if (cp === $.EOF) {
|
|
1324
|
+
this._err(ERR.eofInTag);
|
|
1325
|
+
this._emitEOFToken();
|
|
1326
|
+
} else {
|
|
1327
|
+
this.currentAttr.value += toChar(cp);
|
|
1328
|
+
}
|
|
848
1329
|
}
|
|
849
1330
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1331
|
+
// After attribute value (quoted) state
|
|
1332
|
+
//------------------------------------------------------------------
|
|
1333
|
+
[AFTER_ATTRIBUTE_VALUE_QUOTED_STATE](cp) {
|
|
1334
|
+
if (isWhitespace(cp)) {
|
|
1335
|
+
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1336
|
+
} else if (cp === $.SOLIDUS) {
|
|
1337
|
+
this._leaveAttrValue(SELF_CLOSING_START_TAG_STATE);
|
|
1338
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1339
|
+
this._leaveAttrValue(DATA_STATE);
|
|
1340
|
+
this._emitCurrentToken();
|
|
1341
|
+
} else if (cp === $.EOF) {
|
|
1342
|
+
this._err(ERR.eofInTag);
|
|
1343
|
+
this._emitEOFToken();
|
|
1344
|
+
} else {
|
|
1345
|
+
this._err(ERR.missingWhitespaceBetweenAttributes);
|
|
1346
|
+
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1347
|
+
}
|
|
854
1348
|
}
|
|
855
|
-
};
|
|
856
|
-
|
|
857
1349
|
|
|
858
|
-
//
|
|
859
|
-
//------------------------------------------------------------------
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
1350
|
+
// Self-closing start tag state
|
|
1351
|
+
//------------------------------------------------------------------
|
|
1352
|
+
[SELF_CLOSING_START_TAG_STATE](cp) {
|
|
1353
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1354
|
+
this.currentToken.selfClosing = true;
|
|
1355
|
+
this.state = DATA_STATE;
|
|
1356
|
+
this._emitCurrentToken();
|
|
1357
|
+
} else if (cp === $.EOF) {
|
|
1358
|
+
this._err(ERR.eofInTag);
|
|
1359
|
+
this._emitEOFToken();
|
|
1360
|
+
} else {
|
|
1361
|
+
this._err(ERR.unexpectedSolidusInTag);
|
|
1362
|
+
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1363
|
+
}
|
|
864
1364
|
}
|
|
865
1365
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1366
|
+
// Bogus comment state
|
|
1367
|
+
//------------------------------------------------------------------
|
|
1368
|
+
[BOGUS_COMMENT_STATE](cp) {
|
|
1369
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1370
|
+
this.state = DATA_STATE;
|
|
1371
|
+
this._emitCurrentToken();
|
|
1372
|
+
} else if (cp === $.EOF) {
|
|
1373
|
+
this._emitCurrentToken();
|
|
1374
|
+
this._emitEOFToken();
|
|
1375
|
+
} else if (cp === $.NULL) {
|
|
1376
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1377
|
+
this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
|
|
1378
|
+
} else {
|
|
1379
|
+
this.currentToken.data += toChar(cp);
|
|
1380
|
+
}
|
|
869
1381
|
}
|
|
870
1382
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
this.
|
|
885
|
-
this.
|
|
886
|
-
|
|
1383
|
+
// Markup declaration open state
|
|
1384
|
+
//------------------------------------------------------------------
|
|
1385
|
+
[MARKUP_DECLARATION_OPEN_STATE](cp) {
|
|
1386
|
+
if (this._consumeSequenceIfMatch($$.DASH_DASH_STRING, cp, true)) {
|
|
1387
|
+
this._createCommentToken();
|
|
1388
|
+
this.state = COMMENT_START_STATE;
|
|
1389
|
+
} else if (this._consumeSequenceIfMatch($$.DOCTYPE_STRING, cp, false)) {
|
|
1390
|
+
this.state = DOCTYPE_STATE;
|
|
1391
|
+
} else if (this._consumeSequenceIfMatch($$.CDATA_START_STRING, cp, true)) {
|
|
1392
|
+
if (this.allowCDATA) {
|
|
1393
|
+
this.state = CDATA_SECTION_STATE;
|
|
1394
|
+
} else {
|
|
1395
|
+
this._err(ERR.cdataInHtmlContent);
|
|
1396
|
+
this._createCommentToken();
|
|
1397
|
+
this.currentToken.data = '[CDATA[';
|
|
1398
|
+
this.state = BOGUS_COMMENT_STATE;
|
|
887
1399
|
}
|
|
888
1400
|
}
|
|
889
1401
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
this.
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
//12.2.4.14 RAWTEXT less-than sign state
|
|
899
|
-
//------------------------------------------------------------------
|
|
900
|
-
_[RAWTEXT_LESS_THAN_SIGN_STATE] = function rawtextLessThanSignState(cp) {
|
|
901
|
-
if (cp === $.SOLIDUS) {
|
|
902
|
-
this.tempBuff = [];
|
|
903
|
-
this.state = RAWTEXT_END_TAG_OPEN_STATE;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
else {
|
|
907
|
-
this._emitChar('<');
|
|
908
|
-
this._reconsumeInState(RAWTEXT_STATE);
|
|
909
|
-
}
|
|
910
|
-
};
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
//12.2.4.15 RAWTEXT end tag open state
|
|
914
|
-
//------------------------------------------------------------------
|
|
915
|
-
_[RAWTEXT_END_TAG_OPEN_STATE] = function rawtextEndTagOpenState(cp) {
|
|
916
|
-
if (isAsciiLetter(cp)) {
|
|
917
|
-
this._createEndTagToken();
|
|
918
|
-
this._reconsumeInState(RAWTEXT_END_TAG_NAME_STATE);
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
else {
|
|
922
|
-
this._emitChar('<');
|
|
923
|
-
this._emitChar('/');
|
|
924
|
-
this._reconsumeInState(RAWTEXT_STATE);
|
|
1402
|
+
//NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
|
|
1403
|
+
//results are no longer valid and we will need to start over.
|
|
1404
|
+
else if (!this._ensureHibernation()) {
|
|
1405
|
+
this._err(ERR.incorrectlyOpenedComment);
|
|
1406
|
+
this._createCommentToken();
|
|
1407
|
+
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
1408
|
+
}
|
|
925
1409
|
}
|
|
926
|
-
};
|
|
927
1410
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1411
|
+
// Comment start state
|
|
1412
|
+
//------------------------------------------------------------------
|
|
1413
|
+
[COMMENT_START_STATE](cp) {
|
|
1414
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1415
|
+
this.state = COMMENT_START_DASH_STATE;
|
|
1416
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1417
|
+
this._err(ERR.abruptClosingOfEmptyComment);
|
|
1418
|
+
this.state = DATA_STATE;
|
|
1419
|
+
this._emitCurrentToken();
|
|
1420
|
+
} else {
|
|
1421
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1422
|
+
}
|
|
935
1423
|
}
|
|
936
1424
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1425
|
+
// Comment start dash state
|
|
1426
|
+
//------------------------------------------------------------------
|
|
1427
|
+
[COMMENT_START_DASH_STATE](cp) {
|
|
1428
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1429
|
+
this.state = COMMENT_END_STATE;
|
|
1430
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1431
|
+
this._err(ERR.abruptClosingOfEmptyComment);
|
|
1432
|
+
this.state = DATA_STATE;
|
|
1433
|
+
this._emitCurrentToken();
|
|
1434
|
+
} else if (cp === $.EOF) {
|
|
1435
|
+
this._err(ERR.eofInComment);
|
|
1436
|
+
this._emitCurrentToken();
|
|
1437
|
+
this._emitEOFToken();
|
|
1438
|
+
} else {
|
|
1439
|
+
this.currentToken.data += '-';
|
|
1440
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1441
|
+
}
|
|
940
1442
|
}
|
|
941
1443
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1444
|
+
// Comment state
|
|
1445
|
+
//------------------------------------------------------------------
|
|
1446
|
+
[COMMENT_STATE](cp) {
|
|
1447
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1448
|
+
this.state = COMMENT_END_DASH_STATE;
|
|
1449
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
1450
|
+
this.currentToken.data += '<';
|
|
1451
|
+
this.state = COMMENT_LESS_THAN_SIGN_STATE;
|
|
1452
|
+
} else if (cp === $.NULL) {
|
|
1453
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1454
|
+
this.currentToken.data += unicode.REPLACEMENT_CHARACTER;
|
|
1455
|
+
} else if (cp === $.EOF) {
|
|
1456
|
+
this._err(ERR.eofInComment);
|
|
1457
|
+
this._emitCurrentToken();
|
|
1458
|
+
this._emitEOFToken();
|
|
1459
|
+
} else {
|
|
1460
|
+
this.currentToken.data += toChar(cp);
|
|
959
1461
|
}
|
|
960
|
-
|
|
961
|
-
this._emitChar('<');
|
|
962
|
-
this._emitChar('/');
|
|
963
|
-
this._emitSeveralCodePoints(this.tempBuff);
|
|
964
|
-
this._reconsumeInState(RAWTEXT_STATE);
|
|
965
1462
|
}
|
|
966
|
-
};
|
|
967
1463
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1464
|
+
// Comment less-than sign state
|
|
1465
|
+
//------------------------------------------------------------------
|
|
1466
|
+
[COMMENT_LESS_THAN_SIGN_STATE](cp) {
|
|
1467
|
+
if (cp === $.EXCLAMATION_MARK) {
|
|
1468
|
+
this.currentToken.data += '!';
|
|
1469
|
+
this.state = COMMENT_LESS_THAN_SIGN_BANG_STATE;
|
|
1470
|
+
} else if (cp === $.LESS_THAN_SIGN) {
|
|
1471
|
+
this.currentToken.data += '!';
|
|
1472
|
+
} else {
|
|
1473
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1474
|
+
}
|
|
975
1475
|
}
|
|
976
1476
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1477
|
+
// Comment less-than sign bang state
|
|
1478
|
+
//------------------------------------------------------------------
|
|
1479
|
+
[COMMENT_LESS_THAN_SIGN_BANG_STATE](cp) {
|
|
1480
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1481
|
+
this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE;
|
|
1482
|
+
} else {
|
|
1483
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1484
|
+
}
|
|
981
1485
|
}
|
|
982
1486
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1487
|
+
// Comment less-than sign bang dash state
|
|
1488
|
+
//------------------------------------------------------------------
|
|
1489
|
+
[COMMENT_LESS_THAN_SIGN_BANG_DASH_STATE](cp) {
|
|
1490
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1491
|
+
this.state = COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE;
|
|
1492
|
+
} else {
|
|
1493
|
+
this._reconsumeInState(COMMENT_END_DASH_STATE);
|
|
1494
|
+
}
|
|
986
1495
|
}
|
|
987
|
-
};
|
|
988
1496
|
|
|
1497
|
+
// Comment less-than sign bang dash dash state
|
|
1498
|
+
//------------------------------------------------------------------
|
|
1499
|
+
[COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH_STATE](cp) {
|
|
1500
|
+
if (cp !== $.GREATER_THAN_SIGN && cp !== $.EOF) {
|
|
1501
|
+
this._err(ERR.nestedComment);
|
|
1502
|
+
}
|
|
989
1503
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1504
|
+
this._reconsumeInState(COMMENT_END_STATE);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// Comment end dash state
|
|
1508
|
+
//------------------------------------------------------------------
|
|
1509
|
+
[COMMENT_END_DASH_STATE](cp) {
|
|
1510
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1511
|
+
this.state = COMMENT_END_STATE;
|
|
1512
|
+
} else if (cp === $.EOF) {
|
|
1513
|
+
this._err(ERR.eofInComment);
|
|
1514
|
+
this._emitCurrentToken();
|
|
1515
|
+
this._emitEOFToken();
|
|
1516
|
+
} else {
|
|
1517
|
+
this.currentToken.data += '-';
|
|
1518
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1519
|
+
}
|
|
1002
1520
|
}
|
|
1003
|
-
};
|
|
1004
|
-
|
|
1005
1521
|
|
|
1006
|
-
//
|
|
1007
|
-
//------------------------------------------------------------------
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1522
|
+
// Comment end state
|
|
1523
|
+
//------------------------------------------------------------------
|
|
1524
|
+
[COMMENT_END_STATE](cp) {
|
|
1525
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1526
|
+
this.state = DATA_STATE;
|
|
1527
|
+
this._emitCurrentToken();
|
|
1528
|
+
} else if (cp === $.EXCLAMATION_MARK) {
|
|
1529
|
+
this.state = COMMENT_END_BANG_STATE;
|
|
1530
|
+
} else if (cp === $.HYPHEN_MINUS) {
|
|
1531
|
+
this.currentToken.data += '-';
|
|
1532
|
+
} else if (cp === $.EOF) {
|
|
1533
|
+
this._err(ERR.eofInComment);
|
|
1534
|
+
this._emitCurrentToken();
|
|
1535
|
+
this._emitEOFToken();
|
|
1536
|
+
} else {
|
|
1537
|
+
this.currentToken.data += '--';
|
|
1538
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1539
|
+
}
|
|
1012
1540
|
}
|
|
1013
1541
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1542
|
+
// Comment end bang state
|
|
1543
|
+
//------------------------------------------------------------------
|
|
1544
|
+
[COMMENT_END_BANG_STATE](cp) {
|
|
1545
|
+
if (cp === $.HYPHEN_MINUS) {
|
|
1546
|
+
this.currentToken.data += '--!';
|
|
1547
|
+
this.state = COMMENT_END_DASH_STATE;
|
|
1548
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1549
|
+
this._err(ERR.incorrectlyClosedComment);
|
|
1550
|
+
this.state = DATA_STATE;
|
|
1551
|
+
this._emitCurrentToken();
|
|
1552
|
+
} else if (cp === $.EOF) {
|
|
1553
|
+
this._err(ERR.eofInComment);
|
|
1554
|
+
this._emitCurrentToken();
|
|
1555
|
+
this._emitEOFToken();
|
|
1556
|
+
} else {
|
|
1557
|
+
this.currentToken.data += '--!';
|
|
1558
|
+
this._reconsumeInState(COMMENT_STATE);
|
|
1559
|
+
}
|
|
1017
1560
|
}
|
|
1018
1561
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
}
|
|
1562
|
+
// DOCTYPE state
|
|
1563
|
+
//------------------------------------------------------------------
|
|
1564
|
+
[DOCTYPE_STATE](cp) {
|
|
1565
|
+
if (isWhitespace(cp)) {
|
|
1566
|
+
this.state = BEFORE_DOCTYPE_NAME_STATE;
|
|
1567
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1568
|
+
this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
|
|
1569
|
+
} else if (cp === $.EOF) {
|
|
1570
|
+
this._err(ERR.eofInDoctype);
|
|
1571
|
+
this._createDoctypeToken(null);
|
|
1572
|
+
this.currentToken.forceQuirks = true;
|
|
1573
|
+
this._emitCurrentToken();
|
|
1574
|
+
this._emitEOFToken();
|
|
1575
|
+
} else {
|
|
1576
|
+
this._err(ERR.missingWhitespaceBeforeDoctypeName);
|
|
1577
|
+
this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
|
|
1036
1578
|
}
|
|
1037
|
-
|
|
1038
|
-
this._emitChar('<');
|
|
1039
|
-
this._emitChar('/');
|
|
1040
|
-
this._emitSeveralCodePoints(this.tempBuff);
|
|
1041
|
-
this._reconsumeInState(SCRIPT_DATA_STATE);
|
|
1042
1579
|
}
|
|
1043
|
-
};
|
|
1044
1580
|
|
|
1581
|
+
// Before DOCTYPE name state
|
|
1582
|
+
//------------------------------------------------------------------
|
|
1583
|
+
[BEFORE_DOCTYPE_NAME_STATE](cp) {
|
|
1584
|
+
if (isWhitespace(cp)) {
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1045
1587
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1588
|
+
if (isAsciiUpper(cp)) {
|
|
1589
|
+
this._createDoctypeToken(toAsciiLowerChar(cp));
|
|
1590
|
+
this.state = DOCTYPE_NAME_STATE;
|
|
1591
|
+
} else if (cp === $.NULL) {
|
|
1592
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1593
|
+
this._createDoctypeToken(unicode.REPLACEMENT_CHARACTER);
|
|
1594
|
+
this.state = DOCTYPE_NAME_STATE;
|
|
1595
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1596
|
+
this._err(ERR.missingDoctypeName);
|
|
1597
|
+
this._createDoctypeToken(null);
|
|
1598
|
+
this.currentToken.forceQuirks = true;
|
|
1599
|
+
this._emitCurrentToken();
|
|
1600
|
+
this.state = DATA_STATE;
|
|
1601
|
+
} else if (cp === $.EOF) {
|
|
1602
|
+
this._err(ERR.eofInDoctype);
|
|
1603
|
+
this._createDoctypeToken(null);
|
|
1604
|
+
this.currentToken.forceQuirks = true;
|
|
1605
|
+
this._emitCurrentToken();
|
|
1606
|
+
this._emitEOFToken();
|
|
1607
|
+
} else {
|
|
1608
|
+
this._createDoctypeToken(toChar(cp));
|
|
1609
|
+
this.state = DOCTYPE_NAME_STATE;
|
|
1610
|
+
}
|
|
1052
1611
|
}
|
|
1053
1612
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1613
|
+
// DOCTYPE name state
|
|
1614
|
+
//------------------------------------------------------------------
|
|
1615
|
+
[DOCTYPE_NAME_STATE](cp) {
|
|
1616
|
+
if (isWhitespace(cp)) {
|
|
1617
|
+
this.state = AFTER_DOCTYPE_NAME_STATE;
|
|
1618
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1619
|
+
this.state = DATA_STATE;
|
|
1620
|
+
this._emitCurrentToken();
|
|
1621
|
+
} else if (isAsciiUpper(cp)) {
|
|
1622
|
+
this.currentToken.name += toAsciiLowerChar(cp);
|
|
1623
|
+
} else if (cp === $.NULL) {
|
|
1624
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1625
|
+
this.currentToken.name += unicode.REPLACEMENT_CHARACTER;
|
|
1626
|
+
} else if (cp === $.EOF) {
|
|
1627
|
+
this._err(ERR.eofInDoctype);
|
|
1628
|
+
this.currentToken.forceQuirks = true;
|
|
1629
|
+
this._emitCurrentToken();
|
|
1630
|
+
this._emitEOFToken();
|
|
1631
|
+
} else {
|
|
1632
|
+
this.currentToken.name += toChar(cp);
|
|
1633
|
+
}
|
|
1065
1634
|
}
|
|
1066
1635
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1636
|
+
// After DOCTYPE name state
|
|
1637
|
+
//------------------------------------------------------------------
|
|
1638
|
+
[AFTER_DOCTYPE_NAME_STATE](cp) {
|
|
1639
|
+
if (isWhitespace(cp)) {
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1071
1642
|
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1643
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1644
|
+
this.state = DATA_STATE;
|
|
1645
|
+
this._emitCurrentToken();
|
|
1646
|
+
} else if (cp === $.EOF) {
|
|
1647
|
+
this._err(ERR.eofInDoctype);
|
|
1648
|
+
this.currentToken.forceQuirks = true;
|
|
1649
|
+
this._emitCurrentToken();
|
|
1650
|
+
this._emitEOFToken();
|
|
1651
|
+
} else if (this._consumeSequenceIfMatch($$.PUBLIC_STRING, cp, false)) {
|
|
1652
|
+
this.state = AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE;
|
|
1653
|
+
} else if (this._consumeSequenceIfMatch($$.SYSTEM_STRING, cp, false)) {
|
|
1654
|
+
this.state = AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE;
|
|
1655
|
+
}
|
|
1656
|
+
//NOTE: sequence lookup can be abrupted by hibernation. In that case lookup
|
|
1657
|
+
//results are no longer valid and we will need to start over.
|
|
1658
|
+
else if (!this._ensureHibernation()) {
|
|
1659
|
+
this._err(ERR.invalidCharacterSequenceAfterDoctypeName);
|
|
1660
|
+
this.currentToken.forceQuirks = true;
|
|
1661
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1662
|
+
}
|
|
1078
1663
|
}
|
|
1079
1664
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1665
|
+
// After DOCTYPE public keyword state
|
|
1666
|
+
//------------------------------------------------------------------
|
|
1667
|
+
[AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE](cp) {
|
|
1668
|
+
if (isWhitespace(cp)) {
|
|
1669
|
+
this.state = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
1670
|
+
} else if (cp === $.QUOTATION_MARK) {
|
|
1671
|
+
this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
|
|
1672
|
+
this.currentToken.publicId = '';
|
|
1673
|
+
this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1674
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1675
|
+
this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
|
|
1676
|
+
this.currentToken.publicId = '';
|
|
1677
|
+
this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1678
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1679
|
+
this._err(ERR.missingDoctypePublicIdentifier);
|
|
1680
|
+
this.currentToken.forceQuirks = true;
|
|
1681
|
+
this.state = DATA_STATE;
|
|
1682
|
+
this._emitCurrentToken();
|
|
1683
|
+
} else if (cp === $.EOF) {
|
|
1684
|
+
this._err(ERR.eofInDoctype);
|
|
1685
|
+
this.currentToken.forceQuirks = true;
|
|
1686
|
+
this._emitCurrentToken();
|
|
1687
|
+
this._emitEOFToken();
|
|
1688
|
+
} else {
|
|
1689
|
+
this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
|
|
1690
|
+
this.currentToken.forceQuirks = true;
|
|
1691
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1692
|
+
}
|
|
1100
1693
|
}
|
|
1101
1694
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1695
|
+
// Before DOCTYPE public identifier state
|
|
1696
|
+
//------------------------------------------------------------------
|
|
1697
|
+
[BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
|
|
1698
|
+
if (isWhitespace(cp)) {
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1104
1701
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1702
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1703
|
+
this.currentToken.publicId = '';
|
|
1704
|
+
this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1705
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1706
|
+
this.currentToken.publicId = '';
|
|
1707
|
+
this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1708
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1709
|
+
this._err(ERR.missingDoctypePublicIdentifier);
|
|
1710
|
+
this.currentToken.forceQuirks = true;
|
|
1711
|
+
this.state = DATA_STATE;
|
|
1712
|
+
this._emitCurrentToken();
|
|
1713
|
+
} else if (cp === $.EOF) {
|
|
1714
|
+
this._err(ERR.eofInDoctype);
|
|
1715
|
+
this.currentToken.forceQuirks = true;
|
|
1716
|
+
this._emitCurrentToken();
|
|
1717
|
+
this._emitEOFToken();
|
|
1718
|
+
} else {
|
|
1719
|
+
this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
|
|
1720
|
+
this.currentToken.forceQuirks = true;
|
|
1721
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1722
|
+
}
|
|
1108
1723
|
}
|
|
1109
1724
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1725
|
+
// DOCTYPE public identifier (double-quoted) state
|
|
1726
|
+
//------------------------------------------------------------------
|
|
1727
|
+
[DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
|
|
1728
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1729
|
+
this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
1730
|
+
} else if (cp === $.NULL) {
|
|
1731
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1732
|
+
this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
|
|
1733
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1734
|
+
this._err(ERR.abruptDoctypePublicIdentifier);
|
|
1735
|
+
this.currentToken.forceQuirks = true;
|
|
1736
|
+
this._emitCurrentToken();
|
|
1737
|
+
this.state = DATA_STATE;
|
|
1738
|
+
} else if (cp === $.EOF) {
|
|
1739
|
+
this._err(ERR.eofInDoctype);
|
|
1740
|
+
this.currentToken.forceQuirks = true;
|
|
1741
|
+
this._emitCurrentToken();
|
|
1742
|
+
this._emitEOFToken();
|
|
1743
|
+
} else {
|
|
1744
|
+
this.currentToken.publicId += toChar(cp);
|
|
1745
|
+
}
|
|
1116
1746
|
}
|
|
1117
|
-
};
|
|
1118
1747
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1748
|
+
// DOCTYPE public identifier (single-quoted) state
|
|
1749
|
+
//------------------------------------------------------------------
|
|
1750
|
+
[DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
|
|
1751
|
+
if (cp === $.APOSTROPHE) {
|
|
1752
|
+
this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
1753
|
+
} else if (cp === $.NULL) {
|
|
1754
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1755
|
+
this.currentToken.publicId += unicode.REPLACEMENT_CHARACTER;
|
|
1756
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1757
|
+
this._err(ERR.abruptDoctypePublicIdentifier);
|
|
1758
|
+
this.currentToken.forceQuirks = true;
|
|
1759
|
+
this._emitCurrentToken();
|
|
1760
|
+
this.state = DATA_STATE;
|
|
1761
|
+
} else if (cp === $.EOF) {
|
|
1762
|
+
this._err(ERR.eofInDoctype);
|
|
1763
|
+
this.currentToken.forceQuirks = true;
|
|
1764
|
+
this._emitCurrentToken();
|
|
1765
|
+
this._emitEOFToken();
|
|
1766
|
+
} else {
|
|
1767
|
+
this.currentToken.publicId += toChar(cp);
|
|
1768
|
+
}
|
|
1132
1769
|
}
|
|
1133
1770
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1771
|
+
// After DOCTYPE public identifier state
|
|
1772
|
+
//------------------------------------------------------------------
|
|
1773
|
+
[AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE](cp) {
|
|
1774
|
+
if (isWhitespace(cp)) {
|
|
1775
|
+
this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
|
|
1776
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1777
|
+
this.state = DATA_STATE;
|
|
1778
|
+
this._emitCurrentToken();
|
|
1779
|
+
} else if (cp === $.QUOTATION_MARK) {
|
|
1780
|
+
this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
|
|
1781
|
+
this.currentToken.systemId = '';
|
|
1782
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1783
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1784
|
+
this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
|
|
1785
|
+
this.currentToken.systemId = '';
|
|
1786
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1787
|
+
} else if (cp === $.EOF) {
|
|
1788
|
+
this._err(ERR.eofInDoctype);
|
|
1789
|
+
this.currentToken.forceQuirks = true;
|
|
1790
|
+
this._emitCurrentToken();
|
|
1791
|
+
this._emitEOFToken();
|
|
1792
|
+
} else {
|
|
1793
|
+
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
1794
|
+
this.currentToken.forceQuirks = true;
|
|
1795
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1796
|
+
}
|
|
1137
1797
|
}
|
|
1138
1798
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1799
|
+
// Between DOCTYPE public and system identifiers state
|
|
1800
|
+
//------------------------------------------------------------------
|
|
1801
|
+
[BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE](cp) {
|
|
1802
|
+
if (isWhitespace(cp)) {
|
|
1803
|
+
return;
|
|
1804
|
+
}
|
|
1141
1805
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1806
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1807
|
+
this._emitCurrentToken();
|
|
1808
|
+
this.state = DATA_STATE;
|
|
1809
|
+
} else if (cp === $.QUOTATION_MARK) {
|
|
1810
|
+
this.currentToken.systemId = '';
|
|
1811
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1812
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1813
|
+
this.currentToken.systemId = '';
|
|
1814
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1815
|
+
} else if (cp === $.EOF) {
|
|
1816
|
+
this._err(ERR.eofInDoctype);
|
|
1817
|
+
this.currentToken.forceQuirks = true;
|
|
1818
|
+
this._emitCurrentToken();
|
|
1819
|
+
this._emitEOFToken();
|
|
1820
|
+
} else {
|
|
1821
|
+
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
1822
|
+
this.currentToken.forceQuirks = true;
|
|
1823
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1824
|
+
}
|
|
1145
1825
|
}
|
|
1146
|
-
};
|
|
1147
1826
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1827
|
+
// After DOCTYPE system keyword state
|
|
1828
|
+
//------------------------------------------------------------------
|
|
1829
|
+
[AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE](cp) {
|
|
1830
|
+
if (isWhitespace(cp)) {
|
|
1831
|
+
this.state = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
1832
|
+
} else if (cp === $.QUOTATION_MARK) {
|
|
1833
|
+
this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
|
|
1834
|
+
this.currentToken.systemId = '';
|
|
1835
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1836
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1837
|
+
this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
|
|
1838
|
+
this.currentToken.systemId = '';
|
|
1839
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1840
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1841
|
+
this._err(ERR.missingDoctypeSystemIdentifier);
|
|
1842
|
+
this.currentToken.forceQuirks = true;
|
|
1843
|
+
this.state = DATA_STATE;
|
|
1844
|
+
this._emitCurrentToken();
|
|
1845
|
+
} else if (cp === $.EOF) {
|
|
1846
|
+
this._err(ERR.eofInDoctype);
|
|
1847
|
+
this.currentToken.forceQuirks = true;
|
|
1848
|
+
this._emitCurrentToken();
|
|
1849
|
+
this._emitEOFToken();
|
|
1850
|
+
} else {
|
|
1851
|
+
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
1852
|
+
this.currentToken.forceQuirks = true;
|
|
1853
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1854
|
+
}
|
|
1155
1855
|
}
|
|
1156
1856
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1857
|
+
// Before DOCTYPE system identifier state
|
|
1858
|
+
//------------------------------------------------------------------
|
|
1859
|
+
[BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
|
|
1860
|
+
if (isWhitespace(cp)) {
|
|
1861
|
+
return;
|
|
1862
|
+
}
|
|
1162
1863
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1864
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1865
|
+
this.currentToken.systemId = '';
|
|
1866
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1867
|
+
} else if (cp === $.APOSTROPHE) {
|
|
1868
|
+
this.currentToken.systemId = '';
|
|
1869
|
+
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1870
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1871
|
+
this._err(ERR.missingDoctypeSystemIdentifier);
|
|
1872
|
+
this.currentToken.forceQuirks = true;
|
|
1873
|
+
this.state = DATA_STATE;
|
|
1874
|
+
this._emitCurrentToken();
|
|
1875
|
+
} else if (cp === $.EOF) {
|
|
1876
|
+
this._err(ERR.eofInDoctype);
|
|
1877
|
+
this.currentToken.forceQuirks = true;
|
|
1878
|
+
this._emitCurrentToken();
|
|
1879
|
+
this._emitEOFToken();
|
|
1880
|
+
} else {
|
|
1881
|
+
this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
|
|
1882
|
+
this.currentToken.forceQuirks = true;
|
|
1883
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1884
|
+
}
|
|
1166
1885
|
}
|
|
1167
|
-
};
|
|
1168
1886
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1887
|
+
// DOCTYPE system identifier (double-quoted) state
|
|
1888
|
+
//------------------------------------------------------------------
|
|
1889
|
+
[DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE](cp) {
|
|
1890
|
+
if (cp === $.QUOTATION_MARK) {
|
|
1891
|
+
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
1892
|
+
} else if (cp === $.NULL) {
|
|
1893
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1894
|
+
this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
|
|
1895
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1896
|
+
this._err(ERR.abruptDoctypeSystemIdentifier);
|
|
1897
|
+
this.currentToken.forceQuirks = true;
|
|
1898
|
+
this._emitCurrentToken();
|
|
1899
|
+
this.state = DATA_STATE;
|
|
1900
|
+
} else if (cp === $.EOF) {
|
|
1901
|
+
this._err(ERR.eofInDoctype);
|
|
1902
|
+
this.currentToken.forceQuirks = true;
|
|
1903
|
+
this._emitCurrentToken();
|
|
1904
|
+
this._emitEOFToken();
|
|
1905
|
+
} else {
|
|
1906
|
+
this.currentToken.systemId += toChar(cp);
|
|
1907
|
+
}
|
|
1176
1908
|
}
|
|
1177
1909
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1910
|
+
// DOCTYPE system identifier (single-quoted) state
|
|
1911
|
+
//------------------------------------------------------------------
|
|
1912
|
+
[DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE](cp) {
|
|
1913
|
+
if (cp === $.APOSTROPHE) {
|
|
1914
|
+
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
1915
|
+
} else if (cp === $.NULL) {
|
|
1916
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1917
|
+
this.currentToken.systemId += unicode.REPLACEMENT_CHARACTER;
|
|
1918
|
+
} else if (cp === $.GREATER_THAN_SIGN) {
|
|
1919
|
+
this._err(ERR.abruptDoctypeSystemIdentifier);
|
|
1920
|
+
this.currentToken.forceQuirks = true;
|
|
1921
|
+
this._emitCurrentToken();
|
|
1922
|
+
this.state = DATA_STATE;
|
|
1923
|
+
} else if (cp === $.EOF) {
|
|
1924
|
+
this._err(ERR.eofInDoctype);
|
|
1925
|
+
this.currentToken.forceQuirks = true;
|
|
1926
|
+
this._emitCurrentToken();
|
|
1927
|
+
this._emitEOFToken();
|
|
1928
|
+
} else {
|
|
1929
|
+
this.currentToken.systemId += toChar(cp);
|
|
1930
|
+
}
|
|
1182
1931
|
}
|
|
1183
|
-
};
|
|
1184
1932
|
|
|
1933
|
+
// After DOCTYPE system identifier state
|
|
1934
|
+
//------------------------------------------------------------------
|
|
1935
|
+
[AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE](cp) {
|
|
1936
|
+
if (isWhitespace(cp)) {
|
|
1937
|
+
return;
|
|
1938
|
+
}
|
|
1185
1939
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1940
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1941
|
+
this._emitCurrentToken();
|
|
1942
|
+
this.state = DATA_STATE;
|
|
1943
|
+
} else if (cp === $.EOF) {
|
|
1944
|
+
this._err(ERR.eofInDoctype);
|
|
1945
|
+
this.currentToken.forceQuirks = true;
|
|
1946
|
+
this._emitCurrentToken();
|
|
1947
|
+
this._emitEOFToken();
|
|
1948
|
+
} else {
|
|
1949
|
+
this._err(ERR.unexpectedCharacterAfterDoctypeSystemIdentifier);
|
|
1950
|
+
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1951
|
+
}
|
|
1197
1952
|
}
|
|
1198
1953
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1212
|
-
this._emitCurrentToken();
|
|
1213
|
-
this.state = DATA_STATE;
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1954
|
+
// Bogus DOCTYPE state
|
|
1955
|
+
//------------------------------------------------------------------
|
|
1956
|
+
[BOGUS_DOCTYPE_STATE](cp) {
|
|
1957
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1958
|
+
this._emitCurrentToken();
|
|
1959
|
+
this.state = DATA_STATE;
|
|
1960
|
+
} else if (cp === $.NULL) {
|
|
1961
|
+
this._err(ERR.unexpectedNullCharacter);
|
|
1962
|
+
} else if (cp === $.EOF) {
|
|
1963
|
+
this._emitCurrentToken();
|
|
1964
|
+
this._emitEOFToken();
|
|
1216
1965
|
}
|
|
1217
|
-
|
|
1218
|
-
this._emitChar('<');
|
|
1219
|
-
this._emitChar('/');
|
|
1220
|
-
this._emitSeveralCodePoints(this.tempBuff);
|
|
1221
|
-
this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
|
|
1222
1966
|
}
|
|
1223
|
-
};
|
|
1224
|
-
|
|
1225
1967
|
|
|
1226
|
-
//
|
|
1227
|
-
//------------------------------------------------------------------
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1968
|
+
// CDATA section state
|
|
1969
|
+
//------------------------------------------------------------------
|
|
1970
|
+
[CDATA_SECTION_STATE](cp) {
|
|
1971
|
+
if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
1972
|
+
this.state = CDATA_SECTION_BRACKET_STATE;
|
|
1973
|
+
} else if (cp === $.EOF) {
|
|
1974
|
+
this._err(ERR.eofInCdata);
|
|
1975
|
+
this._emitEOFToken();
|
|
1976
|
+
} else {
|
|
1977
|
+
this._emitCodePoint(cp);
|
|
1978
|
+
}
|
|
1232
1979
|
}
|
|
1233
1980
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1981
|
+
// CDATA section bracket state
|
|
1982
|
+
//------------------------------------------------------------------
|
|
1983
|
+
[CDATA_SECTION_BRACKET_STATE](cp) {
|
|
1984
|
+
if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
1985
|
+
this.state = CDATA_SECTION_END_STATE;
|
|
1986
|
+
} else {
|
|
1987
|
+
this._emitChars(']');
|
|
1988
|
+
this._reconsumeInState(CDATA_SECTION_STATE);
|
|
1989
|
+
}
|
|
1237
1990
|
}
|
|
1238
1991
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1992
|
+
// CDATA section end state
|
|
1993
|
+
//------------------------------------------------------------------
|
|
1994
|
+
[CDATA_SECTION_END_STATE](cp) {
|
|
1995
|
+
if (cp === $.GREATER_THAN_SIGN) {
|
|
1996
|
+
this.state = DATA_STATE;
|
|
1997
|
+
} else if (cp === $.RIGHT_SQUARE_BRACKET) {
|
|
1998
|
+
this._emitChars(']');
|
|
1999
|
+
} else {
|
|
2000
|
+
this._emitChars(']]');
|
|
2001
|
+
this._reconsumeInState(CDATA_SECTION_STATE);
|
|
2002
|
+
}
|
|
1242
2003
|
}
|
|
1243
2004
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
2005
|
+
// Character reference state
|
|
2006
|
+
//------------------------------------------------------------------
|
|
2007
|
+
[CHARACTER_REFERENCE_STATE](cp) {
|
|
2008
|
+
this.tempBuff = [$.AMPERSAND];
|
|
1248
2009
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
1259
|
-
this._emitChar('<');
|
|
2010
|
+
if (cp === $.NUMBER_SIGN) {
|
|
2011
|
+
this.tempBuff.push(cp);
|
|
2012
|
+
this.state = NUMERIC_CHARACTER_REFERENCE_STATE;
|
|
2013
|
+
} else if (isAsciiAlphaNumeric(cp)) {
|
|
2014
|
+
this._reconsumeInState(NAMED_CHARACTER_REFERENCE_STATE);
|
|
2015
|
+
} else {
|
|
2016
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2017
|
+
this._reconsumeInState(this.returnState);
|
|
2018
|
+
}
|
|
1260
2019
|
}
|
|
1261
2020
|
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
this._reconsumeInState(DATA_STATE);
|
|
1267
|
-
|
|
1268
|
-
else
|
|
1269
|
-
this._emitCodePoint(cp);
|
|
1270
|
-
};
|
|
2021
|
+
// Named character reference state
|
|
2022
|
+
//------------------------------------------------------------------
|
|
2023
|
+
[NAMED_CHARACTER_REFERENCE_STATE](cp) {
|
|
2024
|
+
const matchResult = this._matchNamedCharacterReference(cp);
|
|
1271
2025
|
|
|
2026
|
+
//NOTE: matching can be abrupted by hibernation. In that case match
|
|
2027
|
+
//results are no longer valid and we will need to start over.
|
|
2028
|
+
if (this._ensureHibernation()) {
|
|
2029
|
+
this.tempBuff = [$.AMPERSAND];
|
|
2030
|
+
} else if (matchResult) {
|
|
2031
|
+
const withSemicolon = this.tempBuff[this.tempBuff.length - 1] === $.SEMICOLON;
|
|
1272
2032
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE;
|
|
1278
|
-
this._emitChar('-');
|
|
1279
|
-
}
|
|
2033
|
+
if (!this._isCharacterReferenceAttributeQuirk(withSemicolon)) {
|
|
2034
|
+
if (!withSemicolon) {
|
|
2035
|
+
this._errOnNextCodePoint(ERR.missingSemicolonAfterCharacterReference);
|
|
2036
|
+
}
|
|
1280
2037
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
this._emitChar('<');
|
|
1284
|
-
}
|
|
2038
|
+
this.tempBuff = matchResult;
|
|
2039
|
+
}
|
|
1285
2040
|
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
2041
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2042
|
+
this.state = this.returnState;
|
|
2043
|
+
} else {
|
|
2044
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2045
|
+
this.state = AMBIGUOUS_AMPERSAND_STATE;
|
|
2046
|
+
}
|
|
1289
2047
|
}
|
|
1290
2048
|
|
|
1291
|
-
|
|
1292
|
-
|
|
2049
|
+
// Ambiguos ampersand state
|
|
2050
|
+
//------------------------------------------------------------------
|
|
2051
|
+
[AMBIGUOUS_AMPERSAND_STATE](cp) {
|
|
2052
|
+
if (isAsciiAlphaNumeric(cp)) {
|
|
2053
|
+
if (this._isCharacterReferenceInAttribute()) {
|
|
2054
|
+
this.currentAttr.value += toChar(cp);
|
|
2055
|
+
} else {
|
|
2056
|
+
this._emitCodePoint(cp);
|
|
2057
|
+
}
|
|
2058
|
+
} else {
|
|
2059
|
+
if (cp === $.SEMICOLON) {
|
|
2060
|
+
this._err(ERR.unknownNamedCharacterReference);
|
|
2061
|
+
}
|
|
1293
2062
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
this._emitCodePoint(cp);
|
|
2063
|
+
this._reconsumeInState(this.returnState);
|
|
2064
|
+
}
|
|
1297
2065
|
}
|
|
1298
|
-
};
|
|
1299
2066
|
|
|
2067
|
+
// Numeric character reference state
|
|
2068
|
+
//------------------------------------------------------------------
|
|
2069
|
+
[NUMERIC_CHARACTER_REFERENCE_STATE](cp) {
|
|
2070
|
+
this.charRefCode = 0;
|
|
1300
2071
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
else if (cp === $.LESS_THAN_SIGN) {
|
|
1308
|
-
this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
|
|
1309
|
-
this._emitChar('<');
|
|
2072
|
+
if (cp === $.LATIN_SMALL_X || cp === $.LATIN_CAPITAL_X) {
|
|
2073
|
+
this.tempBuff.push(cp);
|
|
2074
|
+
this.state = HEXADEMICAL_CHARACTER_REFERENCE_START_STATE;
|
|
2075
|
+
} else {
|
|
2076
|
+
this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_START_STATE);
|
|
2077
|
+
}
|
|
1310
2078
|
}
|
|
1311
2079
|
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
2080
|
+
// Hexademical character reference start state
|
|
2081
|
+
//------------------------------------------------------------------
|
|
2082
|
+
[HEXADEMICAL_CHARACTER_REFERENCE_START_STATE](cp) {
|
|
2083
|
+
if (isAsciiHexDigit(cp)) {
|
|
2084
|
+
this._reconsumeInState(HEXADEMICAL_CHARACTER_REFERENCE_STATE);
|
|
2085
|
+
} else {
|
|
2086
|
+
this._err(ERR.absenceOfDigitsInNumericCharacterReference);
|
|
2087
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2088
|
+
this._reconsumeInState(this.returnState);
|
|
2089
|
+
}
|
|
1315
2090
|
}
|
|
1316
2091
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
2092
|
+
// Decimal character reference start state
|
|
2093
|
+
//------------------------------------------------------------------
|
|
2094
|
+
[DECIMAL_CHARACTER_REFERENCE_START_STATE](cp) {
|
|
2095
|
+
if (isAsciiDigit(cp)) {
|
|
2096
|
+
this._reconsumeInState(DECIMAL_CHARACTER_REFERENCE_STATE);
|
|
2097
|
+
} else {
|
|
2098
|
+
this._err(ERR.absenceOfDigitsInNumericCharacterReference);
|
|
2099
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2100
|
+
this._reconsumeInState(this.returnState);
|
|
2101
|
+
}
|
|
1320
2102
|
}
|
|
1321
2103
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
2104
|
+
// Hexademical character reference state
|
|
2105
|
+
//------------------------------------------------------------------
|
|
2106
|
+
[HEXADEMICAL_CHARACTER_REFERENCE_STATE](cp) {
|
|
2107
|
+
if (isAsciiUpperHexDigit(cp)) {
|
|
2108
|
+
this.charRefCode = this.charRefCode * 16 + cp - 0x37;
|
|
2109
|
+
} else if (isAsciiLowerHexDigit(cp)) {
|
|
2110
|
+
this.charRefCode = this.charRefCode * 16 + cp - 0x57;
|
|
2111
|
+
} else if (isAsciiDigit(cp)) {
|
|
2112
|
+
this.charRefCode = this.charRefCode * 16 + cp - 0x30;
|
|
2113
|
+
} else if (cp === $.SEMICOLON) {
|
|
2114
|
+
this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
|
|
2115
|
+
} else {
|
|
2116
|
+
this._err(ERR.missingSemicolonAfterCharacterReference);
|
|
2117
|
+
this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
|
|
2118
|
+
}
|
|
1328
2119
|
}
|
|
1329
|
-
};
|
|
1330
|
-
|
|
1331
2120
|
|
|
1332
|
-
//
|
|
1333
|
-
//------------------------------------------------------------------
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
2121
|
+
// Decimal character reference state
|
|
2122
|
+
//------------------------------------------------------------------
|
|
2123
|
+
[DECIMAL_CHARACTER_REFERENCE_STATE](cp) {
|
|
2124
|
+
if (isAsciiDigit(cp)) {
|
|
2125
|
+
this.charRefCode = this.charRefCode * 10 + cp - 0x30;
|
|
2126
|
+
} else if (cp === $.SEMICOLON) {
|
|
2127
|
+
this.state = NUMERIC_CHARACTER_REFERENCE_END_STATE;
|
|
2128
|
+
} else {
|
|
2129
|
+
this._err(ERR.missingSemicolonAfterCharacterReference);
|
|
2130
|
+
this._reconsumeInState(NUMERIC_CHARACTER_REFERENCE_END_STATE);
|
|
2131
|
+
}
|
|
1339
2132
|
}
|
|
1340
2133
|
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
2134
|
+
// Numeric character reference end state
|
|
2135
|
+
//------------------------------------------------------------------
|
|
2136
|
+
[NUMERIC_CHARACTER_REFERENCE_END_STATE]() {
|
|
2137
|
+
if (this.charRefCode === $.NULL) {
|
|
2138
|
+
this._err(ERR.nullCharacterReference);
|
|
2139
|
+
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
2140
|
+
} else if (this.charRefCode > 0x10ffff) {
|
|
2141
|
+
this._err(ERR.characterReferenceOutsideUnicodeRange);
|
|
2142
|
+
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
2143
|
+
} else if (unicode.isSurrogate(this.charRefCode)) {
|
|
2144
|
+
this._err(ERR.surrogateCharacterReference);
|
|
2145
|
+
this.charRefCode = $.REPLACEMENT_CHARACTER;
|
|
2146
|
+
} else if (unicode.isUndefinedCodePoint(this.charRefCode)) {
|
|
2147
|
+
this._err(ERR.noncharacterCharacterReference);
|
|
2148
|
+
} else if (unicode.isControlCodePoint(this.charRefCode) || this.charRefCode === $.CARRIAGE_RETURN) {
|
|
2149
|
+
this._err(ERR.controlCharacterReference);
|
|
2150
|
+
|
|
2151
|
+
const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS[this.charRefCode];
|
|
2152
|
+
|
|
2153
|
+
if (replacement) {
|
|
2154
|
+
this.charRefCode = replacement;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
1351
2157
|
|
|
1352
|
-
this.
|
|
1353
|
-
}
|
|
2158
|
+
this.tempBuff = [this.charRefCode];
|
|
1354
2159
|
|
|
1355
|
-
|
|
1356
|
-
this.
|
|
1357
|
-
this._emitCodePoint(cp);
|
|
2160
|
+
this._flushCodePointsConsumedAsCharacterReference();
|
|
2161
|
+
this._reconsumeInState(this.returnState);
|
|
1358
2162
|
}
|
|
2163
|
+
}
|
|
1359
2164
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
2165
|
+
//Token types
|
|
2166
|
+
Tokenizer.CHARACTER_TOKEN = 'CHARACTER_TOKEN';
|
|
2167
|
+
Tokenizer.NULL_CHARACTER_TOKEN = 'NULL_CHARACTER_TOKEN';
|
|
2168
|
+
Tokenizer.WHITESPACE_CHARACTER_TOKEN = 'WHITESPACE_CHARACTER_TOKEN';
|
|
2169
|
+
Tokenizer.START_TAG_TOKEN = 'START_TAG_TOKEN';
|
|
2170
|
+
Tokenizer.END_TAG_TOKEN = 'END_TAG_TOKEN';
|
|
2171
|
+
Tokenizer.COMMENT_TOKEN = 'COMMENT_TOKEN';
|
|
2172
|
+
Tokenizer.DOCTYPE_TOKEN = 'DOCTYPE_TOKEN';
|
|
2173
|
+
Tokenizer.EOF_TOKEN = 'EOF_TOKEN';
|
|
2174
|
+
Tokenizer.HIBERNATION_TOKEN = 'HIBERNATION_TOKEN';
|
|
1364
2175
|
|
|
1365
|
-
|
|
1366
|
-
|
|
2176
|
+
//Tokenizer initial states for different modes
|
|
2177
|
+
Tokenizer.MODE = {
|
|
2178
|
+
DATA: DATA_STATE,
|
|
2179
|
+
RCDATA: RCDATA_STATE,
|
|
2180
|
+
RAWTEXT: RAWTEXT_STATE,
|
|
2181
|
+
SCRIPT_DATA: SCRIPT_DATA_STATE,
|
|
2182
|
+
PLAINTEXT: PLAINTEXT_STATE
|
|
1367
2183
|
};
|
|
1368
2184
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
if (cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF)
|
|
1377
|
-
this._reconsumeInState(AFTER_ATTRIBUTE_NAME_STATE);
|
|
1378
|
-
|
|
1379
|
-
else if (cp === $.EQUALS_SIGN) {
|
|
1380
|
-
this._createAttr('=');
|
|
1381
|
-
this.state = ATTRIBUTE_NAME_STATE;
|
|
2185
|
+
//Static
|
|
2186
|
+
Tokenizer.getTokenAttr = function(token, attrName) {
|
|
2187
|
+
for (let i = token.attrs.length - 1; i >= 0; i--) {
|
|
2188
|
+
if (token.attrs[i].name === attrName) {
|
|
2189
|
+
return token.attrs[i].value;
|
|
2190
|
+
}
|
|
1382
2191
|
}
|
|
1383
2192
|
|
|
1384
|
-
|
|
1385
|
-
this._createAttr('');
|
|
1386
|
-
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
1387
|
-
}
|
|
2193
|
+
return null;
|
|
1388
2194
|
};
|
|
1389
2195
|
|
|
1390
|
-
|
|
1391
|
-
//12.2.4.35 Attribute name state
|
|
1392
|
-
//------------------------------------------------------------------
|
|
1393
|
-
_[ATTRIBUTE_NAME_STATE] = function attributeNameState(cp) {
|
|
1394
|
-
if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN || cp === $.EOF) {
|
|
1395
|
-
this._leaveAttrName(AFTER_ATTRIBUTE_NAME_STATE);
|
|
1396
|
-
this._unconsume();
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
else if (cp === $.EQUALS_SIGN)
|
|
1400
|
-
this._leaveAttrName(BEFORE_ATTRIBUTE_VALUE_STATE);
|
|
1401
|
-
|
|
1402
|
-
else if (isAsciiUpper(cp))
|
|
1403
|
-
this.currentAttr.name += toAsciiLowerChar(cp);
|
|
1404
|
-
|
|
1405
|
-
else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN)
|
|
1406
|
-
this.currentAttr.name += toChar(cp);
|
|
1407
|
-
|
|
1408
|
-
else if (cp === $.NULL)
|
|
1409
|
-
this.currentAttr.name += UNICODE.REPLACEMENT_CHARACTER;
|
|
1410
|
-
|
|
1411
|
-
else
|
|
1412
|
-
this.currentAttr.name += toChar(cp);
|
|
1413
|
-
};
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
//12.2.4.36 After attribute name state
|
|
1417
|
-
//------------------------------------------------------------------
|
|
1418
|
-
_[AFTER_ATTRIBUTE_NAME_STATE] = function afterAttributeNameState(cp) {
|
|
1419
|
-
if (isWhitespace(cp))
|
|
1420
|
-
return;
|
|
1421
|
-
|
|
1422
|
-
if (cp === $.SOLIDUS)
|
|
1423
|
-
this.state = SELF_CLOSING_START_TAG_STATE;
|
|
1424
|
-
|
|
1425
|
-
else if (cp === $.EQUALS_SIGN)
|
|
1426
|
-
this.state = BEFORE_ATTRIBUTE_VALUE_STATE;
|
|
1427
|
-
|
|
1428
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1429
|
-
this.state = DATA_STATE;
|
|
1430
|
-
this._emitCurrentToken();
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
else if (cp === $.EOF)
|
|
1434
|
-
this._reconsumeInState(DATA_STATE);
|
|
1435
|
-
|
|
1436
|
-
else {
|
|
1437
|
-
this._createAttr('');
|
|
1438
|
-
this._reconsumeInState(ATTRIBUTE_NAME_STATE);
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
//12.2.4.37 Before attribute value state
|
|
1444
|
-
//------------------------------------------------------------------
|
|
1445
|
-
_[BEFORE_ATTRIBUTE_VALUE_STATE] = function beforeAttributeValueState(cp) {
|
|
1446
|
-
if (isWhitespace(cp))
|
|
1447
|
-
return;
|
|
1448
|
-
|
|
1449
|
-
if (cp === $.QUOTATION_MARK)
|
|
1450
|
-
this.state = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
|
|
1451
|
-
|
|
1452
|
-
else if (cp === $.APOSTROPHE)
|
|
1453
|
-
this.state = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
|
|
1454
|
-
|
|
1455
|
-
else
|
|
1456
|
-
this._reconsumeInState(ATTRIBUTE_VALUE_UNQUOTED_STATE);
|
|
1457
|
-
};
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
//12.2.4.38 Attribute value (double-quoted) state
|
|
1461
|
-
//------------------------------------------------------------------
|
|
1462
|
-
_[ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE] = function attributeValueDoubleQuotedState(cp) {
|
|
1463
|
-
if (cp === $.QUOTATION_MARK)
|
|
1464
|
-
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
1465
|
-
|
|
1466
|
-
else if (cp === $.AMPERSAND) {
|
|
1467
|
-
this.additionalAllowedCp = $.QUOTATION_MARK;
|
|
1468
|
-
this.returnState = this.state;
|
|
1469
|
-
this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
else if (cp === $.NULL)
|
|
1473
|
-
this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
|
|
1474
|
-
|
|
1475
|
-
else if (cp === $.EOF)
|
|
1476
|
-
this._reconsumeInState(DATA_STATE);
|
|
1477
|
-
|
|
1478
|
-
else
|
|
1479
|
-
this.currentAttr.value += toChar(cp);
|
|
1480
|
-
};
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
//12.2.4.39 Attribute value (single-quoted) state
|
|
1484
|
-
//------------------------------------------------------------------
|
|
1485
|
-
_[ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE] = function attributeValueSingleQuotedState(cp) {
|
|
1486
|
-
if (cp === $.APOSTROPHE)
|
|
1487
|
-
this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
|
|
1488
|
-
|
|
1489
|
-
else if (cp === $.AMPERSAND) {
|
|
1490
|
-
this.additionalAllowedCp = $.APOSTROPHE;
|
|
1491
|
-
this.returnState = this.state;
|
|
1492
|
-
this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
else if (cp === $.NULL)
|
|
1496
|
-
this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
|
|
1497
|
-
|
|
1498
|
-
else if (cp === $.EOF)
|
|
1499
|
-
this._reconsumeInState(DATA_STATE);
|
|
1500
|
-
|
|
1501
|
-
else
|
|
1502
|
-
this.currentAttr.value += toChar(cp);
|
|
1503
|
-
};
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
//12.2.4.40 Attribute value (unquoted) state
|
|
1507
|
-
//------------------------------------------------------------------
|
|
1508
|
-
_[ATTRIBUTE_VALUE_UNQUOTED_STATE] = function attributeValueUnquotedState(cp) {
|
|
1509
|
-
if (isWhitespace(cp))
|
|
1510
|
-
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1511
|
-
|
|
1512
|
-
else if (cp === $.AMPERSAND) {
|
|
1513
|
-
this.additionalAllowedCp = $.GREATER_THAN_SIGN;
|
|
1514
|
-
this.returnState = this.state;
|
|
1515
|
-
this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1519
|
-
this._leaveAttrValue(DATA_STATE);
|
|
1520
|
-
this._emitCurrentToken();
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
else if (cp === $.NULL)
|
|
1524
|
-
this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
|
|
1525
|
-
|
|
1526
|
-
else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN ||
|
|
1527
|
-
cp === $.EQUALS_SIGN || cp === $.GRAVE_ACCENT)
|
|
1528
|
-
this.currentAttr.value += toChar(cp);
|
|
1529
|
-
|
|
1530
|
-
else if (cp === $.EOF)
|
|
1531
|
-
this._reconsumeInState(DATA_STATE);
|
|
1532
|
-
|
|
1533
|
-
else
|
|
1534
|
-
this.currentAttr.value += toChar(cp);
|
|
1535
|
-
};
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
//12.2.4.41 Character reference in attribute value state
|
|
1539
|
-
//------------------------------------------------------------------
|
|
1540
|
-
_[CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE] = function characterReferenceInAttributeValueState(cp) {
|
|
1541
|
-
var referencedCodePoints = this._consumeCharacterReference(cp, true);
|
|
1542
|
-
|
|
1543
|
-
if (!this._ensureHibernation()) {
|
|
1544
|
-
if (referencedCodePoints) {
|
|
1545
|
-
for (var i = 0; i < referencedCodePoints.length; i++)
|
|
1546
|
-
this.currentAttr.value += toChar(referencedCodePoints[i]);
|
|
1547
|
-
}
|
|
1548
|
-
else
|
|
1549
|
-
this.currentAttr.value += '&';
|
|
1550
|
-
|
|
1551
|
-
this.state = this.returnState;
|
|
1552
|
-
}
|
|
1553
|
-
};
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
//12.2.4.42 After attribute value (quoted) state
|
|
1557
|
-
//------------------------------------------------------------------
|
|
1558
|
-
_[AFTER_ATTRIBUTE_VALUE_QUOTED_STATE] = function afterAttributeValueQuotedState(cp) {
|
|
1559
|
-
if (isWhitespace(cp))
|
|
1560
|
-
this._leaveAttrValue(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1561
|
-
|
|
1562
|
-
else if (cp === $.SOLIDUS)
|
|
1563
|
-
this._leaveAttrValue(SELF_CLOSING_START_TAG_STATE);
|
|
1564
|
-
|
|
1565
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1566
|
-
this._leaveAttrValue(DATA_STATE);
|
|
1567
|
-
this._emitCurrentToken();
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
else if (cp === $.EOF)
|
|
1571
|
-
this._reconsumeInState(DATA_STATE);
|
|
1572
|
-
|
|
1573
|
-
else
|
|
1574
|
-
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1575
|
-
};
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
//12.2.4.43 Self-closing start tag state
|
|
1579
|
-
//------------------------------------------------------------------
|
|
1580
|
-
_[SELF_CLOSING_START_TAG_STATE] = function selfClosingStartTagState(cp) {
|
|
1581
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1582
|
-
this.currentToken.selfClosing = true;
|
|
1583
|
-
this.state = DATA_STATE;
|
|
1584
|
-
this._emitCurrentToken();
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
else if (cp === $.EOF)
|
|
1588
|
-
this._reconsumeInState(DATA_STATE);
|
|
1589
|
-
|
|
1590
|
-
else
|
|
1591
|
-
this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
|
|
1592
|
-
};
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
//12.2.4.44 Bogus comment state
|
|
1596
|
-
//------------------------------------------------------------------
|
|
1597
|
-
_[BOGUS_COMMENT_STATE] = function bogusCommentState() {
|
|
1598
|
-
this._createCommentToken();
|
|
1599
|
-
this._reconsumeInState(BOGUS_COMMENT_STATE_CONTINUATION);
|
|
1600
|
-
};
|
|
1601
|
-
|
|
1602
|
-
//HACK: to support streaming and make BOGUS_COMMENT_STATE reentrant we've
|
|
1603
|
-
//introduced BOGUS_COMMENT_STATE_CONTINUATION state which will not produce
|
|
1604
|
-
//comment token on each call.
|
|
1605
|
-
_[BOGUS_COMMENT_STATE_CONTINUATION] = function bogusCommentStateContinuation(cp) {
|
|
1606
|
-
while (true) {
|
|
1607
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1608
|
-
this.state = DATA_STATE;
|
|
1609
|
-
break;
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
else if (cp === $.EOF) {
|
|
1613
|
-
this._reconsumeInState(DATA_STATE);
|
|
1614
|
-
break;
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
else {
|
|
1618
|
-
this.currentToken.data += cp === $.NULL ? UNICODE.REPLACEMENT_CHARACTER : toChar(cp);
|
|
1619
|
-
|
|
1620
|
-
this._hibernationSnapshot();
|
|
1621
|
-
cp = this._consume();
|
|
1622
|
-
|
|
1623
|
-
if (this._ensureHibernation())
|
|
1624
|
-
return;
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
this._emitCurrentToken();
|
|
1629
|
-
};
|
|
1630
|
-
|
|
1631
|
-
//12.2.4.45 Markup declaration open state
|
|
1632
|
-
//------------------------------------------------------------------
|
|
1633
|
-
_[MARKUP_DECLARATION_OPEN_STATE] = function markupDeclarationOpenState(cp) {
|
|
1634
|
-
var dashDashMatch = this._consumeSubsequentIfMatch($$.DASH_DASH_STRING, cp, true),
|
|
1635
|
-
doctypeMatch = !dashDashMatch && this._consumeSubsequentIfMatch($$.DOCTYPE_STRING, cp, false),
|
|
1636
|
-
cdataMatch = !dashDashMatch && !doctypeMatch &&
|
|
1637
|
-
this.allowCDATA &&
|
|
1638
|
-
this._consumeSubsequentIfMatch($$.CDATA_START_STRING, cp, true);
|
|
1639
|
-
|
|
1640
|
-
if (!this._ensureHibernation()) {
|
|
1641
|
-
if (dashDashMatch) {
|
|
1642
|
-
this._createCommentToken();
|
|
1643
|
-
this.state = COMMENT_START_STATE;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
else if (doctypeMatch)
|
|
1647
|
-
this.state = DOCTYPE_STATE;
|
|
1648
|
-
|
|
1649
|
-
else if (cdataMatch)
|
|
1650
|
-
this.state = CDATA_SECTION_STATE;
|
|
1651
|
-
|
|
1652
|
-
else
|
|
1653
|
-
this._reconsumeInState(BOGUS_COMMENT_STATE);
|
|
1654
|
-
}
|
|
1655
|
-
};
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
//12.2.4.46 Comment start state
|
|
1659
|
-
//------------------------------------------------------------------
|
|
1660
|
-
_[COMMENT_START_STATE] = function commentStartState(cp) {
|
|
1661
|
-
if (cp === $.HYPHEN_MINUS)
|
|
1662
|
-
this.state = COMMENT_START_DASH_STATE;
|
|
1663
|
-
|
|
1664
|
-
else if (cp === $.NULL) {
|
|
1665
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1666
|
-
this.state = COMMENT_STATE;
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1670
|
-
this.state = DATA_STATE;
|
|
1671
|
-
this._emitCurrentToken();
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
else if (cp === $.EOF) {
|
|
1675
|
-
this._emitCurrentToken();
|
|
1676
|
-
this._reconsumeInState(DATA_STATE);
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
else {
|
|
1680
|
-
this.currentToken.data += toChar(cp);
|
|
1681
|
-
this.state = COMMENT_STATE;
|
|
1682
|
-
}
|
|
1683
|
-
};
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
//12.2.4.47 Comment start dash state
|
|
1687
|
-
//------------------------------------------------------------------
|
|
1688
|
-
_[COMMENT_START_DASH_STATE] = function commentStartDashState(cp) {
|
|
1689
|
-
if (cp === $.HYPHEN_MINUS)
|
|
1690
|
-
this.state = COMMENT_END_STATE;
|
|
1691
|
-
|
|
1692
|
-
else if (cp === $.NULL) {
|
|
1693
|
-
this.currentToken.data += '-';
|
|
1694
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1695
|
-
this.state = COMMENT_STATE;
|
|
1696
|
-
}
|
|
1697
|
-
|
|
1698
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1699
|
-
this.state = DATA_STATE;
|
|
1700
|
-
this._emitCurrentToken();
|
|
1701
|
-
}
|
|
1702
|
-
|
|
1703
|
-
else if (cp === $.EOF) {
|
|
1704
|
-
this._emitCurrentToken();
|
|
1705
|
-
this._reconsumeInState(DATA_STATE);
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
else {
|
|
1709
|
-
this.currentToken.data += '-';
|
|
1710
|
-
this.currentToken.data += toChar(cp);
|
|
1711
|
-
this.state = COMMENT_STATE;
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
//12.2.4.48 Comment state
|
|
1717
|
-
//------------------------------------------------------------------
|
|
1718
|
-
_[COMMENT_STATE] = function commentState(cp) {
|
|
1719
|
-
if (cp === $.HYPHEN_MINUS)
|
|
1720
|
-
this.state = COMMENT_END_DASH_STATE;
|
|
1721
|
-
|
|
1722
|
-
else if (cp === $.NULL)
|
|
1723
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1724
|
-
|
|
1725
|
-
else if (cp === $.EOF) {
|
|
1726
|
-
this._emitCurrentToken();
|
|
1727
|
-
this._reconsumeInState(DATA_STATE);
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
else
|
|
1731
|
-
this.currentToken.data += toChar(cp);
|
|
1732
|
-
};
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
//12.2.4.49 Comment end dash state
|
|
1736
|
-
//------------------------------------------------------------------
|
|
1737
|
-
_[COMMENT_END_DASH_STATE] = function commentEndDashState(cp) {
|
|
1738
|
-
if (cp === $.HYPHEN_MINUS)
|
|
1739
|
-
this.state = COMMENT_END_STATE;
|
|
1740
|
-
|
|
1741
|
-
else if (cp === $.NULL) {
|
|
1742
|
-
this.currentToken.data += '-';
|
|
1743
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1744
|
-
this.state = COMMENT_STATE;
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
else if (cp === $.EOF) {
|
|
1748
|
-
this._emitCurrentToken();
|
|
1749
|
-
this._reconsumeInState(DATA_STATE);
|
|
1750
|
-
}
|
|
1751
|
-
|
|
1752
|
-
else {
|
|
1753
|
-
this.currentToken.data += '-';
|
|
1754
|
-
this.currentToken.data += toChar(cp);
|
|
1755
|
-
this.state = COMMENT_STATE;
|
|
1756
|
-
}
|
|
1757
|
-
};
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
//12.2.4.50 Comment end state
|
|
1761
|
-
//------------------------------------------------------------------
|
|
1762
|
-
_[COMMENT_END_STATE] = function commentEndState(cp) {
|
|
1763
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1764
|
-
this.state = DATA_STATE;
|
|
1765
|
-
this._emitCurrentToken();
|
|
1766
|
-
}
|
|
1767
|
-
|
|
1768
|
-
else if (cp === $.EXCLAMATION_MARK)
|
|
1769
|
-
this.state = COMMENT_END_BANG_STATE;
|
|
1770
|
-
|
|
1771
|
-
else if (cp === $.HYPHEN_MINUS)
|
|
1772
|
-
this.currentToken.data += '-';
|
|
1773
|
-
|
|
1774
|
-
else if (cp === $.NULL) {
|
|
1775
|
-
this.currentToken.data += '--';
|
|
1776
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1777
|
-
this.state = COMMENT_STATE;
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
else if (cp === $.EOF) {
|
|
1781
|
-
this._reconsumeInState(DATA_STATE);
|
|
1782
|
-
this._emitCurrentToken();
|
|
1783
|
-
}
|
|
1784
|
-
|
|
1785
|
-
else {
|
|
1786
|
-
this.currentToken.data += '--';
|
|
1787
|
-
this.currentToken.data += toChar(cp);
|
|
1788
|
-
this.state = COMMENT_STATE;
|
|
1789
|
-
}
|
|
1790
|
-
};
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
//12.2.4.51 Comment end bang state
|
|
1794
|
-
//------------------------------------------------------------------
|
|
1795
|
-
_[COMMENT_END_BANG_STATE] = function commentEndBangState(cp) {
|
|
1796
|
-
if (cp === $.HYPHEN_MINUS) {
|
|
1797
|
-
this.currentToken.data += '--!';
|
|
1798
|
-
this.state = COMMENT_END_DASH_STATE;
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1802
|
-
this.state = DATA_STATE;
|
|
1803
|
-
this._emitCurrentToken();
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
else if (cp === $.NULL) {
|
|
1807
|
-
this.currentToken.data += '--!';
|
|
1808
|
-
this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
|
|
1809
|
-
this.state = COMMENT_STATE;
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
else if (cp === $.EOF) {
|
|
1813
|
-
this._emitCurrentToken();
|
|
1814
|
-
this._reconsumeInState(DATA_STATE);
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
else {
|
|
1818
|
-
this.currentToken.data += '--!';
|
|
1819
|
-
this.currentToken.data += toChar(cp);
|
|
1820
|
-
this.state = COMMENT_STATE;
|
|
1821
|
-
}
|
|
1822
|
-
};
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
//12.2.4.52 DOCTYPE state
|
|
1826
|
-
//------------------------------------------------------------------
|
|
1827
|
-
_[DOCTYPE_STATE] = function doctypeState(cp) {
|
|
1828
|
-
if (isWhitespace(cp))
|
|
1829
|
-
return;
|
|
1830
|
-
|
|
1831
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1832
|
-
this._createDoctypeToken(null);
|
|
1833
|
-
this.currentToken.forceQuirks = true;
|
|
1834
|
-
this._emitCurrentToken();
|
|
1835
|
-
this.state = DATA_STATE;
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
else if (cp === $.EOF) {
|
|
1839
|
-
this._createDoctypeToken(null);
|
|
1840
|
-
this.currentToken.forceQuirks = true;
|
|
1841
|
-
this._emitCurrentToken();
|
|
1842
|
-
this._reconsumeInState(DATA_STATE);
|
|
1843
|
-
}
|
|
1844
|
-
else {
|
|
1845
|
-
this._createDoctypeToken('');
|
|
1846
|
-
this._reconsumeInState(DOCTYPE_NAME_STATE);
|
|
1847
|
-
}
|
|
1848
|
-
};
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
//12.2.4.54 DOCTYPE name state
|
|
1852
|
-
//------------------------------------------------------------------
|
|
1853
|
-
_[DOCTYPE_NAME_STATE] = function doctypeNameState(cp) {
|
|
1854
|
-
if (isWhitespace(cp) || cp === $.GREATER_THAN_SIGN || cp === $.EOF)
|
|
1855
|
-
this._reconsumeInState(AFTER_DOCTYPE_NAME_STATE);
|
|
1856
|
-
|
|
1857
|
-
else if (isAsciiUpper(cp))
|
|
1858
|
-
this.currentToken.name += toAsciiLowerChar(cp);
|
|
1859
|
-
|
|
1860
|
-
else if (cp === $.NULL)
|
|
1861
|
-
this.currentToken.name += UNICODE.REPLACEMENT_CHARACTER;
|
|
1862
|
-
|
|
1863
|
-
else
|
|
1864
|
-
this.currentToken.name += toChar(cp);
|
|
1865
|
-
};
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
//12.2.4.55 After DOCTYPE name state
|
|
1869
|
-
//------------------------------------------------------------------
|
|
1870
|
-
_[AFTER_DOCTYPE_NAME_STATE] = function afterDoctypeNameState(cp) {
|
|
1871
|
-
if (isWhitespace(cp))
|
|
1872
|
-
return;
|
|
1873
|
-
|
|
1874
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1875
|
-
this.state = DATA_STATE;
|
|
1876
|
-
this._emitCurrentToken();
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
else {
|
|
1880
|
-
var publicMatch = this._consumeSubsequentIfMatch($$.PUBLIC_STRING, cp, false),
|
|
1881
|
-
systemMatch = !publicMatch && this._consumeSubsequentIfMatch($$.SYSTEM_STRING, cp, false);
|
|
1882
|
-
|
|
1883
|
-
if (!this._ensureHibernation()) {
|
|
1884
|
-
if (publicMatch)
|
|
1885
|
-
this.state = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
|
|
1886
|
-
|
|
1887
|
-
else if (systemMatch)
|
|
1888
|
-
this.state = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
1889
|
-
|
|
1890
|
-
else {
|
|
1891
|
-
this.currentToken.forceQuirks = true;
|
|
1892
|
-
this.state = BOGUS_DOCTYPE_STATE;
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
|
-
};
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
//12.2.4.57 Before DOCTYPE public identifier state
|
|
1900
|
-
//------------------------------------------------------------------
|
|
1901
|
-
_[BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE] = function beforeDoctypePublicIdentifierState(cp) {
|
|
1902
|
-
if (isWhitespace(cp))
|
|
1903
|
-
return;
|
|
1904
|
-
|
|
1905
|
-
if (cp === $.QUOTATION_MARK) {
|
|
1906
|
-
this.currentToken.publicId = '';
|
|
1907
|
-
this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
else if (cp === $.APOSTROPHE) {
|
|
1911
|
-
this.currentToken.publicId = '';
|
|
1912
|
-
this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
else {
|
|
1916
|
-
this.currentToken.forceQuirks = true;
|
|
1917
|
-
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1918
|
-
}
|
|
1919
|
-
};
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
//12.2.4.58 DOCTYPE public identifier (double-quoted) state
|
|
1923
|
-
//------------------------------------------------------------------
|
|
1924
|
-
_[DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE] = function doctypePublicIdentifierDoubleQuotedState(cp) {
|
|
1925
|
-
if (cp === $.QUOTATION_MARK)
|
|
1926
|
-
this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
|
|
1927
|
-
|
|
1928
|
-
else if (cp === $.NULL)
|
|
1929
|
-
this.currentToken.publicId += UNICODE.REPLACEMENT_CHARACTER;
|
|
1930
|
-
|
|
1931
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1932
|
-
this.currentToken.forceQuirks = true;
|
|
1933
|
-
this._emitCurrentToken();
|
|
1934
|
-
this.state = DATA_STATE;
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
else if (cp === $.EOF) {
|
|
1938
|
-
this.currentToken.forceQuirks = true;
|
|
1939
|
-
this._emitCurrentToken();
|
|
1940
|
-
this._reconsumeInState(DATA_STATE);
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
else
|
|
1944
|
-
this.currentToken.publicId += toChar(cp);
|
|
1945
|
-
};
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
//12.2.4.59 DOCTYPE public identifier (single-quoted) state
|
|
1949
|
-
//------------------------------------------------------------------
|
|
1950
|
-
_[DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE] = function doctypePublicIdentifierSingleQuotedState(cp) {
|
|
1951
|
-
if (cp === $.APOSTROPHE)
|
|
1952
|
-
this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
|
|
1953
|
-
|
|
1954
|
-
else if (cp === $.NULL)
|
|
1955
|
-
this.currentToken.publicId += UNICODE.REPLACEMENT_CHARACTER;
|
|
1956
|
-
|
|
1957
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
1958
|
-
this.currentToken.forceQuirks = true;
|
|
1959
|
-
this._emitCurrentToken();
|
|
1960
|
-
this.state = DATA_STATE;
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
else if (cp === $.EOF) {
|
|
1964
|
-
this.currentToken.forceQuirks = true;
|
|
1965
|
-
this._emitCurrentToken();
|
|
1966
|
-
this._reconsumeInState(DATA_STATE);
|
|
1967
|
-
}
|
|
1968
|
-
|
|
1969
|
-
else
|
|
1970
|
-
this.currentToken.publicId += toChar(cp);
|
|
1971
|
-
};
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
//12.2.4.61 Between DOCTYPE public and system identifiers state
|
|
1975
|
-
//------------------------------------------------------------------
|
|
1976
|
-
_[BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE] = function betweenDoctypePublicAndSystemIdentifiersState(cp) {
|
|
1977
|
-
if (isWhitespace(cp))
|
|
1978
|
-
return;
|
|
1979
|
-
|
|
1980
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
1981
|
-
this._emitCurrentToken();
|
|
1982
|
-
this.state = DATA_STATE;
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
|
-
else if (cp === $.QUOTATION_MARK) {
|
|
1986
|
-
this.currentToken.systemId = '';
|
|
1987
|
-
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
1988
|
-
}
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
else if (cp === $.APOSTROPHE) {
|
|
1992
|
-
this.currentToken.systemId = '';
|
|
1993
|
-
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
else {
|
|
1997
|
-
this.currentToken.forceQuirks = true;
|
|
1998
|
-
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
1999
|
-
}
|
|
2000
|
-
};
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
//12.2.4.63 Before DOCTYPE system identifier state
|
|
2004
|
-
//------------------------------------------------------------------
|
|
2005
|
-
_[BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE] = function beforeDoctypeSystemIdentifierState(cp) {
|
|
2006
|
-
if (isWhitespace(cp))
|
|
2007
|
-
return;
|
|
2008
|
-
|
|
2009
|
-
if (cp === $.QUOTATION_MARK) {
|
|
2010
|
-
this.currentToken.systemId = '';
|
|
2011
|
-
this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
else if (cp === $.APOSTROPHE) {
|
|
2015
|
-
this.currentToken.systemId = '';
|
|
2016
|
-
this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
else {
|
|
2020
|
-
this.currentToken.forceQuirks = true;
|
|
2021
|
-
this._reconsumeInState(BOGUS_DOCTYPE_STATE);
|
|
2022
|
-
}
|
|
2023
|
-
};
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
//12.2.4.64 DOCTYPE system identifier (double-quoted) state
|
|
2027
|
-
//------------------------------------------------------------------
|
|
2028
|
-
_[DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE] = function doctypeSystemIdentifierDoubleQuotedState(cp) {
|
|
2029
|
-
if (cp === $.QUOTATION_MARK)
|
|
2030
|
-
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
2031
|
-
|
|
2032
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
2033
|
-
this.currentToken.forceQuirks = true;
|
|
2034
|
-
this._emitCurrentToken();
|
|
2035
|
-
this.state = DATA_STATE;
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
else if (cp === $.NULL)
|
|
2039
|
-
this.currentToken.systemId += UNICODE.REPLACEMENT_CHARACTER;
|
|
2040
|
-
|
|
2041
|
-
else if (cp === $.EOF) {
|
|
2042
|
-
this.currentToken.forceQuirks = true;
|
|
2043
|
-
this._emitCurrentToken();
|
|
2044
|
-
this._reconsumeInState(DATA_STATE);
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
else
|
|
2048
|
-
this.currentToken.systemId += toChar(cp);
|
|
2049
|
-
};
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
//12.2.4.65 DOCTYPE system identifier (single-quoted) state
|
|
2053
|
-
//------------------------------------------------------------------
|
|
2054
|
-
_[DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE] = function doctypeSystemIdentifierSingleQuotedState(cp) {
|
|
2055
|
-
if (cp === $.APOSTROPHE)
|
|
2056
|
-
this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
|
|
2057
|
-
|
|
2058
|
-
else if (cp === $.GREATER_THAN_SIGN) {
|
|
2059
|
-
this.currentToken.forceQuirks = true;
|
|
2060
|
-
this._emitCurrentToken();
|
|
2061
|
-
this.state = DATA_STATE;
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
else if (cp === $.NULL)
|
|
2065
|
-
this.currentToken.systemId += UNICODE.REPLACEMENT_CHARACTER;
|
|
2066
|
-
|
|
2067
|
-
else if (cp === $.EOF) {
|
|
2068
|
-
this.currentToken.forceQuirks = true;
|
|
2069
|
-
this._emitCurrentToken();
|
|
2070
|
-
this._reconsumeInState(DATA_STATE);
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
else
|
|
2074
|
-
this.currentToken.systemId += toChar(cp);
|
|
2075
|
-
};
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
//12.2.4.66 After DOCTYPE system identifier state
|
|
2079
|
-
//------------------------------------------------------------------
|
|
2080
|
-
_[AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE] = function afterDoctypeSystemIdentifierState(cp) {
|
|
2081
|
-
if (isWhitespace(cp))
|
|
2082
|
-
return;
|
|
2083
|
-
|
|
2084
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
2085
|
-
this._emitCurrentToken();
|
|
2086
|
-
this.state = DATA_STATE;
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
else if (cp === $.EOF) {
|
|
2090
|
-
this.currentToken.forceQuirks = true;
|
|
2091
|
-
this._emitCurrentToken();
|
|
2092
|
-
this._reconsumeInState(DATA_STATE);
|
|
2093
|
-
}
|
|
2094
|
-
|
|
2095
|
-
else
|
|
2096
|
-
this.state = BOGUS_DOCTYPE_STATE;
|
|
2097
|
-
};
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
//12.2.4.67 Bogus DOCTYPE state
|
|
2101
|
-
//------------------------------------------------------------------
|
|
2102
|
-
_[BOGUS_DOCTYPE_STATE] = function bogusDoctypeState(cp) {
|
|
2103
|
-
if (cp === $.GREATER_THAN_SIGN) {
|
|
2104
|
-
this._emitCurrentToken();
|
|
2105
|
-
this.state = DATA_STATE;
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
else if (cp === $.EOF) {
|
|
2109
|
-
this._emitCurrentToken();
|
|
2110
|
-
this._reconsumeInState(DATA_STATE);
|
|
2111
|
-
}
|
|
2112
|
-
};
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
//12.2.4.68 CDATA section state
|
|
2116
|
-
//------------------------------------------------------------------
|
|
2117
|
-
_[CDATA_SECTION_STATE] = function cdataSectionState(cp) {
|
|
2118
|
-
while (true) {
|
|
2119
|
-
if (cp === $.EOF) {
|
|
2120
|
-
this._reconsumeInState(DATA_STATE);
|
|
2121
|
-
break;
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
else {
|
|
2125
|
-
var cdataEndMatch = this._consumeSubsequentIfMatch($$.CDATA_END_STRING, cp, true);
|
|
2126
|
-
|
|
2127
|
-
if (this._ensureHibernation())
|
|
2128
|
-
break;
|
|
2129
|
-
|
|
2130
|
-
if (cdataEndMatch) {
|
|
2131
|
-
this.state = DATA_STATE;
|
|
2132
|
-
break;
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
this._emitCodePoint(cp);
|
|
2136
|
-
|
|
2137
|
-
this._hibernationSnapshot();
|
|
2138
|
-
cp = this._consume();
|
|
2139
|
-
|
|
2140
|
-
if (this._ensureHibernation())
|
|
2141
|
-
break;
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
};
|
|
2196
|
+
module.exports = Tokenizer;
|