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/parser/index.js
CHANGED
|
@@ -1,845 +1,888 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
const Tokenizer = require('../tokenizer');
|
|
4
|
+
const OpenElementStack = require('./open-element-stack');
|
|
5
|
+
const FormattingElementList = require('./formatting-element-list');
|
|
6
|
+
const LocationInfoParserMixin = require('../extensions/location-info/parser-mixin');
|
|
7
|
+
const ErrorReportingParserMixin = require('../extensions/error-reporting/parser-mixin');
|
|
8
|
+
const Mixin = require('../utils/mixin');
|
|
9
|
+
const defaultTreeAdapter = require('../tree-adapters/default');
|
|
10
|
+
const mergeOptions = require('../utils/merge-options');
|
|
11
|
+
const doctype = require('../common/doctype');
|
|
12
|
+
const foreignContent = require('../common/foreign-content');
|
|
13
|
+
const ERR = require('../common/error-codes');
|
|
14
|
+
const unicode = require('../common/unicode');
|
|
15
|
+
const HTML = require('../common/html');
|
|
13
16
|
|
|
14
17
|
//Aliases
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const $ = HTML.TAG_NAMES;
|
|
19
|
+
const NS = HTML.NAMESPACES;
|
|
20
|
+
const ATTRS = HTML.ATTRS;
|
|
21
|
+
|
|
22
|
+
const DEFAULT_OPTIONS = {
|
|
23
|
+
scriptingEnabled: true,
|
|
24
|
+
sourceCodeLocationInfo: false,
|
|
25
|
+
onParseError: null,
|
|
21
26
|
treeAdapter: defaultTreeAdapter
|
|
22
27
|
};
|
|
23
28
|
|
|
24
29
|
//Misc constants
|
|
25
|
-
|
|
30
|
+
const HIDDEN_INPUT_TYPE = 'hidden';
|
|
26
31
|
|
|
27
32
|
//Adoption agency loops iteration count
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
const AA_OUTER_LOOP_ITER = 8;
|
|
34
|
+
const AA_INNER_LOOP_ITER = 3;
|
|
30
35
|
|
|
31
36
|
//Insertion modes
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
37
|
+
const INITIAL_MODE = 'INITIAL_MODE';
|
|
38
|
+
const BEFORE_HTML_MODE = 'BEFORE_HTML_MODE';
|
|
39
|
+
const BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE';
|
|
40
|
+
const IN_HEAD_MODE = 'IN_HEAD_MODE';
|
|
41
|
+
const IN_HEAD_NO_SCRIPT_MODE = 'IN_HEAD_NO_SCRIPT_MODE';
|
|
42
|
+
const AFTER_HEAD_MODE = 'AFTER_HEAD_MODE';
|
|
43
|
+
const IN_BODY_MODE = 'IN_BODY_MODE';
|
|
44
|
+
const TEXT_MODE = 'TEXT_MODE';
|
|
45
|
+
const IN_TABLE_MODE = 'IN_TABLE_MODE';
|
|
46
|
+
const IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE';
|
|
47
|
+
const IN_CAPTION_MODE = 'IN_CAPTION_MODE';
|
|
48
|
+
const IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE';
|
|
49
|
+
const IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE';
|
|
50
|
+
const IN_ROW_MODE = 'IN_ROW_MODE';
|
|
51
|
+
const IN_CELL_MODE = 'IN_CELL_MODE';
|
|
52
|
+
const IN_SELECT_MODE = 'IN_SELECT_MODE';
|
|
53
|
+
const IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE';
|
|
54
|
+
const IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE';
|
|
55
|
+
const AFTER_BODY_MODE = 'AFTER_BODY_MODE';
|
|
56
|
+
const IN_FRAMESET_MODE = 'IN_FRAMESET_MODE';
|
|
57
|
+
const AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE';
|
|
58
|
+
const AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE';
|
|
59
|
+
const AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE';
|
|
54
60
|
|
|
55
61
|
//Insertion mode reset map
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const INSERTION_MODE_RESET_MAP = {
|
|
63
|
+
[$.TR]: IN_ROW_MODE,
|
|
64
|
+
[$.TBODY]: IN_TABLE_BODY_MODE,
|
|
65
|
+
[$.THEAD]: IN_TABLE_BODY_MODE,
|
|
66
|
+
[$.TFOOT]: IN_TABLE_BODY_MODE,
|
|
67
|
+
[$.CAPTION]: IN_CAPTION_MODE,
|
|
68
|
+
[$.COLGROUP]: IN_COLUMN_GROUP_MODE,
|
|
69
|
+
[$.TABLE]: IN_TABLE_MODE,
|
|
70
|
+
[$.BODY]: IN_BODY_MODE,
|
|
71
|
+
[$.FRAMESET]: IN_FRAMESET_MODE
|
|
72
|
+
};
|
|
67
73
|
|
|
68
74
|
//Template insertion mode switch map
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
const TEMPLATE_INSERTION_MODE_SWITCH_MAP = {
|
|
76
|
+
[$.CAPTION]: IN_TABLE_MODE,
|
|
77
|
+
[$.COLGROUP]: IN_TABLE_MODE,
|
|
78
|
+
[$.TBODY]: IN_TABLE_MODE,
|
|
79
|
+
[$.TFOOT]: IN_TABLE_MODE,
|
|
80
|
+
[$.THEAD]: IN_TABLE_MODE,
|
|
81
|
+
[$.COL]: IN_COLUMN_GROUP_MODE,
|
|
82
|
+
[$.TR]: IN_TABLE_BODY_MODE,
|
|
83
|
+
[$.TD]: IN_ROW_MODE,
|
|
84
|
+
[$.TH]: IN_ROW_MODE
|
|
85
|
+
};
|
|
80
86
|
|
|
81
87
|
//Token handlers map for insertion modes
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
88
|
+
const TOKEN_HANDLERS = {
|
|
89
|
+
[INITIAL_MODE]: {
|
|
90
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenInInitialMode,
|
|
91
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInInitialMode,
|
|
92
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
93
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
94
|
+
[Tokenizer.DOCTYPE_TOKEN]: doctypeInInitialMode,
|
|
95
|
+
[Tokenizer.START_TAG_TOKEN]: tokenInInitialMode,
|
|
96
|
+
[Tokenizer.END_TAG_TOKEN]: tokenInInitialMode,
|
|
97
|
+
[Tokenizer.EOF_TOKEN]: tokenInInitialMode
|
|
98
|
+
},
|
|
99
|
+
[BEFORE_HTML_MODE]: {
|
|
100
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenBeforeHtml,
|
|
101
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHtml,
|
|
102
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
103
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
104
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
105
|
+
[Tokenizer.START_TAG_TOKEN]: startTagBeforeHtml,
|
|
106
|
+
[Tokenizer.END_TAG_TOKEN]: endTagBeforeHtml,
|
|
107
|
+
[Tokenizer.EOF_TOKEN]: tokenBeforeHtml
|
|
108
|
+
},
|
|
109
|
+
[BEFORE_HEAD_MODE]: {
|
|
110
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenBeforeHead,
|
|
111
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenBeforeHead,
|
|
112
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: ignoreToken,
|
|
113
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
114
|
+
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
115
|
+
[Tokenizer.START_TAG_TOKEN]: startTagBeforeHead,
|
|
116
|
+
[Tokenizer.END_TAG_TOKEN]: endTagBeforeHead,
|
|
117
|
+
[Tokenizer.EOF_TOKEN]: tokenBeforeHead
|
|
118
|
+
},
|
|
119
|
+
[IN_HEAD_MODE]: {
|
|
120
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenInHead,
|
|
121
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInHead,
|
|
122
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
123
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
124
|
+
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
125
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInHead,
|
|
126
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInHead,
|
|
127
|
+
[Tokenizer.EOF_TOKEN]: tokenInHead
|
|
128
|
+
},
|
|
129
|
+
[IN_HEAD_NO_SCRIPT_MODE]: {
|
|
130
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenInHeadNoScript,
|
|
131
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInHeadNoScript,
|
|
132
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
133
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
134
|
+
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
135
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInHeadNoScript,
|
|
136
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInHeadNoScript,
|
|
137
|
+
[Tokenizer.EOF_TOKEN]: tokenInHeadNoScript
|
|
138
|
+
},
|
|
139
|
+
[AFTER_HEAD_MODE]: {
|
|
140
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenAfterHead,
|
|
141
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterHead,
|
|
142
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
143
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
144
|
+
[Tokenizer.DOCTYPE_TOKEN]: misplacedDoctype,
|
|
145
|
+
[Tokenizer.START_TAG_TOKEN]: startTagAfterHead,
|
|
146
|
+
[Tokenizer.END_TAG_TOKEN]: endTagAfterHead,
|
|
147
|
+
[Tokenizer.EOF_TOKEN]: tokenAfterHead
|
|
148
|
+
},
|
|
149
|
+
[IN_BODY_MODE]: {
|
|
150
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
151
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
152
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
153
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
154
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
155
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInBody,
|
|
156
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInBody,
|
|
157
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
158
|
+
},
|
|
159
|
+
[TEXT_MODE]: {
|
|
160
|
+
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
161
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: insertCharacters,
|
|
162
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
163
|
+
[Tokenizer.COMMENT_TOKEN]: ignoreToken,
|
|
164
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
165
|
+
[Tokenizer.START_TAG_TOKEN]: ignoreToken,
|
|
166
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInText,
|
|
167
|
+
[Tokenizer.EOF_TOKEN]: eofInText
|
|
168
|
+
},
|
|
169
|
+
[IN_TABLE_MODE]: {
|
|
170
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
171
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
172
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
173
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
174
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
175
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInTable,
|
|
176
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInTable,
|
|
177
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
178
|
+
},
|
|
179
|
+
[IN_TABLE_TEXT_MODE]: {
|
|
180
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInTableText,
|
|
181
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
182
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInTableText,
|
|
183
|
+
[Tokenizer.COMMENT_TOKEN]: tokenInTableText,
|
|
184
|
+
[Tokenizer.DOCTYPE_TOKEN]: tokenInTableText,
|
|
185
|
+
[Tokenizer.START_TAG_TOKEN]: tokenInTableText,
|
|
186
|
+
[Tokenizer.END_TAG_TOKEN]: tokenInTableText,
|
|
187
|
+
[Tokenizer.EOF_TOKEN]: tokenInTableText
|
|
188
|
+
},
|
|
189
|
+
[IN_CAPTION_MODE]: {
|
|
190
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
191
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
192
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
193
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
194
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
195
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInCaption,
|
|
196
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInCaption,
|
|
197
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
198
|
+
},
|
|
199
|
+
[IN_COLUMN_GROUP_MODE]: {
|
|
200
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenInColumnGroup,
|
|
201
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenInColumnGroup,
|
|
202
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
203
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
204
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
205
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInColumnGroup,
|
|
206
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInColumnGroup,
|
|
207
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
208
|
+
},
|
|
209
|
+
[IN_TABLE_BODY_MODE]: {
|
|
210
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
211
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
212
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
213
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
214
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
215
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInTableBody,
|
|
216
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInTableBody,
|
|
217
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
218
|
+
},
|
|
219
|
+
[IN_ROW_MODE]: {
|
|
220
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInTable,
|
|
221
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: characterInTable,
|
|
222
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: characterInTable,
|
|
223
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
224
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
225
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInRow,
|
|
226
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInRow,
|
|
227
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
228
|
+
},
|
|
229
|
+
[IN_CELL_MODE]: {
|
|
230
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
231
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
232
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
233
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
234
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
235
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInCell,
|
|
236
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInCell,
|
|
237
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
238
|
+
},
|
|
239
|
+
[IN_SELECT_MODE]: {
|
|
240
|
+
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
241
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
242
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
243
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
244
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
245
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInSelect,
|
|
246
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInSelect,
|
|
247
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
248
|
+
},
|
|
249
|
+
[IN_SELECT_IN_TABLE_MODE]: {
|
|
250
|
+
[Tokenizer.CHARACTER_TOKEN]: insertCharacters,
|
|
251
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
252
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
253
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
254
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
255
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInSelectInTable,
|
|
256
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInSelectInTable,
|
|
257
|
+
[Tokenizer.EOF_TOKEN]: eofInBody
|
|
258
|
+
},
|
|
259
|
+
[IN_TEMPLATE_MODE]: {
|
|
260
|
+
[Tokenizer.CHARACTER_TOKEN]: characterInBody,
|
|
261
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
262
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
263
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
264
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
265
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInTemplate,
|
|
266
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInTemplate,
|
|
267
|
+
[Tokenizer.EOF_TOKEN]: eofInTemplate
|
|
268
|
+
},
|
|
269
|
+
[AFTER_BODY_MODE]: {
|
|
270
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenAfterBody,
|
|
271
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterBody,
|
|
272
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
273
|
+
[Tokenizer.COMMENT_TOKEN]: appendCommentToRootHtmlElement,
|
|
274
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
275
|
+
[Tokenizer.START_TAG_TOKEN]: startTagAfterBody,
|
|
276
|
+
[Tokenizer.END_TAG_TOKEN]: endTagAfterBody,
|
|
277
|
+
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
278
|
+
},
|
|
279
|
+
[IN_FRAMESET_MODE]: {
|
|
280
|
+
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
281
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
282
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
283
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
284
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
285
|
+
[Tokenizer.START_TAG_TOKEN]: startTagInFrameset,
|
|
286
|
+
[Tokenizer.END_TAG_TOKEN]: endTagInFrameset,
|
|
287
|
+
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
288
|
+
},
|
|
289
|
+
[AFTER_FRAMESET_MODE]: {
|
|
290
|
+
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
291
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
292
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: insertCharacters,
|
|
293
|
+
[Tokenizer.COMMENT_TOKEN]: appendComment,
|
|
294
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
295
|
+
[Tokenizer.START_TAG_TOKEN]: startTagAfterFrameset,
|
|
296
|
+
[Tokenizer.END_TAG_TOKEN]: endTagAfterFrameset,
|
|
297
|
+
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
298
|
+
},
|
|
299
|
+
[AFTER_AFTER_BODY_MODE]: {
|
|
300
|
+
[Tokenizer.CHARACTER_TOKEN]: tokenAfterAfterBody,
|
|
301
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: tokenAfterAfterBody,
|
|
302
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
303
|
+
[Tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
|
|
304
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
305
|
+
[Tokenizer.START_TAG_TOKEN]: startTagAfterAfterBody,
|
|
306
|
+
[Tokenizer.END_TAG_TOKEN]: tokenAfterAfterBody,
|
|
307
|
+
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
308
|
+
},
|
|
309
|
+
[AFTER_AFTER_FRAMESET_MODE]: {
|
|
310
|
+
[Tokenizer.CHARACTER_TOKEN]: ignoreToken,
|
|
311
|
+
[Tokenizer.NULL_CHARACTER_TOKEN]: ignoreToken,
|
|
312
|
+
[Tokenizer.WHITESPACE_CHARACTER_TOKEN]: whitespaceCharacterInBody,
|
|
313
|
+
[Tokenizer.COMMENT_TOKEN]: appendCommentToDocument,
|
|
314
|
+
[Tokenizer.DOCTYPE_TOKEN]: ignoreToken,
|
|
315
|
+
[Tokenizer.START_TAG_TOKEN]: startTagAfterAfterFrameset,
|
|
316
|
+
[Tokenizer.END_TAG_TOKEN]: ignoreToken,
|
|
317
|
+
[Tokenizer.EOF_TOKEN]: stopParsing
|
|
318
|
+
}
|
|
319
|
+
};
|
|
304
320
|
|
|
305
321
|
//Parser
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
this.treeAdapter = this.options.treeAdapter;
|
|
310
|
-
this.pendingScript = null;
|
|
322
|
+
class Parser {
|
|
323
|
+
constructor(options) {
|
|
324
|
+
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
311
325
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
};
|
|
326
|
+
this.treeAdapter = this.options.treeAdapter;
|
|
327
|
+
this.pendingScript = null;
|
|
315
328
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
329
|
+
if (this.options.sourceCodeLocationInfo) {
|
|
330
|
+
Mixin.install(this, LocationInfoParserMixin);
|
|
331
|
+
}
|
|
319
332
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
333
|
+
if (this.options.onParseError) {
|
|
334
|
+
Mixin.install(this, ErrorReportingParserMixin, { onParseError: this.options.onParseError });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
323
337
|
|
|
324
|
-
|
|
325
|
-
|
|
338
|
+
// API
|
|
339
|
+
parse(html) {
|
|
340
|
+
const document = this.treeAdapter.createDocument();
|
|
326
341
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
if (!fragmentContext)
|
|
331
|
-
fragmentContext = this.treeAdapter.createElement($.TEMPLATE, NS.HTML, []);
|
|
342
|
+
this._bootstrap(document, null);
|
|
343
|
+
this.tokenizer.write(html, true);
|
|
344
|
+
this._runParsingLoop(null);
|
|
332
345
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
//fragment parsing causes messing of the main `document`.
|
|
336
|
-
var documentMock = this.treeAdapter.createElement('documentmock', NS.HTML, []);
|
|
346
|
+
return document;
|
|
347
|
+
}
|
|
337
348
|
|
|
338
|
-
|
|
349
|
+
parseFragment(html, fragmentContext) {
|
|
350
|
+
//NOTE: use <template> element as a fragment context if context element was not provided,
|
|
351
|
+
//so we will parse in "forgiving" manner
|
|
352
|
+
if (!fragmentContext) {
|
|
353
|
+
fragmentContext = this.treeAdapter.createElement($.TEMPLATE, NS.HTML, []);
|
|
354
|
+
}
|
|
339
355
|
|
|
340
|
-
|
|
341
|
-
|
|
356
|
+
//NOTE: create fake element which will be used as 'document' for fragment parsing.
|
|
357
|
+
//This is important for jsdom there 'document' can't be recreated, therefore
|
|
358
|
+
//fragment parsing causes messing of the main `document`.
|
|
359
|
+
const documentMock = this.treeAdapter.createElement('documentmock', NS.HTML, []);
|
|
342
360
|
|
|
343
|
-
|
|
344
|
-
this._insertFakeRootElement();
|
|
345
|
-
this._resetInsertionMode();
|
|
346
|
-
this._findFormInFragmentContext();
|
|
347
|
-
this.tokenizer.write(html, true);
|
|
348
|
-
this._runParsingLoop(null);
|
|
361
|
+
this._bootstrap(documentMock, fragmentContext);
|
|
349
362
|
|
|
350
|
-
|
|
351
|
-
|
|
363
|
+
if (this.treeAdapter.getTagName(fragmentContext) === $.TEMPLATE) {
|
|
364
|
+
this._pushTmplInsertionMode(IN_TEMPLATE_MODE);
|
|
365
|
+
}
|
|
352
366
|
|
|
353
|
-
|
|
367
|
+
this._initTokenizerForFragmentParsing();
|
|
368
|
+
this._insertFakeRootElement();
|
|
369
|
+
this._resetInsertionMode();
|
|
370
|
+
this._findFormInFragmentContext();
|
|
371
|
+
this.tokenizer.write(html, true);
|
|
372
|
+
this._runParsingLoop(null);
|
|
354
373
|
|
|
355
|
-
|
|
356
|
-
|
|
374
|
+
const rootElement = this.treeAdapter.getFirstChild(documentMock);
|
|
375
|
+
const fragment = this.treeAdapter.createDocumentFragment();
|
|
357
376
|
|
|
358
|
-
|
|
359
|
-
Parser.prototype._bootstrap = function (document, fragmentContext) {
|
|
360
|
-
this.tokenizer = new Tokenizer(this.options);
|
|
377
|
+
this._adoptNodes(rootElement, fragment);
|
|
361
378
|
|
|
362
|
-
|
|
379
|
+
return fragment;
|
|
380
|
+
}
|
|
363
381
|
|
|
364
|
-
|
|
365
|
-
|
|
382
|
+
//Bootstrap parser
|
|
383
|
+
_bootstrap(document, fragmentContext) {
|
|
384
|
+
this.tokenizer = new Tokenizer(this.options);
|
|
366
385
|
|
|
367
|
-
|
|
368
|
-
this.fragmentContext = fragmentContext;
|
|
386
|
+
this.stopped = false;
|
|
369
387
|
|
|
370
|
-
|
|
371
|
-
|
|
388
|
+
this.insertionMode = INITIAL_MODE;
|
|
389
|
+
this.originalInsertionMode = '';
|
|
372
390
|
|
|
373
|
-
|
|
374
|
-
|
|
391
|
+
this.document = document;
|
|
392
|
+
this.fragmentContext = fragmentContext;
|
|
375
393
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
this.currentTmplInsertionMode = null;
|
|
394
|
+
this.headElement = null;
|
|
395
|
+
this.formElement = null;
|
|
379
396
|
|
|
380
|
-
|
|
381
|
-
|
|
397
|
+
this.openElements = new OpenElementStack(this.document, this.treeAdapter);
|
|
398
|
+
this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
|
|
382
399
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
};
|
|
400
|
+
this.tmplInsertionModeStack = [];
|
|
401
|
+
this.tmplInsertionModeStackTop = -1;
|
|
402
|
+
this.currentTmplInsertionMode = null;
|
|
387
403
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
while (!this.stopped) {
|
|
391
|
-
this._setupTokenizerCDATAMode();
|
|
404
|
+
this.pendingCharacterTokens = [];
|
|
405
|
+
this.hasNonWhitespacePendingCharacterToken = false;
|
|
392
406
|
|
|
393
|
-
|
|
407
|
+
this.framesetOk = true;
|
|
408
|
+
this.skipNextNewLine = false;
|
|
409
|
+
this.fosterParentingEnabled = false;
|
|
410
|
+
}
|
|
394
411
|
|
|
395
|
-
|
|
396
|
-
|
|
412
|
+
//Errors
|
|
413
|
+
_err() {
|
|
414
|
+
// NOTE: err reporting is noop by default. Enabled by mixin.
|
|
415
|
+
}
|
|
397
416
|
|
|
398
|
-
|
|
399
|
-
|
|
417
|
+
//Parsing loop
|
|
418
|
+
_runParsingLoop(scriptHandler) {
|
|
419
|
+
while (!this.stopped) {
|
|
420
|
+
this._setupTokenizerCDATAMode();
|
|
400
421
|
|
|
401
|
-
|
|
402
|
-
if (token.chars.length === 1)
|
|
403
|
-
continue;
|
|
422
|
+
const token = this.tokenizer.getNextToken();
|
|
404
423
|
|
|
405
|
-
|
|
424
|
+
if (token.type === Tokenizer.HIBERNATION_TOKEN) {
|
|
425
|
+
break;
|
|
406
426
|
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
this._processInputToken(token);
|
|
410
427
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
};
|
|
428
|
+
if (this.skipNextNewLine) {
|
|
429
|
+
this.skipNextNewLine = false;
|
|
415
430
|
|
|
416
|
-
|
|
417
|
-
|
|
431
|
+
if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
|
|
432
|
+
if (token.chars.length === 1) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
418
435
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
this.pendingScript = null;
|
|
436
|
+
token.chars = token.chars.substr(1);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
423
439
|
|
|
424
|
-
|
|
440
|
+
this._processInputToken(token);
|
|
425
441
|
|
|
426
|
-
|
|
442
|
+
if (scriptHandler && this.pendingScript) {
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
427
446
|
}
|
|
428
447
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
};
|
|
448
|
+
runParsingLoopForCurrentChunk(writeCallback, scriptHandler) {
|
|
449
|
+
this._runParsingLoop(scriptHandler);
|
|
432
450
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
var current = this._getAdjustedCurrentElement();
|
|
451
|
+
if (scriptHandler && this.pendingScript) {
|
|
452
|
+
const script = this.pendingScript;
|
|
436
453
|
|
|
437
|
-
|
|
438
|
-
this.treeAdapter.getNamespaceURI(current) !== NS.HTML && !this._isIntegrationPoint(current);
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
Parser.prototype._switchToTextParsing = function (currentToken, nextTokenizerState) {
|
|
442
|
-
this._insertElement(currentToken, NS.HTML);
|
|
443
|
-
this.tokenizer.state = nextTokenizerState;
|
|
444
|
-
this.originalInsertionMode = this.insertionMode;
|
|
445
|
-
this.insertionMode = TEXT_MODE;
|
|
446
|
-
};
|
|
454
|
+
this.pendingScript = null;
|
|
447
455
|
|
|
448
|
-
|
|
449
|
-
this.insertionMode = TEXT_MODE;
|
|
450
|
-
this.originalInsertionMode = IN_BODY_MODE;
|
|
451
|
-
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
452
|
-
};
|
|
456
|
+
scriptHandler(script);
|
|
453
457
|
|
|
454
|
-
|
|
455
|
-
Parser.prototype._getAdjustedCurrentElement = function () {
|
|
456
|
-
return this.openElements.stackTop === 0 && this.fragmentContext ?
|
|
457
|
-
this.fragmentContext :
|
|
458
|
-
this.openElements.current;
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
Parser.prototype._findFormInFragmentContext = function () {
|
|
462
|
-
var node = this.fragmentContext;
|
|
463
|
-
|
|
464
|
-
do {
|
|
465
|
-
if (this.treeAdapter.getTagName(node) === $.FORM) {
|
|
466
|
-
this.formElement = node;
|
|
467
|
-
break;
|
|
458
|
+
return;
|
|
468
459
|
}
|
|
469
460
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
Parser.prototype._initTokenizerForFragmentParsing = function () {
|
|
475
|
-
if (this.treeAdapter.getNamespaceURI(this.fragmentContext) === NS.HTML) {
|
|
476
|
-
var tn = this.treeAdapter.getTagName(this.fragmentContext);
|
|
461
|
+
if (writeCallback) {
|
|
462
|
+
writeCallback();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
477
465
|
|
|
478
|
-
|
|
479
|
-
|
|
466
|
+
//Text parsing
|
|
467
|
+
_setupTokenizerCDATAMode() {
|
|
468
|
+
const current = this._getAdjustedCurrentElement();
|
|
480
469
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
this.
|
|
470
|
+
this.tokenizer.allowCDATA =
|
|
471
|
+
current &&
|
|
472
|
+
current !== this.document &&
|
|
473
|
+
this.treeAdapter.getNamespaceURI(current) !== NS.HTML &&
|
|
474
|
+
!this._isIntegrationPoint(current);
|
|
475
|
+
}
|
|
484
476
|
|
|
485
|
-
|
|
486
|
-
|
|
477
|
+
_switchToTextParsing(currentToken, nextTokenizerState) {
|
|
478
|
+
this._insertElement(currentToken, NS.HTML);
|
|
479
|
+
this.tokenizer.state = nextTokenizerState;
|
|
480
|
+
this.originalInsertionMode = this.insertionMode;
|
|
481
|
+
this.insertionMode = TEXT_MODE;
|
|
482
|
+
}
|
|
487
483
|
|
|
488
|
-
|
|
489
|
-
|
|
484
|
+
switchToPlaintextParsing() {
|
|
485
|
+
this.insertionMode = TEXT_MODE;
|
|
486
|
+
this.originalInsertionMode = IN_BODY_MODE;
|
|
487
|
+
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
490
488
|
}
|
|
491
|
-
};
|
|
492
489
|
|
|
493
|
-
//
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
490
|
+
//Fragment parsing
|
|
491
|
+
_getAdjustedCurrentElement() {
|
|
492
|
+
return this.openElements.stackTop === 0 && this.fragmentContext
|
|
493
|
+
? this.fragmentContext
|
|
494
|
+
: this.openElements.current;
|
|
495
|
+
}
|
|
497
496
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
this._fosterParentElement(element);
|
|
497
|
+
_findFormInFragmentContext() {
|
|
498
|
+
let node = this.fragmentContext;
|
|
501
499
|
|
|
502
|
-
|
|
503
|
-
|
|
500
|
+
do {
|
|
501
|
+
if (this.treeAdapter.getTagName(node) === $.FORM) {
|
|
502
|
+
this.formElement = node;
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
504
505
|
|
|
505
|
-
|
|
506
|
+
node = this.treeAdapter.getParentNode(node);
|
|
507
|
+
} while (node);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
_initTokenizerForFragmentParsing() {
|
|
511
|
+
if (this.treeAdapter.getNamespaceURI(this.fragmentContext) === NS.HTML) {
|
|
512
|
+
const tn = this.treeAdapter.getTagName(this.fragmentContext);
|
|
513
|
+
|
|
514
|
+
if (tn === $.TITLE || tn === $.TEXTAREA) {
|
|
515
|
+
this.tokenizer.state = Tokenizer.MODE.RCDATA;
|
|
516
|
+
} else if (
|
|
517
|
+
tn === $.STYLE ||
|
|
518
|
+
tn === $.XMP ||
|
|
519
|
+
tn === $.IFRAME ||
|
|
520
|
+
tn === $.NOEMBED ||
|
|
521
|
+
tn === $.NOFRAMES ||
|
|
522
|
+
tn === $.NOSCRIPT
|
|
523
|
+
) {
|
|
524
|
+
this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
|
|
525
|
+
} else if (tn === $.SCRIPT) {
|
|
526
|
+
this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
|
|
527
|
+
} else if (tn === $.PLAINTEXT) {
|
|
528
|
+
this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
506
531
|
}
|
|
507
|
-
};
|
|
508
532
|
|
|
509
|
-
|
|
510
|
-
|
|
533
|
+
//Tree mutation
|
|
534
|
+
_setDocumentType(token) {
|
|
535
|
+
const name = token.name || '';
|
|
536
|
+
const publicId = token.publicId || '';
|
|
537
|
+
const systemId = token.systemId || '';
|
|
511
538
|
|
|
512
|
-
|
|
513
|
-
}
|
|
539
|
+
this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
|
|
540
|
+
}
|
|
514
541
|
|
|
515
|
-
|
|
516
|
-
|
|
542
|
+
_attachElementToTree(element) {
|
|
543
|
+
if (this._shouldFosterParentOnInsertion()) {
|
|
544
|
+
this._fosterParentElement(element);
|
|
545
|
+
} else {
|
|
546
|
+
const parent = this.openElements.currentTmplContent || this.openElements.current;
|
|
517
547
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
548
|
+
this.treeAdapter.appendChild(parent, element);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
521
551
|
|
|
522
|
-
|
|
523
|
-
|
|
552
|
+
_appendElement(token, namespaceURI) {
|
|
553
|
+
const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
|
|
524
554
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
};
|
|
555
|
+
this._attachElementToTree(element);
|
|
556
|
+
}
|
|
528
557
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
content = this.treeAdapter.createDocumentFragment();
|
|
558
|
+
_insertElement(token, namespaceURI) {
|
|
559
|
+
const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
|
|
532
560
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
};
|
|
561
|
+
this._attachElementToTree(element);
|
|
562
|
+
this.openElements.push(element);
|
|
563
|
+
}
|
|
537
564
|
|
|
538
|
-
|
|
539
|
-
|
|
565
|
+
_insertFakeElement(tagName) {
|
|
566
|
+
const element = this.treeAdapter.createElement(tagName, NS.HTML, []);
|
|
540
567
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
Parser.prototype._appendCommentNode = function (token, parent) {
|
|
546
|
-
var commentNode = this.treeAdapter.createCommentNode(token.data);
|
|
568
|
+
this._attachElementToTree(element);
|
|
569
|
+
this.openElements.push(element);
|
|
570
|
+
}
|
|
547
571
|
|
|
548
|
-
|
|
549
|
-
|
|
572
|
+
_insertTemplate(token) {
|
|
573
|
+
const tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs);
|
|
574
|
+
const content = this.treeAdapter.createDocumentFragment();
|
|
550
575
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.
|
|
576
|
+
this.treeAdapter.setTemplateContent(tmpl, content);
|
|
577
|
+
this._attachElementToTree(tmpl);
|
|
578
|
+
this.openElements.push(tmpl);
|
|
579
|
+
}
|
|
554
580
|
|
|
555
|
-
|
|
556
|
-
|
|
581
|
+
_insertFakeRootElement() {
|
|
582
|
+
const element = this.treeAdapter.createElement($.HTML, NS.HTML, []);
|
|
557
583
|
|
|
558
|
-
this.treeAdapter.
|
|
584
|
+
this.treeAdapter.appendChild(this.openElements.current, element);
|
|
585
|
+
this.openElements.push(element);
|
|
559
586
|
}
|
|
560
|
-
};
|
|
561
587
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
var child = this.treeAdapter.getFirstChild(donor);
|
|
588
|
+
_appendCommentNode(token, parent) {
|
|
589
|
+
const commentNode = this.treeAdapter.createCommentNode(token.data);
|
|
565
590
|
|
|
566
|
-
|
|
567
|
-
break;
|
|
568
|
-
|
|
569
|
-
this.treeAdapter.detachNode(child);
|
|
570
|
-
this.treeAdapter.appendChild(recipient, child);
|
|
591
|
+
this.treeAdapter.appendChild(parent, commentNode);
|
|
571
592
|
}
|
|
572
|
-
};
|
|
573
593
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
594
|
+
_insertCharacters(token) {
|
|
595
|
+
if (this._shouldFosterParentOnInsertion()) {
|
|
596
|
+
this._fosterParentText(token.chars);
|
|
597
|
+
} else {
|
|
598
|
+
const parent = this.openElements.currentTmplContent || this.openElements.current;
|
|
577
599
|
|
|
578
|
-
|
|
579
|
-
|
|
600
|
+
this.treeAdapter.insertText(parent, token.chars);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
580
603
|
|
|
581
|
-
|
|
604
|
+
_adoptNodes(donor, recipient) {
|
|
605
|
+
for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
|
|
606
|
+
this.treeAdapter.detachNode(child);
|
|
607
|
+
this.treeAdapter.appendChild(recipient, child);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
582
610
|
|
|
583
|
-
|
|
584
|
-
|
|
611
|
+
//Token processing
|
|
612
|
+
_shouldProcessTokenInForeignContent(token) {
|
|
613
|
+
const current = this._getAdjustedCurrentElement();
|
|
585
614
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
615
|
+
if (!current || current === this.document) {
|
|
616
|
+
return false;
|
|
617
|
+
}
|
|
589
618
|
|
|
590
|
-
|
|
591
|
-
token.type === Tokenizer.NULL_CHARACTER_TOKEN ||
|
|
592
|
-
token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN,
|
|
593
|
-
isMathMLTextStartTag = token.type === Tokenizer.START_TAG_TOKEN &&
|
|
594
|
-
token.tagName !== $.MGLYPH &&
|
|
595
|
-
token.tagName !== $.MALIGNMARK;
|
|
619
|
+
const ns = this.treeAdapter.getNamespaceURI(current);
|
|
596
620
|
|
|
597
|
-
|
|
598
|
-
|
|
621
|
+
if (ns === NS.HTML) {
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
599
624
|
|
|
600
|
-
|
|
601
|
-
|
|
625
|
+
if (
|
|
626
|
+
this.treeAdapter.getTagName(current) === $.ANNOTATION_XML &&
|
|
627
|
+
ns === NS.MATHML &&
|
|
628
|
+
token.type === Tokenizer.START_TAG_TOKEN &&
|
|
629
|
+
token.tagName === $.SVG
|
|
630
|
+
) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
602
633
|
|
|
603
|
-
|
|
604
|
-
|
|
634
|
+
const isCharacterToken =
|
|
635
|
+
token.type === Tokenizer.CHARACTER_TOKEN ||
|
|
636
|
+
token.type === Tokenizer.NULL_CHARACTER_TOKEN ||
|
|
637
|
+
token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN;
|
|
605
638
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
};
|
|
639
|
+
const isMathMLTextStartTag =
|
|
640
|
+
token.type === Tokenizer.START_TAG_TOKEN && token.tagName !== $.MGLYPH && token.tagName !== $.MALIGNMARK;
|
|
609
641
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
642
|
+
if ((isMathMLTextStartTag || isCharacterToken) && this._isIntegrationPoint(current, NS.MATHML)) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
613
645
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
646
|
+
if (
|
|
647
|
+
(token.type === Tokenizer.START_TAG_TOKEN || isCharacterToken) &&
|
|
648
|
+
this._isIntegrationPoint(current, NS.HTML)
|
|
649
|
+
) {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
617
652
|
|
|
618
|
-
|
|
619
|
-
|
|
653
|
+
return token.type !== Tokenizer.EOF_TOKEN;
|
|
654
|
+
}
|
|
620
655
|
|
|
621
|
-
|
|
622
|
-
|
|
656
|
+
_processToken(token) {
|
|
657
|
+
TOKEN_HANDLERS[this.insertionMode][token.type](this, token);
|
|
658
|
+
}
|
|
623
659
|
|
|
624
|
-
|
|
625
|
-
|
|
660
|
+
_processTokenInBodyMode(token) {
|
|
661
|
+
TOKEN_HANDLERS[IN_BODY_MODE][token.type](this, token);
|
|
662
|
+
}
|
|
626
663
|
|
|
627
|
-
|
|
628
|
-
|
|
664
|
+
_processTokenInForeignContent(token) {
|
|
665
|
+
if (token.type === Tokenizer.CHARACTER_TOKEN) {
|
|
666
|
+
characterInForeignContent(this, token);
|
|
667
|
+
} else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
|
|
668
|
+
nullCharacterInForeignContent(this, token);
|
|
669
|
+
} else if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN) {
|
|
670
|
+
insertCharacters(this, token);
|
|
671
|
+
} else if (token.type === Tokenizer.COMMENT_TOKEN) {
|
|
672
|
+
appendComment(this, token);
|
|
673
|
+
} else if (token.type === Tokenizer.START_TAG_TOKEN) {
|
|
674
|
+
startTagInForeignContent(this, token);
|
|
675
|
+
} else if (token.type === Tokenizer.END_TAG_TOKEN) {
|
|
676
|
+
endTagInForeignContent(this, token);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
629
679
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
680
|
+
_processInputToken(token) {
|
|
681
|
+
if (this._shouldProcessTokenInForeignContent(token)) {
|
|
682
|
+
this._processTokenInForeignContent(token);
|
|
683
|
+
} else {
|
|
684
|
+
this._processToken(token);
|
|
685
|
+
}
|
|
633
686
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
687
|
+
if (token.type === Tokenizer.START_TAG_TOKEN && token.selfClosing && !token.ackSelfClosing) {
|
|
688
|
+
this._err(ERR.nonVoidHtmlElementStartTagWithTrailingSolidus);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
637
691
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
692
|
+
//Integration points
|
|
693
|
+
_isIntegrationPoint(element, foreignNS) {
|
|
694
|
+
const tn = this.treeAdapter.getTagName(element);
|
|
695
|
+
const ns = this.treeAdapter.getNamespaceURI(element);
|
|
696
|
+
const attrs = this.treeAdapter.getAttrList(element);
|
|
641
697
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
var tn = this.treeAdapter.getTagName(element),
|
|
645
|
-
ns = this.treeAdapter.getNamespaceURI(element),
|
|
646
|
-
attrs = this.treeAdapter.getAttrList(element);
|
|
698
|
+
return foreignContent.isIntegrationPoint(tn, ns, attrs, foreignNS);
|
|
699
|
+
}
|
|
647
700
|
|
|
648
|
-
|
|
649
|
-
|
|
701
|
+
//Active formatting elements reconstruction
|
|
702
|
+
_reconstructActiveFormattingElements() {
|
|
703
|
+
const listLength = this.activeFormattingElements.length;
|
|
650
704
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
705
|
+
if (listLength) {
|
|
706
|
+
let unopenIdx = listLength;
|
|
707
|
+
let entry = null;
|
|
654
708
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
709
|
+
do {
|
|
710
|
+
unopenIdx--;
|
|
711
|
+
entry = this.activeFormattingElements.entries[unopenIdx];
|
|
658
712
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
713
|
+
if (entry.type === FormattingElementList.MARKER_ENTRY || this.openElements.contains(entry.element)) {
|
|
714
|
+
unopenIdx++;
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
} while (unopenIdx > 0);
|
|
662
718
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
719
|
+
for (let i = unopenIdx; i < listLength; i++) {
|
|
720
|
+
entry = this.activeFormattingElements.entries[i];
|
|
721
|
+
this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
|
|
722
|
+
entry.element = this.openElements.current;
|
|
666
723
|
}
|
|
667
|
-
} while (unopenIdx > 0);
|
|
668
|
-
|
|
669
|
-
for (var i = unopenIdx; i < listLength; i++) {
|
|
670
|
-
entry = this.activeFormattingElements.entries[i];
|
|
671
|
-
this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
|
|
672
|
-
entry.element = this.openElements.current;
|
|
673
724
|
}
|
|
674
725
|
}
|
|
675
|
-
};
|
|
676
|
-
|
|
677
|
-
//Close elements
|
|
678
|
-
Parser.prototype._closeTableCell = function () {
|
|
679
|
-
this.openElements.generateImpliedEndTags();
|
|
680
|
-
this.openElements.popUntilTableCellPopped();
|
|
681
|
-
this.activeFormattingElements.clearToLastMarker();
|
|
682
|
-
this.insertionMode = IN_ROW_MODE;
|
|
683
|
-
};
|
|
684
726
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
for (var i = this.openElements.stackTop, last = false; i >= 0; i--) {
|
|
693
|
-
var element = this.openElements.items[i];
|
|
694
|
-
|
|
695
|
-
if (i === 0) {
|
|
696
|
-
last = true;
|
|
727
|
+
//Close elements
|
|
728
|
+
_closeTableCell() {
|
|
729
|
+
this.openElements.generateImpliedEndTags();
|
|
730
|
+
this.openElements.popUntilTableCellPopped();
|
|
731
|
+
this.activeFormattingElements.clearToLastMarker();
|
|
732
|
+
this.insertionMode = IN_ROW_MODE;
|
|
733
|
+
}
|
|
697
734
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
735
|
+
_closePElement() {
|
|
736
|
+
this.openElements.generateImpliedEndTagsWithExclusion($.P);
|
|
737
|
+
this.openElements.popUntilTagNamePopped($.P);
|
|
738
|
+
}
|
|
701
739
|
|
|
702
|
-
|
|
703
|
-
|
|
740
|
+
//Insertion modes
|
|
741
|
+
_resetInsertionMode() {
|
|
742
|
+
for (let i = this.openElements.stackTop, last = false; i >= 0; i--) {
|
|
743
|
+
let element = this.openElements.items[i];
|
|
704
744
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
745
|
+
if (i === 0) {
|
|
746
|
+
last = true;
|
|
709
747
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
748
|
+
if (this.fragmentContext) {
|
|
749
|
+
element = this.fragmentContext;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
714
752
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
break;
|
|
718
|
-
}
|
|
753
|
+
const tn = this.treeAdapter.getTagName(element);
|
|
754
|
+
const newInsertionMode = INSERTION_MODE_RESET_MAP[tn];
|
|
719
755
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
756
|
+
if (newInsertionMode) {
|
|
757
|
+
this.insertionMode = newInsertionMode;
|
|
758
|
+
break;
|
|
759
|
+
} else if (!last && (tn === $.TD || tn === $.TH)) {
|
|
760
|
+
this.insertionMode = IN_CELL_MODE;
|
|
761
|
+
break;
|
|
762
|
+
} else if (!last && tn === $.HEAD) {
|
|
763
|
+
this.insertionMode = IN_HEAD_MODE;
|
|
764
|
+
break;
|
|
765
|
+
} else if (tn === $.SELECT) {
|
|
766
|
+
this._resetInsertionModeForSelect(i);
|
|
767
|
+
break;
|
|
768
|
+
} else if (tn === $.TEMPLATE) {
|
|
769
|
+
this.insertionMode = this.currentTmplInsertionMode;
|
|
770
|
+
break;
|
|
771
|
+
} else if (tn === $.HTML) {
|
|
772
|
+
this.insertionMode = this.headElement ? AFTER_HEAD_MODE : BEFORE_HEAD_MODE;
|
|
773
|
+
break;
|
|
774
|
+
} else if (last) {
|
|
775
|
+
this.insertionMode = IN_BODY_MODE;
|
|
776
|
+
break;
|
|
777
|
+
}
|
|
723
778
|
}
|
|
779
|
+
}
|
|
724
780
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
781
|
+
_resetInsertionModeForSelect(selectIdx) {
|
|
782
|
+
if (selectIdx > 0) {
|
|
783
|
+
for (let i = selectIdx - 1; i > 0; i--) {
|
|
784
|
+
const ancestor = this.openElements.items[i];
|
|
785
|
+
const tn = this.treeAdapter.getTagName(ancestor);
|
|
729
786
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
787
|
+
if (tn === $.TEMPLATE) {
|
|
788
|
+
break;
|
|
789
|
+
} else if (tn === $.TABLE) {
|
|
790
|
+
this.insertionMode = IN_SELECT_IN_TABLE_MODE;
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
733
794
|
}
|
|
734
795
|
|
|
735
|
-
|
|
736
|
-
this.insertionMode = IN_BODY_MODE;
|
|
737
|
-
break;
|
|
738
|
-
}
|
|
796
|
+
this.insertionMode = IN_SELECT_MODE;
|
|
739
797
|
}
|
|
740
|
-
};
|
|
741
798
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if (tn === $.TEMPLATE)
|
|
749
|
-
break;
|
|
799
|
+
_pushTmplInsertionMode(mode) {
|
|
800
|
+
this.tmplInsertionModeStack.push(mode);
|
|
801
|
+
this.tmplInsertionModeStackTop++;
|
|
802
|
+
this.currentTmplInsertionMode = mode;
|
|
803
|
+
}
|
|
750
804
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}
|
|
805
|
+
_popTmplInsertionMode() {
|
|
806
|
+
this.tmplInsertionModeStack.pop();
|
|
807
|
+
this.tmplInsertionModeStackTop--;
|
|
808
|
+
this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
|
|
756
809
|
}
|
|
757
810
|
|
|
758
|
-
|
|
759
|
-
|
|
811
|
+
//Foster parenting
|
|
812
|
+
_isElementCausesFosterParenting(element) {
|
|
813
|
+
const tn = this.treeAdapter.getTagName(element);
|
|
760
814
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
this.tmplInsertionModeStackTop++;
|
|
764
|
-
this.currentTmplInsertionMode = mode;
|
|
765
|
-
};
|
|
815
|
+
return tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR;
|
|
816
|
+
}
|
|
766
817
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
|
|
771
|
-
};
|
|
818
|
+
_shouldFosterParentOnInsertion() {
|
|
819
|
+
return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.current);
|
|
820
|
+
}
|
|
772
821
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
822
|
+
_findFosterParentingLocation() {
|
|
823
|
+
const location = {
|
|
824
|
+
parent: null,
|
|
825
|
+
beforeElement: null
|
|
826
|
+
};
|
|
776
827
|
|
|
777
|
-
|
|
778
|
-
|
|
828
|
+
for (let i = this.openElements.stackTop; i >= 0; i--) {
|
|
829
|
+
const openElement = this.openElements.items[i];
|
|
830
|
+
const tn = this.treeAdapter.getTagName(openElement);
|
|
831
|
+
const ns = this.treeAdapter.getNamespaceURI(openElement);
|
|
779
832
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
833
|
+
if (tn === $.TEMPLATE && ns === NS.HTML) {
|
|
834
|
+
location.parent = this.treeAdapter.getTemplateContent(openElement);
|
|
835
|
+
break;
|
|
836
|
+
} else if (tn === $.TABLE) {
|
|
837
|
+
location.parent = this.treeAdapter.getParentNode(openElement);
|
|
783
838
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
839
|
+
if (location.parent) {
|
|
840
|
+
location.beforeElement = openElement;
|
|
841
|
+
} else {
|
|
842
|
+
location.parent = this.openElements.items[i - 1];
|
|
843
|
+
}
|
|
789
844
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
ns = this.treeAdapter.getNamespaceURI(openElement);
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
794
848
|
|
|
795
|
-
if (
|
|
796
|
-
location.parent = this.
|
|
797
|
-
break;
|
|
849
|
+
if (!location.parent) {
|
|
850
|
+
location.parent = this.openElements.items[0];
|
|
798
851
|
}
|
|
799
852
|
|
|
800
|
-
|
|
801
|
-
|
|
853
|
+
return location;
|
|
854
|
+
}
|
|
802
855
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
else
|
|
806
|
-
location.parent = this.openElements.items[i - 1];
|
|
856
|
+
_fosterParentElement(element) {
|
|
857
|
+
const location = this._findFosterParentingLocation();
|
|
807
858
|
|
|
808
|
-
|
|
859
|
+
if (location.beforeElement) {
|
|
860
|
+
this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
|
|
861
|
+
} else {
|
|
862
|
+
this.treeAdapter.appendChild(location.parent, element);
|
|
809
863
|
}
|
|
810
864
|
}
|
|
811
865
|
|
|
812
|
-
|
|
813
|
-
location
|
|
814
|
-
|
|
815
|
-
return location;
|
|
816
|
-
};
|
|
817
|
-
|
|
818
|
-
Parser.prototype._fosterParentElement = function (element) {
|
|
819
|
-
var location = this._findFosterParentingLocation();
|
|
866
|
+
_fosterParentText(chars) {
|
|
867
|
+
const location = this._findFosterParentingLocation();
|
|
820
868
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
Parser.prototype._fosterParentText = function (chars) {
|
|
828
|
-
var location = this._findFosterParentingLocation();
|
|
869
|
+
if (location.beforeElement) {
|
|
870
|
+
this.treeAdapter.insertTextBefore(location.parent, chars, location.beforeElement);
|
|
871
|
+
} else {
|
|
872
|
+
this.treeAdapter.insertText(location.parent, chars);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
829
875
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
this.treeAdapter.
|
|
834
|
-
};
|
|
876
|
+
//Special elements
|
|
877
|
+
_isSpecialElement(element) {
|
|
878
|
+
const tn = this.treeAdapter.getTagName(element);
|
|
879
|
+
const ns = this.treeAdapter.getNamespaceURI(element);
|
|
835
880
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
ns = this.treeAdapter.getNamespaceURI(element);
|
|
881
|
+
return HTML.SPECIAL_ELEMENTS[ns][tn];
|
|
882
|
+
}
|
|
883
|
+
}
|
|
840
884
|
|
|
841
|
-
|
|
842
|
-
};
|
|
885
|
+
module.exports = Parser;
|
|
843
886
|
|
|
844
887
|
//Adoption agency algorithm
|
|
845
888
|
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
|
|
@@ -847,36 +890,36 @@ Parser.prototype._isSpecialElement = function (element) {
|
|
|
847
890
|
|
|
848
891
|
//Steps 5-8 of the algorithm
|
|
849
892
|
function aaObtainFormattingElementEntry(p, token) {
|
|
850
|
-
|
|
893
|
+
let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
|
|
851
894
|
|
|
852
895
|
if (formattingElementEntry) {
|
|
853
896
|
if (!p.openElements.contains(formattingElementEntry.element)) {
|
|
854
897
|
p.activeFormattingElements.removeEntry(formattingElementEntry);
|
|
855
898
|
formattingElementEntry = null;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
else if (!p.openElements.hasInScope(token.tagName))
|
|
899
|
+
} else if (!p.openElements.hasInScope(token.tagName)) {
|
|
859
900
|
formattingElementEntry = null;
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
else
|
|
901
|
+
}
|
|
902
|
+
} else {
|
|
863
903
|
genericEndTagInBody(p, token);
|
|
904
|
+
}
|
|
864
905
|
|
|
865
906
|
return formattingElementEntry;
|
|
866
907
|
}
|
|
867
908
|
|
|
868
909
|
//Steps 9 and 10 of the algorithm
|
|
869
910
|
function aaObtainFurthestBlock(p, formattingElementEntry) {
|
|
870
|
-
|
|
911
|
+
let furthestBlock = null;
|
|
871
912
|
|
|
872
|
-
for (
|
|
873
|
-
|
|
913
|
+
for (let i = p.openElements.stackTop; i >= 0; i--) {
|
|
914
|
+
const element = p.openElements.items[i];
|
|
874
915
|
|
|
875
|
-
if (element === formattingElementEntry.element)
|
|
916
|
+
if (element === formattingElementEntry.element) {
|
|
876
917
|
break;
|
|
918
|
+
}
|
|
877
919
|
|
|
878
|
-
if (p._isSpecialElement(element))
|
|
920
|
+
if (p._isSpecialElement(element)) {
|
|
879
921
|
furthestBlock = element;
|
|
922
|
+
}
|
|
880
923
|
}
|
|
881
924
|
|
|
882
925
|
if (!furthestBlock) {
|
|
@@ -889,29 +932,29 @@ function aaObtainFurthestBlock(p, formattingElementEntry) {
|
|
|
889
932
|
|
|
890
933
|
//Step 13 of the algorithm
|
|
891
934
|
function aaInnerLoop(p, furthestBlock, formattingElement) {
|
|
892
|
-
|
|
893
|
-
|
|
935
|
+
let lastElement = furthestBlock;
|
|
936
|
+
let nextElement = p.openElements.getCommonAncestor(furthestBlock);
|
|
894
937
|
|
|
895
|
-
for (
|
|
938
|
+
for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
|
|
896
939
|
//NOTE: store next element for the next loop iteration (it may be deleted from the stack by step 9.5)
|
|
897
940
|
nextElement = p.openElements.getCommonAncestor(element);
|
|
898
941
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
942
|
+
const elementEntry = p.activeFormattingElements.getElementEntry(element);
|
|
943
|
+
const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
|
|
944
|
+
const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
|
|
902
945
|
|
|
903
946
|
if (shouldRemoveFromOpenElements) {
|
|
904
|
-
if (counterOverflow)
|
|
947
|
+
if (counterOverflow) {
|
|
905
948
|
p.activeFormattingElements.removeEntry(elementEntry);
|
|
949
|
+
}
|
|
906
950
|
|
|
907
951
|
p.openElements.remove(element);
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
else {
|
|
952
|
+
} else {
|
|
911
953
|
element = aaRecreateElementFromEntry(p, elementEntry);
|
|
912
954
|
|
|
913
|
-
if (lastElement === furthestBlock)
|
|
955
|
+
if (lastElement === furthestBlock) {
|
|
914
956
|
p.activeFormattingElements.bookmark = elementEntry;
|
|
957
|
+
}
|
|
915
958
|
|
|
916
959
|
p.treeAdapter.detachNode(lastElement);
|
|
917
960
|
p.treeAdapter.appendChild(element, lastElement);
|
|
@@ -924,8 +967,8 @@ function aaInnerLoop(p, furthestBlock, formattingElement) {
|
|
|
924
967
|
|
|
925
968
|
//Step 13.7 of the algorithm
|
|
926
969
|
function aaRecreateElementFromEntry(p, elementEntry) {
|
|
927
|
-
|
|
928
|
-
|
|
970
|
+
const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
|
|
971
|
+
const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
|
|
929
972
|
|
|
930
973
|
p.openElements.replace(elementEntry.element, newElement);
|
|
931
974
|
elementEntry.element = newElement;
|
|
@@ -935,15 +978,15 @@ function aaRecreateElementFromEntry(p, elementEntry) {
|
|
|
935
978
|
|
|
936
979
|
//Step 14 of the algorithm
|
|
937
980
|
function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
|
|
938
|
-
if (p._isElementCausesFosterParenting(commonAncestor))
|
|
981
|
+
if (p._isElementCausesFosterParenting(commonAncestor)) {
|
|
939
982
|
p._fosterParentElement(lastElement);
|
|
983
|
+
} else {
|
|
984
|
+
const tn = p.treeAdapter.getTagName(commonAncestor);
|
|
985
|
+
const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
|
|
940
986
|
|
|
941
|
-
|
|
942
|
-
var tn = p.treeAdapter.getTagName(commonAncestor),
|
|
943
|
-
ns = p.treeAdapter.getNamespaceURI(commonAncestor);
|
|
944
|
-
|
|
945
|
-
if (tn === $.TEMPLATE && ns === NS.HTML)
|
|
987
|
+
if (tn === $.TEMPLATE && ns === NS.HTML) {
|
|
946
988
|
commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
|
|
989
|
+
}
|
|
947
990
|
|
|
948
991
|
p.treeAdapter.appendChild(commonAncestor, lastElement);
|
|
949
992
|
}
|
|
@@ -951,9 +994,9 @@ function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
|
|
|
951
994
|
|
|
952
995
|
//Steps 15-19 of the algorithm
|
|
953
996
|
function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
997
|
+
const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
|
|
998
|
+
const token = formattingElementEntry.token;
|
|
999
|
+
const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
|
|
957
1000
|
|
|
958
1001
|
p._adoptNodes(furthestBlock, newElement);
|
|
959
1002
|
p.treeAdapter.appendChild(furthestBlock, newElement);
|
|
@@ -967,23 +1010,25 @@ function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
|
|
|
967
1010
|
|
|
968
1011
|
//Algorithm entry point
|
|
969
1012
|
function callAdoptionAgency(p, token) {
|
|
970
|
-
|
|
1013
|
+
let formattingElementEntry;
|
|
971
1014
|
|
|
972
|
-
for (
|
|
1015
|
+
for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
|
|
973
1016
|
formattingElementEntry = aaObtainFormattingElementEntry(p, token, formattingElementEntry);
|
|
974
1017
|
|
|
975
|
-
if (!formattingElementEntry)
|
|
1018
|
+
if (!formattingElementEntry) {
|
|
976
1019
|
break;
|
|
1020
|
+
}
|
|
977
1021
|
|
|
978
|
-
|
|
1022
|
+
const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
|
|
979
1023
|
|
|
980
|
-
if (!furthestBlock)
|
|
1024
|
+
if (!furthestBlock) {
|
|
981
1025
|
break;
|
|
1026
|
+
}
|
|
982
1027
|
|
|
983
1028
|
p.activeFormattingElements.bookmark = formattingElementEntry;
|
|
984
1029
|
|
|
985
|
-
|
|
986
|
-
|
|
1030
|
+
const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
|
|
1031
|
+
const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
|
|
987
1032
|
|
|
988
1033
|
p.treeAdapter.detachNode(lastElement);
|
|
989
1034
|
aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
|
|
@@ -991,13 +1036,16 @@ function callAdoptionAgency(p, token) {
|
|
|
991
1036
|
}
|
|
992
1037
|
}
|
|
993
1038
|
|
|
994
|
-
|
|
995
1039
|
//Generic token handlers
|
|
996
1040
|
//------------------------------------------------------------------
|
|
997
1041
|
function ignoreToken() {
|
|
998
1042
|
//NOTE: do nothing =)
|
|
999
1043
|
}
|
|
1000
1044
|
|
|
1045
|
+
function misplacedDoctype(p) {
|
|
1046
|
+
p._err(ERR.misplacedDoctype);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1001
1049
|
function appendComment(p, token) {
|
|
1002
1050
|
p._appendCommentNode(token, p.openElements.currentTmplContent || p.openElements.current);
|
|
1003
1051
|
}
|
|
@@ -1018,14 +1066,16 @@ function stopParsing(p) {
|
|
|
1018
1066
|
p.stopped = true;
|
|
1019
1067
|
}
|
|
1020
1068
|
|
|
1021
|
-
//
|
|
1069
|
+
// The "initial" insertion mode
|
|
1022
1070
|
//------------------------------------------------------------------
|
|
1023
1071
|
function doctypeInInitialMode(p, token) {
|
|
1024
1072
|
p._setDocumentType(token);
|
|
1025
1073
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1074
|
+
const mode = token.forceQuirks ? HTML.DOCUMENT_MODE.QUIRKS : doctype.getDocumentMode(token);
|
|
1075
|
+
|
|
1076
|
+
if (!doctype.isConforming(token)) {
|
|
1077
|
+
p._err(ERR.nonConformingDoctype);
|
|
1078
|
+
}
|
|
1029
1079
|
|
|
1030
1080
|
p.treeAdapter.setDocumentMode(p.document, mode);
|
|
1031
1081
|
|
|
@@ -1033,29 +1083,29 @@ function doctypeInInitialMode(p, token) {
|
|
|
1033
1083
|
}
|
|
1034
1084
|
|
|
1035
1085
|
function tokenInInitialMode(p, token) {
|
|
1086
|
+
p._err(ERR.missingDoctype, { beforeToken: true });
|
|
1036
1087
|
p.treeAdapter.setDocumentMode(p.document, HTML.DOCUMENT_MODE.QUIRKS);
|
|
1037
1088
|
p.insertionMode = BEFORE_HTML_MODE;
|
|
1038
1089
|
p._processToken(token);
|
|
1039
1090
|
}
|
|
1040
1091
|
|
|
1041
|
-
|
|
1042
|
-
//12.2.5.4.2 The "before html" insertion mode
|
|
1092
|
+
// The "before html" insertion mode
|
|
1043
1093
|
//------------------------------------------------------------------
|
|
1044
1094
|
function startTagBeforeHtml(p, token) {
|
|
1045
1095
|
if (token.tagName === $.HTML) {
|
|
1046
1096
|
p._insertElement(token, NS.HTML);
|
|
1047
1097
|
p.insertionMode = BEFORE_HEAD_MODE;
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
else
|
|
1098
|
+
} else {
|
|
1051
1099
|
tokenBeforeHtml(p, token);
|
|
1100
|
+
}
|
|
1052
1101
|
}
|
|
1053
1102
|
|
|
1054
1103
|
function endTagBeforeHtml(p, token) {
|
|
1055
|
-
|
|
1104
|
+
const tn = token.tagName;
|
|
1056
1105
|
|
|
1057
|
-
if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR)
|
|
1106
|
+
if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR) {
|
|
1058
1107
|
tokenBeforeHtml(p, token);
|
|
1108
|
+
}
|
|
1059
1109
|
}
|
|
1060
1110
|
|
|
1061
1111
|
function tokenBeforeHtml(p, token) {
|
|
@@ -1064,30 +1114,30 @@ function tokenBeforeHtml(p, token) {
|
|
|
1064
1114
|
p._processToken(token);
|
|
1065
1115
|
}
|
|
1066
1116
|
|
|
1067
|
-
|
|
1068
|
-
//12.2.5.4.3 The "before head" insertion mode
|
|
1117
|
+
// The "before head" insertion mode
|
|
1069
1118
|
//------------------------------------------------------------------
|
|
1070
1119
|
function startTagBeforeHead(p, token) {
|
|
1071
|
-
|
|
1120
|
+
const tn = token.tagName;
|
|
1072
1121
|
|
|
1073
|
-
if (tn === $.HTML)
|
|
1122
|
+
if (tn === $.HTML) {
|
|
1074
1123
|
startTagInBody(p, token);
|
|
1075
|
-
|
|
1076
|
-
else if (tn === $.HEAD) {
|
|
1124
|
+
} else if (tn === $.HEAD) {
|
|
1077
1125
|
p._insertElement(token, NS.HTML);
|
|
1078
1126
|
p.headElement = p.openElements.current;
|
|
1079
1127
|
p.insertionMode = IN_HEAD_MODE;
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
else
|
|
1128
|
+
} else {
|
|
1083
1129
|
tokenBeforeHead(p, token);
|
|
1130
|
+
}
|
|
1084
1131
|
}
|
|
1085
1132
|
|
|
1086
1133
|
function endTagBeforeHead(p, token) {
|
|
1087
|
-
|
|
1134
|
+
const tn = token.tagName;
|
|
1088
1135
|
|
|
1089
|
-
if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR)
|
|
1136
|
+
if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR) {
|
|
1090
1137
|
tokenBeforeHead(p, token);
|
|
1138
|
+
} else {
|
|
1139
|
+
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
1140
|
+
}
|
|
1091
1141
|
}
|
|
1092
1142
|
|
|
1093
1143
|
function tokenBeforeHead(p, token) {
|
|
@@ -1097,58 +1147,67 @@ function tokenBeforeHead(p, token) {
|
|
|
1097
1147
|
p._processToken(token);
|
|
1098
1148
|
}
|
|
1099
1149
|
|
|
1100
|
-
|
|
1101
|
-
//12.2.5.4.4 The "in head" insertion mode
|
|
1150
|
+
// The "in head" insertion mode
|
|
1102
1151
|
//------------------------------------------------------------------
|
|
1103
1152
|
function startTagInHead(p, token) {
|
|
1104
|
-
|
|
1153
|
+
const tn = token.tagName;
|
|
1105
1154
|
|
|
1106
|
-
if (tn === $.HTML)
|
|
1155
|
+
if (tn === $.HTML) {
|
|
1107
1156
|
startTagInBody(p, token);
|
|
1108
|
-
|
|
1109
|
-
else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META)
|
|
1157
|
+
} else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META) {
|
|
1110
1158
|
p._appendElement(token, NS.HTML);
|
|
1111
|
-
|
|
1112
|
-
else if (tn === $.TITLE)
|
|
1159
|
+
token.ackSelfClosing = true;
|
|
1160
|
+
} else if (tn === $.TITLE) {
|
|
1113
1161
|
p._switchToTextParsing(token, Tokenizer.MODE.RCDATA);
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1162
|
+
} else if (tn === $.NOSCRIPT) {
|
|
1163
|
+
if (p.options.scriptingEnabled) {
|
|
1164
|
+
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
1165
|
+
} else {
|
|
1166
|
+
p._insertElement(token, NS.HTML);
|
|
1167
|
+
p.insertionMode = IN_HEAD_NO_SCRIPT_MODE;
|
|
1168
|
+
}
|
|
1169
|
+
} else if (tn === $.NOFRAMES || tn === $.STYLE) {
|
|
1118
1170
|
p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
|
|
1119
|
-
|
|
1120
|
-
else if (tn === $.SCRIPT)
|
|
1171
|
+
} else if (tn === $.SCRIPT) {
|
|
1121
1172
|
p._switchToTextParsing(token, Tokenizer.MODE.SCRIPT_DATA);
|
|
1122
|
-
|
|
1123
|
-
else if (tn === $.TEMPLATE) {
|
|
1173
|
+
} else if (tn === $.TEMPLATE) {
|
|
1124
1174
|
p._insertTemplate(token, NS.HTML);
|
|
1125
1175
|
p.activeFormattingElements.insertMarker();
|
|
1126
1176
|
p.framesetOk = false;
|
|
1127
1177
|
p.insertionMode = IN_TEMPLATE_MODE;
|
|
1128
1178
|
p._pushTmplInsertionMode(IN_TEMPLATE_MODE);
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
else
|
|
1179
|
+
} else if (tn === $.HEAD) {
|
|
1180
|
+
p._err(ERR.misplacedStartTagForHeadElement);
|
|
1181
|
+
} else {
|
|
1132
1182
|
tokenInHead(p, token);
|
|
1183
|
+
}
|
|
1133
1184
|
}
|
|
1134
1185
|
|
|
1135
1186
|
function endTagInHead(p, token) {
|
|
1136
|
-
|
|
1187
|
+
const tn = token.tagName;
|
|
1137
1188
|
|
|
1138
1189
|
if (tn === $.HEAD) {
|
|
1139
1190
|
p.openElements.pop();
|
|
1140
1191
|
p.insertionMode = AFTER_HEAD_MODE;
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
else if (tn === $.BODY || tn === $.BR || tn === $.HTML)
|
|
1192
|
+
} else if (tn === $.BODY || tn === $.BR || tn === $.HTML) {
|
|
1144
1193
|
tokenInHead(p, token);
|
|
1194
|
+
} else if (tn === $.TEMPLATE) {
|
|
1195
|
+
if (p.openElements.tmplCount > 0) {
|
|
1196
|
+
p.openElements.generateImpliedEndTagsThoroughly();
|
|
1145
1197
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1198
|
+
if (p.openElements.currentTagName !== $.TEMPLATE) {
|
|
1199
|
+
p._err(ERR.closingOfElementWithOpenChildElements);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
p.openElements.popUntilTagNamePopped($.TEMPLATE);
|
|
1203
|
+
p.activeFormattingElements.clearToLastMarker();
|
|
1204
|
+
p._popTmplInsertionMode();
|
|
1205
|
+
p._resetInsertionMode();
|
|
1206
|
+
} else {
|
|
1207
|
+
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
1208
|
+
}
|
|
1209
|
+
} else {
|
|
1210
|
+
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
1152
1211
|
}
|
|
1153
1212
|
}
|
|
1154
1213
|
|
|
@@ -1158,45 +1217,100 @@ function tokenInHead(p, token) {
|
|
|
1158
1217
|
p._processToken(token);
|
|
1159
1218
|
}
|
|
1160
1219
|
|
|
1220
|
+
// The "in head no script" insertion mode
|
|
1221
|
+
//------------------------------------------------------------------
|
|
1222
|
+
function startTagInHeadNoScript(p, token) {
|
|
1223
|
+
const tn = token.tagName;
|
|
1224
|
+
|
|
1225
|
+
if (tn === $.HTML) {
|
|
1226
|
+
startTagInBody(p, token);
|
|
1227
|
+
} else if (
|
|
1228
|
+
tn === $.BASEFONT ||
|
|
1229
|
+
tn === $.BGSOUND ||
|
|
1230
|
+
tn === $.HEAD ||
|
|
1231
|
+
tn === $.LINK ||
|
|
1232
|
+
tn === $.META ||
|
|
1233
|
+
tn === $.NOFRAMES ||
|
|
1234
|
+
tn === $.STYLE
|
|
1235
|
+
) {
|
|
1236
|
+
startTagInHead(p, token);
|
|
1237
|
+
} else if (tn === $.NOSCRIPT) {
|
|
1238
|
+
p._err(ERR.nestedNoscriptInHead);
|
|
1239
|
+
} else {
|
|
1240
|
+
tokenInHeadNoScript(p, token);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
function endTagInHeadNoScript(p, token) {
|
|
1245
|
+
const tn = token.tagName;
|
|
1161
1246
|
|
|
1162
|
-
|
|
1247
|
+
if (tn === $.NOSCRIPT) {
|
|
1248
|
+
p.openElements.pop();
|
|
1249
|
+
p.insertionMode = IN_HEAD_MODE;
|
|
1250
|
+
} else if (tn === $.BR) {
|
|
1251
|
+
tokenInHeadNoScript(p, token);
|
|
1252
|
+
} else {
|
|
1253
|
+
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
function tokenInHeadNoScript(p, token) {
|
|
1258
|
+
const errCode =
|
|
1259
|
+
token.type === Tokenizer.EOF_TOKEN ? ERR.openElementsLeftAfterEof : ERR.disallowedContentInNoscriptInHead;
|
|
1260
|
+
|
|
1261
|
+
p._err(errCode);
|
|
1262
|
+
p.openElements.pop();
|
|
1263
|
+
p.insertionMode = IN_HEAD_MODE;
|
|
1264
|
+
p._processToken(token);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// The "after head" insertion mode
|
|
1163
1268
|
//------------------------------------------------------------------
|
|
1164
1269
|
function startTagAfterHead(p, token) {
|
|
1165
|
-
|
|
1270
|
+
const tn = token.tagName;
|
|
1166
1271
|
|
|
1167
|
-
if (tn === $.HTML)
|
|
1272
|
+
if (tn === $.HTML) {
|
|
1168
1273
|
startTagInBody(p, token);
|
|
1169
|
-
|
|
1170
|
-
else if (tn === $.BODY) {
|
|
1274
|
+
} else if (tn === $.BODY) {
|
|
1171
1275
|
p._insertElement(token, NS.HTML);
|
|
1172
1276
|
p.framesetOk = false;
|
|
1173
1277
|
p.insertionMode = IN_BODY_MODE;
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
else if (tn === $.FRAMESET) {
|
|
1278
|
+
} else if (tn === $.FRAMESET) {
|
|
1177
1279
|
p._insertElement(token, NS.HTML);
|
|
1178
1280
|
p.insertionMode = IN_FRAMESET_MODE;
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1281
|
+
} else if (
|
|
1282
|
+
tn === $.BASE ||
|
|
1283
|
+
tn === $.BASEFONT ||
|
|
1284
|
+
tn === $.BGSOUND ||
|
|
1285
|
+
tn === $.LINK ||
|
|
1286
|
+
tn === $.META ||
|
|
1287
|
+
tn === $.NOFRAMES ||
|
|
1288
|
+
tn === $.SCRIPT ||
|
|
1289
|
+
tn === $.STYLE ||
|
|
1290
|
+
tn === $.TEMPLATE ||
|
|
1291
|
+
tn === $.TITLE
|
|
1292
|
+
) {
|
|
1293
|
+
p._err(ERR.abandonedHeadElementChild);
|
|
1183
1294
|
p.openElements.push(p.headElement);
|
|
1184
1295
|
startTagInHead(p, token);
|
|
1185
1296
|
p.openElements.remove(p.headElement);
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
else
|
|
1297
|
+
} else if (tn === $.HEAD) {
|
|
1298
|
+
p._err(ERR.misplacedStartTagForHeadElement);
|
|
1299
|
+
} else {
|
|
1189
1300
|
tokenAfterHead(p, token);
|
|
1301
|
+
}
|
|
1190
1302
|
}
|
|
1191
1303
|
|
|
1192
1304
|
function endTagAfterHead(p, token) {
|
|
1193
|
-
|
|
1305
|
+
const tn = token.tagName;
|
|
1194
1306
|
|
|
1195
|
-
if (tn === $.BODY || tn === $.HTML || tn === $.BR)
|
|
1307
|
+
if (tn === $.BODY || tn === $.HTML || tn === $.BR) {
|
|
1196
1308
|
tokenAfterHead(p, token);
|
|
1197
|
-
|
|
1198
|
-
else if (tn === $.TEMPLATE)
|
|
1309
|
+
} else if (tn === $.TEMPLATE) {
|
|
1199
1310
|
endTagInHead(p, token);
|
|
1311
|
+
} else {
|
|
1312
|
+
p._err(ERR.endTagWithoutMatchingOpenElement);
|
|
1313
|
+
}
|
|
1200
1314
|
}
|
|
1201
1315
|
|
|
1202
1316
|
function tokenAfterHead(p, token) {
|
|
@@ -1205,8 +1319,7 @@ function tokenAfterHead(p, token) {
|
|
|
1205
1319
|
p._processToken(token);
|
|
1206
1320
|
}
|
|
1207
1321
|
|
|
1208
|
-
|
|
1209
|
-
//12.2.5.4.7 The "in body" insertion mode
|
|
1322
|
+
// The "in body" insertion mode
|
|
1210
1323
|
//------------------------------------------------------------------
|
|
1211
1324
|
function whitespaceCharacterInBody(p, token) {
|
|
1212
1325
|
p._reconstructActiveFormattingElements();
|
|
@@ -1220,12 +1333,13 @@ function characterInBody(p, token) {
|
|
|
1220
1333
|
}
|
|
1221
1334
|
|
|
1222
1335
|
function htmlStartTagInBody(p, token) {
|
|
1223
|
-
if (p.openElements.tmplCount === 0)
|
|
1336
|
+
if (p.openElements.tmplCount === 0) {
|
|
1224
1337
|
p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
|
|
1338
|
+
}
|
|
1225
1339
|
}
|
|
1226
1340
|
|
|
1227
1341
|
function bodyStartTagInBody(p, token) {
|
|
1228
|
-
|
|
1342
|
+
const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
|
|
1229
1343
|
|
|
1230
1344
|
if (bodyElement && p.openElements.tmplCount === 0) {
|
|
1231
1345
|
p.framesetOk = false;
|
|
@@ -1234,7 +1348,7 @@ function bodyStartTagInBody(p, token) {
|
|
|
1234
1348
|
}
|
|
1235
1349
|
|
|
1236
1350
|
function framesetStartTagInBody(p, token) {
|
|
1237
|
-
|
|
1351
|
+
const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
|
|
1238
1352
|
|
|
1239
1353
|
if (p.framesetOk && bodyElement) {
|
|
1240
1354
|
p.treeAdapter.detachNode(bodyElement);
|
|
@@ -1245,27 +1359,31 @@ function framesetStartTagInBody(p, token) {
|
|
|
1245
1359
|
}
|
|
1246
1360
|
|
|
1247
1361
|
function addressStartTagInBody(p, token) {
|
|
1248
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1362
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1249
1363
|
p._closePElement();
|
|
1364
|
+
}
|
|
1250
1365
|
|
|
1251
1366
|
p._insertElement(token, NS.HTML);
|
|
1252
1367
|
}
|
|
1253
1368
|
|
|
1254
1369
|
function numberedHeaderStartTagInBody(p, token) {
|
|
1255
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1370
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1256
1371
|
p._closePElement();
|
|
1372
|
+
}
|
|
1257
1373
|
|
|
1258
|
-
|
|
1374
|
+
const tn = p.openElements.currentTagName;
|
|
1259
1375
|
|
|
1260
|
-
if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
|
|
1376
|
+
if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
1261
1377
|
p.openElements.pop();
|
|
1378
|
+
}
|
|
1262
1379
|
|
|
1263
1380
|
p._insertElement(token, NS.HTML);
|
|
1264
1381
|
}
|
|
1265
1382
|
|
|
1266
1383
|
function preStartTagInBody(p, token) {
|
|
1267
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1384
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1268
1385
|
p._closePElement();
|
|
1386
|
+
}
|
|
1269
1387
|
|
|
1270
1388
|
p._insertElement(token, NS.HTML);
|
|
1271
1389
|
//NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
|
|
@@ -1275,34 +1393,36 @@ function preStartTagInBody(p, token) {
|
|
|
1275
1393
|
}
|
|
1276
1394
|
|
|
1277
1395
|
function formStartTagInBody(p, token) {
|
|
1278
|
-
|
|
1396
|
+
const inTemplate = p.openElements.tmplCount > 0;
|
|
1279
1397
|
|
|
1280
1398
|
if (!p.formElement || inTemplate) {
|
|
1281
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1399
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1282
1400
|
p._closePElement();
|
|
1401
|
+
}
|
|
1283
1402
|
|
|
1284
1403
|
p._insertElement(token, NS.HTML);
|
|
1285
1404
|
|
|
1286
|
-
if (!inTemplate)
|
|
1405
|
+
if (!inTemplate) {
|
|
1287
1406
|
p.formElement = p.openElements.current;
|
|
1407
|
+
}
|
|
1288
1408
|
}
|
|
1289
1409
|
}
|
|
1290
1410
|
|
|
1291
1411
|
function listItemStartTagInBody(p, token) {
|
|
1292
1412
|
p.framesetOk = false;
|
|
1293
1413
|
|
|
1294
|
-
|
|
1414
|
+
const tn = token.tagName;
|
|
1295
1415
|
|
|
1296
|
-
for (
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1416
|
+
for (let i = p.openElements.stackTop; i >= 0; i--) {
|
|
1417
|
+
const element = p.openElements.items[i];
|
|
1418
|
+
const elementTn = p.treeAdapter.getTagName(element);
|
|
1419
|
+
let closeTn = null;
|
|
1300
1420
|
|
|
1301
|
-
if (tn === $.LI && elementTn === $.LI)
|
|
1421
|
+
if (tn === $.LI && elementTn === $.LI) {
|
|
1302
1422
|
closeTn = $.LI;
|
|
1303
|
-
|
|
1304
|
-
else if ((tn === $.DD || tn === $.DT) && (elementTn === $.DD || elementTn === $.DT))
|
|
1423
|
+
} else if ((tn === $.DD || tn === $.DT) && (elementTn === $.DD || elementTn === $.DT)) {
|
|
1305
1424
|
closeTn = elementTn;
|
|
1425
|
+
}
|
|
1306
1426
|
|
|
1307
1427
|
if (closeTn) {
|
|
1308
1428
|
p.openElements.generateImpliedEndTagsWithExclusion(closeTn);
|
|
@@ -1310,19 +1430,22 @@ function listItemStartTagInBody(p, token) {
|
|
|
1310
1430
|
break;
|
|
1311
1431
|
}
|
|
1312
1432
|
|
|
1313
|
-
if (elementTn !== $.ADDRESS && elementTn !== $.DIV && elementTn !== $.P && p._isSpecialElement(element))
|
|
1433
|
+
if (elementTn !== $.ADDRESS && elementTn !== $.DIV && elementTn !== $.P && p._isSpecialElement(element)) {
|
|
1314
1434
|
break;
|
|
1435
|
+
}
|
|
1315
1436
|
}
|
|
1316
1437
|
|
|
1317
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1438
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1318
1439
|
p._closePElement();
|
|
1440
|
+
}
|
|
1319
1441
|
|
|
1320
1442
|
p._insertElement(token, NS.HTML);
|
|
1321
1443
|
}
|
|
1322
1444
|
|
|
1323
1445
|
function plaintextStartTagInBody(p, token) {
|
|
1324
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1446
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1325
1447
|
p._closePElement();
|
|
1448
|
+
}
|
|
1326
1449
|
|
|
1327
1450
|
p._insertElement(token, NS.HTML);
|
|
1328
1451
|
p.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
|
|
@@ -1340,7 +1463,7 @@ function buttonStartTagInBody(p, token) {
|
|
|
1340
1463
|
}
|
|
1341
1464
|
|
|
1342
1465
|
function aStartTagInBody(p, token) {
|
|
1343
|
-
|
|
1466
|
+
const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName($.A);
|
|
1344
1467
|
|
|
1345
1468
|
if (activeElementEntry) {
|
|
1346
1469
|
callAdoptionAgency(p, token);
|
|
@@ -1379,8 +1502,12 @@ function appletStartTagInBody(p, token) {
|
|
|
1379
1502
|
}
|
|
1380
1503
|
|
|
1381
1504
|
function tableStartTagInBody(p, token) {
|
|
1382
|
-
if (
|
|
1505
|
+
if (
|
|
1506
|
+
p.treeAdapter.getDocumentMode(p.document) !== HTML.DOCUMENT_MODE.QUIRKS &&
|
|
1507
|
+
p.openElements.hasInButtonScope($.P)
|
|
1508
|
+
) {
|
|
1383
1509
|
p._closePElement();
|
|
1510
|
+
}
|
|
1384
1511
|
|
|
1385
1512
|
p._insertElement(token, NS.HTML);
|
|
1386
1513
|
p.framesetOk = false;
|
|
@@ -1391,32 +1518,35 @@ function areaStartTagInBody(p, token) {
|
|
|
1391
1518
|
p._reconstructActiveFormattingElements();
|
|
1392
1519
|
p._appendElement(token, NS.HTML);
|
|
1393
1520
|
p.framesetOk = false;
|
|
1521
|
+
token.ackSelfClosing = true;
|
|
1394
1522
|
}
|
|
1395
1523
|
|
|
1396
1524
|
function inputStartTagInBody(p, token) {
|
|
1397
1525
|
p._reconstructActiveFormattingElements();
|
|
1398
1526
|
p._appendElement(token, NS.HTML);
|
|
1399
1527
|
|
|
1400
|
-
|
|
1528
|
+
const inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
|
|
1401
1529
|
|
|
1402
|
-
if (!inputType || inputType.toLowerCase() !== HIDDEN_INPUT_TYPE)
|
|
1530
|
+
if (!inputType || inputType.toLowerCase() !== HIDDEN_INPUT_TYPE) {
|
|
1403
1531
|
p.framesetOk = false;
|
|
1532
|
+
}
|
|
1404
1533
|
|
|
1534
|
+
token.ackSelfClosing = true;
|
|
1405
1535
|
}
|
|
1406
1536
|
|
|
1407
1537
|
function paramStartTagInBody(p, token) {
|
|
1408
1538
|
p._appendElement(token, NS.HTML);
|
|
1539
|
+
token.ackSelfClosing = true;
|
|
1409
1540
|
}
|
|
1410
1541
|
|
|
1411
1542
|
function hrStartTagInBody(p, token) {
|
|
1412
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1543
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1413
1544
|
p._closePElement();
|
|
1414
|
-
|
|
1415
|
-
if (p.openElements.currentTagName === $.MENUITEM)
|
|
1416
|
-
p.openElements.pop();
|
|
1545
|
+
}
|
|
1417
1546
|
|
|
1418
1547
|
p._appendElement(token, NS.HTML);
|
|
1419
1548
|
p.framesetOk = false;
|
|
1549
|
+
p.ackSelfClosing = true;
|
|
1420
1550
|
}
|
|
1421
1551
|
|
|
1422
1552
|
function imageStartTagInBody(p, token) {
|
|
@@ -1436,8 +1566,9 @@ function textareaStartTagInBody(p, token) {
|
|
|
1436
1566
|
}
|
|
1437
1567
|
|
|
1438
1568
|
function xmpStartTagInBody(p, token) {
|
|
1439
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1569
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1440
1570
|
p._closePElement();
|
|
1571
|
+
}
|
|
1441
1572
|
|
|
1442
1573
|
p._reconstructActiveFormattingElements();
|
|
1443
1574
|
p.framesetOk = false;
|
|
@@ -1460,56 +1591,48 @@ function selectStartTagInBody(p, token) {
|
|
|
1460
1591
|
p._insertElement(token, NS.HTML);
|
|
1461
1592
|
p.framesetOk = false;
|
|
1462
1593
|
|
|
1463
|
-
if (
|
|
1594
|
+
if (
|
|
1595
|
+
p.insertionMode === IN_TABLE_MODE ||
|
|
1464
1596
|
p.insertionMode === IN_CAPTION_MODE ||
|
|
1465
1597
|
p.insertionMode === IN_TABLE_BODY_MODE ||
|
|
1466
1598
|
p.insertionMode === IN_ROW_MODE ||
|
|
1467
|
-
p.insertionMode === IN_CELL_MODE
|
|
1468
|
-
|
|
1599
|
+
p.insertionMode === IN_CELL_MODE
|
|
1600
|
+
) {
|
|
1469
1601
|
p.insertionMode = IN_SELECT_IN_TABLE_MODE;
|
|
1470
|
-
|
|
1471
|
-
else
|
|
1602
|
+
} else {
|
|
1472
1603
|
p.insertionMode = IN_SELECT_MODE;
|
|
1604
|
+
}
|
|
1473
1605
|
}
|
|
1474
1606
|
|
|
1475
1607
|
function optgroupStartTagInBody(p, token) {
|
|
1476
|
-
if (p.openElements.currentTagName === $.OPTION)
|
|
1608
|
+
if (p.openElements.currentTagName === $.OPTION) {
|
|
1477
1609
|
p.openElements.pop();
|
|
1610
|
+
}
|
|
1478
1611
|
|
|
1479
1612
|
p._reconstructActiveFormattingElements();
|
|
1480
1613
|
p._insertElement(token, NS.HTML);
|
|
1481
1614
|
}
|
|
1482
1615
|
|
|
1483
1616
|
function rbStartTagInBody(p, token) {
|
|
1484
|
-
if (p.openElements.hasInScope($.RUBY))
|
|
1617
|
+
if (p.openElements.hasInScope($.RUBY)) {
|
|
1485
1618
|
p.openElements.generateImpliedEndTags();
|
|
1619
|
+
}
|
|
1486
1620
|
|
|
1487
1621
|
p._insertElement(token, NS.HTML);
|
|
1488
1622
|
}
|
|
1489
1623
|
|
|
1490
1624
|
function rtStartTagInBody(p, token) {
|
|
1491
|
-
if (p.openElements.hasInScope($.RUBY))
|
|
1625
|
+
if (p.openElements.hasInScope($.RUBY)) {
|
|
1492
1626
|
p.openElements.generateImpliedEndTagsWithExclusion($.RTC);
|
|
1493
|
-
|
|
1494
|
-
p._insertElement(token, NS.HTML);
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
function menuitemStartTagInBody(p, token) {
|
|
1498
|
-
if (p.openElements.currentTagName === $.MENUITEM)
|
|
1499
|
-
p.openElements.pop();
|
|
1500
|
-
|
|
1501
|
-
// TODO needs clarification, see https://github.com/whatwg/html/pull/907/files#r73505877
|
|
1502
|
-
p._reconstructActiveFormattingElements();
|
|
1627
|
+
}
|
|
1503
1628
|
|
|
1504
1629
|
p._insertElement(token, NS.HTML);
|
|
1505
1630
|
}
|
|
1506
1631
|
|
|
1507
1632
|
function menuStartTagInBody(p, token) {
|
|
1508
|
-
if (p.openElements.hasInButtonScope($.P))
|
|
1633
|
+
if (p.openElements.hasInButtonScope($.P)) {
|
|
1509
1634
|
p._closePElement();
|
|
1510
|
-
|
|
1511
|
-
if (p.openElements.currentTagName === $.MENUITEM)
|
|
1512
|
-
p.openElements.pop();
|
|
1635
|
+
}
|
|
1513
1636
|
|
|
1514
1637
|
p._insertElement(token, NS.HTML);
|
|
1515
1638
|
}
|
|
@@ -1520,10 +1643,13 @@ function mathStartTagInBody(p, token) {
|
|
|
1520
1643
|
foreignContent.adjustTokenMathMLAttrs(token);
|
|
1521
1644
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
1522
1645
|
|
|
1523
|
-
if (token.selfClosing)
|
|
1646
|
+
if (token.selfClosing) {
|
|
1524
1647
|
p._appendElement(token, NS.MATHML);
|
|
1525
|
-
else
|
|
1648
|
+
} else {
|
|
1526
1649
|
p._insertElement(token, NS.MATHML);
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
token.ackSelfClosing = true;
|
|
1527
1653
|
}
|
|
1528
1654
|
|
|
1529
1655
|
function svgStartTagInBody(p, token) {
|
|
@@ -1532,10 +1658,13 @@ function svgStartTagInBody(p, token) {
|
|
|
1532
1658
|
foreignContent.adjustTokenSVGAttrs(token);
|
|
1533
1659
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
1534
1660
|
|
|
1535
|
-
if (token.selfClosing)
|
|
1661
|
+
if (token.selfClosing) {
|
|
1536
1662
|
p._appendElement(token, NS.SVG);
|
|
1537
|
-
else
|
|
1663
|
+
} else {
|
|
1538
1664
|
p._insertElement(token, NS.SVG);
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
token.ackSelfClosing = true;
|
|
1539
1668
|
}
|
|
1540
1669
|
|
|
1541
1670
|
function genericStartTagInBody(p, token) {
|
|
@@ -1546,249 +1675,213 @@ function genericStartTagInBody(p, token) {
|
|
|
1546
1675
|
//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
|
|
1547
1676
|
//It's faster than using dictionary.
|
|
1548
1677
|
function startTagInBody(p, token) {
|
|
1549
|
-
|
|
1678
|
+
const tn = token.tagName;
|
|
1550
1679
|
|
|
1551
1680
|
switch (tn.length) {
|
|
1552
1681
|
case 1:
|
|
1553
|
-
if (tn === $.I || tn === $.S || tn === $.B || tn === $.U)
|
|
1682
|
+
if (tn === $.I || tn === $.S || tn === $.B || tn === $.U) {
|
|
1554
1683
|
bStartTagInBody(p, token);
|
|
1555
|
-
|
|
1556
|
-
else if (tn === $.P)
|
|
1684
|
+
} else if (tn === $.P) {
|
|
1557
1685
|
addressStartTagInBody(p, token);
|
|
1558
|
-
|
|
1559
|
-
else if (tn === $.A)
|
|
1686
|
+
} else if (tn === $.A) {
|
|
1560
1687
|
aStartTagInBody(p, token);
|
|
1561
|
-
|
|
1562
|
-
else
|
|
1688
|
+
} else {
|
|
1563
1689
|
genericStartTagInBody(p, token);
|
|
1690
|
+
}
|
|
1564
1691
|
|
|
1565
1692
|
break;
|
|
1566
1693
|
|
|
1567
1694
|
case 2:
|
|
1568
|
-
if (tn === $.DL || tn === $.OL || tn === $.UL)
|
|
1695
|
+
if (tn === $.DL || tn === $.OL || tn === $.UL) {
|
|
1569
1696
|
addressStartTagInBody(p, token);
|
|
1570
|
-
|
|
1571
|
-
else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
|
|
1697
|
+
} else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
1572
1698
|
numberedHeaderStartTagInBody(p, token);
|
|
1573
|
-
|
|
1574
|
-
else if (tn === $.LI || tn === $.DD || tn === $.DT)
|
|
1699
|
+
} else if (tn === $.LI || tn === $.DD || tn === $.DT) {
|
|
1575
1700
|
listItemStartTagInBody(p, token);
|
|
1576
|
-
|
|
1577
|
-
else if (tn === $.EM || tn === $.TT)
|
|
1701
|
+
} else if (tn === $.EM || tn === $.TT) {
|
|
1578
1702
|
bStartTagInBody(p, token);
|
|
1579
|
-
|
|
1580
|
-
else if (tn === $.BR)
|
|
1703
|
+
} else if (tn === $.BR) {
|
|
1581
1704
|
areaStartTagInBody(p, token);
|
|
1582
|
-
|
|
1583
|
-
else if (tn === $.HR)
|
|
1705
|
+
} else if (tn === $.HR) {
|
|
1584
1706
|
hrStartTagInBody(p, token);
|
|
1585
|
-
|
|
1586
|
-
else if (tn === $.RB)
|
|
1707
|
+
} else if (tn === $.RB) {
|
|
1587
1708
|
rbStartTagInBody(p, token);
|
|
1588
|
-
|
|
1589
|
-
else if (tn === $.RT || tn === $.RP)
|
|
1709
|
+
} else if (tn === $.RT || tn === $.RP) {
|
|
1590
1710
|
rtStartTagInBody(p, token);
|
|
1591
|
-
|
|
1592
|
-
else if (tn !== $.TH && tn !== $.TD && tn !== $.TR)
|
|
1711
|
+
} else if (tn !== $.TH && tn !== $.TD && tn !== $.TR) {
|
|
1593
1712
|
genericStartTagInBody(p, token);
|
|
1713
|
+
}
|
|
1594
1714
|
|
|
1595
1715
|
break;
|
|
1596
1716
|
|
|
1597
1717
|
case 3:
|
|
1598
|
-
if (tn === $.DIV || tn === $.DIR || tn === $.NAV)
|
|
1718
|
+
if (tn === $.DIV || tn === $.DIR || tn === $.NAV) {
|
|
1599
1719
|
addressStartTagInBody(p, token);
|
|
1600
|
-
|
|
1601
|
-
else if (tn === $.PRE)
|
|
1720
|
+
} else if (tn === $.PRE) {
|
|
1602
1721
|
preStartTagInBody(p, token);
|
|
1603
|
-
|
|
1604
|
-
else if (tn === $.BIG)
|
|
1722
|
+
} else if (tn === $.BIG) {
|
|
1605
1723
|
bStartTagInBody(p, token);
|
|
1606
|
-
|
|
1607
|
-
else if (tn === $.IMG || tn === $.WBR)
|
|
1724
|
+
} else if (tn === $.IMG || tn === $.WBR) {
|
|
1608
1725
|
areaStartTagInBody(p, token);
|
|
1609
|
-
|
|
1610
|
-
else if (tn === $.XMP)
|
|
1726
|
+
} else if (tn === $.XMP) {
|
|
1611
1727
|
xmpStartTagInBody(p, token);
|
|
1612
|
-
|
|
1613
|
-
else if (tn === $.SVG)
|
|
1728
|
+
} else if (tn === $.SVG) {
|
|
1614
1729
|
svgStartTagInBody(p, token);
|
|
1615
|
-
|
|
1616
|
-
else if (tn === $.RTC)
|
|
1730
|
+
} else if (tn === $.RTC) {
|
|
1617
1731
|
rbStartTagInBody(p, token);
|
|
1618
|
-
|
|
1619
|
-
else if (tn !== $.COL)
|
|
1732
|
+
} else if (tn !== $.COL) {
|
|
1620
1733
|
genericStartTagInBody(p, token);
|
|
1734
|
+
}
|
|
1621
1735
|
|
|
1622
1736
|
break;
|
|
1623
1737
|
|
|
1624
1738
|
case 4:
|
|
1625
|
-
if (tn === $.HTML)
|
|
1739
|
+
if (tn === $.HTML) {
|
|
1626
1740
|
htmlStartTagInBody(p, token);
|
|
1627
|
-
|
|
1628
|
-
else if (tn === $.BASE || tn === $.LINK || tn === $.META)
|
|
1741
|
+
} else if (tn === $.BASE || tn === $.LINK || tn === $.META) {
|
|
1629
1742
|
startTagInHead(p, token);
|
|
1630
|
-
|
|
1631
|
-
else if (tn === $.BODY)
|
|
1743
|
+
} else if (tn === $.BODY) {
|
|
1632
1744
|
bodyStartTagInBody(p, token);
|
|
1633
|
-
|
|
1634
|
-
else if (tn === $.MAIN)
|
|
1745
|
+
} else if (tn === $.MAIN || tn === $.MENU) {
|
|
1635
1746
|
addressStartTagInBody(p, token);
|
|
1636
|
-
|
|
1637
|
-
else if (tn === $.FORM)
|
|
1747
|
+
} else if (tn === $.FORM) {
|
|
1638
1748
|
formStartTagInBody(p, token);
|
|
1639
|
-
|
|
1640
|
-
else if (tn === $.CODE || tn === $.FONT)
|
|
1749
|
+
} else if (tn === $.CODE || tn === $.FONT) {
|
|
1641
1750
|
bStartTagInBody(p, token);
|
|
1642
|
-
|
|
1643
|
-
else if (tn === $.NOBR)
|
|
1751
|
+
} else if (tn === $.NOBR) {
|
|
1644
1752
|
nobrStartTagInBody(p, token);
|
|
1645
|
-
|
|
1646
|
-
else if (tn === $.AREA)
|
|
1753
|
+
} else if (tn === $.AREA) {
|
|
1647
1754
|
areaStartTagInBody(p, token);
|
|
1648
|
-
|
|
1649
|
-
else if (tn === $.MATH)
|
|
1755
|
+
} else if (tn === $.MATH) {
|
|
1650
1756
|
mathStartTagInBody(p, token);
|
|
1651
|
-
|
|
1652
|
-
else if (tn === $.MENU)
|
|
1757
|
+
} else if (tn === $.MENU) {
|
|
1653
1758
|
menuStartTagInBody(p, token);
|
|
1654
|
-
|
|
1655
|
-
else if (tn !== $.HEAD)
|
|
1759
|
+
} else if (tn !== $.HEAD) {
|
|
1656
1760
|
genericStartTagInBody(p, token);
|
|
1761
|
+
}
|
|
1657
1762
|
|
|
1658
1763
|
break;
|
|
1659
1764
|
|
|
1660
1765
|
case 5:
|
|
1661
|
-
if (tn === $.STYLE || tn === $.TITLE)
|
|
1766
|
+
if (tn === $.STYLE || tn === $.TITLE) {
|
|
1662
1767
|
startTagInHead(p, token);
|
|
1663
|
-
|
|
1664
|
-
else if (tn === $.ASIDE)
|
|
1768
|
+
} else if (tn === $.ASIDE) {
|
|
1665
1769
|
addressStartTagInBody(p, token);
|
|
1666
|
-
|
|
1667
|
-
else if (tn === $.SMALL)
|
|
1770
|
+
} else if (tn === $.SMALL) {
|
|
1668
1771
|
bStartTagInBody(p, token);
|
|
1669
|
-
|
|
1670
|
-
else if (tn === $.TABLE)
|
|
1772
|
+
} else if (tn === $.TABLE) {
|
|
1671
1773
|
tableStartTagInBody(p, token);
|
|
1672
|
-
|
|
1673
|
-
else if (tn === $.EMBED)
|
|
1774
|
+
} else if (tn === $.EMBED) {
|
|
1674
1775
|
areaStartTagInBody(p, token);
|
|
1675
|
-
|
|
1676
|
-
else if (tn === $.INPUT)
|
|
1776
|
+
} else if (tn === $.INPUT) {
|
|
1677
1777
|
inputStartTagInBody(p, token);
|
|
1678
|
-
|
|
1679
|
-
else if (tn === $.PARAM || tn === $.TRACK)
|
|
1778
|
+
} else if (tn === $.PARAM || tn === $.TRACK) {
|
|
1680
1779
|
paramStartTagInBody(p, token);
|
|
1681
|
-
|
|
1682
|
-
else if (tn === $.IMAGE)
|
|
1780
|
+
} else if (tn === $.IMAGE) {
|
|
1683
1781
|
imageStartTagInBody(p, token);
|
|
1684
|
-
|
|
1685
|
-
else if (tn !== $.FRAME && tn !== $.TBODY && tn !== $.TFOOT && tn !== $.THEAD)
|
|
1782
|
+
} else if (tn !== $.FRAME && tn !== $.TBODY && tn !== $.TFOOT && tn !== $.THEAD) {
|
|
1686
1783
|
genericStartTagInBody(p, token);
|
|
1784
|
+
}
|
|
1687
1785
|
|
|
1688
1786
|
break;
|
|
1689
1787
|
|
|
1690
1788
|
case 6:
|
|
1691
|
-
if (tn === $.SCRIPT)
|
|
1789
|
+
if (tn === $.SCRIPT) {
|
|
1692
1790
|
startTagInHead(p, token);
|
|
1693
|
-
|
|
1694
|
-
|
|
1791
|
+
} else if (
|
|
1792
|
+
tn === $.CENTER ||
|
|
1793
|
+
tn === $.FIGURE ||
|
|
1794
|
+
tn === $.FOOTER ||
|
|
1795
|
+
tn === $.HEADER ||
|
|
1796
|
+
tn === $.HGROUP ||
|
|
1797
|
+
tn === $.DIALOG
|
|
1798
|
+
) {
|
|
1695
1799
|
addressStartTagInBody(p, token);
|
|
1696
|
-
|
|
1697
|
-
else if (tn === $.BUTTON)
|
|
1800
|
+
} else if (tn === $.BUTTON) {
|
|
1698
1801
|
buttonStartTagInBody(p, token);
|
|
1699
|
-
|
|
1700
|
-
else if (tn === $.STRIKE || tn === $.STRONG)
|
|
1802
|
+
} else if (tn === $.STRIKE || tn === $.STRONG) {
|
|
1701
1803
|
bStartTagInBody(p, token);
|
|
1702
|
-
|
|
1703
|
-
else if (tn === $.APPLET || tn === $.OBJECT)
|
|
1804
|
+
} else if (tn === $.APPLET || tn === $.OBJECT) {
|
|
1704
1805
|
appletStartTagInBody(p, token);
|
|
1705
|
-
|
|
1706
|
-
else if (tn === $.KEYGEN)
|
|
1806
|
+
} else if (tn === $.KEYGEN) {
|
|
1707
1807
|
areaStartTagInBody(p, token);
|
|
1708
|
-
|
|
1709
|
-
else if (tn === $.SOURCE)
|
|
1808
|
+
} else if (tn === $.SOURCE) {
|
|
1710
1809
|
paramStartTagInBody(p, token);
|
|
1711
|
-
|
|
1712
|
-
else if (tn === $.IFRAME)
|
|
1810
|
+
} else if (tn === $.IFRAME) {
|
|
1713
1811
|
iframeStartTagInBody(p, token);
|
|
1714
|
-
|
|
1715
|
-
else if (tn === $.SELECT)
|
|
1812
|
+
} else if (tn === $.SELECT) {
|
|
1716
1813
|
selectStartTagInBody(p, token);
|
|
1717
|
-
|
|
1718
|
-
else if (tn === $.OPTION)
|
|
1814
|
+
} else if (tn === $.OPTION) {
|
|
1719
1815
|
optgroupStartTagInBody(p, token);
|
|
1720
|
-
|
|
1721
|
-
else
|
|
1816
|
+
} else {
|
|
1722
1817
|
genericStartTagInBody(p, token);
|
|
1818
|
+
}
|
|
1723
1819
|
|
|
1724
1820
|
break;
|
|
1725
1821
|
|
|
1726
1822
|
case 7:
|
|
1727
|
-
if (tn === $.BGSOUND)
|
|
1823
|
+
if (tn === $.BGSOUND) {
|
|
1728
1824
|
startTagInHead(p, token);
|
|
1729
|
-
|
|
1730
|
-
|
|
1825
|
+
} else if (
|
|
1826
|
+
tn === $.DETAILS ||
|
|
1827
|
+
tn === $.ADDRESS ||
|
|
1828
|
+
tn === $.ARTICLE ||
|
|
1829
|
+
tn === $.SECTION ||
|
|
1830
|
+
tn === $.SUMMARY
|
|
1831
|
+
) {
|
|
1731
1832
|
addressStartTagInBody(p, token);
|
|
1732
|
-
|
|
1733
|
-
else if (tn === $.LISTING)
|
|
1833
|
+
} else if (tn === $.LISTING) {
|
|
1734
1834
|
preStartTagInBody(p, token);
|
|
1735
|
-
|
|
1736
|
-
else if (tn === $.MARQUEE)
|
|
1835
|
+
} else if (tn === $.MARQUEE) {
|
|
1737
1836
|
appletStartTagInBody(p, token);
|
|
1738
|
-
|
|
1739
|
-
else if (tn === $.NOEMBED)
|
|
1837
|
+
} else if (tn === $.NOEMBED) {
|
|
1740
1838
|
noembedStartTagInBody(p, token);
|
|
1741
|
-
|
|
1742
|
-
else if (tn !== $.CAPTION)
|
|
1839
|
+
} else if (tn !== $.CAPTION) {
|
|
1743
1840
|
genericStartTagInBody(p, token);
|
|
1841
|
+
}
|
|
1744
1842
|
|
|
1745
1843
|
break;
|
|
1746
1844
|
|
|
1747
1845
|
case 8:
|
|
1748
|
-
if (tn === $.BASEFONT)
|
|
1846
|
+
if (tn === $.BASEFONT) {
|
|
1749
1847
|
startTagInHead(p, token);
|
|
1750
|
-
|
|
1751
|
-
else if (tn === $.MENUITEM)
|
|
1752
|
-
menuitemStartTagInBody(p, token);
|
|
1753
|
-
|
|
1754
|
-
else if (tn === $.FRAMESET)
|
|
1848
|
+
} else if (tn === $.FRAMESET) {
|
|
1755
1849
|
framesetStartTagInBody(p, token);
|
|
1756
|
-
|
|
1757
|
-
else if (tn === $.FIELDSET)
|
|
1850
|
+
} else if (tn === $.FIELDSET) {
|
|
1758
1851
|
addressStartTagInBody(p, token);
|
|
1759
|
-
|
|
1760
|
-
else if (tn === $.TEXTAREA)
|
|
1852
|
+
} else if (tn === $.TEXTAREA) {
|
|
1761
1853
|
textareaStartTagInBody(p, token);
|
|
1762
|
-
|
|
1763
|
-
else if (tn === $.TEMPLATE)
|
|
1854
|
+
} else if (tn === $.TEMPLATE) {
|
|
1764
1855
|
startTagInHead(p, token);
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1856
|
+
} else if (tn === $.NOSCRIPT) {
|
|
1857
|
+
if (p.options.scriptingEnabled) {
|
|
1858
|
+
noembedStartTagInBody(p, token);
|
|
1859
|
+
} else {
|
|
1860
|
+
genericStartTagInBody(p, token);
|
|
1861
|
+
}
|
|
1862
|
+
} else if (tn === $.OPTGROUP) {
|
|
1770
1863
|
optgroupStartTagInBody(p, token);
|
|
1771
|
-
|
|
1772
|
-
else if (tn !== $.COLGROUP)
|
|
1864
|
+
} else if (tn !== $.COLGROUP) {
|
|
1773
1865
|
genericStartTagInBody(p, token);
|
|
1866
|
+
}
|
|
1774
1867
|
|
|
1775
1868
|
break;
|
|
1776
1869
|
|
|
1777
1870
|
case 9:
|
|
1778
|
-
if (tn === $.PLAINTEXT)
|
|
1871
|
+
if (tn === $.PLAINTEXT) {
|
|
1779
1872
|
plaintextStartTagInBody(p, token);
|
|
1780
|
-
|
|
1781
|
-
else
|
|
1873
|
+
} else {
|
|
1782
1874
|
genericStartTagInBody(p, token);
|
|
1875
|
+
}
|
|
1783
1876
|
|
|
1784
1877
|
break;
|
|
1785
1878
|
|
|
1786
1879
|
case 10:
|
|
1787
|
-
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION)
|
|
1880
|
+
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION) {
|
|
1788
1881
|
addressStartTagInBody(p, token);
|
|
1789
|
-
|
|
1790
|
-
else
|
|
1882
|
+
} else {
|
|
1791
1883
|
genericStartTagInBody(p, token);
|
|
1884
|
+
}
|
|
1792
1885
|
|
|
1793
1886
|
break;
|
|
1794
1887
|
|
|
@@ -1798,8 +1891,9 @@ function startTagInBody(p, token) {
|
|
|
1798
1891
|
}
|
|
1799
1892
|
|
|
1800
1893
|
function bodyEndTagInBody(p) {
|
|
1801
|
-
if (p.openElements.hasInScope($.BODY))
|
|
1894
|
+
if (p.openElements.hasInScope($.BODY)) {
|
|
1802
1895
|
p.insertionMode = AFTER_BODY_MODE;
|
|
1896
|
+
}
|
|
1803
1897
|
}
|
|
1804
1898
|
|
|
1805
1899
|
function htmlEndTagInBody(p, token) {
|
|
@@ -1810,7 +1904,7 @@ function htmlEndTagInBody(p, token) {
|
|
|
1810
1904
|
}
|
|
1811
1905
|
|
|
1812
1906
|
function addressEndTagInBody(p, token) {
|
|
1813
|
-
|
|
1907
|
+
const tn = token.tagName;
|
|
1814
1908
|
|
|
1815
1909
|
if (p.openElements.hasInScope(tn)) {
|
|
1816
1910
|
p.openElements.generateImpliedEndTags();
|
|
@@ -1819,26 +1913,28 @@ function addressEndTagInBody(p, token) {
|
|
|
1819
1913
|
}
|
|
1820
1914
|
|
|
1821
1915
|
function formEndTagInBody(p) {
|
|
1822
|
-
|
|
1823
|
-
|
|
1916
|
+
const inTemplate = p.openElements.tmplCount > 0;
|
|
1917
|
+
const formElement = p.formElement;
|
|
1824
1918
|
|
|
1825
|
-
if (!inTemplate)
|
|
1919
|
+
if (!inTemplate) {
|
|
1826
1920
|
p.formElement = null;
|
|
1921
|
+
}
|
|
1827
1922
|
|
|
1828
1923
|
if ((formElement || inTemplate) && p.openElements.hasInScope($.FORM)) {
|
|
1829
1924
|
p.openElements.generateImpliedEndTags();
|
|
1830
1925
|
|
|
1831
|
-
if (inTemplate)
|
|
1926
|
+
if (inTemplate) {
|
|
1832
1927
|
p.openElements.popUntilTagNamePopped($.FORM);
|
|
1833
|
-
|
|
1834
|
-
else
|
|
1928
|
+
} else {
|
|
1835
1929
|
p.openElements.remove(formElement);
|
|
1930
|
+
}
|
|
1836
1931
|
}
|
|
1837
1932
|
}
|
|
1838
1933
|
|
|
1839
1934
|
function pEndTagInBody(p) {
|
|
1840
|
-
if (!p.openElements.hasInButtonScope($.P))
|
|
1935
|
+
if (!p.openElements.hasInButtonScope($.P)) {
|
|
1841
1936
|
p._insertFakeElement($.P);
|
|
1937
|
+
}
|
|
1842
1938
|
|
|
1843
1939
|
p._closePElement();
|
|
1844
1940
|
}
|
|
@@ -1851,7 +1947,7 @@ function liEndTagInBody(p) {
|
|
|
1851
1947
|
}
|
|
1852
1948
|
|
|
1853
1949
|
function ddEndTagInBody(p, token) {
|
|
1854
|
-
|
|
1950
|
+
const tn = token.tagName;
|
|
1855
1951
|
|
|
1856
1952
|
if (p.openElements.hasInScope(tn)) {
|
|
1857
1953
|
p.openElements.generateImpliedEndTagsWithExclusion(tn);
|
|
@@ -1867,7 +1963,7 @@ function numberedHeaderEndTagInBody(p) {
|
|
|
1867
1963
|
}
|
|
1868
1964
|
|
|
1869
1965
|
function appletEndTagInBody(p, token) {
|
|
1870
|
-
|
|
1966
|
+
const tn = token.tagName;
|
|
1871
1967
|
|
|
1872
1968
|
if (p.openElements.hasInScope(tn)) {
|
|
1873
1969
|
p.openElements.generateImpliedEndTags();
|
|
@@ -1884,10 +1980,10 @@ function brEndTagInBody(p) {
|
|
|
1884
1980
|
}
|
|
1885
1981
|
|
|
1886
1982
|
function genericEndTagInBody(p, token) {
|
|
1887
|
-
|
|
1983
|
+
const tn = token.tagName;
|
|
1888
1984
|
|
|
1889
|
-
for (
|
|
1890
|
-
|
|
1985
|
+
for (let i = p.openElements.stackTop; i > 0; i--) {
|
|
1986
|
+
const element = p.openElements.items[i];
|
|
1891
1987
|
|
|
1892
1988
|
if (p.treeAdapter.getTagName(element) === tn) {
|
|
1893
1989
|
p.openElements.generateImpliedEndTagsWithExclusion(tn);
|
|
@@ -1895,181 +1991,180 @@ function genericEndTagInBody(p, token) {
|
|
|
1895
1991
|
break;
|
|
1896
1992
|
}
|
|
1897
1993
|
|
|
1898
|
-
if (p._isSpecialElement(element))
|
|
1994
|
+
if (p._isSpecialElement(element)) {
|
|
1899
1995
|
break;
|
|
1996
|
+
}
|
|
1900
1997
|
}
|
|
1901
1998
|
}
|
|
1902
1999
|
|
|
1903
2000
|
//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
|
|
1904
2001
|
//It's faster than using dictionary.
|
|
1905
2002
|
function endTagInBody(p, token) {
|
|
1906
|
-
|
|
2003
|
+
const tn = token.tagName;
|
|
1907
2004
|
|
|
1908
2005
|
switch (tn.length) {
|
|
1909
2006
|
case 1:
|
|
1910
|
-
if (tn === $.A || tn === $.B || tn === $.I || tn === $.S || tn === $.U)
|
|
2007
|
+
if (tn === $.A || tn === $.B || tn === $.I || tn === $.S || tn === $.U) {
|
|
1911
2008
|
callAdoptionAgency(p, token);
|
|
1912
|
-
|
|
1913
|
-
else if (tn === $.P)
|
|
2009
|
+
} else if (tn === $.P) {
|
|
1914
2010
|
pEndTagInBody(p, token);
|
|
1915
|
-
|
|
1916
|
-
else
|
|
2011
|
+
} else {
|
|
1917
2012
|
genericEndTagInBody(p, token);
|
|
2013
|
+
}
|
|
1918
2014
|
|
|
1919
2015
|
break;
|
|
1920
2016
|
|
|
1921
2017
|
case 2:
|
|
1922
|
-
if (tn === $.DL || tn === $.UL || tn === $.OL)
|
|
2018
|
+
if (tn === $.DL || tn === $.UL || tn === $.OL) {
|
|
1923
2019
|
addressEndTagInBody(p, token);
|
|
1924
|
-
|
|
1925
|
-
else if (tn === $.LI)
|
|
2020
|
+
} else if (tn === $.LI) {
|
|
1926
2021
|
liEndTagInBody(p, token);
|
|
1927
|
-
|
|
1928
|
-
else if (tn === $.DD || tn === $.DT)
|
|
2022
|
+
} else if (tn === $.DD || tn === $.DT) {
|
|
1929
2023
|
ddEndTagInBody(p, token);
|
|
1930
|
-
|
|
1931
|
-
else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
|
|
2024
|
+
} else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6) {
|
|
1932
2025
|
numberedHeaderEndTagInBody(p, token);
|
|
1933
|
-
|
|
1934
|
-
else if (tn === $.BR)
|
|
2026
|
+
} else if (tn === $.BR) {
|
|
1935
2027
|
brEndTagInBody(p, token);
|
|
1936
|
-
|
|
1937
|
-
else if (tn === $.EM || tn === $.TT)
|
|
2028
|
+
} else if (tn === $.EM || tn === $.TT) {
|
|
1938
2029
|
callAdoptionAgency(p, token);
|
|
1939
|
-
|
|
1940
|
-
else
|
|
2030
|
+
} else {
|
|
1941
2031
|
genericEndTagInBody(p, token);
|
|
2032
|
+
}
|
|
1942
2033
|
|
|
1943
2034
|
break;
|
|
1944
2035
|
|
|
1945
2036
|
case 3:
|
|
1946
|
-
if (tn === $.BIG)
|
|
2037
|
+
if (tn === $.BIG) {
|
|
1947
2038
|
callAdoptionAgency(p, token);
|
|
1948
|
-
|
|
1949
|
-
else if (tn === $.DIR || tn === $.DIV || tn === $.NAV)
|
|
2039
|
+
} else if (tn === $.DIR || tn === $.DIV || tn === $.NAV || tn === $.PRE) {
|
|
1950
2040
|
addressEndTagInBody(p, token);
|
|
1951
|
-
|
|
1952
|
-
else
|
|
2041
|
+
} else {
|
|
1953
2042
|
genericEndTagInBody(p, token);
|
|
2043
|
+
}
|
|
1954
2044
|
|
|
1955
2045
|
break;
|
|
1956
2046
|
|
|
1957
2047
|
case 4:
|
|
1958
|
-
if (tn === $.BODY)
|
|
2048
|
+
if (tn === $.BODY) {
|
|
1959
2049
|
bodyEndTagInBody(p, token);
|
|
1960
|
-
|
|
1961
|
-
else if (tn === $.HTML)
|
|
2050
|
+
} else if (tn === $.HTML) {
|
|
1962
2051
|
htmlEndTagInBody(p, token);
|
|
1963
|
-
|
|
1964
|
-
else if (tn === $.FORM)
|
|
2052
|
+
} else if (tn === $.FORM) {
|
|
1965
2053
|
formEndTagInBody(p, token);
|
|
1966
|
-
|
|
1967
|
-
else if (tn === $.CODE || tn === $.FONT || tn === $.NOBR)
|
|
2054
|
+
} else if (tn === $.CODE || tn === $.FONT || tn === $.NOBR) {
|
|
1968
2055
|
callAdoptionAgency(p, token);
|
|
1969
|
-
|
|
1970
|
-
else if (tn === $.MAIN || tn === $.MENU)
|
|
2056
|
+
} else if (tn === $.MAIN || tn === $.MENU) {
|
|
1971
2057
|
addressEndTagInBody(p, token);
|
|
1972
|
-
|
|
1973
|
-
else
|
|
2058
|
+
} else {
|
|
1974
2059
|
genericEndTagInBody(p, token);
|
|
2060
|
+
}
|
|
1975
2061
|
|
|
1976
2062
|
break;
|
|
1977
2063
|
|
|
1978
2064
|
case 5:
|
|
1979
|
-
if (tn === $.ASIDE)
|
|
2065
|
+
if (tn === $.ASIDE) {
|
|
1980
2066
|
addressEndTagInBody(p, token);
|
|
1981
|
-
|
|
1982
|
-
else if (tn === $.SMALL)
|
|
2067
|
+
} else if (tn === $.SMALL) {
|
|
1983
2068
|
callAdoptionAgency(p, token);
|
|
1984
|
-
|
|
1985
|
-
else
|
|
2069
|
+
} else {
|
|
1986
2070
|
genericEndTagInBody(p, token);
|
|
2071
|
+
}
|
|
1987
2072
|
|
|
1988
2073
|
break;
|
|
1989
2074
|
|
|
1990
2075
|
case 6:
|
|
1991
|
-
if (
|
|
2076
|
+
if (
|
|
2077
|
+
tn === $.CENTER ||
|
|
2078
|
+
tn === $.FIGURE ||
|
|
2079
|
+
tn === $.FOOTER ||
|
|
2080
|
+
tn === $.HEADER ||
|
|
2081
|
+
tn === $.HGROUP ||
|
|
2082
|
+
tn === $.DIALOG
|
|
2083
|
+
) {
|
|
1992
2084
|
addressEndTagInBody(p, token);
|
|
1993
|
-
|
|
1994
|
-
else if (tn === $.APPLET || tn === $.OBJECT)
|
|
2085
|
+
} else if (tn === $.APPLET || tn === $.OBJECT) {
|
|
1995
2086
|
appletEndTagInBody(p, token);
|
|
1996
|
-
|
|
1997
|
-
else if (tn === $.STRIKE || tn === $.STRONG)
|
|
2087
|
+
} else if (tn === $.STRIKE || tn === $.STRONG) {
|
|
1998
2088
|
callAdoptionAgency(p, token);
|
|
1999
|
-
|
|
2000
|
-
else
|
|
2089
|
+
} else {
|
|
2001
2090
|
genericEndTagInBody(p, token);
|
|
2091
|
+
}
|
|
2002
2092
|
|
|
2003
2093
|
break;
|
|
2004
2094
|
|
|
2005
2095
|
case 7:
|
|
2006
|
-
if (
|
|
2096
|
+
if (
|
|
2097
|
+
tn === $.ADDRESS ||
|
|
2098
|
+
tn === $.ARTICLE ||
|
|
2099
|
+
tn === $.DETAILS ||
|
|
2100
|
+
tn === $.SECTION ||
|
|
2101
|
+
tn === $.SUMMARY ||
|
|
2102
|
+
tn === $.LISTING
|
|
2103
|
+
) {
|
|
2007
2104
|
addressEndTagInBody(p, token);
|
|
2008
|
-
|
|
2009
|
-
else if (tn === $.MARQUEE)
|
|
2105
|
+
} else if (tn === $.MARQUEE) {
|
|
2010
2106
|
appletEndTagInBody(p, token);
|
|
2011
|
-
|
|
2012
|
-
else
|
|
2107
|
+
} else {
|
|
2013
2108
|
genericEndTagInBody(p, token);
|
|
2109
|
+
}
|
|
2014
2110
|
|
|
2015
2111
|
break;
|
|
2016
2112
|
|
|
2017
2113
|
case 8:
|
|
2018
|
-
if (tn === $.FIELDSET)
|
|
2114
|
+
if (tn === $.FIELDSET) {
|
|
2019
2115
|
addressEndTagInBody(p, token);
|
|
2020
|
-
|
|
2021
|
-
else if (tn === $.TEMPLATE)
|
|
2116
|
+
} else if (tn === $.TEMPLATE) {
|
|
2022
2117
|
endTagInHead(p, token);
|
|
2023
|
-
|
|
2024
|
-
else
|
|
2118
|
+
} else {
|
|
2025
2119
|
genericEndTagInBody(p, token);
|
|
2120
|
+
}
|
|
2026
2121
|
|
|
2027
2122
|
break;
|
|
2028
2123
|
|
|
2029
2124
|
case 10:
|
|
2030
|
-
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION)
|
|
2125
|
+
if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION) {
|
|
2031
2126
|
addressEndTagInBody(p, token);
|
|
2032
|
-
|
|
2033
|
-
else
|
|
2127
|
+
} else {
|
|
2034
2128
|
genericEndTagInBody(p, token);
|
|
2129
|
+
}
|
|
2035
2130
|
|
|
2036
2131
|
break;
|
|
2037
2132
|
|
|
2038
|
-
default
|
|
2133
|
+
default:
|
|
2039
2134
|
genericEndTagInBody(p, token);
|
|
2040
2135
|
}
|
|
2041
2136
|
}
|
|
2042
2137
|
|
|
2043
2138
|
function eofInBody(p, token) {
|
|
2044
|
-
if (p.tmplInsertionModeStackTop > -1)
|
|
2139
|
+
if (p.tmplInsertionModeStackTop > -1) {
|
|
2045
2140
|
eofInTemplate(p, token);
|
|
2046
|
-
|
|
2047
|
-
else
|
|
2141
|
+
} else {
|
|
2048
2142
|
p.stopped = true;
|
|
2143
|
+
}
|
|
2049
2144
|
}
|
|
2050
2145
|
|
|
2051
|
-
//
|
|
2146
|
+
// The "text" insertion mode
|
|
2052
2147
|
//------------------------------------------------------------------
|
|
2053
2148
|
function endTagInText(p, token) {
|
|
2054
|
-
if (token.tagName === $.SCRIPT)
|
|
2149
|
+
if (token.tagName === $.SCRIPT) {
|
|
2055
2150
|
p.pendingScript = p.openElements.current;
|
|
2151
|
+
}
|
|
2056
2152
|
|
|
2057
2153
|
p.openElements.pop();
|
|
2058
2154
|
p.insertionMode = p.originalInsertionMode;
|
|
2059
2155
|
}
|
|
2060
2156
|
|
|
2061
|
-
|
|
2062
2157
|
function eofInText(p, token) {
|
|
2158
|
+
p._err(ERR.eofInElementThatCanContainOnlyText);
|
|
2063
2159
|
p.openElements.pop();
|
|
2064
2160
|
p.insertionMode = p.originalInsertionMode;
|
|
2065
2161
|
p._processToken(token);
|
|
2066
2162
|
}
|
|
2067
2163
|
|
|
2068
|
-
|
|
2069
|
-
//12.2.5.4.9 The "in table" insertion mode
|
|
2164
|
+
// The "in table" insertion mode
|
|
2070
2165
|
//------------------------------------------------------------------
|
|
2071
2166
|
function characterInTable(p, token) {
|
|
2072
|
-
|
|
2167
|
+
const curTn = p.openElements.currentTagName;
|
|
2073
2168
|
|
|
2074
2169
|
if (curTn === $.TABLE || curTn === $.TBODY || curTn === $.TFOOT || curTn === $.THEAD || curTn === $.TR) {
|
|
2075
2170
|
p.pendingCharacterTokens = [];
|
|
@@ -2077,10 +2172,9 @@ function characterInTable(p, token) {
|
|
|
2077
2172
|
p.originalInsertionMode = p.insertionMode;
|
|
2078
2173
|
p.insertionMode = IN_TABLE_TEXT_MODE;
|
|
2079
2174
|
p._processToken(token);
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
else
|
|
2175
|
+
} else {
|
|
2083
2176
|
tokenInTable(p, token);
|
|
2177
|
+
}
|
|
2084
2178
|
}
|
|
2085
2179
|
|
|
2086
2180
|
function captionStartTagInTable(p, token) {
|
|
@@ -2125,13 +2219,15 @@ function tableStartTagInTable(p, token) {
|
|
|
2125
2219
|
}
|
|
2126
2220
|
|
|
2127
2221
|
function inputStartTagInTable(p, token) {
|
|
2128
|
-
|
|
2222
|
+
const inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
|
|
2129
2223
|
|
|
2130
|
-
if (inputType && inputType.toLowerCase() === HIDDEN_INPUT_TYPE)
|
|
2224
|
+
if (inputType && inputType.toLowerCase() === HIDDEN_INPUT_TYPE) {
|
|
2131
2225
|
p._appendElement(token, NS.HTML);
|
|
2132
|
-
|
|
2133
|
-
else
|
|
2226
|
+
} else {
|
|
2134
2227
|
tokenInTable(p, token);
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
token.ackSelfClosing = true;
|
|
2135
2231
|
}
|
|
2136
2232
|
|
|
2137
2233
|
function formStartTagInTable(p, token) {
|
|
@@ -2143,118 +2239,121 @@ function formStartTagInTable(p, token) {
|
|
|
2143
2239
|
}
|
|
2144
2240
|
|
|
2145
2241
|
function startTagInTable(p, token) {
|
|
2146
|
-
|
|
2242
|
+
const tn = token.tagName;
|
|
2147
2243
|
|
|
2148
2244
|
switch (tn.length) {
|
|
2149
2245
|
case 2:
|
|
2150
|
-
if (tn === $.TD || tn === $.TH || tn === $.TR)
|
|
2246
|
+
if (tn === $.TD || tn === $.TH || tn === $.TR) {
|
|
2151
2247
|
tdStartTagInTable(p, token);
|
|
2152
|
-
|
|
2153
|
-
else
|
|
2248
|
+
} else {
|
|
2154
2249
|
tokenInTable(p, token);
|
|
2250
|
+
}
|
|
2155
2251
|
|
|
2156
2252
|
break;
|
|
2157
2253
|
|
|
2158
2254
|
case 3:
|
|
2159
|
-
if (tn === $.COL)
|
|
2255
|
+
if (tn === $.COL) {
|
|
2160
2256
|
colStartTagInTable(p, token);
|
|
2161
|
-
|
|
2162
|
-
else
|
|
2257
|
+
} else {
|
|
2163
2258
|
tokenInTable(p, token);
|
|
2259
|
+
}
|
|
2164
2260
|
|
|
2165
2261
|
break;
|
|
2166
2262
|
|
|
2167
2263
|
case 4:
|
|
2168
|
-
if (tn === $.FORM)
|
|
2264
|
+
if (tn === $.FORM) {
|
|
2169
2265
|
formStartTagInTable(p, token);
|
|
2170
|
-
|
|
2171
|
-
else
|
|
2266
|
+
} else {
|
|
2172
2267
|
tokenInTable(p, token);
|
|
2268
|
+
}
|
|
2173
2269
|
|
|
2174
2270
|
break;
|
|
2175
2271
|
|
|
2176
2272
|
case 5:
|
|
2177
|
-
if (tn === $.TABLE)
|
|
2273
|
+
if (tn === $.TABLE) {
|
|
2178
2274
|
tableStartTagInTable(p, token);
|
|
2179
|
-
|
|
2180
|
-
else if (tn === $.STYLE)
|
|
2275
|
+
} else if (tn === $.STYLE) {
|
|
2181
2276
|
startTagInHead(p, token);
|
|
2182
|
-
|
|
2183
|
-
else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD)
|
|
2277
|
+
} else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
2184
2278
|
tbodyStartTagInTable(p, token);
|
|
2185
|
-
|
|
2186
|
-
else if (tn === $.INPUT)
|
|
2279
|
+
} else if (tn === $.INPUT) {
|
|
2187
2280
|
inputStartTagInTable(p, token);
|
|
2188
|
-
|
|
2189
|
-
else
|
|
2281
|
+
} else {
|
|
2190
2282
|
tokenInTable(p, token);
|
|
2283
|
+
}
|
|
2191
2284
|
|
|
2192
2285
|
break;
|
|
2193
2286
|
|
|
2194
2287
|
case 6:
|
|
2195
|
-
if (tn === $.SCRIPT)
|
|
2288
|
+
if (tn === $.SCRIPT) {
|
|
2196
2289
|
startTagInHead(p, token);
|
|
2197
|
-
|
|
2198
|
-
else
|
|
2290
|
+
} else {
|
|
2199
2291
|
tokenInTable(p, token);
|
|
2292
|
+
}
|
|
2200
2293
|
|
|
2201
2294
|
break;
|
|
2202
2295
|
|
|
2203
2296
|
case 7:
|
|
2204
|
-
if (tn === $.CAPTION)
|
|
2297
|
+
if (tn === $.CAPTION) {
|
|
2205
2298
|
captionStartTagInTable(p, token);
|
|
2206
|
-
|
|
2207
|
-
else
|
|
2299
|
+
} else {
|
|
2208
2300
|
tokenInTable(p, token);
|
|
2301
|
+
}
|
|
2209
2302
|
|
|
2210
2303
|
break;
|
|
2211
2304
|
|
|
2212
2305
|
case 8:
|
|
2213
|
-
if (tn === $.COLGROUP)
|
|
2306
|
+
if (tn === $.COLGROUP) {
|
|
2214
2307
|
colgroupStartTagInTable(p, token);
|
|
2215
|
-
|
|
2216
|
-
else if (tn === $.TEMPLATE)
|
|
2308
|
+
} else if (tn === $.TEMPLATE) {
|
|
2217
2309
|
startTagInHead(p, token);
|
|
2218
|
-
|
|
2219
|
-
else
|
|
2310
|
+
} else {
|
|
2220
2311
|
tokenInTable(p, token);
|
|
2312
|
+
}
|
|
2221
2313
|
|
|
2222
2314
|
break;
|
|
2223
2315
|
|
|
2224
2316
|
default:
|
|
2225
2317
|
tokenInTable(p, token);
|
|
2226
2318
|
}
|
|
2227
|
-
|
|
2228
2319
|
}
|
|
2229
2320
|
|
|
2230
2321
|
function endTagInTable(p, token) {
|
|
2231
|
-
|
|
2322
|
+
const tn = token.tagName;
|
|
2232
2323
|
|
|
2233
2324
|
if (tn === $.TABLE) {
|
|
2234
2325
|
if (p.openElements.hasInTableScope($.TABLE)) {
|
|
2235
2326
|
p.openElements.popUntilTagNamePopped($.TABLE);
|
|
2236
2327
|
p._resetInsertionMode();
|
|
2237
2328
|
}
|
|
2238
|
-
}
|
|
2239
|
-
|
|
2240
|
-
else if (tn === $.TEMPLATE)
|
|
2329
|
+
} else if (tn === $.TEMPLATE) {
|
|
2241
2330
|
endTagInHead(p, token);
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2331
|
+
} else if (
|
|
2332
|
+
tn !== $.BODY &&
|
|
2333
|
+
tn !== $.CAPTION &&
|
|
2334
|
+
tn !== $.COL &&
|
|
2335
|
+
tn !== $.COLGROUP &&
|
|
2336
|
+
tn !== $.HTML &&
|
|
2337
|
+
tn !== $.TBODY &&
|
|
2338
|
+
tn !== $.TD &&
|
|
2339
|
+
tn !== $.TFOOT &&
|
|
2340
|
+
tn !== $.TH &&
|
|
2341
|
+
tn !== $.THEAD &&
|
|
2342
|
+
tn !== $.TR
|
|
2343
|
+
) {
|
|
2245
2344
|
tokenInTable(p, token);
|
|
2345
|
+
}
|
|
2246
2346
|
}
|
|
2247
2347
|
|
|
2248
2348
|
function tokenInTable(p, token) {
|
|
2249
|
-
|
|
2349
|
+
const savedFosterParentingState = p.fosterParentingEnabled;
|
|
2250
2350
|
|
|
2251
2351
|
p.fosterParentingEnabled = true;
|
|
2252
2352
|
p._processTokenInBodyMode(token);
|
|
2253
2353
|
p.fosterParentingEnabled = savedFosterParentingState;
|
|
2254
2354
|
}
|
|
2255
2355
|
|
|
2256
|
-
|
|
2257
|
-
//12.2.5.4.10 The "in table text" insertion mode
|
|
2356
|
+
// The "in table text" insertion mode
|
|
2258
2357
|
//------------------------------------------------------------------
|
|
2259
2358
|
function whitespaceCharacterInTableText(p, token) {
|
|
2260
2359
|
p.pendingCharacterTokens.push(token);
|
|
@@ -2266,30 +2365,38 @@ function characterInTableText(p, token) {
|
|
|
2266
2365
|
}
|
|
2267
2366
|
|
|
2268
2367
|
function tokenInTableText(p, token) {
|
|
2269
|
-
|
|
2368
|
+
let i = 0;
|
|
2270
2369
|
|
|
2271
2370
|
if (p.hasNonWhitespacePendingCharacterToken) {
|
|
2272
|
-
for (; i < p.pendingCharacterTokens.length; i++)
|
|
2371
|
+
for (; i < p.pendingCharacterTokens.length; i++) {
|
|
2273
2372
|
tokenInTable(p, p.pendingCharacterTokens[i]);
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
for (; i < p.pendingCharacterTokens.length; i++)
|
|
2373
|
+
}
|
|
2374
|
+
} else {
|
|
2375
|
+
for (; i < p.pendingCharacterTokens.length; i++) {
|
|
2278
2376
|
p._insertCharacters(p.pendingCharacterTokens[i]);
|
|
2377
|
+
}
|
|
2279
2378
|
}
|
|
2280
2379
|
|
|
2281
2380
|
p.insertionMode = p.originalInsertionMode;
|
|
2282
2381
|
p._processToken(token);
|
|
2283
2382
|
}
|
|
2284
2383
|
|
|
2285
|
-
|
|
2286
|
-
//12.2.5.4.11 The "in caption" insertion mode
|
|
2384
|
+
// The "in caption" insertion mode
|
|
2287
2385
|
//------------------------------------------------------------------
|
|
2288
2386
|
function startTagInCaption(p, token) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
if (
|
|
2292
|
-
tn === $.
|
|
2387
|
+
const tn = token.tagName;
|
|
2388
|
+
|
|
2389
|
+
if (
|
|
2390
|
+
tn === $.CAPTION ||
|
|
2391
|
+
tn === $.COL ||
|
|
2392
|
+
tn === $.COLGROUP ||
|
|
2393
|
+
tn === $.TBODY ||
|
|
2394
|
+
tn === $.TD ||
|
|
2395
|
+
tn === $.TFOOT ||
|
|
2396
|
+
tn === $.TH ||
|
|
2397
|
+
tn === $.THEAD ||
|
|
2398
|
+
tn === $.TR
|
|
2399
|
+
) {
|
|
2293
2400
|
if (p.openElements.hasInTableScope($.CAPTION)) {
|
|
2294
2401
|
p.openElements.generateImpliedEndTags();
|
|
2295
2402
|
p.openElements.popUntilTagNamePopped($.CAPTION);
|
|
@@ -2297,14 +2404,13 @@ function startTagInCaption(p, token) {
|
|
|
2297
2404
|
p.insertionMode = IN_TABLE_MODE;
|
|
2298
2405
|
p._processToken(token);
|
|
2299
2406
|
}
|
|
2300
|
-
}
|
|
2301
|
-
|
|
2302
|
-
else
|
|
2407
|
+
} else {
|
|
2303
2408
|
startTagInBody(p, token);
|
|
2409
|
+
}
|
|
2304
2410
|
}
|
|
2305
2411
|
|
|
2306
2412
|
function endTagInCaption(p, token) {
|
|
2307
|
-
|
|
2413
|
+
const tn = token.tagName;
|
|
2308
2414
|
|
|
2309
2415
|
if (tn === $.CAPTION || tn === $.TABLE) {
|
|
2310
2416
|
if (p.openElements.hasInTableScope($.CAPTION)) {
|
|
@@ -2313,50 +2419,56 @@ function endTagInCaption(p, token) {
|
|
|
2313
2419
|
p.activeFormattingElements.clearToLastMarker();
|
|
2314
2420
|
p.insertionMode = IN_TABLE_MODE;
|
|
2315
2421
|
|
|
2316
|
-
if (tn === $.TABLE)
|
|
2422
|
+
if (tn === $.TABLE) {
|
|
2317
2423
|
p._processToken(token);
|
|
2424
|
+
}
|
|
2318
2425
|
}
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2426
|
+
} else if (
|
|
2427
|
+
tn !== $.BODY &&
|
|
2428
|
+
tn !== $.COL &&
|
|
2429
|
+
tn !== $.COLGROUP &&
|
|
2430
|
+
tn !== $.HTML &&
|
|
2431
|
+
tn !== $.TBODY &&
|
|
2432
|
+
tn !== $.TD &&
|
|
2433
|
+
tn !== $.TFOOT &&
|
|
2434
|
+
tn !== $.TH &&
|
|
2435
|
+
tn !== $.THEAD &&
|
|
2436
|
+
tn !== $.TR
|
|
2437
|
+
) {
|
|
2323
2438
|
endTagInBody(p, token);
|
|
2439
|
+
}
|
|
2324
2440
|
}
|
|
2325
2441
|
|
|
2326
|
-
|
|
2327
|
-
//12.2.5.4.12 The "in column group" insertion mode
|
|
2442
|
+
// The "in column group" insertion mode
|
|
2328
2443
|
//------------------------------------------------------------------
|
|
2329
2444
|
function startTagInColumnGroup(p, token) {
|
|
2330
|
-
|
|
2445
|
+
const tn = token.tagName;
|
|
2331
2446
|
|
|
2332
|
-
if (tn === $.HTML)
|
|
2447
|
+
if (tn === $.HTML) {
|
|
2333
2448
|
startTagInBody(p, token);
|
|
2334
|
-
|
|
2335
|
-
else if (tn === $.COL)
|
|
2449
|
+
} else if (tn === $.COL) {
|
|
2336
2450
|
p._appendElement(token, NS.HTML);
|
|
2337
|
-
|
|
2338
|
-
else if (tn === $.TEMPLATE)
|
|
2451
|
+
token.ackSelfClosing = true;
|
|
2452
|
+
} else if (tn === $.TEMPLATE) {
|
|
2339
2453
|
startTagInHead(p, token);
|
|
2340
|
-
|
|
2341
|
-
else
|
|
2454
|
+
} else {
|
|
2342
2455
|
tokenInColumnGroup(p, token);
|
|
2456
|
+
}
|
|
2343
2457
|
}
|
|
2344
2458
|
|
|
2345
2459
|
function endTagInColumnGroup(p, token) {
|
|
2346
|
-
|
|
2460
|
+
const tn = token.tagName;
|
|
2347
2461
|
|
|
2348
2462
|
if (tn === $.COLGROUP) {
|
|
2349
2463
|
if (p.openElements.currentTagName === $.COLGROUP) {
|
|
2350
2464
|
p.openElements.pop();
|
|
2351
2465
|
p.insertionMode = IN_TABLE_MODE;
|
|
2352
2466
|
}
|
|
2353
|
-
}
|
|
2354
|
-
|
|
2355
|
-
else if (tn === $.TEMPLATE)
|
|
2467
|
+
} else if (tn === $.TEMPLATE) {
|
|
2356
2468
|
endTagInHead(p, token);
|
|
2357
|
-
|
|
2358
|
-
else if (tn !== $.COL)
|
|
2469
|
+
} else if (tn !== $.COL) {
|
|
2359
2470
|
tokenInColumnGroup(p, token);
|
|
2471
|
+
}
|
|
2360
2472
|
}
|
|
2361
2473
|
|
|
2362
2474
|
function tokenInColumnGroup(p, token) {
|
|
@@ -2367,41 +2479,41 @@ function tokenInColumnGroup(p, token) {
|
|
|
2367
2479
|
}
|
|
2368
2480
|
}
|
|
2369
2481
|
|
|
2370
|
-
//
|
|
2482
|
+
// The "in table body" insertion mode
|
|
2371
2483
|
//------------------------------------------------------------------
|
|
2372
2484
|
function startTagInTableBody(p, token) {
|
|
2373
|
-
|
|
2485
|
+
const tn = token.tagName;
|
|
2374
2486
|
|
|
2375
2487
|
if (tn === $.TR) {
|
|
2376
2488
|
p.openElements.clearBackToTableBodyContext();
|
|
2377
2489
|
p._insertElement(token, NS.HTML);
|
|
2378
2490
|
p.insertionMode = IN_ROW_MODE;
|
|
2379
|
-
}
|
|
2380
|
-
|
|
2381
|
-
else if (tn === $.TH || tn === $.TD) {
|
|
2491
|
+
} else if (tn === $.TH || tn === $.TD) {
|
|
2382
2492
|
p.openElements.clearBackToTableBodyContext();
|
|
2383
2493
|
p._insertFakeElement($.TR);
|
|
2384
2494
|
p.insertionMode = IN_ROW_MODE;
|
|
2385
2495
|
p._processToken(token);
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2496
|
+
} else if (
|
|
2497
|
+
tn === $.CAPTION ||
|
|
2498
|
+
tn === $.COL ||
|
|
2499
|
+
tn === $.COLGROUP ||
|
|
2500
|
+
tn === $.TBODY ||
|
|
2501
|
+
tn === $.TFOOT ||
|
|
2502
|
+
tn === $.THEAD
|
|
2503
|
+
) {
|
|
2391
2504
|
if (p.openElements.hasTableBodyContextInTableScope()) {
|
|
2392
2505
|
p.openElements.clearBackToTableBodyContext();
|
|
2393
2506
|
p.openElements.pop();
|
|
2394
2507
|
p.insertionMode = IN_TABLE_MODE;
|
|
2395
2508
|
p._processToken(token);
|
|
2396
2509
|
}
|
|
2397
|
-
}
|
|
2398
|
-
|
|
2399
|
-
else
|
|
2510
|
+
} else {
|
|
2400
2511
|
startTagInTable(p, token);
|
|
2512
|
+
}
|
|
2401
2513
|
}
|
|
2402
2514
|
|
|
2403
2515
|
function endTagInTableBody(p, token) {
|
|
2404
|
-
|
|
2516
|
+
const tn = token.tagName;
|
|
2405
2517
|
|
|
2406
2518
|
if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
2407
2519
|
if (p.openElements.hasInTableScope(tn)) {
|
|
@@ -2409,50 +2521,53 @@ function endTagInTableBody(p, token) {
|
|
|
2409
2521
|
p.openElements.pop();
|
|
2410
2522
|
p.insertionMode = IN_TABLE_MODE;
|
|
2411
2523
|
}
|
|
2412
|
-
}
|
|
2413
|
-
|
|
2414
|
-
else if (tn === $.TABLE) {
|
|
2524
|
+
} else if (tn === $.TABLE) {
|
|
2415
2525
|
if (p.openElements.hasTableBodyContextInTableScope()) {
|
|
2416
2526
|
p.openElements.clearBackToTableBodyContext();
|
|
2417
2527
|
p.openElements.pop();
|
|
2418
2528
|
p.insertionMode = IN_TABLE_MODE;
|
|
2419
2529
|
p._processToken(token);
|
|
2420
2530
|
}
|
|
2421
|
-
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2531
|
+
} else if (
|
|
2532
|
+
(tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP) ||
|
|
2533
|
+
(tn !== $.HTML && tn !== $.TD && tn !== $.TH && tn !== $.TR)
|
|
2534
|
+
) {
|
|
2425
2535
|
endTagInTable(p, token);
|
|
2536
|
+
}
|
|
2426
2537
|
}
|
|
2427
2538
|
|
|
2428
|
-
//
|
|
2539
|
+
// The "in row" insertion mode
|
|
2429
2540
|
//------------------------------------------------------------------
|
|
2430
2541
|
function startTagInRow(p, token) {
|
|
2431
|
-
|
|
2542
|
+
const tn = token.tagName;
|
|
2432
2543
|
|
|
2433
2544
|
if (tn === $.TH || tn === $.TD) {
|
|
2434
2545
|
p.openElements.clearBackToTableRowContext();
|
|
2435
2546
|
p._insertElement(token, NS.HTML);
|
|
2436
2547
|
p.insertionMode = IN_CELL_MODE;
|
|
2437
2548
|
p.activeFormattingElements.insertMarker();
|
|
2438
|
-
}
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2549
|
+
} else if (
|
|
2550
|
+
tn === $.CAPTION ||
|
|
2551
|
+
tn === $.COL ||
|
|
2552
|
+
tn === $.COLGROUP ||
|
|
2553
|
+
tn === $.TBODY ||
|
|
2554
|
+
tn === $.TFOOT ||
|
|
2555
|
+
tn === $.THEAD ||
|
|
2556
|
+
tn === $.TR
|
|
2557
|
+
) {
|
|
2442
2558
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
2443
2559
|
p.openElements.clearBackToTableRowContext();
|
|
2444
2560
|
p.openElements.pop();
|
|
2445
2561
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
2446
2562
|
p._processToken(token);
|
|
2447
2563
|
}
|
|
2448
|
-
}
|
|
2449
|
-
|
|
2450
|
-
else
|
|
2564
|
+
} else {
|
|
2451
2565
|
startTagInTable(p, token);
|
|
2566
|
+
}
|
|
2452
2567
|
}
|
|
2453
2568
|
|
|
2454
2569
|
function endTagInRow(p, token) {
|
|
2455
|
-
|
|
2570
|
+
const tn = token.tagName;
|
|
2456
2571
|
|
|
2457
2572
|
if (tn === $.TR) {
|
|
2458
2573
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
@@ -2460,52 +2575,55 @@ function endTagInRow(p, token) {
|
|
|
2460
2575
|
p.openElements.pop();
|
|
2461
2576
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
2462
2577
|
}
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
else if (tn === $.TABLE) {
|
|
2578
|
+
} else if (tn === $.TABLE) {
|
|
2466
2579
|
if (p.openElements.hasInTableScope($.TR)) {
|
|
2467
2580
|
p.openElements.clearBackToTableRowContext();
|
|
2468
2581
|
p.openElements.pop();
|
|
2469
2582
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
2470
2583
|
p._processToken(token);
|
|
2471
2584
|
}
|
|
2472
|
-
}
|
|
2473
|
-
|
|
2474
|
-
else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
2585
|
+
} else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
|
|
2475
2586
|
if (p.openElements.hasInTableScope(tn) || p.openElements.hasInTableScope($.TR)) {
|
|
2476
2587
|
p.openElements.clearBackToTableRowContext();
|
|
2477
2588
|
p.openElements.pop();
|
|
2478
2589
|
p.insertionMode = IN_TABLE_BODY_MODE;
|
|
2479
2590
|
p._processToken(token);
|
|
2480
2591
|
}
|
|
2481
|
-
}
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2592
|
+
} else if (
|
|
2593
|
+
(tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP) ||
|
|
2594
|
+
(tn !== $.HTML && tn !== $.TD && tn !== $.TH)
|
|
2595
|
+
) {
|
|
2485
2596
|
endTagInTable(p, token);
|
|
2597
|
+
}
|
|
2486
2598
|
}
|
|
2487
2599
|
|
|
2488
|
-
|
|
2489
|
-
//12.2.5.4.15 The "in cell" insertion mode
|
|
2600
|
+
// The "in cell" insertion mode
|
|
2490
2601
|
//------------------------------------------------------------------
|
|
2491
2602
|
function startTagInCell(p, token) {
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
if (
|
|
2495
|
-
tn === $.
|
|
2496
|
-
|
|
2603
|
+
const tn = token.tagName;
|
|
2604
|
+
|
|
2605
|
+
if (
|
|
2606
|
+
tn === $.CAPTION ||
|
|
2607
|
+
tn === $.COL ||
|
|
2608
|
+
tn === $.COLGROUP ||
|
|
2609
|
+
tn === $.TBODY ||
|
|
2610
|
+
tn === $.TD ||
|
|
2611
|
+
tn === $.TFOOT ||
|
|
2612
|
+
tn === $.TH ||
|
|
2613
|
+
tn === $.THEAD ||
|
|
2614
|
+
tn === $.TR
|
|
2615
|
+
) {
|
|
2497
2616
|
if (p.openElements.hasInTableScope($.TD) || p.openElements.hasInTableScope($.TH)) {
|
|
2498
2617
|
p._closeTableCell();
|
|
2499
2618
|
p._processToken(token);
|
|
2500
2619
|
}
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
|
-
else
|
|
2620
|
+
} else {
|
|
2504
2621
|
startTagInBody(p, token);
|
|
2622
|
+
}
|
|
2505
2623
|
}
|
|
2506
2624
|
|
|
2507
2625
|
function endTagInCell(p, token) {
|
|
2508
|
-
|
|
2626
|
+
const tn = token.tagName;
|
|
2509
2627
|
|
|
2510
2628
|
if (tn === $.TD || tn === $.TH) {
|
|
2511
2629
|
if (p.openElements.hasInTableScope(tn)) {
|
|
@@ -2514,129 +2632,145 @@ function endTagInCell(p, token) {
|
|
|
2514
2632
|
p.activeFormattingElements.clearToLastMarker();
|
|
2515
2633
|
p.insertionMode = IN_ROW_MODE;
|
|
2516
2634
|
}
|
|
2517
|
-
}
|
|
2518
|
-
|
|
2519
|
-
else if (tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR) {
|
|
2635
|
+
} else if (tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR) {
|
|
2520
2636
|
if (p.openElements.hasInTableScope(tn)) {
|
|
2521
2637
|
p._closeTableCell();
|
|
2522
2638
|
p._processToken(token);
|
|
2523
2639
|
}
|
|
2524
|
-
}
|
|
2525
|
-
|
|
2526
|
-
else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML)
|
|
2640
|
+
} else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML) {
|
|
2527
2641
|
endTagInBody(p, token);
|
|
2642
|
+
}
|
|
2528
2643
|
}
|
|
2529
2644
|
|
|
2530
|
-
//
|
|
2645
|
+
// The "in select" insertion mode
|
|
2531
2646
|
//------------------------------------------------------------------
|
|
2532
2647
|
function startTagInSelect(p, token) {
|
|
2533
|
-
|
|
2648
|
+
const tn = token.tagName;
|
|
2534
2649
|
|
|
2535
|
-
if (tn === $.HTML)
|
|
2650
|
+
if (tn === $.HTML) {
|
|
2536
2651
|
startTagInBody(p, token);
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
if (p.openElements.currentTagName === $.OPTION)
|
|
2652
|
+
} else if (tn === $.OPTION) {
|
|
2653
|
+
if (p.openElements.currentTagName === $.OPTION) {
|
|
2540
2654
|
p.openElements.pop();
|
|
2655
|
+
}
|
|
2541
2656
|
|
|
2542
2657
|
p._insertElement(token, NS.HTML);
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
|
-
else if (tn === $.OPTGROUP) {
|
|
2546
|
-
if (p.openElements.currentTagName === $.OPTION)
|
|
2658
|
+
} else if (tn === $.OPTGROUP) {
|
|
2659
|
+
if (p.openElements.currentTagName === $.OPTION) {
|
|
2547
2660
|
p.openElements.pop();
|
|
2661
|
+
}
|
|
2548
2662
|
|
|
2549
|
-
if (p.openElements.currentTagName === $.OPTGROUP)
|
|
2663
|
+
if (p.openElements.currentTagName === $.OPTGROUP) {
|
|
2550
2664
|
p.openElements.pop();
|
|
2665
|
+
}
|
|
2551
2666
|
|
|
2552
2667
|
p._insertElement(token, NS.HTML);
|
|
2553
|
-
}
|
|
2554
|
-
|
|
2555
|
-
else if (tn === $.INPUT || tn === $.KEYGEN || tn === $.TEXTAREA || tn === $.SELECT) {
|
|
2668
|
+
} else if (tn === $.INPUT || tn === $.KEYGEN || tn === $.TEXTAREA || tn === $.SELECT) {
|
|
2556
2669
|
if (p.openElements.hasInSelectScope($.SELECT)) {
|
|
2557
2670
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
2558
2671
|
p._resetInsertionMode();
|
|
2559
2672
|
|
|
2560
|
-
if (tn !== $.SELECT)
|
|
2673
|
+
if (tn !== $.SELECT) {
|
|
2561
2674
|
p._processToken(token);
|
|
2675
|
+
}
|
|
2562
2676
|
}
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
else if (tn === $.SCRIPT || tn === $.TEMPLATE)
|
|
2677
|
+
} else if (tn === $.SCRIPT || tn === $.TEMPLATE) {
|
|
2566
2678
|
startTagInHead(p, token);
|
|
2679
|
+
}
|
|
2567
2680
|
}
|
|
2568
2681
|
|
|
2569
2682
|
function endTagInSelect(p, token) {
|
|
2570
|
-
|
|
2683
|
+
const tn = token.tagName;
|
|
2571
2684
|
|
|
2572
2685
|
if (tn === $.OPTGROUP) {
|
|
2573
|
-
|
|
2574
|
-
|
|
2686
|
+
const prevOpenElement = p.openElements.items[p.openElements.stackTop - 1];
|
|
2687
|
+
const prevOpenElementTn = prevOpenElement && p.treeAdapter.getTagName(prevOpenElement);
|
|
2575
2688
|
|
|
2576
|
-
if (p.openElements.currentTagName === $.OPTION && prevOpenElementTn === $.OPTGROUP)
|
|
2689
|
+
if (p.openElements.currentTagName === $.OPTION && prevOpenElementTn === $.OPTGROUP) {
|
|
2577
2690
|
p.openElements.pop();
|
|
2691
|
+
}
|
|
2578
2692
|
|
|
2579
|
-
if (p.openElements.currentTagName === $.OPTGROUP)
|
|
2693
|
+
if (p.openElements.currentTagName === $.OPTGROUP) {
|
|
2580
2694
|
p.openElements.pop();
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
if (p.openElements.currentTagName === $.OPTION)
|
|
2695
|
+
}
|
|
2696
|
+
} else if (tn === $.OPTION) {
|
|
2697
|
+
if (p.openElements.currentTagName === $.OPTION) {
|
|
2585
2698
|
p.openElements.pop();
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
else if (tn === $.SELECT && p.openElements.hasInSelectScope($.SELECT)) {
|
|
2699
|
+
}
|
|
2700
|
+
} else if (tn === $.SELECT && p.openElements.hasInSelectScope($.SELECT)) {
|
|
2589
2701
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
2590
2702
|
p._resetInsertionMode();
|
|
2591
|
-
}
|
|
2592
|
-
|
|
2593
|
-
else if (tn === $.TEMPLATE)
|
|
2703
|
+
} else if (tn === $.TEMPLATE) {
|
|
2594
2704
|
endTagInHead(p, token);
|
|
2705
|
+
}
|
|
2595
2706
|
}
|
|
2596
2707
|
|
|
2597
2708
|
//12.2.5.4.17 The "in select in table" insertion mode
|
|
2598
2709
|
//------------------------------------------------------------------
|
|
2599
2710
|
function startTagInSelectInTable(p, token) {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
if (
|
|
2603
|
-
tn === $.
|
|
2711
|
+
const tn = token.tagName;
|
|
2712
|
+
|
|
2713
|
+
if (
|
|
2714
|
+
tn === $.CAPTION ||
|
|
2715
|
+
tn === $.TABLE ||
|
|
2716
|
+
tn === $.TBODY ||
|
|
2717
|
+
tn === $.TFOOT ||
|
|
2718
|
+
tn === $.THEAD ||
|
|
2719
|
+
tn === $.TR ||
|
|
2720
|
+
tn === $.TD ||
|
|
2721
|
+
tn === $.TH
|
|
2722
|
+
) {
|
|
2604
2723
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
2605
2724
|
p._resetInsertionMode();
|
|
2606
2725
|
p._processToken(token);
|
|
2607
|
-
}
|
|
2608
|
-
|
|
2609
|
-
else
|
|
2726
|
+
} else {
|
|
2610
2727
|
startTagInSelect(p, token);
|
|
2728
|
+
}
|
|
2611
2729
|
}
|
|
2612
2730
|
|
|
2613
2731
|
function endTagInSelectInTable(p, token) {
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
if (
|
|
2617
|
-
tn === $.
|
|
2732
|
+
const tn = token.tagName;
|
|
2733
|
+
|
|
2734
|
+
if (
|
|
2735
|
+
tn === $.CAPTION ||
|
|
2736
|
+
tn === $.TABLE ||
|
|
2737
|
+
tn === $.TBODY ||
|
|
2738
|
+
tn === $.TFOOT ||
|
|
2739
|
+
tn === $.THEAD ||
|
|
2740
|
+
tn === $.TR ||
|
|
2741
|
+
tn === $.TD ||
|
|
2742
|
+
tn === $.TH
|
|
2743
|
+
) {
|
|
2618
2744
|
if (p.openElements.hasInTableScope(tn)) {
|
|
2619
2745
|
p.openElements.popUntilTagNamePopped($.SELECT);
|
|
2620
2746
|
p._resetInsertionMode();
|
|
2621
2747
|
p._processToken(token);
|
|
2622
2748
|
}
|
|
2623
|
-
}
|
|
2624
|
-
|
|
2625
|
-
else
|
|
2749
|
+
} else {
|
|
2626
2750
|
endTagInSelect(p, token);
|
|
2751
|
+
}
|
|
2627
2752
|
}
|
|
2628
2753
|
|
|
2629
|
-
//
|
|
2754
|
+
// The "in template" insertion mode
|
|
2630
2755
|
//------------------------------------------------------------------
|
|
2631
2756
|
function startTagInTemplate(p, token) {
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
if (
|
|
2635
|
-
tn === $.
|
|
2757
|
+
const tn = token.tagName;
|
|
2758
|
+
|
|
2759
|
+
if (
|
|
2760
|
+
tn === $.BASE ||
|
|
2761
|
+
tn === $.BASEFONT ||
|
|
2762
|
+
tn === $.BGSOUND ||
|
|
2763
|
+
tn === $.LINK ||
|
|
2764
|
+
tn === $.META ||
|
|
2765
|
+
tn === $.NOFRAMES ||
|
|
2766
|
+
tn === $.SCRIPT ||
|
|
2767
|
+
tn === $.STYLE ||
|
|
2768
|
+
tn === $.TEMPLATE ||
|
|
2769
|
+
tn === $.TITLE
|
|
2770
|
+
) {
|
|
2636
2771
|
startTagInHead(p, token);
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
var newInsertionMode = TEMPLATE_INSERTION_MODE_SWITCH_MAP[tn] || IN_BODY_MODE;
|
|
2772
|
+
} else {
|
|
2773
|
+
const newInsertionMode = TEMPLATE_INSERTION_MODE_SWITCH_MAP[tn] || IN_BODY_MODE;
|
|
2640
2774
|
|
|
2641
2775
|
p._popTmplInsertionMode();
|
|
2642
2776
|
p._pushTmplInsertionMode(newInsertionMode);
|
|
@@ -2646,8 +2780,9 @@ function startTagInTemplate(p, token) {
|
|
|
2646
2780
|
}
|
|
2647
2781
|
|
|
2648
2782
|
function endTagInTemplate(p, token) {
|
|
2649
|
-
if (token.tagName === $.TEMPLATE)
|
|
2783
|
+
if (token.tagName === $.TEMPLATE) {
|
|
2650
2784
|
endTagInHead(p, token);
|
|
2785
|
+
}
|
|
2651
2786
|
}
|
|
2652
2787
|
|
|
2653
2788
|
function eofInTemplate(p, token) {
|
|
@@ -2657,31 +2792,29 @@ function eofInTemplate(p, token) {
|
|
|
2657
2792
|
p._popTmplInsertionMode();
|
|
2658
2793
|
p._resetInsertionMode();
|
|
2659
2794
|
p._processToken(token);
|
|
2660
|
-
}
|
|
2661
|
-
|
|
2662
|
-
else
|
|
2795
|
+
} else {
|
|
2663
2796
|
p.stopped = true;
|
|
2797
|
+
}
|
|
2664
2798
|
}
|
|
2665
2799
|
|
|
2666
|
-
|
|
2667
|
-
//12.2.5.4.19 The "after body" insertion mode
|
|
2800
|
+
// The "after body" insertion mode
|
|
2668
2801
|
//------------------------------------------------------------------
|
|
2669
2802
|
function startTagAfterBody(p, token) {
|
|
2670
|
-
if (token.tagName === $.HTML)
|
|
2803
|
+
if (token.tagName === $.HTML) {
|
|
2671
2804
|
startTagInBody(p, token);
|
|
2672
|
-
|
|
2673
|
-
else
|
|
2805
|
+
} else {
|
|
2674
2806
|
tokenAfterBody(p, token);
|
|
2807
|
+
}
|
|
2675
2808
|
}
|
|
2676
2809
|
|
|
2677
2810
|
function endTagAfterBody(p, token) {
|
|
2678
2811
|
if (token.tagName === $.HTML) {
|
|
2679
|
-
if (!p.fragmentContext)
|
|
2812
|
+
if (!p.fragmentContext) {
|
|
2680
2813
|
p.insertionMode = AFTER_AFTER_BODY_MODE;
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
else
|
|
2814
|
+
}
|
|
2815
|
+
} else {
|
|
2684
2816
|
tokenAfterBody(p, token);
|
|
2817
|
+
}
|
|
2685
2818
|
}
|
|
2686
2819
|
|
|
2687
2820
|
function tokenAfterBody(p, token) {
|
|
@@ -2689,58 +2822,59 @@ function tokenAfterBody(p, token) {
|
|
|
2689
2822
|
p._processToken(token);
|
|
2690
2823
|
}
|
|
2691
2824
|
|
|
2692
|
-
//
|
|
2825
|
+
// The "in frameset" insertion mode
|
|
2693
2826
|
//------------------------------------------------------------------
|
|
2694
2827
|
function startTagInFrameset(p, token) {
|
|
2695
|
-
|
|
2828
|
+
const tn = token.tagName;
|
|
2696
2829
|
|
|
2697
|
-
if (tn === $.HTML)
|
|
2830
|
+
if (tn === $.HTML) {
|
|
2698
2831
|
startTagInBody(p, token);
|
|
2699
|
-
|
|
2700
|
-
else if (tn === $.FRAMESET)
|
|
2832
|
+
} else if (tn === $.FRAMESET) {
|
|
2701
2833
|
p._insertElement(token, NS.HTML);
|
|
2702
|
-
|
|
2703
|
-
else if (tn === $.FRAME)
|
|
2834
|
+
} else if (tn === $.FRAME) {
|
|
2704
2835
|
p._appendElement(token, NS.HTML);
|
|
2705
|
-
|
|
2706
|
-
else if (tn === $.NOFRAMES)
|
|
2836
|
+
token.ackSelfClosing = true;
|
|
2837
|
+
} else if (tn === $.NOFRAMES) {
|
|
2707
2838
|
startTagInHead(p, token);
|
|
2839
|
+
}
|
|
2708
2840
|
}
|
|
2709
2841
|
|
|
2710
2842
|
function endTagInFrameset(p, token) {
|
|
2711
2843
|
if (token.tagName === $.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
|
|
2712
2844
|
p.openElements.pop();
|
|
2713
2845
|
|
|
2714
|
-
if (!p.fragmentContext && p.openElements.currentTagName !== $.FRAMESET)
|
|
2846
|
+
if (!p.fragmentContext && p.openElements.currentTagName !== $.FRAMESET) {
|
|
2715
2847
|
p.insertionMode = AFTER_FRAMESET_MODE;
|
|
2848
|
+
}
|
|
2716
2849
|
}
|
|
2717
2850
|
}
|
|
2718
2851
|
|
|
2719
|
-
//
|
|
2852
|
+
// The "after frameset" insertion mode
|
|
2720
2853
|
//------------------------------------------------------------------
|
|
2721
2854
|
function startTagAfterFrameset(p, token) {
|
|
2722
|
-
|
|
2855
|
+
const tn = token.tagName;
|
|
2723
2856
|
|
|
2724
|
-
if (tn === $.HTML)
|
|
2857
|
+
if (tn === $.HTML) {
|
|
2725
2858
|
startTagInBody(p, token);
|
|
2726
|
-
|
|
2727
|
-
else if (tn === $.NOFRAMES)
|
|
2859
|
+
} else if (tn === $.NOFRAMES) {
|
|
2728
2860
|
startTagInHead(p, token);
|
|
2861
|
+
}
|
|
2729
2862
|
}
|
|
2730
2863
|
|
|
2731
2864
|
function endTagAfterFrameset(p, token) {
|
|
2732
|
-
if (token.tagName === $.HTML)
|
|
2865
|
+
if (token.tagName === $.HTML) {
|
|
2733
2866
|
p.insertionMode = AFTER_AFTER_FRAMESET_MODE;
|
|
2867
|
+
}
|
|
2734
2868
|
}
|
|
2735
2869
|
|
|
2736
|
-
//
|
|
2870
|
+
// The "after after body" insertion mode
|
|
2737
2871
|
//------------------------------------------------------------------
|
|
2738
2872
|
function startTagAfterAfterBody(p, token) {
|
|
2739
|
-
if (token.tagName === $.HTML)
|
|
2873
|
+
if (token.tagName === $.HTML) {
|
|
2740
2874
|
startTagInBody(p, token);
|
|
2741
|
-
|
|
2742
|
-
else
|
|
2875
|
+
} else {
|
|
2743
2876
|
tokenAfterAfterBody(p, token);
|
|
2877
|
+
}
|
|
2744
2878
|
}
|
|
2745
2879
|
|
|
2746
2880
|
function tokenAfterAfterBody(p, token) {
|
|
@@ -2748,23 +2882,22 @@ function tokenAfterAfterBody(p, token) {
|
|
|
2748
2882
|
p._processToken(token);
|
|
2749
2883
|
}
|
|
2750
2884
|
|
|
2751
|
-
//
|
|
2885
|
+
// The "after after frameset" insertion mode
|
|
2752
2886
|
//------------------------------------------------------------------
|
|
2753
2887
|
function startTagAfterAfterFrameset(p, token) {
|
|
2754
|
-
|
|
2888
|
+
const tn = token.tagName;
|
|
2755
2889
|
|
|
2756
|
-
if (tn === $.HTML)
|
|
2890
|
+
if (tn === $.HTML) {
|
|
2757
2891
|
startTagInBody(p, token);
|
|
2758
|
-
|
|
2759
|
-
else if (tn === $.NOFRAMES)
|
|
2892
|
+
} else if (tn === $.NOFRAMES) {
|
|
2760
2893
|
startTagInHead(p, token);
|
|
2894
|
+
}
|
|
2761
2895
|
}
|
|
2762
2896
|
|
|
2763
|
-
|
|
2764
|
-
//12.2.5.5 The rules for parsing tokens in foreign content
|
|
2897
|
+
// The rules for parsing tokens in foreign content
|
|
2765
2898
|
//------------------------------------------------------------------
|
|
2766
2899
|
function nullCharacterInForeignContent(p, token) {
|
|
2767
|
-
token.chars =
|
|
2900
|
+
token.chars = unicode.REPLACEMENT_CHARACTER;
|
|
2768
2901
|
p._insertCharacters(token);
|
|
2769
2902
|
}
|
|
2770
2903
|
|
|
@@ -2775,36 +2908,40 @@ function characterInForeignContent(p, token) {
|
|
|
2775
2908
|
|
|
2776
2909
|
function startTagInForeignContent(p, token) {
|
|
2777
2910
|
if (foreignContent.causesExit(token) && !p.fragmentContext) {
|
|
2778
|
-
while (
|
|
2911
|
+
while (
|
|
2912
|
+
p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML &&
|
|
2913
|
+
!p._isIntegrationPoint(p.openElements.current)
|
|
2914
|
+
) {
|
|
2779
2915
|
p.openElements.pop();
|
|
2916
|
+
}
|
|
2780
2917
|
|
|
2781
2918
|
p._processToken(token);
|
|
2782
|
-
}
|
|
2919
|
+
} else {
|
|
2920
|
+
const current = p._getAdjustedCurrentElement();
|
|
2921
|
+
const currentNs = p.treeAdapter.getNamespaceURI(current);
|
|
2783
2922
|
|
|
2784
|
-
|
|
2785
|
-
var current = p._getAdjustedCurrentElement(),
|
|
2786
|
-
currentNs = p.treeAdapter.getNamespaceURI(current);
|
|
2787
|
-
|
|
2788
|
-
if (currentNs === NS.MATHML)
|
|
2923
|
+
if (currentNs === NS.MATHML) {
|
|
2789
2924
|
foreignContent.adjustTokenMathMLAttrs(token);
|
|
2790
|
-
|
|
2791
|
-
else if (currentNs === NS.SVG) {
|
|
2925
|
+
} else if (currentNs === NS.SVG) {
|
|
2792
2926
|
foreignContent.adjustTokenSVGTagName(token);
|
|
2793
2927
|
foreignContent.adjustTokenSVGAttrs(token);
|
|
2794
2928
|
}
|
|
2795
2929
|
|
|
2796
2930
|
foreignContent.adjustTokenXMLAttrs(token);
|
|
2797
2931
|
|
|
2798
|
-
if (token.selfClosing)
|
|
2932
|
+
if (token.selfClosing) {
|
|
2799
2933
|
p._appendElement(token, currentNs);
|
|
2800
|
-
else
|
|
2934
|
+
} else {
|
|
2801
2935
|
p._insertElement(token, currentNs);
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
token.ackSelfClosing = true;
|
|
2802
2939
|
}
|
|
2803
2940
|
}
|
|
2804
2941
|
|
|
2805
2942
|
function endTagInForeignContent(p, token) {
|
|
2806
|
-
for (
|
|
2807
|
-
|
|
2943
|
+
for (let i = p.openElements.stackTop; i > 0; i--) {
|
|
2944
|
+
const element = p.openElements.items[i];
|
|
2808
2945
|
|
|
2809
2946
|
if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
|
|
2810
2947
|
p._processToken(token);
|