|
1 /* |
|
2 * Copyright (c) 2007 Henri Sivonen |
|
3 * Copyright (c) 2007-2011 Mozilla Foundation |
|
4 * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla |
|
5 * Foundation, and Opera Software ASA. |
|
6 * |
|
7 * Permission is hereby granted, free of charge, to any person obtaining a |
|
8 * copy of this software and associated documentation files (the "Software"), |
|
9 * to deal in the Software without restriction, including without limitation |
|
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
11 * and/or sell copies of the Software, and to permit persons to whom the |
|
12 * Software is furnished to do so, subject to the following conditions: |
|
13 * |
|
14 * The above copyright notice and this permission notice shall be included in |
|
15 * all copies or substantial portions of the Software. |
|
16 * |
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
23 * DEALINGS IN THE SOFTWARE. |
|
24 */ |
|
25 |
|
26 /* |
|
27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT. |
|
28 * Please edit TreeBuilder.java instead and regenerate. |
|
29 */ |
|
30 |
|
31 #define nsHtml5TreeBuilder_cpp__ |
|
32 |
|
33 #include "nsContentUtils.h" |
|
34 #include "nsIAtom.h" |
|
35 #include "nsHtml5AtomTable.h" |
|
36 #include "nsITimer.h" |
|
37 #include "nsString.h" |
|
38 #include "nsNameSpaceManager.h" |
|
39 #include "nsIContent.h" |
|
40 #include "nsTraceRefcnt.h" |
|
41 #include "jArray.h" |
|
42 #include "nsHtml5DocumentMode.h" |
|
43 #include "nsHtml5ArrayCopy.h" |
|
44 #include "nsHtml5Parser.h" |
|
45 #include "nsHtml5Atoms.h" |
|
46 #include "nsHtml5TreeOperation.h" |
|
47 #include "nsHtml5PendingNotification.h" |
|
48 #include "nsHtml5StateSnapshot.h" |
|
49 #include "nsHtml5StackNode.h" |
|
50 #include "nsHtml5TreeOpExecutor.h" |
|
51 #include "nsHtml5StreamParser.h" |
|
52 #include "nsAHtml5TreeBuilderState.h" |
|
53 #include "nsHtml5Highlighter.h" |
|
54 #include "nsHtml5PlainTextUtils.h" |
|
55 #include "nsHtml5ViewSourceUtils.h" |
|
56 #include "mozilla/Likely.h" |
|
57 #include "nsIContentHandle.h" |
|
58 #include "nsHtml5OplessBuilder.h" |
|
59 |
|
60 #include "nsHtml5Tokenizer.h" |
|
61 #include "nsHtml5MetaScanner.h" |
|
62 #include "nsHtml5AttributeName.h" |
|
63 #include "nsHtml5ElementName.h" |
|
64 #include "nsHtml5HtmlAttributes.h" |
|
65 #include "nsHtml5StackNode.h" |
|
66 #include "nsHtml5UTF16Buffer.h" |
|
67 #include "nsHtml5StateSnapshot.h" |
|
68 #include "nsHtml5Portability.h" |
|
69 |
|
70 #include "nsHtml5TreeBuilder.h" |
|
71 |
|
72 char16_t nsHtml5TreeBuilder::REPLACEMENT_CHARACTER[] = { 0xfffd }; |
|
73 static const char* const QUIRKY_PUBLIC_IDS_DATA[] = { "+//silmaril//dtd html pro v0r11 19970101//", "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", "-//as//dtd html 3.0 aswedit + extensions//", "-//ietf//dtd html 2.0 level 1//", "-//ietf//dtd html 2.0 level 2//", "-//ietf//dtd html 2.0 strict level 1//", "-//ietf//dtd html 2.0 strict level 2//", "-//ietf//dtd html 2.0 strict//", "-//ietf//dtd html 2.0//", "-//ietf//dtd html 2.1e//", "-//ietf//dtd html 3.0//", "-//ietf//dtd html 3.2 final//", "-//ietf//dtd html 3.2//", "-//ietf//dtd html 3//", "-//ietf//dtd html level 0//", "-//ietf//dtd html level 1//", "-//ietf//dtd html level 2//", "-//ietf//dtd html level 3//", "-//ietf//dtd html strict level 0//", "-//ietf//dtd html strict level 1//", "-//ietf//dtd html strict level 2//", "-//ietf//dtd html strict level 3//", "-//ietf//dtd html strict//", "-//ietf//dtd html//", "-//metrius//dtd metrius presentational//", "-//microsoft//dtd internet explorer 2.0 html strict//", "-//microsoft//dtd internet explorer 2.0 html//", "-//microsoft//dtd internet explorer 2.0 tables//", "-//microsoft//dtd internet explorer 3.0 html strict//", "-//microsoft//dtd internet explorer 3.0 html//", "-//microsoft//dtd internet explorer 3.0 tables//", "-//netscape comm. corp.//dtd html//", "-//netscape comm. corp.//dtd strict html//", "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", "-//spyglass//dtd html 2.0 extended//", "-//sq//dtd html 2.0 hotmetal + extensions//", "-//sun microsystems corp.//dtd hotjava html//", "-//sun microsystems corp.//dtd hotjava strict html//", "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//", "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//", "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//", "-//w3c//dtd html 4.0 transitional//", "-//w3c//dtd html experimental 19960712//", "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//", "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//", "-//webtechs//dtd mozilla html//" }; |
|
74 staticJArray<const char*,int32_t> nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = { QUIRKY_PUBLIC_IDS_DATA, MOZ_ARRAY_LENGTH(QUIRKY_PUBLIC_IDS_DATA) }; |
|
75 void |
|
76 nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self) |
|
77 { |
|
78 tokenizer = self; |
|
79 stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(64); |
|
80 templateModeStack = jArray<int32_t,int32_t>::newJArray(64); |
|
81 listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(64); |
|
82 needToDropLF = false; |
|
83 originalMode = NS_HTML5TREE_BUILDER_INITIAL; |
|
84 templateModePtr = -1; |
|
85 currentPtr = -1; |
|
86 listPtr = -1; |
|
87 formPointer = nullptr; |
|
88 headPointer = nullptr; |
|
89 deepTreeSurrogateParent = nullptr; |
|
90 start(fragment); |
|
91 charBufferLen = 0; |
|
92 charBuffer = jArray<char16_t,int32_t>::newJArray(1024); |
|
93 framesetOk = true; |
|
94 if (fragment) { |
|
95 nsIContentHandle* elt; |
|
96 if (contextNode) { |
|
97 elt = contextNode; |
|
98 } else { |
|
99 elt = createHtmlElementSetAsRoot(tokenizer->emptyAttributes()); |
|
100 } |
|
101 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt); |
|
102 currentPtr++; |
|
103 stack[currentPtr] = node; |
|
104 if (nsHtml5Atoms::template_ == contextName) { |
|
105 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE); |
|
106 } |
|
107 resetTheInsertionMode(); |
|
108 formPointer = getFormPointerForContext(contextNode); |
|
109 if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) { |
|
110 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, contextName); |
|
111 } else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) { |
|
112 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, contextName); |
|
113 } else if (nsHtml5Atoms::plaintext == contextName) { |
|
114 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, contextName); |
|
115 } else if (nsHtml5Atoms::script == contextName) { |
|
116 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, contextName); |
|
117 } else { |
|
118 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName); |
|
119 } |
|
120 contextName = nullptr; |
|
121 contextNode = nullptr; |
|
122 } else { |
|
123 mode = NS_HTML5TREE_BUILDER_INITIAL; |
|
124 if (tokenizer->isViewingXmlSource()) { |
|
125 nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes()); |
|
126 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_SVG, nsHtml5Atoms::svg, elt); |
|
127 currentPtr++; |
|
128 stack[currentPtr] = node; |
|
129 } |
|
130 } |
|
131 } |
|
132 |
|
133 void |
|
134 nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks) |
|
135 { |
|
136 needToDropLF = false; |
|
137 if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) { |
|
138 nsString* emptyString = nsHtml5Portability::newEmptyString(); |
|
139 appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier); |
|
140 nsHtml5Portability::releaseString(emptyString); |
|
141 if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) { |
|
142 errQuirkyDoctype(); |
|
143 documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false); |
|
144 } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) { |
|
145 errAlmostStandardsDoctype(); |
|
146 documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, false); |
|
147 } else { |
|
148 documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, false); |
|
149 } |
|
150 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; |
|
151 return; |
|
152 } |
|
153 errStrayDoctype(); |
|
154 return; |
|
155 } |
|
156 |
|
157 void |
|
158 nsHtml5TreeBuilder::comment(char16_t* buf, int32_t start, int32_t length) |
|
159 { |
|
160 needToDropLF = false; |
|
161 if (!isInForeign()) { |
|
162 switch(mode) { |
|
163 case NS_HTML5TREE_BUILDER_INITIAL: |
|
164 case NS_HTML5TREE_BUILDER_BEFORE_HTML: |
|
165 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: |
|
166 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: { |
|
167 appendCommentToDocument(buf, start, length); |
|
168 return; |
|
169 } |
|
170 case NS_HTML5TREE_BUILDER_AFTER_BODY: { |
|
171 flushCharacters(); |
|
172 appendComment(stack[0]->node, buf, start, length); |
|
173 return; |
|
174 } |
|
175 default: { |
|
176 break; |
|
177 } |
|
178 } |
|
179 } |
|
180 flushCharacters(); |
|
181 appendComment(stack[currentPtr]->node, buf, start, length); |
|
182 return; |
|
183 } |
|
184 |
|
185 void |
|
186 nsHtml5TreeBuilder::characters(const char16_t* buf, int32_t start, int32_t length) |
|
187 { |
|
188 if (tokenizer->isViewingXmlSource()) { |
|
189 return; |
|
190 } |
|
191 if (needToDropLF) { |
|
192 needToDropLF = false; |
|
193 if (buf[start] == '\n') { |
|
194 start++; |
|
195 length--; |
|
196 if (!length) { |
|
197 return; |
|
198 } |
|
199 } |
|
200 } |
|
201 switch(mode) { |
|
202 case NS_HTML5TREE_BUILDER_IN_BODY: |
|
203 case NS_HTML5TREE_BUILDER_IN_CELL: |
|
204 case NS_HTML5TREE_BUILDER_IN_CAPTION: { |
|
205 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { |
|
206 reconstructTheActiveFormattingElements(); |
|
207 } |
|
208 } |
|
209 case NS_HTML5TREE_BUILDER_TEXT: { |
|
210 accumulateCharacters(buf, start, length); |
|
211 return; |
|
212 } |
|
213 case NS_HTML5TREE_BUILDER_IN_TABLE: |
|
214 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: |
|
215 case NS_HTML5TREE_BUILDER_IN_ROW: { |
|
216 accumulateCharactersForced(buf, start, length); |
|
217 return; |
|
218 } |
|
219 default: { |
|
220 int32_t end = start + length; |
|
221 for (int32_t i = start; i < end; i++) { |
|
222 switch(buf[i]) { |
|
223 case ' ': |
|
224 case '\t': |
|
225 case '\n': |
|
226 case '\r': |
|
227 case '\f': { |
|
228 switch(mode) { |
|
229 case NS_HTML5TREE_BUILDER_INITIAL: |
|
230 case NS_HTML5TREE_BUILDER_BEFORE_HTML: |
|
231 case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { |
|
232 start = i + 1; |
|
233 continue; |
|
234 } |
|
235 case NS_HTML5TREE_BUILDER_IN_HEAD: |
|
236 case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: |
|
237 case NS_HTML5TREE_BUILDER_AFTER_HEAD: |
|
238 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: |
|
239 case NS_HTML5TREE_BUILDER_IN_FRAMESET: |
|
240 case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: { |
|
241 continue; |
|
242 } |
|
243 case NS_HTML5TREE_BUILDER_FRAMESET_OK: |
|
244 case NS_HTML5TREE_BUILDER_IN_TEMPLATE: |
|
245 case NS_HTML5TREE_BUILDER_IN_BODY: |
|
246 case NS_HTML5TREE_BUILDER_IN_CELL: |
|
247 case NS_HTML5TREE_BUILDER_IN_CAPTION: { |
|
248 if (start < i) { |
|
249 accumulateCharacters(buf, start, i - start); |
|
250 start = i; |
|
251 } |
|
252 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { |
|
253 flushCharacters(); |
|
254 reconstructTheActiveFormattingElements(); |
|
255 } |
|
256 NS_HTML5_BREAK(charactersloop); |
|
257 } |
|
258 case NS_HTML5TREE_BUILDER_IN_SELECT: |
|
259 case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: { |
|
260 NS_HTML5_BREAK(charactersloop); |
|
261 } |
|
262 case NS_HTML5TREE_BUILDER_IN_TABLE: |
|
263 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: |
|
264 case NS_HTML5TREE_BUILDER_IN_ROW: { |
|
265 accumulateCharactersForced(buf, i, 1); |
|
266 start = i + 1; |
|
267 continue; |
|
268 } |
|
269 case NS_HTML5TREE_BUILDER_AFTER_BODY: |
|
270 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: |
|
271 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: { |
|
272 if (start < i) { |
|
273 accumulateCharacters(buf, start, i - start); |
|
274 start = i; |
|
275 } |
|
276 flushCharacters(); |
|
277 reconstructTheActiveFormattingElements(); |
|
278 continue; |
|
279 } |
|
280 } |
|
281 } |
|
282 default: { |
|
283 switch(mode) { |
|
284 case NS_HTML5TREE_BUILDER_INITIAL: { |
|
285 documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false); |
|
286 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; |
|
287 i--; |
|
288 continue; |
|
289 } |
|
290 case NS_HTML5TREE_BUILDER_BEFORE_HTML: { |
|
291 appendHtmlElementToDocumentAndPush(); |
|
292 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
293 i--; |
|
294 continue; |
|
295 } |
|
296 case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { |
|
297 if (start < i) { |
|
298 accumulateCharacters(buf, start, i - start); |
|
299 start = i; |
|
300 } |
|
301 flushCharacters(); |
|
302 appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
303 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
304 i--; |
|
305 continue; |
|
306 } |
|
307 case NS_HTML5TREE_BUILDER_IN_HEAD: { |
|
308 if (start < i) { |
|
309 accumulateCharacters(buf, start, i - start); |
|
310 start = i; |
|
311 } |
|
312 flushCharacters(); |
|
313 pop(); |
|
314 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
315 i--; |
|
316 continue; |
|
317 } |
|
318 case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { |
|
319 if (start < i) { |
|
320 accumulateCharacters(buf, start, i - start); |
|
321 start = i; |
|
322 } |
|
323 errNonSpaceInNoscriptInHead(); |
|
324 flushCharacters(); |
|
325 pop(); |
|
326 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
327 i--; |
|
328 continue; |
|
329 } |
|
330 case NS_HTML5TREE_BUILDER_AFTER_HEAD: { |
|
331 if (start < i) { |
|
332 accumulateCharacters(buf, start, i - start); |
|
333 start = i; |
|
334 } |
|
335 flushCharacters(); |
|
336 appendToCurrentNodeAndPushBodyElement(); |
|
337 mode = NS_HTML5TREE_BUILDER_FRAMESET_OK; |
|
338 i--; |
|
339 continue; |
|
340 } |
|
341 case NS_HTML5TREE_BUILDER_FRAMESET_OK: { |
|
342 framesetOk = false; |
|
343 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
344 i--; |
|
345 continue; |
|
346 } |
|
347 case NS_HTML5TREE_BUILDER_IN_TEMPLATE: |
|
348 case NS_HTML5TREE_BUILDER_IN_BODY: |
|
349 case NS_HTML5TREE_BUILDER_IN_CELL: |
|
350 case NS_HTML5TREE_BUILDER_IN_CAPTION: { |
|
351 if (start < i) { |
|
352 accumulateCharacters(buf, start, i - start); |
|
353 start = i; |
|
354 } |
|
355 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) { |
|
356 flushCharacters(); |
|
357 reconstructTheActiveFormattingElements(); |
|
358 } |
|
359 NS_HTML5_BREAK(charactersloop); |
|
360 } |
|
361 case NS_HTML5TREE_BUILDER_IN_TABLE: |
|
362 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: |
|
363 case NS_HTML5TREE_BUILDER_IN_ROW: { |
|
364 accumulateCharactersForced(buf, i, 1); |
|
365 start = i + 1; |
|
366 continue; |
|
367 } |
|
368 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: { |
|
369 if (start < i) { |
|
370 accumulateCharacters(buf, start, i - start); |
|
371 start = i; |
|
372 } |
|
373 if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
374 errNonSpaceInColgroupInFragment(); |
|
375 start = i + 1; |
|
376 continue; |
|
377 } |
|
378 flushCharacters(); |
|
379 pop(); |
|
380 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
381 i--; |
|
382 continue; |
|
383 } |
|
384 case NS_HTML5TREE_BUILDER_IN_SELECT: |
|
385 case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: { |
|
386 NS_HTML5_BREAK(charactersloop); |
|
387 } |
|
388 case NS_HTML5TREE_BUILDER_AFTER_BODY: { |
|
389 errNonSpaceAfterBody(); |
|
390 |
|
391 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
392 i--; |
|
393 continue; |
|
394 } |
|
395 case NS_HTML5TREE_BUILDER_IN_FRAMESET: { |
|
396 if (start < i) { |
|
397 accumulateCharacters(buf, start, i - start); |
|
398 start = i; |
|
399 } |
|
400 errNonSpaceInFrameset(); |
|
401 start = i + 1; |
|
402 continue; |
|
403 } |
|
404 case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: { |
|
405 if (start < i) { |
|
406 accumulateCharacters(buf, start, i - start); |
|
407 start = i; |
|
408 } |
|
409 errNonSpaceAfterFrameset(); |
|
410 start = i + 1; |
|
411 continue; |
|
412 } |
|
413 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: { |
|
414 errNonSpaceInTrailer(); |
|
415 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
416 i--; |
|
417 continue; |
|
418 } |
|
419 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: { |
|
420 errNonSpaceInTrailer(); |
|
421 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; |
|
422 i--; |
|
423 continue; |
|
424 } |
|
425 } |
|
426 } |
|
427 } |
|
428 } |
|
429 charactersloop_end: ; |
|
430 if (start < end) { |
|
431 accumulateCharacters(buf, start, end - start); |
|
432 } |
|
433 } |
|
434 } |
|
435 } |
|
436 |
|
437 void |
|
438 nsHtml5TreeBuilder::zeroOriginatingReplacementCharacter() |
|
439 { |
|
440 if (mode == NS_HTML5TREE_BUILDER_TEXT) { |
|
441 accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1); |
|
442 return; |
|
443 } |
|
444 if (currentPtr >= 0) { |
|
445 if (isSpecialParentInForeign(stack[currentPtr])) { |
|
446 return; |
|
447 } |
|
448 accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1); |
|
449 } |
|
450 } |
|
451 |
|
452 void |
|
453 nsHtml5TreeBuilder::eof() |
|
454 { |
|
455 flushCharacters(); |
|
456 for (; ; ) { |
|
457 switch(mode) { |
|
458 case NS_HTML5TREE_BUILDER_INITIAL: { |
|
459 documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false); |
|
460 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; |
|
461 continue; |
|
462 } |
|
463 case NS_HTML5TREE_BUILDER_BEFORE_HTML: { |
|
464 appendHtmlElementToDocumentAndPush(); |
|
465 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
466 continue; |
|
467 } |
|
468 case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { |
|
469 appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
470 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
471 continue; |
|
472 } |
|
473 case NS_HTML5TREE_BUILDER_IN_HEAD: { |
|
474 while (currentPtr > 0) { |
|
475 popOnEof(); |
|
476 } |
|
477 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
478 continue; |
|
479 } |
|
480 case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { |
|
481 while (currentPtr > 1) { |
|
482 popOnEof(); |
|
483 } |
|
484 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
485 continue; |
|
486 } |
|
487 case NS_HTML5TREE_BUILDER_AFTER_HEAD: { |
|
488 appendToCurrentNodeAndPushBodyElement(); |
|
489 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
490 continue; |
|
491 } |
|
492 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: |
|
493 case NS_HTML5TREE_BUILDER_IN_ROW: |
|
494 case NS_HTML5TREE_BUILDER_IN_TABLE: |
|
495 case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: |
|
496 case NS_HTML5TREE_BUILDER_IN_SELECT: |
|
497 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: |
|
498 case NS_HTML5TREE_BUILDER_FRAMESET_OK: |
|
499 case NS_HTML5TREE_BUILDER_IN_CAPTION: |
|
500 case NS_HTML5TREE_BUILDER_IN_CELL: |
|
501 case NS_HTML5TREE_BUILDER_IN_BODY: { |
|
502 if (isTemplateModeStackEmpty()) { |
|
503 NS_HTML5_BREAK(eofloop); |
|
504 } |
|
505 } |
|
506 case NS_HTML5TREE_BUILDER_IN_TEMPLATE: { |
|
507 int32_t eltPos = findLast(nsHtml5Atoms::template_); |
|
508 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
509 MOZ_ASSERT(fragment); |
|
510 NS_HTML5_BREAK(eofloop); |
|
511 } |
|
512 if (MOZ_UNLIKELY(mViewSource)) { |
|
513 errUnclosedElements(eltPos, nsHtml5Atoms::template_); |
|
514 } |
|
515 while (currentPtr >= eltPos) { |
|
516 pop(); |
|
517 } |
|
518 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
519 popTemplateMode(); |
|
520 resetTheInsertionMode(); |
|
521 continue; |
|
522 } |
|
523 case NS_HTML5TREE_BUILDER_TEXT: { |
|
524 if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { |
|
525 popOnEof(); |
|
526 } |
|
527 popOnEof(); |
|
528 mode = originalMode; |
|
529 continue; |
|
530 } |
|
531 case NS_HTML5TREE_BUILDER_IN_FRAMESET: { |
|
532 NS_HTML5_BREAK(eofloop); |
|
533 } |
|
534 case NS_HTML5TREE_BUILDER_AFTER_BODY: |
|
535 case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: |
|
536 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: |
|
537 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: |
|
538 default: { |
|
539 NS_HTML5_BREAK(eofloop); |
|
540 } |
|
541 } |
|
542 } |
|
543 eofloop_end: ; |
|
544 while (currentPtr > 0) { |
|
545 popOnEof(); |
|
546 } |
|
547 if (!fragment) { |
|
548 popOnEof(); |
|
549 } |
|
550 } |
|
551 |
|
552 void |
|
553 nsHtml5TreeBuilder::endTokenization() |
|
554 { |
|
555 formPointer = nullptr; |
|
556 headPointer = nullptr; |
|
557 deepTreeSurrogateParent = nullptr; |
|
558 templateModeStack = nullptr; |
|
559 if (stack) { |
|
560 while (currentPtr > -1) { |
|
561 stack[currentPtr]->release(); |
|
562 currentPtr--; |
|
563 } |
|
564 stack = nullptr; |
|
565 } |
|
566 if (listOfActiveFormattingElements) { |
|
567 while (listPtr > -1) { |
|
568 if (listOfActiveFormattingElements[listPtr]) { |
|
569 listOfActiveFormattingElements[listPtr]->release(); |
|
570 } |
|
571 listPtr--; |
|
572 } |
|
573 listOfActiveFormattingElements = nullptr; |
|
574 } |
|
575 charBuffer = nullptr; |
|
576 end(); |
|
577 } |
|
578 |
|
579 void |
|
580 nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing) |
|
581 { |
|
582 flushCharacters(); |
|
583 int32_t eltPos; |
|
584 needToDropLF = false; |
|
585 starttagloop: for (; ; ) { |
|
586 int32_t group = elementName->getGroup(); |
|
587 nsIAtom* name = elementName->name; |
|
588 if (isInForeign()) { |
|
589 nsHtml5StackNode* currentNode = stack[currentPtr]; |
|
590 int32_t currNs = currentNode->ns; |
|
591 if (!(currentNode->isHtmlIntegrationPoint() || (currNs == kNameSpaceID_MathML && ((currentNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT && group != NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK) || (currentNode->getGroup() == NS_HTML5TREE_BUILDER_ANNOTATION_XML && group == NS_HTML5TREE_BUILDER_SVG))))) { |
|
592 switch(group) { |
|
593 case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U: |
|
594 case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU: |
|
595 case NS_HTML5TREE_BUILDER_BODY: |
|
596 case NS_HTML5TREE_BUILDER_BR: |
|
597 case NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR: |
|
598 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
599 case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL: |
|
600 case NS_HTML5TREE_BUILDER_EMBED: |
|
601 case NS_HTML5TREE_BUILDER_IMG: |
|
602 case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: |
|
603 case NS_HTML5TREE_BUILDER_HEAD: |
|
604 case NS_HTML5TREE_BUILDER_HR: |
|
605 case NS_HTML5TREE_BUILDER_LI: |
|
606 case NS_HTML5TREE_BUILDER_META: |
|
607 case NS_HTML5TREE_BUILDER_NOBR: |
|
608 case NS_HTML5TREE_BUILDER_P: |
|
609 case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: |
|
610 case NS_HTML5TREE_BUILDER_TABLE: { |
|
611 errHtmlStartTagInForeignContext(name); |
|
612 while (!isSpecialParentInForeign(stack[currentPtr])) { |
|
613 pop(); |
|
614 } |
|
615 NS_HTML5_CONTINUE(starttagloop); |
|
616 } |
|
617 case NS_HTML5TREE_BUILDER_FONT: { |
|
618 if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) { |
|
619 errHtmlStartTagInForeignContext(name); |
|
620 while (!isSpecialParentInForeign(stack[currentPtr])) { |
|
621 pop(); |
|
622 } |
|
623 NS_HTML5_CONTINUE(starttagloop); |
|
624 } |
|
625 } |
|
626 default: { |
|
627 if (kNameSpaceID_SVG == currNs) { |
|
628 attributes->adjustForSvg(); |
|
629 if (selfClosing) { |
|
630 appendVoidElementToCurrentMayFosterSVG(elementName, attributes); |
|
631 selfClosing = false; |
|
632 } else { |
|
633 appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes); |
|
634 } |
|
635 attributes = nullptr; |
|
636 NS_HTML5_BREAK(starttagloop); |
|
637 } else { |
|
638 attributes->adjustForMath(); |
|
639 if (selfClosing) { |
|
640 appendVoidElementToCurrentMayFosterMathML(elementName, attributes); |
|
641 selfClosing = false; |
|
642 } else { |
|
643 appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes); |
|
644 } |
|
645 attributes = nullptr; |
|
646 NS_HTML5_BREAK(starttagloop); |
|
647 } |
|
648 } |
|
649 } |
|
650 } |
|
651 } |
|
652 switch(mode) { |
|
653 case NS_HTML5TREE_BUILDER_IN_TEMPLATE: { |
|
654 switch(group) { |
|
655 case NS_HTML5TREE_BUILDER_COL: { |
|
656 popTemplateMode(); |
|
657 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP); |
|
658 mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP; |
|
659 continue; |
|
660 } |
|
661 case NS_HTML5TREE_BUILDER_CAPTION: |
|
662 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
663 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
664 popTemplateMode(); |
|
665 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE); |
|
666 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
667 continue; |
|
668 } |
|
669 case NS_HTML5TREE_BUILDER_TR: { |
|
670 popTemplateMode(); |
|
671 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE_BODY); |
|
672 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
673 continue; |
|
674 } |
|
675 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
676 popTemplateMode(); |
|
677 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_ROW); |
|
678 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
679 continue; |
|
680 } |
|
681 case NS_HTML5TREE_BUILDER_META: { |
|
682 checkMetaCharset(attributes); |
|
683 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
684 selfClosing = false; |
|
685 attributes = nullptr; |
|
686 NS_HTML5_BREAK(starttagloop); |
|
687 } |
|
688 case NS_HTML5TREE_BUILDER_TITLE: { |
|
689 startTagTitleInHead(elementName, attributes); |
|
690 attributes = nullptr; |
|
691 NS_HTML5_BREAK(starttagloop); |
|
692 } |
|
693 case NS_HTML5TREE_BUILDER_BASE: |
|
694 case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: { |
|
695 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
696 selfClosing = false; |
|
697 attributes = nullptr; |
|
698 NS_HTML5_BREAK(starttagloop); |
|
699 } |
|
700 case NS_HTML5TREE_BUILDER_SCRIPT: { |
|
701 startTagScriptInHead(elementName, attributes); |
|
702 attributes = nullptr; |
|
703 NS_HTML5_BREAK(starttagloop); |
|
704 } |
|
705 case NS_HTML5TREE_BUILDER_NOFRAMES: |
|
706 case NS_HTML5TREE_BUILDER_STYLE: { |
|
707 startTagGenericRawText(elementName, attributes); |
|
708 attributes = nullptr; |
|
709 NS_HTML5_BREAK(starttagloop); |
|
710 } |
|
711 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
712 startTagTemplateInHead(elementName, attributes); |
|
713 attributes = nullptr; |
|
714 NS_HTML5_BREAK(starttagloop); |
|
715 } |
|
716 default: { |
|
717 popTemplateMode(); |
|
718 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_BODY); |
|
719 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
720 continue; |
|
721 } |
|
722 } |
|
723 } |
|
724 case NS_HTML5TREE_BUILDER_IN_ROW: { |
|
725 switch(group) { |
|
726 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
727 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR)); |
|
728 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
729 mode = NS_HTML5TREE_BUILDER_IN_CELL; |
|
730 insertMarker(); |
|
731 attributes = nullptr; |
|
732 NS_HTML5_BREAK(starttagloop); |
|
733 } |
|
734 case NS_HTML5TREE_BUILDER_CAPTION: |
|
735 case NS_HTML5TREE_BUILDER_COL: |
|
736 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
737 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
738 case NS_HTML5TREE_BUILDER_TR: { |
|
739 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); |
|
740 if (!eltPos) { |
|
741 MOZ_ASSERT(fragment || isTemplateContents()); |
|
742 errNoTableRowToClose(); |
|
743 NS_HTML5_BREAK(starttagloop); |
|
744 } |
|
745 clearStackBackTo(eltPos); |
|
746 pop(); |
|
747 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
748 continue; |
|
749 } |
|
750 default: |
|
751 ; // fall through |
|
752 } |
|
753 } |
|
754 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: { |
|
755 switch(group) { |
|
756 case NS_HTML5TREE_BUILDER_TR: { |
|
757 clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot()); |
|
758 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
759 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
760 attributes = nullptr; |
|
761 NS_HTML5_BREAK(starttagloop); |
|
762 } |
|
763 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
764 errStartTagInTableBody(name); |
|
765 clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot()); |
|
766 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
767 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
768 continue; |
|
769 } |
|
770 case NS_HTML5TREE_BUILDER_CAPTION: |
|
771 case NS_HTML5TREE_BUILDER_COL: |
|
772 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
773 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
774 eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot(); |
|
775 if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
776 MOZ_ASSERT(fragment || isTemplateContents()); |
|
777 errStrayStartTag(name); |
|
778 NS_HTML5_BREAK(starttagloop); |
|
779 } else { |
|
780 clearStackBackTo(eltPos); |
|
781 pop(); |
|
782 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
783 continue; |
|
784 } |
|
785 } |
|
786 default: |
|
787 ; // fall through |
|
788 } |
|
789 } |
|
790 case NS_HTML5TREE_BUILDER_IN_TABLE: { |
|
791 for (; ; ) { |
|
792 switch(group) { |
|
793 case NS_HTML5TREE_BUILDER_CAPTION: { |
|
794 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); |
|
795 insertMarker(); |
|
796 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
797 mode = NS_HTML5TREE_BUILDER_IN_CAPTION; |
|
798 attributes = nullptr; |
|
799 NS_HTML5_BREAK(starttagloop); |
|
800 } |
|
801 case NS_HTML5TREE_BUILDER_COLGROUP: { |
|
802 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); |
|
803 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
804 mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP; |
|
805 attributes = nullptr; |
|
806 NS_HTML5_BREAK(starttagloop); |
|
807 } |
|
808 case NS_HTML5TREE_BUILDER_COL: { |
|
809 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); |
|
810 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_COLGROUP, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
811 mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP; |
|
812 NS_HTML5_CONTINUE(starttagloop); |
|
813 } |
|
814 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
815 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); |
|
816 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
817 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
818 attributes = nullptr; |
|
819 NS_HTML5_BREAK(starttagloop); |
|
820 } |
|
821 case NS_HTML5TREE_BUILDER_TR: |
|
822 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
823 clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); |
|
824 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TBODY, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
825 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
826 NS_HTML5_CONTINUE(starttagloop); |
|
827 } |
|
828 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
829 NS_HTML5_BREAK(intableloop); |
|
830 } |
|
831 case NS_HTML5TREE_BUILDER_TABLE: { |
|
832 errTableSeenWhileTableOpen(); |
|
833 eltPos = findLastInTableScope(name); |
|
834 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
835 MOZ_ASSERT(fragment || isTemplateContents()); |
|
836 NS_HTML5_BREAK(starttagloop); |
|
837 } |
|
838 generateImpliedEndTags(); |
|
839 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::table)) { |
|
840 errNoCheckUnclosedElementsOnStack(); |
|
841 } |
|
842 while (currentPtr >= eltPos) { |
|
843 pop(); |
|
844 } |
|
845 resetTheInsertionMode(); |
|
846 NS_HTML5_CONTINUE(starttagloop); |
|
847 } |
|
848 case NS_HTML5TREE_BUILDER_SCRIPT: { |
|
849 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
850 originalMode = mode; |
|
851 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
852 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); |
|
853 attributes = nullptr; |
|
854 NS_HTML5_BREAK(starttagloop); |
|
855 } |
|
856 case NS_HTML5TREE_BUILDER_STYLE: { |
|
857 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
858 originalMode = mode; |
|
859 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
860 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
861 attributes = nullptr; |
|
862 NS_HTML5_BREAK(starttagloop); |
|
863 } |
|
864 case NS_HTML5TREE_BUILDER_INPUT: { |
|
865 errStartTagInTable(name); |
|
866 if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE))) { |
|
867 NS_HTML5_BREAK(intableloop); |
|
868 } |
|
869 appendVoidElementToCurrent(name, attributes, formPointer); |
|
870 selfClosing = false; |
|
871 attributes = nullptr; |
|
872 NS_HTML5_BREAK(starttagloop); |
|
873 } |
|
874 case NS_HTML5TREE_BUILDER_FORM: { |
|
875 if (!!formPointer || isTemplateContents()) { |
|
876 errFormWhenFormOpen(); |
|
877 NS_HTML5_BREAK(starttagloop); |
|
878 } else { |
|
879 errStartTagInTable(name); |
|
880 appendVoidFormToCurrent(attributes); |
|
881 attributes = nullptr; |
|
882 NS_HTML5_BREAK(starttagloop); |
|
883 } |
|
884 } |
|
885 default: { |
|
886 errStartTagInTable(name); |
|
887 NS_HTML5_BREAK(intableloop); |
|
888 } |
|
889 } |
|
890 } |
|
891 intableloop_end: ; |
|
892 } |
|
893 case NS_HTML5TREE_BUILDER_IN_CAPTION: { |
|
894 switch(group) { |
|
895 case NS_HTML5TREE_BUILDER_CAPTION: |
|
896 case NS_HTML5TREE_BUILDER_COL: |
|
897 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
898 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
899 case NS_HTML5TREE_BUILDER_TR: |
|
900 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
901 errStrayStartTag(name); |
|
902 eltPos = findLastInTableScope(nsHtml5Atoms::caption); |
|
903 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
904 NS_HTML5_BREAK(starttagloop); |
|
905 } |
|
906 generateImpliedEndTags(); |
|
907 if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) { |
|
908 errNoCheckUnclosedElementsOnStack(); |
|
909 } |
|
910 while (currentPtr >= eltPos) { |
|
911 pop(); |
|
912 } |
|
913 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
914 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
915 continue; |
|
916 } |
|
917 default: |
|
918 ; // fall through |
|
919 } |
|
920 } |
|
921 case NS_HTML5TREE_BUILDER_IN_CELL: { |
|
922 switch(group) { |
|
923 case NS_HTML5TREE_BUILDER_CAPTION: |
|
924 case NS_HTML5TREE_BUILDER_COL: |
|
925 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
926 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
927 case NS_HTML5TREE_BUILDER_TR: |
|
928 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
929 eltPos = findLastInTableScopeTdTh(); |
|
930 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
931 errNoCellToClose(); |
|
932 NS_HTML5_BREAK(starttagloop); |
|
933 } else { |
|
934 closeTheCell(eltPos); |
|
935 continue; |
|
936 } |
|
937 } |
|
938 default: |
|
939 ; // fall through |
|
940 } |
|
941 } |
|
942 case NS_HTML5TREE_BUILDER_FRAMESET_OK: { |
|
943 switch(group) { |
|
944 case NS_HTML5TREE_BUILDER_FRAMESET: { |
|
945 if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) { |
|
946 if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY) { |
|
947 MOZ_ASSERT(fragment || isTemplateContents()); |
|
948 errStrayStartTag(name); |
|
949 NS_HTML5_BREAK(starttagloop); |
|
950 } else { |
|
951 errFramesetStart(); |
|
952 detachFromParent(stack[1]->node); |
|
953 while (currentPtr > 0) { |
|
954 pop(); |
|
955 } |
|
956 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
957 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; |
|
958 attributes = nullptr; |
|
959 NS_HTML5_BREAK(starttagloop); |
|
960 } |
|
961 } else { |
|
962 errStrayStartTag(name); |
|
963 NS_HTML5_BREAK(starttagloop); |
|
964 } |
|
965 } |
|
966 case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: |
|
967 case NS_HTML5TREE_BUILDER_LI: |
|
968 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
969 case NS_HTML5TREE_BUILDER_BUTTON: |
|
970 case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: |
|
971 case NS_HTML5TREE_BUILDER_OBJECT: |
|
972 case NS_HTML5TREE_BUILDER_TABLE: |
|
973 case NS_HTML5TREE_BUILDER_AREA_OR_WBR: |
|
974 case NS_HTML5TREE_BUILDER_BR: |
|
975 case NS_HTML5TREE_BUILDER_EMBED: |
|
976 case NS_HTML5TREE_BUILDER_IMG: |
|
977 case NS_HTML5TREE_BUILDER_INPUT: |
|
978 case NS_HTML5TREE_BUILDER_KEYGEN: |
|
979 case NS_HTML5TREE_BUILDER_HR: |
|
980 case NS_HTML5TREE_BUILDER_TEXTAREA: |
|
981 case NS_HTML5TREE_BUILDER_XMP: |
|
982 case NS_HTML5TREE_BUILDER_IFRAME: |
|
983 case NS_HTML5TREE_BUILDER_SELECT: { |
|
984 if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK && !(group == NS_HTML5TREE_BUILDER_INPUT && nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE)))) { |
|
985 framesetOk = false; |
|
986 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
987 } |
|
988 } |
|
989 default: |
|
990 ; // fall through |
|
991 } |
|
992 } |
|
993 case NS_HTML5TREE_BUILDER_IN_BODY: { |
|
994 for (; ; ) { |
|
995 switch(group) { |
|
996 case NS_HTML5TREE_BUILDER_HTML: { |
|
997 errStrayStartTag(name); |
|
998 if (!fragment && !isTemplateContents()) { |
|
999 addAttributesToHtml(attributes); |
|
1000 attributes = nullptr; |
|
1001 } |
|
1002 NS_HTML5_BREAK(starttagloop); |
|
1003 } |
|
1004 case NS_HTML5TREE_BUILDER_BASE: |
|
1005 case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: |
|
1006 case NS_HTML5TREE_BUILDER_META: |
|
1007 case NS_HTML5TREE_BUILDER_STYLE: |
|
1008 case NS_HTML5TREE_BUILDER_SCRIPT: |
|
1009 case NS_HTML5TREE_BUILDER_TITLE: |
|
1010 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
1011 NS_HTML5_BREAK(inbodyloop); |
|
1012 } |
|
1013 case NS_HTML5TREE_BUILDER_BODY: { |
|
1014 if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY || isTemplateContents()) { |
|
1015 MOZ_ASSERT(fragment || isTemplateContents()); |
|
1016 errStrayStartTag(name); |
|
1017 NS_HTML5_BREAK(starttagloop); |
|
1018 } |
|
1019 errFooSeenWhenFooOpen(name); |
|
1020 framesetOk = false; |
|
1021 if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) { |
|
1022 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
1023 } |
|
1024 if (addAttributesToBody(attributes)) { |
|
1025 attributes = nullptr; |
|
1026 } |
|
1027 NS_HTML5_BREAK(starttagloop); |
|
1028 } |
|
1029 case NS_HTML5TREE_BUILDER_P: |
|
1030 case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU: |
|
1031 case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL: |
|
1032 case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: { |
|
1033 implicitlyCloseP(); |
|
1034 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1035 attributes = nullptr; |
|
1036 NS_HTML5_BREAK(starttagloop); |
|
1037 } |
|
1038 case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: { |
|
1039 implicitlyCloseP(); |
|
1040 if (stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) { |
|
1041 errHeadingWhenHeadingOpen(); |
|
1042 pop(); |
|
1043 } |
|
1044 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1045 attributes = nullptr; |
|
1046 NS_HTML5_BREAK(starttagloop); |
|
1047 } |
|
1048 case NS_HTML5TREE_BUILDER_FIELDSET: { |
|
1049 implicitlyCloseP(); |
|
1050 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1051 attributes = nullptr; |
|
1052 NS_HTML5_BREAK(starttagloop); |
|
1053 } |
|
1054 case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: { |
|
1055 implicitlyCloseP(); |
|
1056 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1057 needToDropLF = true; |
|
1058 attributes = nullptr; |
|
1059 NS_HTML5_BREAK(starttagloop); |
|
1060 } |
|
1061 case NS_HTML5TREE_BUILDER_FORM: { |
|
1062 if (!!formPointer && !isTemplateContents()) { |
|
1063 errFormWhenFormOpen(); |
|
1064 NS_HTML5_BREAK(starttagloop); |
|
1065 } else { |
|
1066 implicitlyCloseP(); |
|
1067 appendToCurrentNodeAndPushFormElementMayFoster(attributes); |
|
1068 attributes = nullptr; |
|
1069 NS_HTML5_BREAK(starttagloop); |
|
1070 } |
|
1071 } |
|
1072 case NS_HTML5TREE_BUILDER_LI: |
|
1073 case NS_HTML5TREE_BUILDER_DD_OR_DT: { |
|
1074 eltPos = currentPtr; |
|
1075 for (; ; ) { |
|
1076 nsHtml5StackNode* node = stack[eltPos]; |
|
1077 if (node->getGroup() == group) { |
|
1078 generateImpliedEndTagsExceptFor(node->name); |
|
1079 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
1080 errUnclosedElementsImplied(eltPos, name); |
|
1081 } |
|
1082 while (currentPtr >= eltPos) { |
|
1083 pop(); |
|
1084 } |
|
1085 break; |
|
1086 } else if (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div))) { |
|
1087 break; |
|
1088 } |
|
1089 eltPos--; |
|
1090 } |
|
1091 implicitlyCloseP(); |
|
1092 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1093 attributes = nullptr; |
|
1094 NS_HTML5_BREAK(starttagloop); |
|
1095 } |
|
1096 case NS_HTML5TREE_BUILDER_PLAINTEXT: { |
|
1097 implicitlyCloseP(); |
|
1098 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1099 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, elementName); |
|
1100 attributes = nullptr; |
|
1101 NS_HTML5_BREAK(starttagloop); |
|
1102 } |
|
1103 case NS_HTML5TREE_BUILDER_A: { |
|
1104 int32_t activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsHtml5Atoms::a); |
|
1105 if (activeAPos != -1) { |
|
1106 errFooSeenWhenFooOpen(name); |
|
1107 nsHtml5StackNode* activeA = listOfActiveFormattingElements[activeAPos]; |
|
1108 activeA->retain(); |
|
1109 adoptionAgencyEndTag(nsHtml5Atoms::a); |
|
1110 removeFromStack(activeA); |
|
1111 activeAPos = findInListOfActiveFormattingElements(activeA); |
|
1112 if (activeAPos != -1) { |
|
1113 removeFromListOfActiveFormattingElements(activeAPos); |
|
1114 } |
|
1115 activeA->release(); |
|
1116 } |
|
1117 reconstructTheActiveFormattingElements(); |
|
1118 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes); |
|
1119 attributes = nullptr; |
|
1120 NS_HTML5_BREAK(starttagloop); |
|
1121 } |
|
1122 case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U: |
|
1123 case NS_HTML5TREE_BUILDER_FONT: { |
|
1124 reconstructTheActiveFormattingElements(); |
|
1125 maybeForgetEarlierDuplicateFormattingElement(elementName->name, attributes); |
|
1126 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes); |
|
1127 attributes = nullptr; |
|
1128 NS_HTML5_BREAK(starttagloop); |
|
1129 } |
|
1130 case NS_HTML5TREE_BUILDER_NOBR: { |
|
1131 reconstructTheActiveFormattingElements(); |
|
1132 if (NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLastInScope(nsHtml5Atoms::nobr)) { |
|
1133 errFooSeenWhenFooOpen(name); |
|
1134 adoptionAgencyEndTag(nsHtml5Atoms::nobr); |
|
1135 reconstructTheActiveFormattingElements(); |
|
1136 } |
|
1137 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes); |
|
1138 attributes = nullptr; |
|
1139 NS_HTML5_BREAK(starttagloop); |
|
1140 } |
|
1141 case NS_HTML5TREE_BUILDER_BUTTON: { |
|
1142 eltPos = findLastInScope(name); |
|
1143 if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1144 errFooSeenWhenFooOpen(name); |
|
1145 generateImpliedEndTags(); |
|
1146 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
1147 errUnclosedElementsImplied(eltPos, name); |
|
1148 } |
|
1149 while (currentPtr >= eltPos) { |
|
1150 pop(); |
|
1151 } |
|
1152 NS_HTML5_CONTINUE(starttagloop); |
|
1153 } else { |
|
1154 reconstructTheActiveFormattingElements(); |
|
1155 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1156 attributes = nullptr; |
|
1157 NS_HTML5_BREAK(starttagloop); |
|
1158 } |
|
1159 } |
|
1160 case NS_HTML5TREE_BUILDER_OBJECT: { |
|
1161 reconstructTheActiveFormattingElements(); |
|
1162 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1163 insertMarker(); |
|
1164 attributes = nullptr; |
|
1165 NS_HTML5_BREAK(starttagloop); |
|
1166 } |
|
1167 case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: { |
|
1168 reconstructTheActiveFormattingElements(); |
|
1169 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1170 insertMarker(); |
|
1171 attributes = nullptr; |
|
1172 NS_HTML5_BREAK(starttagloop); |
|
1173 } |
|
1174 case NS_HTML5TREE_BUILDER_TABLE: { |
|
1175 if (!quirks) { |
|
1176 implicitlyCloseP(); |
|
1177 } |
|
1178 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1179 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
1180 attributes = nullptr; |
|
1181 NS_HTML5_BREAK(starttagloop); |
|
1182 } |
|
1183 case NS_HTML5TREE_BUILDER_BR: |
|
1184 case NS_HTML5TREE_BUILDER_EMBED: |
|
1185 case NS_HTML5TREE_BUILDER_AREA_OR_WBR: { |
|
1186 reconstructTheActiveFormattingElements(); |
|
1187 } |
|
1188 #ifdef ENABLE_VOID_MENUITEM |
|
1189 case NS_HTML5TREE_BUILDER_MENUITEM: |
|
1190 #endif |
|
1191 case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK: { |
|
1192 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1193 selfClosing = false; |
|
1194 attributes = nullptr; |
|
1195 NS_HTML5_BREAK(starttagloop); |
|
1196 } |
|
1197 case NS_HTML5TREE_BUILDER_HR: { |
|
1198 implicitlyCloseP(); |
|
1199 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1200 selfClosing = false; |
|
1201 attributes = nullptr; |
|
1202 NS_HTML5_BREAK(starttagloop); |
|
1203 } |
|
1204 case NS_HTML5TREE_BUILDER_IMAGE: { |
|
1205 errImage(); |
|
1206 elementName = nsHtml5ElementName::ELT_IMG; |
|
1207 NS_HTML5_CONTINUE(starttagloop); |
|
1208 } |
|
1209 case NS_HTML5TREE_BUILDER_IMG: |
|
1210 case NS_HTML5TREE_BUILDER_KEYGEN: |
|
1211 case NS_HTML5TREE_BUILDER_INPUT: { |
|
1212 reconstructTheActiveFormattingElements(); |
|
1213 appendVoidElementToCurrentMayFoster(name, attributes, formPointer); |
|
1214 selfClosing = false; |
|
1215 attributes = nullptr; |
|
1216 NS_HTML5_BREAK(starttagloop); |
|
1217 } |
|
1218 case NS_HTML5TREE_BUILDER_ISINDEX: { |
|
1219 errIsindex(); |
|
1220 if (!!formPointer && !isTemplateContents()) { |
|
1221 NS_HTML5_BREAK(starttagloop); |
|
1222 } |
|
1223 implicitlyCloseP(); |
|
1224 nsHtml5HtmlAttributes* formAttrs = new nsHtml5HtmlAttributes(0); |
|
1225 int32_t actionIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_ACTION); |
|
1226 if (actionIndex > -1) { |
|
1227 formAttrs->addAttribute(nsHtml5AttributeName::ATTR_ACTION, attributes->getValueNoBoundsCheck(actionIndex)); |
|
1228 } |
|
1229 appendToCurrentNodeAndPushFormElementMayFoster(formAttrs); |
|
1230 appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
1231 appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
1232 int32_t promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT); |
|
1233 if (promptIndex > -1) { |
|
1234 autoJArray<char16_t,int32_t> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValueNoBoundsCheck(promptIndex)); |
|
1235 appendCharacters(stack[currentPtr]->node, prompt, 0, prompt.length); |
|
1236 } else { |
|
1237 appendIsindexPrompt(stack[currentPtr]->node); |
|
1238 } |
|
1239 nsHtml5HtmlAttributes* inputAttributes = new nsHtml5HtmlAttributes(0); |
|
1240 inputAttributes->addAttribute(nsHtml5AttributeName::ATTR_NAME, nsHtml5Portability::newStringFromLiteral("isindex")); |
|
1241 for (int32_t i = 0; i < attributes->getLength(); i++) { |
|
1242 nsHtml5AttributeName* attributeQName = attributes->getAttributeNameNoBoundsCheck(i); |
|
1243 if (nsHtml5AttributeName::ATTR_NAME == attributeQName || nsHtml5AttributeName::ATTR_PROMPT == attributeQName) { |
|
1244 attributes->releaseValue(i); |
|
1245 } else if (nsHtml5AttributeName::ATTR_ACTION != attributeQName) { |
|
1246 inputAttributes->addAttribute(attributeQName, attributes->getValueNoBoundsCheck(i)); |
|
1247 } |
|
1248 } |
|
1249 attributes->clearWithoutReleasingContents(); |
|
1250 appendVoidElementToCurrentMayFoster(nsHtml5Atoms::input, inputAttributes, formPointer); |
|
1251 pop(); |
|
1252 appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
1253 pop(); |
|
1254 if (!isTemplateContents()) { |
|
1255 formPointer = nullptr; |
|
1256 } |
|
1257 selfClosing = false; |
|
1258 NS_HTML5_BREAK(starttagloop); |
|
1259 } |
|
1260 case NS_HTML5TREE_BUILDER_TEXTAREA: { |
|
1261 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1262 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName); |
|
1263 originalMode = mode; |
|
1264 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1265 needToDropLF = true; |
|
1266 attributes = nullptr; |
|
1267 NS_HTML5_BREAK(starttagloop); |
|
1268 } |
|
1269 case NS_HTML5TREE_BUILDER_XMP: { |
|
1270 implicitlyCloseP(); |
|
1271 reconstructTheActiveFormattingElements(); |
|
1272 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1273 originalMode = mode; |
|
1274 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1275 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1276 attributes = nullptr; |
|
1277 NS_HTML5_BREAK(starttagloop); |
|
1278 } |
|
1279 case NS_HTML5TREE_BUILDER_NOSCRIPT: { |
|
1280 if (!scriptingEnabled) { |
|
1281 reconstructTheActiveFormattingElements(); |
|
1282 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1283 attributes = nullptr; |
|
1284 NS_HTML5_BREAK(starttagloop); |
|
1285 } else { |
|
1286 } |
|
1287 } |
|
1288 case NS_HTML5TREE_BUILDER_NOFRAMES: |
|
1289 case NS_HTML5TREE_BUILDER_IFRAME: |
|
1290 case NS_HTML5TREE_BUILDER_NOEMBED: { |
|
1291 startTagGenericRawText(elementName, attributes); |
|
1292 attributes = nullptr; |
|
1293 NS_HTML5_BREAK(starttagloop); |
|
1294 } |
|
1295 case NS_HTML5TREE_BUILDER_SELECT: { |
|
1296 reconstructTheActiveFormattingElements(); |
|
1297 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1298 switch(mode) { |
|
1299 case NS_HTML5TREE_BUILDER_IN_TABLE: |
|
1300 case NS_HTML5TREE_BUILDER_IN_CAPTION: |
|
1301 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: |
|
1302 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: |
|
1303 case NS_HTML5TREE_BUILDER_IN_ROW: |
|
1304 case NS_HTML5TREE_BUILDER_IN_CELL: { |
|
1305 mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE; |
|
1306 break; |
|
1307 } |
|
1308 default: { |
|
1309 mode = NS_HTML5TREE_BUILDER_IN_SELECT; |
|
1310 break; |
|
1311 } |
|
1312 } |
|
1313 attributes = nullptr; |
|
1314 NS_HTML5_BREAK(starttagloop); |
|
1315 } |
|
1316 case NS_HTML5TREE_BUILDER_OPTGROUP: |
|
1317 case NS_HTML5TREE_BUILDER_OPTION: { |
|
1318 if (isCurrent(nsHtml5Atoms::option)) { |
|
1319 pop(); |
|
1320 } |
|
1321 reconstructTheActiveFormattingElements(); |
|
1322 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1323 attributes = nullptr; |
|
1324 NS_HTML5_BREAK(starttagloop); |
|
1325 } |
|
1326 case NS_HTML5TREE_BUILDER_RT_OR_RP: { |
|
1327 eltPos = findLastInScope(nsHtml5Atoms::ruby); |
|
1328 if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1329 generateImpliedEndTags(); |
|
1330 } |
|
1331 if (eltPos != currentPtr) { |
|
1332 if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1333 errStartTagSeenWithoutRuby(name); |
|
1334 } else { |
|
1335 errUnclosedChildrenInRuby(); |
|
1336 } |
|
1337 } |
|
1338 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1339 attributes = nullptr; |
|
1340 NS_HTML5_BREAK(starttagloop); |
|
1341 } |
|
1342 case NS_HTML5TREE_BUILDER_MATH: { |
|
1343 reconstructTheActiveFormattingElements(); |
|
1344 attributes->adjustForMath(); |
|
1345 if (selfClosing) { |
|
1346 appendVoidElementToCurrentMayFosterMathML(elementName, attributes); |
|
1347 selfClosing = false; |
|
1348 } else { |
|
1349 appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes); |
|
1350 } |
|
1351 attributes = nullptr; |
|
1352 NS_HTML5_BREAK(starttagloop); |
|
1353 } |
|
1354 case NS_HTML5TREE_BUILDER_SVG: { |
|
1355 reconstructTheActiveFormattingElements(); |
|
1356 attributes->adjustForSvg(); |
|
1357 if (selfClosing) { |
|
1358 appendVoidElementToCurrentMayFosterSVG(elementName, attributes); |
|
1359 selfClosing = false; |
|
1360 } else { |
|
1361 appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes); |
|
1362 } |
|
1363 attributes = nullptr; |
|
1364 NS_HTML5_BREAK(starttagloop); |
|
1365 } |
|
1366 case NS_HTML5TREE_BUILDER_CAPTION: |
|
1367 case NS_HTML5TREE_BUILDER_COL: |
|
1368 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
1369 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
1370 case NS_HTML5TREE_BUILDER_TR: |
|
1371 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
1372 case NS_HTML5TREE_BUILDER_FRAME: |
|
1373 case NS_HTML5TREE_BUILDER_FRAMESET: |
|
1374 case NS_HTML5TREE_BUILDER_HEAD: { |
|
1375 errStrayStartTag(name); |
|
1376 NS_HTML5_BREAK(starttagloop); |
|
1377 } |
|
1378 case NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL: { |
|
1379 reconstructTheActiveFormattingElements(); |
|
1380 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer); |
|
1381 attributes = nullptr; |
|
1382 NS_HTML5_BREAK(starttagloop); |
|
1383 } |
|
1384 default: { |
|
1385 reconstructTheActiveFormattingElements(); |
|
1386 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1387 attributes = nullptr; |
|
1388 NS_HTML5_BREAK(starttagloop); |
|
1389 } |
|
1390 } |
|
1391 } |
|
1392 inbodyloop_end: ; |
|
1393 } |
|
1394 case NS_HTML5TREE_BUILDER_IN_HEAD: { |
|
1395 for (; ; ) { |
|
1396 switch(group) { |
|
1397 case NS_HTML5TREE_BUILDER_HTML: { |
|
1398 errStrayStartTag(name); |
|
1399 if (!fragment && !isTemplateContents()) { |
|
1400 addAttributesToHtml(attributes); |
|
1401 attributes = nullptr; |
|
1402 } |
|
1403 NS_HTML5_BREAK(starttagloop); |
|
1404 } |
|
1405 case NS_HTML5TREE_BUILDER_BASE: |
|
1406 case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: { |
|
1407 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1408 selfClosing = false; |
|
1409 attributes = nullptr; |
|
1410 NS_HTML5_BREAK(starttagloop); |
|
1411 } |
|
1412 case NS_HTML5TREE_BUILDER_META: { |
|
1413 NS_HTML5_BREAK(inheadloop); |
|
1414 } |
|
1415 case NS_HTML5TREE_BUILDER_TITLE: { |
|
1416 startTagTitleInHead(elementName, attributes); |
|
1417 attributes = nullptr; |
|
1418 NS_HTML5_BREAK(starttagloop); |
|
1419 } |
|
1420 case NS_HTML5TREE_BUILDER_NOSCRIPT: { |
|
1421 if (scriptingEnabled) { |
|
1422 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1423 originalMode = mode; |
|
1424 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1425 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1426 } else { |
|
1427 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1428 mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT; |
|
1429 } |
|
1430 attributes = nullptr; |
|
1431 NS_HTML5_BREAK(starttagloop); |
|
1432 } |
|
1433 case NS_HTML5TREE_BUILDER_SCRIPT: { |
|
1434 startTagScriptInHead(elementName, attributes); |
|
1435 attributes = nullptr; |
|
1436 NS_HTML5_BREAK(starttagloop); |
|
1437 } |
|
1438 case NS_HTML5TREE_BUILDER_STYLE: |
|
1439 case NS_HTML5TREE_BUILDER_NOFRAMES: { |
|
1440 startTagGenericRawText(elementName, attributes); |
|
1441 attributes = nullptr; |
|
1442 NS_HTML5_BREAK(starttagloop); |
|
1443 } |
|
1444 case NS_HTML5TREE_BUILDER_HEAD: { |
|
1445 errFooSeenWhenFooOpen(name); |
|
1446 NS_HTML5_BREAK(starttagloop); |
|
1447 } |
|
1448 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
1449 startTagTemplateInHead(elementName, attributes); |
|
1450 attributes = nullptr; |
|
1451 NS_HTML5_BREAK(starttagloop); |
|
1452 } |
|
1453 default: { |
|
1454 pop(); |
|
1455 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
1456 NS_HTML5_CONTINUE(starttagloop); |
|
1457 } |
|
1458 } |
|
1459 } |
|
1460 inheadloop_end: ; |
|
1461 } |
|
1462 case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { |
|
1463 switch(group) { |
|
1464 case NS_HTML5TREE_BUILDER_HTML: { |
|
1465 errStrayStartTag(name); |
|
1466 if (!fragment && !isTemplateContents()) { |
|
1467 addAttributesToHtml(attributes); |
|
1468 attributes = nullptr; |
|
1469 } |
|
1470 NS_HTML5_BREAK(starttagloop); |
|
1471 } |
|
1472 case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: { |
|
1473 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1474 selfClosing = false; |
|
1475 attributes = nullptr; |
|
1476 NS_HTML5_BREAK(starttagloop); |
|
1477 } |
|
1478 case NS_HTML5TREE_BUILDER_META: { |
|
1479 checkMetaCharset(attributes); |
|
1480 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1481 selfClosing = false; |
|
1482 attributes = nullptr; |
|
1483 NS_HTML5_BREAK(starttagloop); |
|
1484 } |
|
1485 case NS_HTML5TREE_BUILDER_STYLE: |
|
1486 case NS_HTML5TREE_BUILDER_NOFRAMES: { |
|
1487 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1488 originalMode = mode; |
|
1489 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1490 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1491 attributes = nullptr; |
|
1492 NS_HTML5_BREAK(starttagloop); |
|
1493 } |
|
1494 case NS_HTML5TREE_BUILDER_HEAD: { |
|
1495 errFooSeenWhenFooOpen(name); |
|
1496 NS_HTML5_BREAK(starttagloop); |
|
1497 } |
|
1498 case NS_HTML5TREE_BUILDER_NOSCRIPT: { |
|
1499 errFooSeenWhenFooOpen(name); |
|
1500 NS_HTML5_BREAK(starttagloop); |
|
1501 } |
|
1502 default: { |
|
1503 errBadStartTagInHead(name); |
|
1504 pop(); |
|
1505 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
1506 continue; |
|
1507 } |
|
1508 } |
|
1509 } |
|
1510 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: { |
|
1511 switch(group) { |
|
1512 case NS_HTML5TREE_BUILDER_HTML: { |
|
1513 errStrayStartTag(name); |
|
1514 if (!fragment && !isTemplateContents()) { |
|
1515 addAttributesToHtml(attributes); |
|
1516 attributes = nullptr; |
|
1517 } |
|
1518 NS_HTML5_BREAK(starttagloop); |
|
1519 } |
|
1520 case NS_HTML5TREE_BUILDER_COL: { |
|
1521 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1522 selfClosing = false; |
|
1523 attributes = nullptr; |
|
1524 NS_HTML5_BREAK(starttagloop); |
|
1525 } |
|
1526 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
1527 startTagTemplateInHead(elementName, attributes); |
|
1528 attributes = nullptr; |
|
1529 NS_HTML5_BREAK(starttagloop); |
|
1530 } |
|
1531 default: { |
|
1532 if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
1533 MOZ_ASSERT(fragment || isTemplateContents()); |
|
1534 errGarbageInColgroup(); |
|
1535 NS_HTML5_BREAK(starttagloop); |
|
1536 } |
|
1537 pop(); |
|
1538 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
1539 continue; |
|
1540 } |
|
1541 } |
|
1542 } |
|
1543 case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: { |
|
1544 switch(group) { |
|
1545 case NS_HTML5TREE_BUILDER_CAPTION: |
|
1546 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
1547 case NS_HTML5TREE_BUILDER_TR: |
|
1548 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
1549 case NS_HTML5TREE_BUILDER_TABLE: { |
|
1550 errStartTagWithSelectOpen(name); |
|
1551 eltPos = findLastInTableScope(nsHtml5Atoms::select); |
|
1552 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1553 MOZ_ASSERT(fragment); |
|
1554 NS_HTML5_BREAK(starttagloop); |
|
1555 } |
|
1556 while (currentPtr >= eltPos) { |
|
1557 pop(); |
|
1558 } |
|
1559 resetTheInsertionMode(); |
|
1560 continue; |
|
1561 } |
|
1562 default: |
|
1563 ; // fall through |
|
1564 } |
|
1565 } |
|
1566 case NS_HTML5TREE_BUILDER_IN_SELECT: { |
|
1567 switch(group) { |
|
1568 case NS_HTML5TREE_BUILDER_HTML: { |
|
1569 errStrayStartTag(name); |
|
1570 if (!fragment) { |
|
1571 addAttributesToHtml(attributes); |
|
1572 attributes = nullptr; |
|
1573 } |
|
1574 NS_HTML5_BREAK(starttagloop); |
|
1575 } |
|
1576 case NS_HTML5TREE_BUILDER_OPTION: { |
|
1577 if (isCurrent(nsHtml5Atoms::option)) { |
|
1578 pop(); |
|
1579 } |
|
1580 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1581 attributes = nullptr; |
|
1582 NS_HTML5_BREAK(starttagloop); |
|
1583 } |
|
1584 case NS_HTML5TREE_BUILDER_OPTGROUP: { |
|
1585 if (isCurrent(nsHtml5Atoms::option)) { |
|
1586 pop(); |
|
1587 } |
|
1588 if (isCurrent(nsHtml5Atoms::optgroup)) { |
|
1589 pop(); |
|
1590 } |
|
1591 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1592 attributes = nullptr; |
|
1593 NS_HTML5_BREAK(starttagloop); |
|
1594 } |
|
1595 case NS_HTML5TREE_BUILDER_SELECT: { |
|
1596 errStartSelectWhereEndSelectExpected(); |
|
1597 eltPos = findLastInTableScope(name); |
|
1598 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1599 MOZ_ASSERT(fragment); |
|
1600 errNoSelectInTableScope(); |
|
1601 NS_HTML5_BREAK(starttagloop); |
|
1602 } else { |
|
1603 while (currentPtr >= eltPos) { |
|
1604 pop(); |
|
1605 } |
|
1606 resetTheInsertionMode(); |
|
1607 NS_HTML5_BREAK(starttagloop); |
|
1608 } |
|
1609 } |
|
1610 case NS_HTML5TREE_BUILDER_INPUT: |
|
1611 case NS_HTML5TREE_BUILDER_TEXTAREA: |
|
1612 case NS_HTML5TREE_BUILDER_KEYGEN: { |
|
1613 errStartTagWithSelectOpen(name); |
|
1614 eltPos = findLastInTableScope(nsHtml5Atoms::select); |
|
1615 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
1616 MOZ_ASSERT(fragment); |
|
1617 NS_HTML5_BREAK(starttagloop); |
|
1618 } |
|
1619 while (currentPtr >= eltPos) { |
|
1620 pop(); |
|
1621 } |
|
1622 resetTheInsertionMode(); |
|
1623 continue; |
|
1624 } |
|
1625 case NS_HTML5TREE_BUILDER_SCRIPT: { |
|
1626 startTagScriptInHead(elementName, attributes); |
|
1627 attributes = nullptr; |
|
1628 NS_HTML5_BREAK(starttagloop); |
|
1629 } |
|
1630 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
1631 startTagTemplateInHead(elementName, attributes); |
|
1632 attributes = nullptr; |
|
1633 NS_HTML5_BREAK(starttagloop); |
|
1634 } |
|
1635 default: { |
|
1636 errStrayStartTag(name); |
|
1637 NS_HTML5_BREAK(starttagloop); |
|
1638 } |
|
1639 } |
|
1640 } |
|
1641 case NS_HTML5TREE_BUILDER_AFTER_BODY: { |
|
1642 switch(group) { |
|
1643 case NS_HTML5TREE_BUILDER_HTML: { |
|
1644 errStrayStartTag(name); |
|
1645 if (!fragment && !isTemplateContents()) { |
|
1646 addAttributesToHtml(attributes); |
|
1647 attributes = nullptr; |
|
1648 } |
|
1649 NS_HTML5_BREAK(starttagloop); |
|
1650 } |
|
1651 default: { |
|
1652 errStrayStartTag(name); |
|
1653 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
1654 continue; |
|
1655 } |
|
1656 } |
|
1657 } |
|
1658 case NS_HTML5TREE_BUILDER_IN_FRAMESET: { |
|
1659 switch(group) { |
|
1660 case NS_HTML5TREE_BUILDER_FRAMESET: { |
|
1661 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1662 attributes = nullptr; |
|
1663 NS_HTML5_BREAK(starttagloop); |
|
1664 } |
|
1665 case NS_HTML5TREE_BUILDER_FRAME: { |
|
1666 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1667 selfClosing = false; |
|
1668 attributes = nullptr; |
|
1669 NS_HTML5_BREAK(starttagloop); |
|
1670 } |
|
1671 default: |
|
1672 ; // fall through |
|
1673 } |
|
1674 } |
|
1675 case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: { |
|
1676 switch(group) { |
|
1677 case NS_HTML5TREE_BUILDER_HTML: { |
|
1678 errStrayStartTag(name); |
|
1679 if (!fragment && !isTemplateContents()) { |
|
1680 addAttributesToHtml(attributes); |
|
1681 attributes = nullptr; |
|
1682 } |
|
1683 NS_HTML5_BREAK(starttagloop); |
|
1684 } |
|
1685 case NS_HTML5TREE_BUILDER_NOFRAMES: { |
|
1686 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1687 originalMode = mode; |
|
1688 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1689 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1690 attributes = nullptr; |
|
1691 NS_HTML5_BREAK(starttagloop); |
|
1692 } |
|
1693 default: { |
|
1694 errStrayStartTag(name); |
|
1695 NS_HTML5_BREAK(starttagloop); |
|
1696 } |
|
1697 } |
|
1698 } |
|
1699 case NS_HTML5TREE_BUILDER_INITIAL: { |
|
1700 errStartTagWithoutDoctype(); |
|
1701 documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false); |
|
1702 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; |
|
1703 continue; |
|
1704 } |
|
1705 case NS_HTML5TREE_BUILDER_BEFORE_HTML: { |
|
1706 switch(group) { |
|
1707 case NS_HTML5TREE_BUILDER_HTML: { |
|
1708 if (attributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) { |
|
1709 appendHtmlElementToDocumentAndPush(); |
|
1710 } else { |
|
1711 appendHtmlElementToDocumentAndPush(attributes); |
|
1712 } |
|
1713 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
1714 attributes = nullptr; |
|
1715 NS_HTML5_BREAK(starttagloop); |
|
1716 } |
|
1717 default: { |
|
1718 appendHtmlElementToDocumentAndPush(); |
|
1719 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
1720 continue; |
|
1721 } |
|
1722 } |
|
1723 } |
|
1724 case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { |
|
1725 switch(group) { |
|
1726 case NS_HTML5TREE_BUILDER_HTML: { |
|
1727 errStrayStartTag(name); |
|
1728 if (!fragment && !isTemplateContents()) { |
|
1729 addAttributesToHtml(attributes); |
|
1730 attributes = nullptr; |
|
1731 } |
|
1732 NS_HTML5_BREAK(starttagloop); |
|
1733 } |
|
1734 case NS_HTML5TREE_BUILDER_HEAD: { |
|
1735 appendToCurrentNodeAndPushHeadElement(attributes); |
|
1736 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
1737 attributes = nullptr; |
|
1738 NS_HTML5_BREAK(starttagloop); |
|
1739 } |
|
1740 default: { |
|
1741 appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
1742 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
1743 continue; |
|
1744 } |
|
1745 } |
|
1746 } |
|
1747 case NS_HTML5TREE_BUILDER_AFTER_HEAD: { |
|
1748 switch(group) { |
|
1749 case NS_HTML5TREE_BUILDER_HTML: { |
|
1750 errStrayStartTag(name); |
|
1751 if (!fragment && !isTemplateContents()) { |
|
1752 addAttributesToHtml(attributes); |
|
1753 attributes = nullptr; |
|
1754 } |
|
1755 NS_HTML5_BREAK(starttagloop); |
|
1756 } |
|
1757 case NS_HTML5TREE_BUILDER_BODY: { |
|
1758 if (!attributes->getLength()) { |
|
1759 appendToCurrentNodeAndPushBodyElement(); |
|
1760 } else { |
|
1761 appendToCurrentNodeAndPushBodyElement(attributes); |
|
1762 } |
|
1763 framesetOk = false; |
|
1764 mode = NS_HTML5TREE_BUILDER_IN_BODY; |
|
1765 attributes = nullptr; |
|
1766 NS_HTML5_BREAK(starttagloop); |
|
1767 } |
|
1768 case NS_HTML5TREE_BUILDER_FRAMESET: { |
|
1769 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1770 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; |
|
1771 attributes = nullptr; |
|
1772 NS_HTML5_BREAK(starttagloop); |
|
1773 } |
|
1774 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
1775 errFooBetweenHeadAndBody(name); |
|
1776 pushHeadPointerOntoStack(); |
|
1777 nsHtml5StackNode* headOnStack = stack[currentPtr]; |
|
1778 startTagTemplateInHead(elementName, attributes); |
|
1779 removeFromStack(headOnStack); |
|
1780 attributes = nullptr; |
|
1781 NS_HTML5_BREAK(starttagloop); |
|
1782 } |
|
1783 case NS_HTML5TREE_BUILDER_BASE: |
|
1784 case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: { |
|
1785 errFooBetweenHeadAndBody(name); |
|
1786 pushHeadPointerOntoStack(); |
|
1787 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1788 selfClosing = false; |
|
1789 pop(); |
|
1790 attributes = nullptr; |
|
1791 NS_HTML5_BREAK(starttagloop); |
|
1792 } |
|
1793 case NS_HTML5TREE_BUILDER_META: { |
|
1794 errFooBetweenHeadAndBody(name); |
|
1795 checkMetaCharset(attributes); |
|
1796 pushHeadPointerOntoStack(); |
|
1797 appendVoidElementToCurrentMayFoster(elementName, attributes); |
|
1798 selfClosing = false; |
|
1799 pop(); |
|
1800 attributes = nullptr; |
|
1801 NS_HTML5_BREAK(starttagloop); |
|
1802 } |
|
1803 case NS_HTML5TREE_BUILDER_SCRIPT: { |
|
1804 errFooBetweenHeadAndBody(name); |
|
1805 pushHeadPointerOntoStack(); |
|
1806 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1807 originalMode = mode; |
|
1808 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1809 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); |
|
1810 attributes = nullptr; |
|
1811 NS_HTML5_BREAK(starttagloop); |
|
1812 } |
|
1813 case NS_HTML5TREE_BUILDER_STYLE: |
|
1814 case NS_HTML5TREE_BUILDER_NOFRAMES: { |
|
1815 errFooBetweenHeadAndBody(name); |
|
1816 pushHeadPointerOntoStack(); |
|
1817 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1818 originalMode = mode; |
|
1819 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1820 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1821 attributes = nullptr; |
|
1822 NS_HTML5_BREAK(starttagloop); |
|
1823 } |
|
1824 case NS_HTML5TREE_BUILDER_TITLE: { |
|
1825 errFooBetweenHeadAndBody(name); |
|
1826 pushHeadPointerOntoStack(); |
|
1827 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1828 originalMode = mode; |
|
1829 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1830 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName); |
|
1831 attributes = nullptr; |
|
1832 NS_HTML5_BREAK(starttagloop); |
|
1833 } |
|
1834 case NS_HTML5TREE_BUILDER_HEAD: { |
|
1835 errStrayStartTag(name); |
|
1836 NS_HTML5_BREAK(starttagloop); |
|
1837 } |
|
1838 default: { |
|
1839 appendToCurrentNodeAndPushBodyElement(); |
|
1840 mode = NS_HTML5TREE_BUILDER_FRAMESET_OK; |
|
1841 continue; |
|
1842 } |
|
1843 } |
|
1844 } |
|
1845 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: { |
|
1846 switch(group) { |
|
1847 case NS_HTML5TREE_BUILDER_HTML: { |
|
1848 errStrayStartTag(name); |
|
1849 if (!fragment && !isTemplateContents()) { |
|
1850 addAttributesToHtml(attributes); |
|
1851 attributes = nullptr; |
|
1852 } |
|
1853 NS_HTML5_BREAK(starttagloop); |
|
1854 } |
|
1855 default: { |
|
1856 errStrayStartTag(name); |
|
1857 |
|
1858 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
1859 continue; |
|
1860 } |
|
1861 } |
|
1862 } |
|
1863 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: { |
|
1864 switch(group) { |
|
1865 case NS_HTML5TREE_BUILDER_HTML: { |
|
1866 errStrayStartTag(name); |
|
1867 if (!fragment && !isTemplateContents()) { |
|
1868 addAttributesToHtml(attributes); |
|
1869 attributes = nullptr; |
|
1870 } |
|
1871 NS_HTML5_BREAK(starttagloop); |
|
1872 } |
|
1873 case NS_HTML5TREE_BUILDER_NOFRAMES: { |
|
1874 startTagGenericRawText(elementName, attributes); |
|
1875 attributes = nullptr; |
|
1876 NS_HTML5_BREAK(starttagloop); |
|
1877 } |
|
1878 default: { |
|
1879 errStrayStartTag(name); |
|
1880 NS_HTML5_BREAK(starttagloop); |
|
1881 } |
|
1882 } |
|
1883 } |
|
1884 case NS_HTML5TREE_BUILDER_TEXT: { |
|
1885 MOZ_ASSERT(false); |
|
1886 NS_HTML5_BREAK(starttagloop); |
|
1887 } |
|
1888 } |
|
1889 } |
|
1890 starttagloop_end: ; |
|
1891 if (selfClosing) { |
|
1892 errSelfClosing(); |
|
1893 } |
|
1894 if (!mBuilder && attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) { |
|
1895 delete attributes; |
|
1896 } |
|
1897 } |
|
1898 |
|
1899 void |
|
1900 nsHtml5TreeBuilder::startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
1901 { |
|
1902 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1903 originalMode = mode; |
|
1904 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1905 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName); |
|
1906 } |
|
1907 |
|
1908 void |
|
1909 nsHtml5TreeBuilder::startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
1910 { |
|
1911 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1912 originalMode = mode; |
|
1913 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1914 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName); |
|
1915 } |
|
1916 |
|
1917 void |
|
1918 nsHtml5TreeBuilder::startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
1919 { |
|
1920 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); |
|
1921 originalMode = mode; |
|
1922 mode = NS_HTML5TREE_BUILDER_TEXT; |
|
1923 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); |
|
1924 } |
|
1925 |
|
1926 void |
|
1927 nsHtml5TreeBuilder::startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
1928 { |
|
1929 appendToCurrentNodeAndPushElement(elementName, attributes); |
|
1930 insertMarker(); |
|
1931 framesetOk = false; |
|
1932 originalMode = mode; |
|
1933 mode = NS_HTML5TREE_BUILDER_IN_TEMPLATE; |
|
1934 pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE); |
|
1935 } |
|
1936 |
|
1937 bool |
|
1938 nsHtml5TreeBuilder::isTemplateContents() |
|
1939 { |
|
1940 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_); |
|
1941 } |
|
1942 |
|
1943 bool |
|
1944 nsHtml5TreeBuilder::isTemplateModeStackEmpty() |
|
1945 { |
|
1946 return templateModePtr == -1; |
|
1947 } |
|
1948 |
|
1949 bool |
|
1950 nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode) |
|
1951 { |
|
1952 int32_t ns = stackNode->ns; |
|
1953 return (kNameSpaceID_XHTML == ns) || (stackNode->isHtmlIntegrationPoint()) || ((kNameSpaceID_MathML == ns) && (stackNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT)); |
|
1954 } |
|
1955 |
|
1956 nsString* |
|
1957 nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue) |
|
1958 { |
|
1959 int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
1960 int32_t start = -1; |
|
1961 int32_t end = -1; |
|
1962 autoJArray<char16_t,int32_t> buffer = nsHtml5Portability::newCharArrayFromString(attributeValue); |
|
1963 for (int32_t i = 0; i < buffer.length; i++) { |
|
1964 char16_t c = buffer[i]; |
|
1965 switch(charsetState) { |
|
1966 case NS_HTML5TREE_BUILDER_CHARSET_INITIAL: { |
|
1967 switch(c) { |
|
1968 case 'c': |
|
1969 case 'C': { |
|
1970 charsetState = NS_HTML5TREE_BUILDER_CHARSET_C; |
|
1971 continue; |
|
1972 } |
|
1973 default: { |
|
1974 continue; |
|
1975 } |
|
1976 } |
|
1977 } |
|
1978 case NS_HTML5TREE_BUILDER_CHARSET_C: { |
|
1979 switch(c) { |
|
1980 case 'h': |
|
1981 case 'H': { |
|
1982 charsetState = NS_HTML5TREE_BUILDER_CHARSET_H; |
|
1983 continue; |
|
1984 } |
|
1985 default: { |
|
1986 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
1987 continue; |
|
1988 } |
|
1989 } |
|
1990 } |
|
1991 case NS_HTML5TREE_BUILDER_CHARSET_H: { |
|
1992 switch(c) { |
|
1993 case 'a': |
|
1994 case 'A': { |
|
1995 charsetState = NS_HTML5TREE_BUILDER_CHARSET_A; |
|
1996 continue; |
|
1997 } |
|
1998 default: { |
|
1999 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
2000 continue; |
|
2001 } |
|
2002 } |
|
2003 } |
|
2004 case NS_HTML5TREE_BUILDER_CHARSET_A: { |
|
2005 switch(c) { |
|
2006 case 'r': |
|
2007 case 'R': { |
|
2008 charsetState = NS_HTML5TREE_BUILDER_CHARSET_R; |
|
2009 continue; |
|
2010 } |
|
2011 default: { |
|
2012 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
2013 continue; |
|
2014 } |
|
2015 } |
|
2016 } |
|
2017 case NS_HTML5TREE_BUILDER_CHARSET_R: { |
|
2018 switch(c) { |
|
2019 case 's': |
|
2020 case 'S': { |
|
2021 charsetState = NS_HTML5TREE_BUILDER_CHARSET_S; |
|
2022 continue; |
|
2023 } |
|
2024 default: { |
|
2025 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
2026 continue; |
|
2027 } |
|
2028 } |
|
2029 } |
|
2030 case NS_HTML5TREE_BUILDER_CHARSET_S: { |
|
2031 switch(c) { |
|
2032 case 'e': |
|
2033 case 'E': { |
|
2034 charsetState = NS_HTML5TREE_BUILDER_CHARSET_E; |
|
2035 continue; |
|
2036 } |
|
2037 default: { |
|
2038 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
2039 continue; |
|
2040 } |
|
2041 } |
|
2042 } |
|
2043 case NS_HTML5TREE_BUILDER_CHARSET_E: { |
|
2044 switch(c) { |
|
2045 case 't': |
|
2046 case 'T': { |
|
2047 charsetState = NS_HTML5TREE_BUILDER_CHARSET_T; |
|
2048 continue; |
|
2049 } |
|
2050 default: { |
|
2051 charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; |
|
2052 continue; |
|
2053 } |
|
2054 } |
|
2055 } |
|
2056 case NS_HTML5TREE_BUILDER_CHARSET_T: { |
|
2057 switch(c) { |
|
2058 case '\t': |
|
2059 case '\n': |
|
2060 case '\f': |
|
2061 case '\r': |
|
2062 case ' ': { |
|
2063 continue; |
|
2064 } |
|
2065 case '=': { |
|
2066 charsetState = NS_HTML5TREE_BUILDER_CHARSET_EQUALS; |
|
2067 continue; |
|
2068 } |
|
2069 default: { |
|
2070 return nullptr; |
|
2071 } |
|
2072 } |
|
2073 } |
|
2074 case NS_HTML5TREE_BUILDER_CHARSET_EQUALS: { |
|
2075 switch(c) { |
|
2076 case '\t': |
|
2077 case '\n': |
|
2078 case '\f': |
|
2079 case '\r': |
|
2080 case ' ': { |
|
2081 continue; |
|
2082 } |
|
2083 case '\'': { |
|
2084 start = i + 1; |
|
2085 charsetState = NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED; |
|
2086 continue; |
|
2087 } |
|
2088 case '\"': { |
|
2089 start = i + 1; |
|
2090 charsetState = NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED; |
|
2091 continue; |
|
2092 } |
|
2093 default: { |
|
2094 start = i; |
|
2095 charsetState = NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED; |
|
2096 continue; |
|
2097 } |
|
2098 } |
|
2099 } |
|
2100 case NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED: { |
|
2101 switch(c) { |
|
2102 case '\'': { |
|
2103 end = i; |
|
2104 NS_HTML5_BREAK(charsetloop); |
|
2105 } |
|
2106 default: { |
|
2107 continue; |
|
2108 } |
|
2109 } |
|
2110 } |
|
2111 case NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED: { |
|
2112 switch(c) { |
|
2113 case '\"': { |
|
2114 end = i; |
|
2115 NS_HTML5_BREAK(charsetloop); |
|
2116 } |
|
2117 default: { |
|
2118 continue; |
|
2119 } |
|
2120 } |
|
2121 } |
|
2122 case NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED: { |
|
2123 switch(c) { |
|
2124 case '\t': |
|
2125 case '\n': |
|
2126 case '\f': |
|
2127 case '\r': |
|
2128 case ' ': |
|
2129 case ';': { |
|
2130 end = i; |
|
2131 NS_HTML5_BREAK(charsetloop); |
|
2132 } |
|
2133 default: { |
|
2134 continue; |
|
2135 } |
|
2136 } |
|
2137 } |
|
2138 } |
|
2139 } |
|
2140 charsetloop_end: ; |
|
2141 nsString* charset = nullptr; |
|
2142 if (start != -1) { |
|
2143 if (end == -1) { |
|
2144 end = buffer.length; |
|
2145 } |
|
2146 charset = nsHtml5Portability::newStringFromBuffer(buffer, start, end - start); |
|
2147 } |
|
2148 return charset; |
|
2149 } |
|
2150 |
|
2151 void |
|
2152 nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes) |
|
2153 { |
|
2154 nsString* charset = attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET); |
|
2155 if (charset) { |
|
2156 if (tokenizer->internalEncodingDeclaration(charset)) { |
|
2157 requestSuspension(); |
|
2158 return; |
|
2159 } |
|
2160 return; |
|
2161 } |
|
2162 if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) { |
|
2163 return; |
|
2164 } |
|
2165 nsString* content = attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT); |
|
2166 if (content) { |
|
2167 nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content); |
|
2168 if (extract) { |
|
2169 if (tokenizer->internalEncodingDeclaration(extract)) { |
|
2170 requestSuspension(); |
|
2171 } |
|
2172 } |
|
2173 nsHtml5Portability::releaseString(extract); |
|
2174 } |
|
2175 } |
|
2176 |
|
2177 void |
|
2178 nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) |
|
2179 { |
|
2180 flushCharacters(); |
|
2181 needToDropLF = false; |
|
2182 int32_t eltPos; |
|
2183 int32_t group = elementName->getGroup(); |
|
2184 nsIAtom* name = elementName->name; |
|
2185 for (; ; ) { |
|
2186 if (isInForeign()) { |
|
2187 if (stack[currentPtr]->name != name) { |
|
2188 errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr]->popName); |
|
2189 } |
|
2190 eltPos = currentPtr; |
|
2191 for (; ; ) { |
|
2192 if (stack[eltPos]->name == name) { |
|
2193 while (currentPtr >= eltPos) { |
|
2194 pop(); |
|
2195 } |
|
2196 NS_HTML5_BREAK(endtagloop); |
|
2197 } |
|
2198 if (stack[--eltPos]->ns == kNameSpaceID_XHTML) { |
|
2199 break; |
|
2200 } |
|
2201 } |
|
2202 } |
|
2203 switch(mode) { |
|
2204 case NS_HTML5TREE_BUILDER_IN_TEMPLATE: { |
|
2205 switch(group) { |
|
2206 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2207 break; |
|
2208 } |
|
2209 default: { |
|
2210 errStrayEndTag(name); |
|
2211 NS_HTML5_BREAK(endtagloop); |
|
2212 } |
|
2213 } |
|
2214 } |
|
2215 case NS_HTML5TREE_BUILDER_IN_ROW: { |
|
2216 switch(group) { |
|
2217 case NS_HTML5TREE_BUILDER_TR: { |
|
2218 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); |
|
2219 if (!eltPos) { |
|
2220 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2221 errNoTableRowToClose(); |
|
2222 NS_HTML5_BREAK(endtagloop); |
|
2223 } |
|
2224 clearStackBackTo(eltPos); |
|
2225 pop(); |
|
2226 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
2227 NS_HTML5_BREAK(endtagloop); |
|
2228 } |
|
2229 case NS_HTML5TREE_BUILDER_TABLE: { |
|
2230 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); |
|
2231 if (!eltPos) { |
|
2232 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2233 errNoTableRowToClose(); |
|
2234 NS_HTML5_BREAK(endtagloop); |
|
2235 } |
|
2236 clearStackBackTo(eltPos); |
|
2237 pop(); |
|
2238 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
2239 continue; |
|
2240 } |
|
2241 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
2242 if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2243 errStrayEndTag(name); |
|
2244 NS_HTML5_BREAK(endtagloop); |
|
2245 } |
|
2246 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); |
|
2247 if (!eltPos) { |
|
2248 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2249 errNoTableRowToClose(); |
|
2250 NS_HTML5_BREAK(endtagloop); |
|
2251 } |
|
2252 clearStackBackTo(eltPos); |
|
2253 pop(); |
|
2254 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
2255 continue; |
|
2256 } |
|
2257 case NS_HTML5TREE_BUILDER_BODY: |
|
2258 case NS_HTML5TREE_BUILDER_CAPTION: |
|
2259 case NS_HTML5TREE_BUILDER_COL: |
|
2260 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
2261 case NS_HTML5TREE_BUILDER_HTML: |
|
2262 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
2263 errStrayEndTag(name); |
|
2264 NS_HTML5_BREAK(endtagloop); |
|
2265 } |
|
2266 default: |
|
2267 ; // fall through |
|
2268 } |
|
2269 } |
|
2270 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: { |
|
2271 switch(group) { |
|
2272 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
2273 eltPos = findLastOrRoot(name); |
|
2274 if (!eltPos) { |
|
2275 errStrayEndTag(name); |
|
2276 NS_HTML5_BREAK(endtagloop); |
|
2277 } |
|
2278 clearStackBackTo(eltPos); |
|
2279 pop(); |
|
2280 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2281 NS_HTML5_BREAK(endtagloop); |
|
2282 } |
|
2283 case NS_HTML5TREE_BUILDER_TABLE: { |
|
2284 eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot(); |
|
2285 if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
2286 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2287 errStrayEndTag(name); |
|
2288 NS_HTML5_BREAK(endtagloop); |
|
2289 } |
|
2290 clearStackBackTo(eltPos); |
|
2291 pop(); |
|
2292 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2293 continue; |
|
2294 } |
|
2295 case NS_HTML5TREE_BUILDER_BODY: |
|
2296 case NS_HTML5TREE_BUILDER_CAPTION: |
|
2297 case NS_HTML5TREE_BUILDER_COL: |
|
2298 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
2299 case NS_HTML5TREE_BUILDER_HTML: |
|
2300 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
2301 case NS_HTML5TREE_BUILDER_TR: { |
|
2302 errStrayEndTag(name); |
|
2303 NS_HTML5_BREAK(endtagloop); |
|
2304 } |
|
2305 default: |
|
2306 ; // fall through |
|
2307 } |
|
2308 } |
|
2309 case NS_HTML5TREE_BUILDER_IN_TABLE: { |
|
2310 switch(group) { |
|
2311 case NS_HTML5TREE_BUILDER_TABLE: { |
|
2312 eltPos = findLast(nsHtml5Atoms::table); |
|
2313 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2314 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2315 errStrayEndTag(name); |
|
2316 NS_HTML5_BREAK(endtagloop); |
|
2317 } |
|
2318 while (currentPtr >= eltPos) { |
|
2319 pop(); |
|
2320 } |
|
2321 resetTheInsertionMode(); |
|
2322 NS_HTML5_BREAK(endtagloop); |
|
2323 } |
|
2324 case NS_HTML5TREE_BUILDER_BODY: |
|
2325 case NS_HTML5TREE_BUILDER_CAPTION: |
|
2326 case NS_HTML5TREE_BUILDER_COL: |
|
2327 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
2328 case NS_HTML5TREE_BUILDER_HTML: |
|
2329 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
2330 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
2331 case NS_HTML5TREE_BUILDER_TR: { |
|
2332 errStrayEndTag(name); |
|
2333 NS_HTML5_BREAK(endtagloop); |
|
2334 } |
|
2335 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2336 break; |
|
2337 } |
|
2338 default: { |
|
2339 errStrayEndTag(name); |
|
2340 } |
|
2341 } |
|
2342 } |
|
2343 case NS_HTML5TREE_BUILDER_IN_CAPTION: { |
|
2344 switch(group) { |
|
2345 case NS_HTML5TREE_BUILDER_CAPTION: { |
|
2346 eltPos = findLastInTableScope(nsHtml5Atoms::caption); |
|
2347 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2348 NS_HTML5_BREAK(endtagloop); |
|
2349 } |
|
2350 generateImpliedEndTags(); |
|
2351 if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) { |
|
2352 errUnclosedElements(eltPos, name); |
|
2353 } |
|
2354 while (currentPtr >= eltPos) { |
|
2355 pop(); |
|
2356 } |
|
2357 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
2358 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2359 NS_HTML5_BREAK(endtagloop); |
|
2360 } |
|
2361 case NS_HTML5TREE_BUILDER_TABLE: { |
|
2362 errTableClosedWhileCaptionOpen(); |
|
2363 eltPos = findLastInTableScope(nsHtml5Atoms::caption); |
|
2364 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2365 NS_HTML5_BREAK(endtagloop); |
|
2366 } |
|
2367 generateImpliedEndTags(); |
|
2368 if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) { |
|
2369 errUnclosedElements(eltPos, name); |
|
2370 } |
|
2371 while (currentPtr >= eltPos) { |
|
2372 pop(); |
|
2373 } |
|
2374 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
2375 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2376 continue; |
|
2377 } |
|
2378 case NS_HTML5TREE_BUILDER_BODY: |
|
2379 case NS_HTML5TREE_BUILDER_COL: |
|
2380 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
2381 case NS_HTML5TREE_BUILDER_HTML: |
|
2382 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
2383 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
2384 case NS_HTML5TREE_BUILDER_TR: { |
|
2385 errStrayEndTag(name); |
|
2386 NS_HTML5_BREAK(endtagloop); |
|
2387 } |
|
2388 default: |
|
2389 ; // fall through |
|
2390 } |
|
2391 } |
|
2392 case NS_HTML5TREE_BUILDER_IN_CELL: { |
|
2393 switch(group) { |
|
2394 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
2395 eltPos = findLastInTableScope(name); |
|
2396 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2397 errStrayEndTag(name); |
|
2398 NS_HTML5_BREAK(endtagloop); |
|
2399 } |
|
2400 generateImpliedEndTags(); |
|
2401 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2402 errUnclosedElements(eltPos, name); |
|
2403 } |
|
2404 while (currentPtr >= eltPos) { |
|
2405 pop(); |
|
2406 } |
|
2407 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
2408 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
2409 NS_HTML5_BREAK(endtagloop); |
|
2410 } |
|
2411 case NS_HTML5TREE_BUILDER_TABLE: |
|
2412 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
2413 case NS_HTML5TREE_BUILDER_TR: { |
|
2414 if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2415 MOZ_ASSERT(name == nsHtml5Atoms::tbody || name == nsHtml5Atoms::tfoot || name == nsHtml5Atoms::thead || fragment || isTemplateContents()); |
|
2416 errStrayEndTag(name); |
|
2417 NS_HTML5_BREAK(endtagloop); |
|
2418 } |
|
2419 closeTheCell(findLastInTableScopeTdTh()); |
|
2420 continue; |
|
2421 } |
|
2422 case NS_HTML5TREE_BUILDER_BODY: |
|
2423 case NS_HTML5TREE_BUILDER_CAPTION: |
|
2424 case NS_HTML5TREE_BUILDER_COL: |
|
2425 case NS_HTML5TREE_BUILDER_COLGROUP: |
|
2426 case NS_HTML5TREE_BUILDER_HTML: { |
|
2427 errStrayEndTag(name); |
|
2428 NS_HTML5_BREAK(endtagloop); |
|
2429 } |
|
2430 default: |
|
2431 ; // fall through |
|
2432 } |
|
2433 } |
|
2434 case NS_HTML5TREE_BUILDER_FRAMESET_OK: |
|
2435 case NS_HTML5TREE_BUILDER_IN_BODY: { |
|
2436 switch(group) { |
|
2437 case NS_HTML5TREE_BUILDER_BODY: { |
|
2438 if (!isSecondOnStackBody()) { |
|
2439 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2440 errStrayEndTag(name); |
|
2441 NS_HTML5_BREAK(endtagloop); |
|
2442 } |
|
2443 MOZ_ASSERT(currentPtr >= 1); |
|
2444 if (MOZ_UNLIKELY(mViewSource)) { |
|
2445 for (int32_t i = 2; i <= currentPtr; i++) { |
|
2446 switch(stack[i]->getGroup()) { |
|
2447 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
2448 case NS_HTML5TREE_BUILDER_LI: |
|
2449 case NS_HTML5TREE_BUILDER_OPTGROUP: |
|
2450 case NS_HTML5TREE_BUILDER_OPTION: |
|
2451 case NS_HTML5TREE_BUILDER_P: |
|
2452 case NS_HTML5TREE_BUILDER_RT_OR_RP: |
|
2453 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
2454 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: { |
|
2455 break; |
|
2456 } |
|
2457 default: { |
|
2458 errEndWithUnclosedElements(name); |
|
2459 NS_HTML5_BREAK(uncloseloop1); |
|
2460 } |
|
2461 } |
|
2462 } |
|
2463 uncloseloop1_end: ; |
|
2464 } |
|
2465 mode = NS_HTML5TREE_BUILDER_AFTER_BODY; |
|
2466 NS_HTML5_BREAK(endtagloop); |
|
2467 } |
|
2468 case NS_HTML5TREE_BUILDER_HTML: { |
|
2469 if (!isSecondOnStackBody()) { |
|
2470 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2471 errStrayEndTag(name); |
|
2472 NS_HTML5_BREAK(endtagloop); |
|
2473 } |
|
2474 if (MOZ_UNLIKELY(mViewSource)) { |
|
2475 for (int32_t i = 0; i <= currentPtr; i++) { |
|
2476 switch(stack[i]->getGroup()) { |
|
2477 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
2478 case NS_HTML5TREE_BUILDER_LI: |
|
2479 case NS_HTML5TREE_BUILDER_P: |
|
2480 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
2481 case NS_HTML5TREE_BUILDER_TD_OR_TH: |
|
2482 case NS_HTML5TREE_BUILDER_BODY: |
|
2483 case NS_HTML5TREE_BUILDER_HTML: { |
|
2484 break; |
|
2485 } |
|
2486 default: { |
|
2487 errEndWithUnclosedElements(name); |
|
2488 NS_HTML5_BREAK(uncloseloop2); |
|
2489 } |
|
2490 } |
|
2491 } |
|
2492 uncloseloop2_end: ; |
|
2493 } |
|
2494 mode = NS_HTML5TREE_BUILDER_AFTER_BODY; |
|
2495 continue; |
|
2496 } |
|
2497 case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU: |
|
2498 case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL: |
|
2499 case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: |
|
2500 case NS_HTML5TREE_BUILDER_FIELDSET: |
|
2501 case NS_HTML5TREE_BUILDER_BUTTON: |
|
2502 case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: { |
|
2503 eltPos = findLastInScope(name); |
|
2504 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2505 errStrayEndTag(name); |
|
2506 } else { |
|
2507 generateImpliedEndTags(); |
|
2508 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2509 errUnclosedElements(eltPos, name); |
|
2510 } |
|
2511 while (currentPtr >= eltPos) { |
|
2512 pop(); |
|
2513 } |
|
2514 } |
|
2515 NS_HTML5_BREAK(endtagloop); |
|
2516 } |
|
2517 case NS_HTML5TREE_BUILDER_FORM: { |
|
2518 if (!isTemplateContents()) { |
|
2519 if (!formPointer) { |
|
2520 errStrayEndTag(name); |
|
2521 NS_HTML5_BREAK(endtagloop); |
|
2522 } |
|
2523 formPointer = nullptr; |
|
2524 eltPos = findLastInScope(name); |
|
2525 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2526 errStrayEndTag(name); |
|
2527 NS_HTML5_BREAK(endtagloop); |
|
2528 } |
|
2529 generateImpliedEndTags(); |
|
2530 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2531 errUnclosedElements(eltPos, name); |
|
2532 } |
|
2533 removeFromStack(eltPos); |
|
2534 NS_HTML5_BREAK(endtagloop); |
|
2535 } else { |
|
2536 eltPos = findLastInScope(name); |
|
2537 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2538 errStrayEndTag(name); |
|
2539 NS_HTML5_BREAK(endtagloop); |
|
2540 } |
|
2541 generateImpliedEndTags(); |
|
2542 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2543 errUnclosedElements(eltPos, name); |
|
2544 } |
|
2545 while (currentPtr >= eltPos) { |
|
2546 pop(); |
|
2547 } |
|
2548 NS_HTML5_BREAK(endtagloop); |
|
2549 } |
|
2550 } |
|
2551 case NS_HTML5TREE_BUILDER_P: { |
|
2552 eltPos = findLastInButtonScope(nsHtml5Atoms::p); |
|
2553 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2554 errNoElementToCloseButEndTagSeen(nsHtml5Atoms::p); |
|
2555 if (isInForeign()) { |
|
2556 errHtmlStartTagInForeignContext(name); |
|
2557 while (stack[currentPtr]->ns != kNameSpaceID_XHTML) { |
|
2558 pop(); |
|
2559 } |
|
2560 } |
|
2561 appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
2562 NS_HTML5_BREAK(endtagloop); |
|
2563 } |
|
2564 generateImpliedEndTagsExceptFor(nsHtml5Atoms::p); |
|
2565 MOZ_ASSERT(eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK); |
|
2566 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
2567 errUnclosedElements(eltPos, name); |
|
2568 } |
|
2569 while (currentPtr >= eltPos) { |
|
2570 pop(); |
|
2571 } |
|
2572 NS_HTML5_BREAK(endtagloop); |
|
2573 } |
|
2574 case NS_HTML5TREE_BUILDER_LI: { |
|
2575 eltPos = findLastInListScope(name); |
|
2576 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2577 errNoElementToCloseButEndTagSeen(name); |
|
2578 } else { |
|
2579 generateImpliedEndTagsExceptFor(name); |
|
2580 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
2581 errUnclosedElements(eltPos, name); |
|
2582 } |
|
2583 while (currentPtr >= eltPos) { |
|
2584 pop(); |
|
2585 } |
|
2586 } |
|
2587 NS_HTML5_BREAK(endtagloop); |
|
2588 } |
|
2589 case NS_HTML5TREE_BUILDER_DD_OR_DT: { |
|
2590 eltPos = findLastInScope(name); |
|
2591 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2592 errNoElementToCloseButEndTagSeen(name); |
|
2593 } else { |
|
2594 generateImpliedEndTagsExceptFor(name); |
|
2595 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
2596 errUnclosedElements(eltPos, name); |
|
2597 } |
|
2598 while (currentPtr >= eltPos) { |
|
2599 pop(); |
|
2600 } |
|
2601 } |
|
2602 NS_HTML5_BREAK(endtagloop); |
|
2603 } |
|
2604 case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: { |
|
2605 eltPos = findLastInScopeHn(); |
|
2606 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2607 errStrayEndTag(name); |
|
2608 } else { |
|
2609 generateImpliedEndTags(); |
|
2610 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2611 errUnclosedElements(eltPos, name); |
|
2612 } |
|
2613 while (currentPtr >= eltPos) { |
|
2614 pop(); |
|
2615 } |
|
2616 } |
|
2617 NS_HTML5_BREAK(endtagloop); |
|
2618 } |
|
2619 case NS_HTML5TREE_BUILDER_OBJECT: |
|
2620 case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: { |
|
2621 eltPos = findLastInScope(name); |
|
2622 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2623 errStrayEndTag(name); |
|
2624 } else { |
|
2625 generateImpliedEndTags(); |
|
2626 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2627 errUnclosedElements(eltPos, name); |
|
2628 } |
|
2629 while (currentPtr >= eltPos) { |
|
2630 pop(); |
|
2631 } |
|
2632 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
2633 } |
|
2634 NS_HTML5_BREAK(endtagloop); |
|
2635 } |
|
2636 case NS_HTML5TREE_BUILDER_BR: { |
|
2637 errEndTagBr(); |
|
2638 if (isInForeign()) { |
|
2639 errHtmlStartTagInForeignContext(name); |
|
2640 while (stack[currentPtr]->ns != kNameSpaceID_XHTML) { |
|
2641 pop(); |
|
2642 } |
|
2643 } |
|
2644 reconstructTheActiveFormattingElements(); |
|
2645 appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
2646 NS_HTML5_BREAK(endtagloop); |
|
2647 } |
|
2648 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2649 break; |
|
2650 } |
|
2651 case NS_HTML5TREE_BUILDER_AREA_OR_WBR: |
|
2652 #ifdef ENABLE_VOID_MENUITEM |
|
2653 case NS_HTML5TREE_BUILDER_MENUITEM: |
|
2654 #endif |
|
2655 case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK: |
|
2656 case NS_HTML5TREE_BUILDER_EMBED: |
|
2657 case NS_HTML5TREE_BUILDER_IMG: |
|
2658 case NS_HTML5TREE_BUILDER_IMAGE: |
|
2659 case NS_HTML5TREE_BUILDER_INPUT: |
|
2660 case NS_HTML5TREE_BUILDER_KEYGEN: |
|
2661 case NS_HTML5TREE_BUILDER_HR: |
|
2662 case NS_HTML5TREE_BUILDER_ISINDEX: |
|
2663 case NS_HTML5TREE_BUILDER_IFRAME: |
|
2664 case NS_HTML5TREE_BUILDER_NOEMBED: |
|
2665 case NS_HTML5TREE_BUILDER_NOFRAMES: |
|
2666 case NS_HTML5TREE_BUILDER_SELECT: |
|
2667 case NS_HTML5TREE_BUILDER_TABLE: |
|
2668 case NS_HTML5TREE_BUILDER_TEXTAREA: { |
|
2669 errStrayEndTag(name); |
|
2670 NS_HTML5_BREAK(endtagloop); |
|
2671 } |
|
2672 case NS_HTML5TREE_BUILDER_NOSCRIPT: { |
|
2673 if (scriptingEnabled) { |
|
2674 errStrayEndTag(name); |
|
2675 NS_HTML5_BREAK(endtagloop); |
|
2676 } else { |
|
2677 } |
|
2678 } |
|
2679 case NS_HTML5TREE_BUILDER_A: |
|
2680 case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U: |
|
2681 case NS_HTML5TREE_BUILDER_FONT: |
|
2682 case NS_HTML5TREE_BUILDER_NOBR: { |
|
2683 if (adoptionAgencyEndTag(name)) { |
|
2684 NS_HTML5_BREAK(endtagloop); |
|
2685 } |
|
2686 } |
|
2687 default: { |
|
2688 if (isCurrent(name)) { |
|
2689 pop(); |
|
2690 NS_HTML5_BREAK(endtagloop); |
|
2691 } |
|
2692 eltPos = currentPtr; |
|
2693 for (; ; ) { |
|
2694 nsHtml5StackNode* node = stack[eltPos]; |
|
2695 if (node->ns == kNameSpaceID_XHTML && node->name == name) { |
|
2696 generateImpliedEndTags(); |
|
2697 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { |
|
2698 errUnclosedElements(eltPos, name); |
|
2699 } |
|
2700 while (currentPtr >= eltPos) { |
|
2701 pop(); |
|
2702 } |
|
2703 NS_HTML5_BREAK(endtagloop); |
|
2704 } else if (node->isSpecial()) { |
|
2705 errStrayEndTag(name); |
|
2706 NS_HTML5_BREAK(endtagloop); |
|
2707 } |
|
2708 eltPos--; |
|
2709 } |
|
2710 } |
|
2711 } |
|
2712 } |
|
2713 case NS_HTML5TREE_BUILDER_IN_HEAD: { |
|
2714 switch(group) { |
|
2715 case NS_HTML5TREE_BUILDER_HEAD: { |
|
2716 pop(); |
|
2717 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
2718 NS_HTML5_BREAK(endtagloop); |
|
2719 } |
|
2720 case NS_HTML5TREE_BUILDER_BR: |
|
2721 case NS_HTML5TREE_BUILDER_HTML: |
|
2722 case NS_HTML5TREE_BUILDER_BODY: { |
|
2723 pop(); |
|
2724 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
2725 continue; |
|
2726 } |
|
2727 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2728 endTagTemplateInHead(); |
|
2729 NS_HTML5_BREAK(endtagloop); |
|
2730 } |
|
2731 default: { |
|
2732 errStrayEndTag(name); |
|
2733 NS_HTML5_BREAK(endtagloop); |
|
2734 } |
|
2735 } |
|
2736 } |
|
2737 case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { |
|
2738 switch(group) { |
|
2739 case NS_HTML5TREE_BUILDER_NOSCRIPT: { |
|
2740 pop(); |
|
2741 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
2742 NS_HTML5_BREAK(endtagloop); |
|
2743 } |
|
2744 case NS_HTML5TREE_BUILDER_BR: { |
|
2745 errStrayEndTag(name); |
|
2746 pop(); |
|
2747 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
2748 continue; |
|
2749 } |
|
2750 default: { |
|
2751 errStrayEndTag(name); |
|
2752 NS_HTML5_BREAK(endtagloop); |
|
2753 } |
|
2754 } |
|
2755 } |
|
2756 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: { |
|
2757 switch(group) { |
|
2758 case NS_HTML5TREE_BUILDER_COLGROUP: { |
|
2759 if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
2760 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2761 errGarbageInColgroup(); |
|
2762 NS_HTML5_BREAK(endtagloop); |
|
2763 } |
|
2764 pop(); |
|
2765 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2766 NS_HTML5_BREAK(endtagloop); |
|
2767 } |
|
2768 case NS_HTML5TREE_BUILDER_COL: { |
|
2769 errStrayEndTag(name); |
|
2770 NS_HTML5_BREAK(endtagloop); |
|
2771 } |
|
2772 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2773 endTagTemplateInHead(); |
|
2774 NS_HTML5_BREAK(endtagloop); |
|
2775 } |
|
2776 default: { |
|
2777 if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
2778 MOZ_ASSERT(fragment || isTemplateContents()); |
|
2779 errGarbageInColgroup(); |
|
2780 NS_HTML5_BREAK(endtagloop); |
|
2781 } |
|
2782 pop(); |
|
2783 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
2784 continue; |
|
2785 } |
|
2786 } |
|
2787 } |
|
2788 case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: { |
|
2789 switch(group) { |
|
2790 case NS_HTML5TREE_BUILDER_CAPTION: |
|
2791 case NS_HTML5TREE_BUILDER_TABLE: |
|
2792 case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: |
|
2793 case NS_HTML5TREE_BUILDER_TR: |
|
2794 case NS_HTML5TREE_BUILDER_TD_OR_TH: { |
|
2795 errEndTagSeenWithSelectOpen(name); |
|
2796 if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2797 eltPos = findLastInTableScope(nsHtml5Atoms::select); |
|
2798 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2799 MOZ_ASSERT(fragment); |
|
2800 NS_HTML5_BREAK(endtagloop); |
|
2801 } |
|
2802 while (currentPtr >= eltPos) { |
|
2803 pop(); |
|
2804 } |
|
2805 resetTheInsertionMode(); |
|
2806 continue; |
|
2807 } else { |
|
2808 NS_HTML5_BREAK(endtagloop); |
|
2809 } |
|
2810 } |
|
2811 default: |
|
2812 ; // fall through |
|
2813 } |
|
2814 } |
|
2815 case NS_HTML5TREE_BUILDER_IN_SELECT: { |
|
2816 switch(group) { |
|
2817 case NS_HTML5TREE_BUILDER_OPTION: { |
|
2818 if (isCurrent(nsHtml5Atoms::option)) { |
|
2819 pop(); |
|
2820 NS_HTML5_BREAK(endtagloop); |
|
2821 } else { |
|
2822 errStrayEndTag(name); |
|
2823 NS_HTML5_BREAK(endtagloop); |
|
2824 } |
|
2825 } |
|
2826 case NS_HTML5TREE_BUILDER_OPTGROUP: { |
|
2827 if (isCurrent(nsHtml5Atoms::option) && nsHtml5Atoms::optgroup == stack[currentPtr - 1]->name) { |
|
2828 pop(); |
|
2829 } |
|
2830 if (isCurrent(nsHtml5Atoms::optgroup)) { |
|
2831 pop(); |
|
2832 } else { |
|
2833 errStrayEndTag(name); |
|
2834 } |
|
2835 NS_HTML5_BREAK(endtagloop); |
|
2836 } |
|
2837 case NS_HTML5TREE_BUILDER_SELECT: { |
|
2838 eltPos = findLastInTableScope(nsHtml5Atoms::select); |
|
2839 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2840 MOZ_ASSERT(fragment); |
|
2841 errStrayEndTag(name); |
|
2842 NS_HTML5_BREAK(endtagloop); |
|
2843 } |
|
2844 while (currentPtr >= eltPos) { |
|
2845 pop(); |
|
2846 } |
|
2847 resetTheInsertionMode(); |
|
2848 NS_HTML5_BREAK(endtagloop); |
|
2849 } |
|
2850 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2851 endTagTemplateInHead(); |
|
2852 NS_HTML5_BREAK(endtagloop); |
|
2853 } |
|
2854 default: { |
|
2855 errStrayEndTag(name); |
|
2856 NS_HTML5_BREAK(endtagloop); |
|
2857 } |
|
2858 } |
|
2859 } |
|
2860 case NS_HTML5TREE_BUILDER_AFTER_BODY: { |
|
2861 switch(group) { |
|
2862 case NS_HTML5TREE_BUILDER_HTML: { |
|
2863 if (fragment) { |
|
2864 errStrayEndTag(name); |
|
2865 NS_HTML5_BREAK(endtagloop); |
|
2866 } else { |
|
2867 mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY; |
|
2868 NS_HTML5_BREAK(endtagloop); |
|
2869 } |
|
2870 } |
|
2871 default: { |
|
2872 errEndTagAfterBody(); |
|
2873 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
2874 continue; |
|
2875 } |
|
2876 } |
|
2877 } |
|
2878 case NS_HTML5TREE_BUILDER_IN_FRAMESET: { |
|
2879 switch(group) { |
|
2880 case NS_HTML5TREE_BUILDER_FRAMESET: { |
|
2881 if (!currentPtr) { |
|
2882 MOZ_ASSERT(fragment); |
|
2883 errStrayEndTag(name); |
|
2884 NS_HTML5_BREAK(endtagloop); |
|
2885 } |
|
2886 pop(); |
|
2887 if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) { |
|
2888 mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET; |
|
2889 } |
|
2890 NS_HTML5_BREAK(endtagloop); |
|
2891 } |
|
2892 default: { |
|
2893 errStrayEndTag(name); |
|
2894 NS_HTML5_BREAK(endtagloop); |
|
2895 } |
|
2896 } |
|
2897 } |
|
2898 case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: { |
|
2899 switch(group) { |
|
2900 case NS_HTML5TREE_BUILDER_HTML: { |
|
2901 mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET; |
|
2902 NS_HTML5_BREAK(endtagloop); |
|
2903 } |
|
2904 default: { |
|
2905 errStrayEndTag(name); |
|
2906 NS_HTML5_BREAK(endtagloop); |
|
2907 } |
|
2908 } |
|
2909 } |
|
2910 case NS_HTML5TREE_BUILDER_INITIAL: { |
|
2911 errEndTagSeenWithoutDoctype(); |
|
2912 documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false); |
|
2913 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; |
|
2914 continue; |
|
2915 } |
|
2916 case NS_HTML5TREE_BUILDER_BEFORE_HTML: { |
|
2917 switch(group) { |
|
2918 case NS_HTML5TREE_BUILDER_HEAD: |
|
2919 case NS_HTML5TREE_BUILDER_BR: |
|
2920 case NS_HTML5TREE_BUILDER_HTML: |
|
2921 case NS_HTML5TREE_BUILDER_BODY: { |
|
2922 appendHtmlElementToDocumentAndPush(); |
|
2923 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
2924 continue; |
|
2925 } |
|
2926 default: { |
|
2927 errStrayEndTag(name); |
|
2928 NS_HTML5_BREAK(endtagloop); |
|
2929 } |
|
2930 } |
|
2931 } |
|
2932 case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { |
|
2933 switch(group) { |
|
2934 case NS_HTML5TREE_BUILDER_HEAD: |
|
2935 case NS_HTML5TREE_BUILDER_BR: |
|
2936 case NS_HTML5TREE_BUILDER_HTML: |
|
2937 case NS_HTML5TREE_BUILDER_BODY: { |
|
2938 appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); |
|
2939 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
2940 continue; |
|
2941 } |
|
2942 default: { |
|
2943 errStrayEndTag(name); |
|
2944 NS_HTML5_BREAK(endtagloop); |
|
2945 } |
|
2946 } |
|
2947 } |
|
2948 case NS_HTML5TREE_BUILDER_AFTER_HEAD: { |
|
2949 switch(group) { |
|
2950 case NS_HTML5TREE_BUILDER_TEMPLATE: { |
|
2951 endTagTemplateInHead(); |
|
2952 NS_HTML5_BREAK(endtagloop); |
|
2953 } |
|
2954 case NS_HTML5TREE_BUILDER_HTML: |
|
2955 case NS_HTML5TREE_BUILDER_BODY: |
|
2956 case NS_HTML5TREE_BUILDER_BR: { |
|
2957 appendToCurrentNodeAndPushBodyElement(); |
|
2958 mode = NS_HTML5TREE_BUILDER_FRAMESET_OK; |
|
2959 continue; |
|
2960 } |
|
2961 default: { |
|
2962 errStrayEndTag(name); |
|
2963 NS_HTML5_BREAK(endtagloop); |
|
2964 } |
|
2965 } |
|
2966 } |
|
2967 case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: { |
|
2968 errStrayEndTag(name); |
|
2969 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
2970 continue; |
|
2971 } |
|
2972 case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: { |
|
2973 errStrayEndTag(name); |
|
2974 NS_HTML5_BREAK(endtagloop); |
|
2975 } |
|
2976 case NS_HTML5TREE_BUILDER_TEXT: { |
|
2977 pop(); |
|
2978 if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { |
|
2979 silentPop(); |
|
2980 } |
|
2981 mode = originalMode; |
|
2982 NS_HTML5_BREAK(endtagloop); |
|
2983 } |
|
2984 } |
|
2985 } |
|
2986 endtagloop_end: ; |
|
2987 } |
|
2988 |
|
2989 void |
|
2990 nsHtml5TreeBuilder::endTagTemplateInHead() |
|
2991 { |
|
2992 int32_t eltPos = findLast(nsHtml5Atoms::template_); |
|
2993 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
2994 errStrayEndTag(nsHtml5Atoms::template_); |
|
2995 return; |
|
2996 } |
|
2997 generateImpliedEndTags(); |
|
2998 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::template_)) { |
|
2999 errUnclosedElements(eltPos, nsHtml5Atoms::template_); |
|
3000 } |
|
3001 while (currentPtr >= eltPos) { |
|
3002 pop(); |
|
3003 } |
|
3004 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
3005 popTemplateMode(); |
|
3006 resetTheInsertionMode(); |
|
3007 } |
|
3008 |
|
3009 int32_t |
|
3010 nsHtml5TreeBuilder::findLastInTableScopeOrRootTemplateTbodyTheadTfoot() |
|
3011 { |
|
3012 for (int32_t i = currentPtr; i > 0; i--) { |
|
3013 if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) { |
|
3014 return i; |
|
3015 } |
|
3016 } |
|
3017 return 0; |
|
3018 } |
|
3019 |
|
3020 int32_t |
|
3021 nsHtml5TreeBuilder::findLast(nsIAtom* name) |
|
3022 { |
|
3023 for (int32_t i = currentPtr; i > 0; i--) { |
|
3024 if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) { |
|
3025 return i; |
|
3026 } |
|
3027 } |
|
3028 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3029 } |
|
3030 |
|
3031 int32_t |
|
3032 nsHtml5TreeBuilder::findLastInTableScope(nsIAtom* name) |
|
3033 { |
|
3034 for (int32_t i = currentPtr; i > 0; i--) { |
|
3035 if (stack[i]->ns == kNameSpaceID_XHTML) { |
|
3036 if (stack[i]->name == name) { |
|
3037 return i; |
|
3038 } else if (stack[i]->name == nsHtml5Atoms::table || stack[i]->name == nsHtml5Atoms::template_) { |
|
3039 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3040 } |
|
3041 } |
|
3042 } |
|
3043 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3044 } |
|
3045 |
|
3046 int32_t |
|
3047 nsHtml5TreeBuilder::findLastInButtonScope(nsIAtom* name) |
|
3048 { |
|
3049 for (int32_t i = currentPtr; i > 0; i--) { |
|
3050 if (stack[i]->ns == kNameSpaceID_XHTML) { |
|
3051 if (stack[i]->name == name) { |
|
3052 return i; |
|
3053 } else if (stack[i]->name == nsHtml5Atoms::button) { |
|
3054 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3055 } |
|
3056 } |
|
3057 if (stack[i]->isScoping()) { |
|
3058 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3059 } |
|
3060 } |
|
3061 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3062 } |
|
3063 |
|
3064 int32_t |
|
3065 nsHtml5TreeBuilder::findLastInScope(nsIAtom* name) |
|
3066 { |
|
3067 for (int32_t i = currentPtr; i > 0; i--) { |
|
3068 if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) { |
|
3069 return i; |
|
3070 } else if (stack[i]->isScoping()) { |
|
3071 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3072 } |
|
3073 } |
|
3074 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3075 } |
|
3076 |
|
3077 int32_t |
|
3078 nsHtml5TreeBuilder::findLastInListScope(nsIAtom* name) |
|
3079 { |
|
3080 for (int32_t i = currentPtr; i > 0; i--) { |
|
3081 if (stack[i]->ns == kNameSpaceID_XHTML) { |
|
3082 if (stack[i]->name == name) { |
|
3083 return i; |
|
3084 } else if (stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) { |
|
3085 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3086 } |
|
3087 } |
|
3088 if (stack[i]->isScoping()) { |
|
3089 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3090 } |
|
3091 } |
|
3092 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3093 } |
|
3094 |
|
3095 int32_t |
|
3096 nsHtml5TreeBuilder::findLastInScopeHn() |
|
3097 { |
|
3098 for (int32_t i = currentPtr; i > 0; i--) { |
|
3099 if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) { |
|
3100 return i; |
|
3101 } else if (stack[i]->isScoping()) { |
|
3102 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3103 } |
|
3104 } |
|
3105 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3106 } |
|
3107 |
|
3108 void |
|
3109 nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsIAtom* name) |
|
3110 { |
|
3111 for (; ; ) { |
|
3112 nsHtml5StackNode* node = stack[currentPtr]; |
|
3113 switch(node->getGroup()) { |
|
3114 case NS_HTML5TREE_BUILDER_P: |
|
3115 case NS_HTML5TREE_BUILDER_LI: |
|
3116 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
3117 case NS_HTML5TREE_BUILDER_OPTION: |
|
3118 case NS_HTML5TREE_BUILDER_OPTGROUP: |
|
3119 case NS_HTML5TREE_BUILDER_RT_OR_RP: { |
|
3120 if (node->ns == kNameSpaceID_XHTML && node->name == name) { |
|
3121 return; |
|
3122 } |
|
3123 pop(); |
|
3124 continue; |
|
3125 } |
|
3126 default: { |
|
3127 return; |
|
3128 } |
|
3129 } |
|
3130 } |
|
3131 } |
|
3132 |
|
3133 void |
|
3134 nsHtml5TreeBuilder::generateImpliedEndTags() |
|
3135 { |
|
3136 for (; ; ) { |
|
3137 switch(stack[currentPtr]->getGroup()) { |
|
3138 case NS_HTML5TREE_BUILDER_P: |
|
3139 case NS_HTML5TREE_BUILDER_LI: |
|
3140 case NS_HTML5TREE_BUILDER_DD_OR_DT: |
|
3141 case NS_HTML5TREE_BUILDER_OPTION: |
|
3142 case NS_HTML5TREE_BUILDER_OPTGROUP: |
|
3143 case NS_HTML5TREE_BUILDER_RT_OR_RP: { |
|
3144 pop(); |
|
3145 continue; |
|
3146 } |
|
3147 default: { |
|
3148 return; |
|
3149 } |
|
3150 } |
|
3151 } |
|
3152 } |
|
3153 |
|
3154 bool |
|
3155 nsHtml5TreeBuilder::isSecondOnStackBody() |
|
3156 { |
|
3157 return currentPtr >= 1 && stack[1]->getGroup() == NS_HTML5TREE_BUILDER_BODY; |
|
3158 } |
|
3159 |
|
3160 void |
|
3161 nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks) |
|
3162 { |
|
3163 if (isSrcdocDocument) { |
|
3164 quirks = false; |
|
3165 if (this) { |
|
3166 this->documentMode(STANDARDS_MODE); |
|
3167 } |
|
3168 return; |
|
3169 } |
|
3170 quirks = (m == QUIRKS_MODE); |
|
3171 if (this) { |
|
3172 this->documentMode(m); |
|
3173 } |
|
3174 } |
|
3175 |
|
3176 bool |
|
3177 nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier) |
|
3178 { |
|
3179 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) { |
|
3180 return true; |
|
3181 } |
|
3182 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 frameset//en", publicIdentifier)) { |
|
3183 return true; |
|
3184 } |
|
3185 if (systemIdentifier) { |
|
3186 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) { |
|
3187 return true; |
|
3188 } |
|
3189 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) { |
|
3190 return true; |
|
3191 } |
|
3192 } |
|
3193 return false; |
|
3194 } |
|
3195 |
|
3196 bool |
|
3197 nsHtml5TreeBuilder::isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks) |
|
3198 { |
|
3199 if (forceQuirks) { |
|
3200 return true; |
|
3201 } |
|
3202 if (name != nsHtml5Atoms::html) { |
|
3203 return true; |
|
3204 } |
|
3205 if (publicIdentifier) { |
|
3206 for (int32_t i = 0; i < nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS.length; i++) { |
|
3207 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS[i], publicIdentifier)) { |
|
3208 return true; |
|
3209 } |
|
3210 } |
|
3211 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-/w3c/dtd html 4.0 transitional/en", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("html", publicIdentifier)) { |
|
3212 return true; |
|
3213 } |
|
3214 } |
|
3215 if (!systemIdentifier) { |
|
3216 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) { |
|
3217 return true; |
|
3218 } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) { |
|
3219 return true; |
|
3220 } |
|
3221 } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", systemIdentifier)) { |
|
3222 return true; |
|
3223 } |
|
3224 return false; |
|
3225 } |
|
3226 |
|
3227 void |
|
3228 nsHtml5TreeBuilder::closeTheCell(int32_t eltPos) |
|
3229 { |
|
3230 generateImpliedEndTags(); |
|
3231 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
3232 errUnclosedElementsCell(eltPos); |
|
3233 } |
|
3234 while (currentPtr >= eltPos) { |
|
3235 pop(); |
|
3236 } |
|
3237 clearTheListOfActiveFormattingElementsUpToTheLastMarker(); |
|
3238 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
3239 return; |
|
3240 } |
|
3241 |
|
3242 int32_t |
|
3243 nsHtml5TreeBuilder::findLastInTableScopeTdTh() |
|
3244 { |
|
3245 for (int32_t i = currentPtr; i > 0; i--) { |
|
3246 nsIAtom* name = stack[i]->name; |
|
3247 if (stack[i]->ns == kNameSpaceID_XHTML) { |
|
3248 if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) { |
|
3249 return i; |
|
3250 } else if (name == nsHtml5Atoms::table || name == nsHtml5Atoms::template_) { |
|
3251 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3252 } |
|
3253 } |
|
3254 } |
|
3255 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; |
|
3256 } |
|
3257 |
|
3258 void |
|
3259 nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos) |
|
3260 { |
|
3261 int32_t eltGroup = stack[eltPos]->getGroup(); |
|
3262 while (currentPtr > eltPos) { |
|
3263 if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || eltGroup == NS_HTML5TREE_BUILDER_HTML)) { |
|
3264 return; |
|
3265 } |
|
3266 pop(); |
|
3267 } |
|
3268 } |
|
3269 |
|
3270 void |
|
3271 nsHtml5TreeBuilder::resetTheInsertionMode() |
|
3272 { |
|
3273 nsHtml5StackNode* node; |
|
3274 nsIAtom* name; |
|
3275 int32_t ns; |
|
3276 for (int32_t i = currentPtr; i >= 0; i--) { |
|
3277 node = stack[i]; |
|
3278 name = node->name; |
|
3279 ns = node->ns; |
|
3280 if (!i) { |
|
3281 if (!(contextNamespace == kNameSpaceID_XHTML && (contextName == nsHtml5Atoms::td || contextName == nsHtml5Atoms::th))) { |
|
3282 if (fragment) { |
|
3283 name = contextName; |
|
3284 ns = contextNamespace; |
|
3285 } |
|
3286 } else { |
|
3287 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
3288 return; |
|
3289 } |
|
3290 } |
|
3291 if (nsHtml5Atoms::select == name) { |
|
3292 int32_t ancestorIndex = i; |
|
3293 while (ancestorIndex > 0) { |
|
3294 nsHtml5StackNode* ancestor = stack[ancestorIndex--]; |
|
3295 if (kNameSpaceID_XHTML == ancestor->ns) { |
|
3296 if (nsHtml5Atoms::template_ == ancestor->name) { |
|
3297 break; |
|
3298 } |
|
3299 if (nsHtml5Atoms::table == ancestor->name) { |
|
3300 mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE; |
|
3301 return; |
|
3302 } |
|
3303 } |
|
3304 } |
|
3305 mode = NS_HTML5TREE_BUILDER_IN_SELECT; |
|
3306 return; |
|
3307 } else if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) { |
|
3308 mode = NS_HTML5TREE_BUILDER_IN_CELL; |
|
3309 return; |
|
3310 } else if (nsHtml5Atoms::tr == name) { |
|
3311 mode = NS_HTML5TREE_BUILDER_IN_ROW; |
|
3312 return; |
|
3313 } else if (nsHtml5Atoms::tbody == name || nsHtml5Atoms::thead == name || nsHtml5Atoms::tfoot == name) { |
|
3314 mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; |
|
3315 return; |
|
3316 } else if (nsHtml5Atoms::caption == name) { |
|
3317 mode = NS_HTML5TREE_BUILDER_IN_CAPTION; |
|
3318 return; |
|
3319 } else if (nsHtml5Atoms::colgroup == name) { |
|
3320 mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP; |
|
3321 return; |
|
3322 } else if (nsHtml5Atoms::table == name) { |
|
3323 mode = NS_HTML5TREE_BUILDER_IN_TABLE; |
|
3324 return; |
|
3325 } else if (kNameSpaceID_XHTML != ns) { |
|
3326 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
3327 return; |
|
3328 } else if (nsHtml5Atoms::template_ == name) { |
|
3329 MOZ_ASSERT(templateModePtr >= 0); |
|
3330 mode = templateModeStack[templateModePtr]; |
|
3331 return; |
|
3332 } else if (nsHtml5Atoms::head == name) { |
|
3333 if (name == contextName) { |
|
3334 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
3335 } else { |
|
3336 mode = NS_HTML5TREE_BUILDER_IN_HEAD; |
|
3337 } |
|
3338 return; |
|
3339 } else if (nsHtml5Atoms::body == name) { |
|
3340 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
3341 return; |
|
3342 } else if (nsHtml5Atoms::frameset == name) { |
|
3343 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; |
|
3344 return; |
|
3345 } else if (nsHtml5Atoms::html == name) { |
|
3346 if (!headPointer) { |
|
3347 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; |
|
3348 } else { |
|
3349 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; |
|
3350 } |
|
3351 return; |
|
3352 } else if (!i) { |
|
3353 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; |
|
3354 return; |
|
3355 } |
|
3356 } |
|
3357 } |
|
3358 |
|
3359 void |
|
3360 nsHtml5TreeBuilder::implicitlyCloseP() |
|
3361 { |
|
3362 int32_t eltPos = findLastInButtonScope(nsHtml5Atoms::p); |
|
3363 if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { |
|
3364 return; |
|
3365 } |
|
3366 generateImpliedEndTagsExceptFor(nsHtml5Atoms::p); |
|
3367 if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) { |
|
3368 errUnclosedElementsImplied(eltPos, nsHtml5Atoms::p); |
|
3369 } |
|
3370 while (currentPtr >= eltPos) { |
|
3371 pop(); |
|
3372 } |
|
3373 } |
|
3374 |
|
3375 bool |
|
3376 nsHtml5TreeBuilder::debugOnlyClearLastStackSlot() |
|
3377 { |
|
3378 stack[currentPtr] = nullptr; |
|
3379 return true; |
|
3380 } |
|
3381 |
|
3382 bool |
|
3383 nsHtml5TreeBuilder::debugOnlyClearLastListSlot() |
|
3384 { |
|
3385 listOfActiveFormattingElements[listPtr] = nullptr; |
|
3386 return true; |
|
3387 } |
|
3388 |
|
3389 void |
|
3390 nsHtml5TreeBuilder::pushTemplateMode(int32_t mode) |
|
3391 { |
|
3392 templateModePtr++; |
|
3393 if (templateModePtr == templateModeStack.length) { |
|
3394 jArray<int32_t,int32_t> newStack = jArray<int32_t,int32_t>::newJArray(templateModeStack.length + 64); |
|
3395 nsHtml5ArrayCopy::arraycopy(templateModeStack, newStack, templateModeStack.length); |
|
3396 templateModeStack = newStack; |
|
3397 } |
|
3398 templateModeStack[templateModePtr] = mode; |
|
3399 } |
|
3400 |
|
3401 void |
|
3402 nsHtml5TreeBuilder::push(nsHtml5StackNode* node) |
|
3403 { |
|
3404 currentPtr++; |
|
3405 if (currentPtr == stack.length) { |
|
3406 jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64); |
|
3407 nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length); |
|
3408 stack = newStack; |
|
3409 } |
|
3410 stack[currentPtr] = node; |
|
3411 elementPushed(node->ns, node->popName, node->node); |
|
3412 } |
|
3413 |
|
3414 void |
|
3415 nsHtml5TreeBuilder::silentPush(nsHtml5StackNode* node) |
|
3416 { |
|
3417 currentPtr++; |
|
3418 if (currentPtr == stack.length) { |
|
3419 jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64); |
|
3420 nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length); |
|
3421 stack = newStack; |
|
3422 } |
|
3423 stack[currentPtr] = node; |
|
3424 } |
|
3425 |
|
3426 void |
|
3427 nsHtml5TreeBuilder::append(nsHtml5StackNode* node) |
|
3428 { |
|
3429 listPtr++; |
|
3430 if (listPtr == listOfActiveFormattingElements.length) { |
|
3431 jArray<nsHtml5StackNode*,int32_t> newList = jArray<nsHtml5StackNode*,int32_t>::newJArray(listOfActiveFormattingElements.length + 64); |
|
3432 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, newList, listOfActiveFormattingElements.length); |
|
3433 listOfActiveFormattingElements = newList; |
|
3434 } |
|
3435 listOfActiveFormattingElements[listPtr] = node; |
|
3436 } |
|
3437 |
|
3438 void |
|
3439 nsHtml5TreeBuilder::clearTheListOfActiveFormattingElementsUpToTheLastMarker() |
|
3440 { |
|
3441 while (listPtr > -1) { |
|
3442 if (!listOfActiveFormattingElements[listPtr]) { |
|
3443 --listPtr; |
|
3444 return; |
|
3445 } |
|
3446 listOfActiveFormattingElements[listPtr]->release(); |
|
3447 --listPtr; |
|
3448 } |
|
3449 } |
|
3450 |
|
3451 void |
|
3452 nsHtml5TreeBuilder::removeFromStack(int32_t pos) |
|
3453 { |
|
3454 if (currentPtr == pos) { |
|
3455 pop(); |
|
3456 } else { |
|
3457 |
|
3458 stack[pos]->release(); |
|
3459 nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos); |
|
3460 MOZ_ASSERT(debugOnlyClearLastStackSlot()); |
|
3461 currentPtr--; |
|
3462 } |
|
3463 } |
|
3464 |
|
3465 void |
|
3466 nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode* node) |
|
3467 { |
|
3468 if (stack[currentPtr] == node) { |
|
3469 pop(); |
|
3470 } else { |
|
3471 int32_t pos = currentPtr - 1; |
|
3472 while (pos >= 0 && stack[pos] != node) { |
|
3473 pos--; |
|
3474 } |
|
3475 if (pos == -1) { |
|
3476 return; |
|
3477 } |
|
3478 |
|
3479 node->release(); |
|
3480 nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos); |
|
3481 currentPtr--; |
|
3482 } |
|
3483 } |
|
3484 |
|
3485 void |
|
3486 nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos) |
|
3487 { |
|
3488 MOZ_ASSERT(!!listOfActiveFormattingElements[pos]); |
|
3489 listOfActiveFormattingElements[pos]->release(); |
|
3490 if (pos == listPtr) { |
|
3491 MOZ_ASSERT(debugOnlyClearLastListSlot()); |
|
3492 listPtr--; |
|
3493 return; |
|
3494 } |
|
3495 MOZ_ASSERT(pos < listPtr); |
|
3496 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, pos + 1, pos, listPtr - pos); |
|
3497 MOZ_ASSERT(debugOnlyClearLastListSlot()); |
|
3498 listPtr--; |
|
3499 } |
|
3500 |
|
3501 bool |
|
3502 nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name) |
|
3503 { |
|
3504 if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->name == name && findInListOfActiveFormattingElements(stack[currentPtr]) == -1) { |
|
3505 pop(); |
|
3506 return true; |
|
3507 } |
|
3508 for (int32_t i = 0; i < 8; ++i) { |
|
3509 int32_t formattingEltListPos = listPtr; |
|
3510 while (formattingEltListPos > -1) { |
|
3511 nsHtml5StackNode* listNode = listOfActiveFormattingElements[formattingEltListPos]; |
|
3512 if (!listNode) { |
|
3513 formattingEltListPos = -1; |
|
3514 break; |
|
3515 } else if (listNode->name == name) { |
|
3516 break; |
|
3517 } |
|
3518 formattingEltListPos--; |
|
3519 } |
|
3520 if (formattingEltListPos == -1) { |
|
3521 return false; |
|
3522 } |
|
3523 nsHtml5StackNode* formattingElt = listOfActiveFormattingElements[formattingEltListPos]; |
|
3524 int32_t formattingEltStackPos = currentPtr; |
|
3525 bool inScope = true; |
|
3526 while (formattingEltStackPos > -1) { |
|
3527 nsHtml5StackNode* node = stack[formattingEltStackPos]; |
|
3528 if (node == formattingElt) { |
|
3529 break; |
|
3530 } else if (node->isScoping()) { |
|
3531 inScope = false; |
|
3532 } |
|
3533 formattingEltStackPos--; |
|
3534 } |
|
3535 if (formattingEltStackPos == -1) { |
|
3536 errNoElementToCloseButEndTagSeen(name); |
|
3537 removeFromListOfActiveFormattingElements(formattingEltListPos); |
|
3538 return true; |
|
3539 } |
|
3540 if (!inScope) { |
|
3541 errNoElementToCloseButEndTagSeen(name); |
|
3542 return true; |
|
3543 } |
|
3544 if (formattingEltStackPos != currentPtr) { |
|
3545 errEndTagViolatesNestingRules(name); |
|
3546 } |
|
3547 int32_t furthestBlockPos = formattingEltStackPos + 1; |
|
3548 while (furthestBlockPos <= currentPtr) { |
|
3549 nsHtml5StackNode* node = stack[furthestBlockPos]; |
|
3550 if (node->isSpecial()) { |
|
3551 break; |
|
3552 } |
|
3553 furthestBlockPos++; |
|
3554 } |
|
3555 if (furthestBlockPos > currentPtr) { |
|
3556 while (currentPtr >= formattingEltStackPos) { |
|
3557 pop(); |
|
3558 } |
|
3559 removeFromListOfActiveFormattingElements(formattingEltListPos); |
|
3560 return true; |
|
3561 } |
|
3562 nsHtml5StackNode* commonAncestor = stack[formattingEltStackPos - 1]; |
|
3563 nsHtml5StackNode* furthestBlock = stack[furthestBlockPos]; |
|
3564 int32_t bookmark = formattingEltListPos; |
|
3565 int32_t nodePos = furthestBlockPos; |
|
3566 nsHtml5StackNode* lastNode = furthestBlock; |
|
3567 int32_t j = 0; |
|
3568 for (; ; ) { |
|
3569 ++j; |
|
3570 nodePos--; |
|
3571 if (nodePos == formattingEltStackPos) { |
|
3572 break; |
|
3573 } |
|
3574 nsHtml5StackNode* node = stack[nodePos]; |
|
3575 int32_t nodeListPos = findInListOfActiveFormattingElements(node); |
|
3576 if (j > 3 && nodeListPos != -1) { |
|
3577 removeFromListOfActiveFormattingElements(nodeListPos); |
|
3578 if (nodeListPos <= formattingEltListPos) { |
|
3579 formattingEltListPos--; |
|
3580 } |
|
3581 if (nodeListPos <= bookmark) { |
|
3582 bookmark--; |
|
3583 } |
|
3584 nodeListPos = -1; |
|
3585 } |
|
3586 if (nodeListPos == -1) { |
|
3587 MOZ_ASSERT(formattingEltStackPos < nodePos); |
|
3588 MOZ_ASSERT(bookmark < nodePos); |
|
3589 MOZ_ASSERT(furthestBlockPos > nodePos); |
|
3590 removeFromStack(nodePos); |
|
3591 furthestBlockPos--; |
|
3592 continue; |
|
3593 } |
|
3594 if (nodePos == furthestBlockPos) { |
|
3595 bookmark = nodeListPos + 1; |
|
3596 } |
|
3597 MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]); |
|
3598 MOZ_ASSERT(node == stack[nodePos]); |
|
3599 nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr)); |
|
3600 nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes); |
|
3601 node->dropAttributes(); |
|
3602 stack[nodePos] = newNode; |
|
3603 newNode->retain(); |
|
3604 listOfActiveFormattingElements[nodeListPos] = newNode; |
|
3605 node->release(); |
|
3606 node->release(); |
|
3607 node = newNode; |
|
3608 detachFromParent(lastNode->node); |
|
3609 appendElement(lastNode->node, node->node); |
|
3610 lastNode = node; |
|
3611 } |
|
3612 if (commonAncestor->isFosterParenting()) { |
|
3613 |
|
3614 detachFromParent(lastNode->node); |
|
3615 insertIntoFosterParent(lastNode->node); |
|
3616 } else { |
|
3617 detachFromParent(lastNode->node); |
|
3618 appendElement(lastNode->node, commonAncestor->node); |
|
3619 } |
|
3620 nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr)); |
|
3621 nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes); |
|
3622 formattingElt->dropAttributes(); |
|
3623 appendChildrenToNewParent(furthestBlock->node, clone); |
|
3624 appendElement(clone, furthestBlock->node); |
|
3625 removeFromListOfActiveFormattingElements(formattingEltListPos); |
|
3626 insertIntoListOfActiveFormattingElements(formattingClone, bookmark); |
|
3627 MOZ_ASSERT(formattingEltStackPos < furthestBlockPos); |
|
3628 removeFromStack(formattingEltStackPos); |
|
3629 insertIntoStack(formattingClone, furthestBlockPos); |
|
3630 } |
|
3631 return true; |
|
3632 } |
|
3633 |
|
3634 void |
|
3635 nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode* node, int32_t position) |
|
3636 { |
|
3637 MOZ_ASSERT(currentPtr + 1 < stack.length); |
|
3638 MOZ_ASSERT(position <= currentPtr + 1); |
|
3639 if (position == currentPtr + 1) { |
|
3640 push(node); |
|
3641 } else { |
|
3642 nsHtml5ArrayCopy::arraycopy(stack, position, position + 1, (currentPtr - position) + 1); |
|
3643 currentPtr++; |
|
3644 stack[position] = node; |
|
3645 } |
|
3646 } |
|
3647 |
|
3648 void |
|
3649 nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark) |
|
3650 { |
|
3651 formattingClone->retain(); |
|
3652 MOZ_ASSERT(listPtr + 1 < listOfActiveFormattingElements.length); |
|
3653 if (bookmark <= listPtr) { |
|
3654 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, bookmark, bookmark + 1, (listPtr - bookmark) + 1); |
|
3655 } |
|
3656 listPtr++; |
|
3657 listOfActiveFormattingElements[bookmark] = formattingClone; |
|
3658 } |
|
3659 |
|
3660 int32_t |
|
3661 nsHtml5TreeBuilder::findInListOfActiveFormattingElements(nsHtml5StackNode* node) |
|
3662 { |
|
3663 for (int32_t i = listPtr; i >= 0; i--) { |
|
3664 if (node == listOfActiveFormattingElements[i]) { |
|
3665 return i; |
|
3666 } |
|
3667 } |
|
3668 return -1; |
|
3669 } |
|
3670 |
|
3671 int32_t |
|
3672 nsHtml5TreeBuilder::findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name) |
|
3673 { |
|
3674 for (int32_t i = listPtr; i >= 0; i--) { |
|
3675 nsHtml5StackNode* node = listOfActiveFormattingElements[i]; |
|
3676 if (!node) { |
|
3677 return -1; |
|
3678 } else if (node->name == name) { |
|
3679 return i; |
|
3680 } |
|
3681 } |
|
3682 return -1; |
|
3683 } |
|
3684 |
|
3685 void |
|
3686 nsHtml5TreeBuilder::maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes) |
|
3687 { |
|
3688 int32_t candidate = -1; |
|
3689 int32_t count = 0; |
|
3690 for (int32_t i = listPtr; i >= 0; i--) { |
|
3691 nsHtml5StackNode* node = listOfActiveFormattingElements[i]; |
|
3692 if (!node) { |
|
3693 break; |
|
3694 } |
|
3695 if (node->name == name && node->attributes->equalsAnother(attributes)) { |
|
3696 candidate = i; |
|
3697 ++count; |
|
3698 } |
|
3699 } |
|
3700 if (count >= 3) { |
|
3701 removeFromListOfActiveFormattingElements(candidate); |
|
3702 } |
|
3703 } |
|
3704 |
|
3705 int32_t |
|
3706 nsHtml5TreeBuilder::findLastOrRoot(nsIAtom* name) |
|
3707 { |
|
3708 for (int32_t i = currentPtr; i > 0; i--) { |
|
3709 if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) { |
|
3710 return i; |
|
3711 } |
|
3712 } |
|
3713 return 0; |
|
3714 } |
|
3715 |
|
3716 int32_t |
|
3717 nsHtml5TreeBuilder::findLastOrRoot(int32_t group) |
|
3718 { |
|
3719 for (int32_t i = currentPtr; i > 0; i--) { |
|
3720 if (stack[i]->getGroup() == group) { |
|
3721 return i; |
|
3722 } |
|
3723 } |
|
3724 return 0; |
|
3725 } |
|
3726 |
|
3727 bool |
|
3728 nsHtml5TreeBuilder::addAttributesToBody(nsHtml5HtmlAttributes* attributes) |
|
3729 { |
|
3730 if (currentPtr >= 1) { |
|
3731 nsHtml5StackNode* body = stack[1]; |
|
3732 if (body->getGroup() == NS_HTML5TREE_BUILDER_BODY) { |
|
3733 addAttributesToElement(body->node, attributes); |
|
3734 return true; |
|
3735 } |
|
3736 } |
|
3737 return false; |
|
3738 } |
|
3739 |
|
3740 void |
|
3741 nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes) |
|
3742 { |
|
3743 addAttributesToElement(stack[0]->node, attributes); |
|
3744 } |
|
3745 |
|
3746 void |
|
3747 nsHtml5TreeBuilder::pushHeadPointerOntoStack() |
|
3748 { |
|
3749 MOZ_ASSERT(!!headPointer); |
|
3750 MOZ_ASSERT(mode == NS_HTML5TREE_BUILDER_AFTER_HEAD); |
|
3751 |
|
3752 silentPush(new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, headPointer)); |
|
3753 } |
|
3754 |
|
3755 void |
|
3756 nsHtml5TreeBuilder::reconstructTheActiveFormattingElements() |
|
3757 { |
|
3758 if (listPtr == -1) { |
|
3759 return; |
|
3760 } |
|
3761 nsHtml5StackNode* mostRecent = listOfActiveFormattingElements[listPtr]; |
|
3762 if (!mostRecent || isInStack(mostRecent)) { |
|
3763 return; |
|
3764 } |
|
3765 int32_t entryPos = listPtr; |
|
3766 for (; ; ) { |
|
3767 entryPos--; |
|
3768 if (entryPos == -1) { |
|
3769 break; |
|
3770 } |
|
3771 if (!listOfActiveFormattingElements[entryPos]) { |
|
3772 break; |
|
3773 } |
|
3774 if (isInStack(listOfActiveFormattingElements[entryPos])) { |
|
3775 break; |
|
3776 } |
|
3777 } |
|
3778 while (entryPos < listPtr) { |
|
3779 entryPos++; |
|
3780 nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos]; |
|
3781 nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr)); |
|
3782 nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes); |
|
3783 entry->dropAttributes(); |
|
3784 nsHtml5StackNode* currentNode = stack[currentPtr]; |
|
3785 if (currentNode->isFosterParenting()) { |
|
3786 insertIntoFosterParent(clone); |
|
3787 } else { |
|
3788 appendElement(clone, currentNode->node); |
|
3789 } |
|
3790 push(entryClone); |
|
3791 listOfActiveFormattingElements[entryPos] = entryClone; |
|
3792 entry->release(); |
|
3793 entryClone->retain(); |
|
3794 } |
|
3795 } |
|
3796 |
|
3797 void |
|
3798 nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child) |
|
3799 { |
|
3800 int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE); |
|
3801 int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE); |
|
3802 if (templatePos >= tablePos) { |
|
3803 appendElement(child, stack[templatePos]->node); |
|
3804 return; |
|
3805 } |
|
3806 nsHtml5StackNode* node = stack[tablePos]; |
|
3807 insertFosterParentedChild(child, node->node, stack[tablePos - 1]->node); |
|
3808 } |
|
3809 |
|
3810 bool |
|
3811 nsHtml5TreeBuilder::isInStack(nsHtml5StackNode* node) |
|
3812 { |
|
3813 for (int32_t i = currentPtr; i >= 0; i--) { |
|
3814 if (stack[i] == node) { |
|
3815 return true; |
|
3816 } |
|
3817 } |
|
3818 return false; |
|
3819 } |
|
3820 |
|
3821 void |
|
3822 nsHtml5TreeBuilder::popTemplateMode() |
|
3823 { |
|
3824 templateModePtr--; |
|
3825 } |
|
3826 |
|
3827 void |
|
3828 nsHtml5TreeBuilder::pop() |
|
3829 { |
|
3830 nsHtml5StackNode* node = stack[currentPtr]; |
|
3831 MOZ_ASSERT(debugOnlyClearLastStackSlot()); |
|
3832 currentPtr--; |
|
3833 elementPopped(node->ns, node->popName, node->node); |
|
3834 node->release(); |
|
3835 } |
|
3836 |
|
3837 void |
|
3838 nsHtml5TreeBuilder::silentPop() |
|
3839 { |
|
3840 nsHtml5StackNode* node = stack[currentPtr]; |
|
3841 MOZ_ASSERT(debugOnlyClearLastStackSlot()); |
|
3842 currentPtr--; |
|
3843 node->release(); |
|
3844 } |
|
3845 |
|
3846 void |
|
3847 nsHtml5TreeBuilder::popOnEof() |
|
3848 { |
|
3849 nsHtml5StackNode* node = stack[currentPtr]; |
|
3850 MOZ_ASSERT(debugOnlyClearLastStackSlot()); |
|
3851 currentPtr--; |
|
3852 markMalformedIfScript(node->node); |
|
3853 elementPopped(node->ns, node->popName, node->node); |
|
3854 node->release(); |
|
3855 } |
|
3856 |
|
3857 void |
|
3858 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes) |
|
3859 { |
|
3860 nsIContentHandle* elt = createHtmlElementSetAsRoot(attributes); |
|
3861 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt); |
|
3862 push(node); |
|
3863 } |
|
3864 |
|
3865 void |
|
3866 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush() |
|
3867 { |
|
3868 appendHtmlElementToDocumentAndPush(tokenizer->emptyAttributes()); |
|
3869 } |
|
3870 |
|
3871 void |
|
3872 nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes) |
|
3873 { |
|
3874 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes); |
|
3875 appendElement(elt, stack[currentPtr]->node); |
|
3876 headPointer = elt; |
|
3877 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, elt); |
|
3878 push(node); |
|
3879 } |
|
3880 |
|
3881 void |
|
3882 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes) |
|
3883 { |
|
3884 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY, attributes); |
|
3885 } |
|
3886 |
|
3887 void |
|
3888 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement() |
|
3889 { |
|
3890 appendToCurrentNodeAndPushBodyElement(tokenizer->emptyAttributes()); |
|
3891 } |
|
3892 |
|
3893 void |
|
3894 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes) |
|
3895 { |
|
3896 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes); |
|
3897 if (!isTemplateContents()) { |
|
3898 formPointer = elt; |
|
3899 } |
|
3900 nsHtml5StackNode* current = stack[currentPtr]; |
|
3901 if (current->isFosterParenting()) { |
|
3902 |
|
3903 insertIntoFosterParent(elt); |
|
3904 } else { |
|
3905 appendElement(elt, current->node); |
|
3906 } |
|
3907 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt); |
|
3908 push(node); |
|
3909 } |
|
3910 |
|
3911 void |
|
3912 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
3913 { |
|
3914 nsHtml5HtmlAttributes* clone = attributes->cloneAttributes(nullptr); |
|
3915 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes); |
|
3916 nsHtml5StackNode* current = stack[currentPtr]; |
|
3917 if (current->isFosterParenting()) { |
|
3918 |
|
3919 insertIntoFosterParent(elt); |
|
3920 } else { |
|
3921 appendElement(elt, current->node); |
|
3922 } |
|
3923 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, clone); |
|
3924 push(node); |
|
3925 append(node); |
|
3926 node->retain(); |
|
3927 } |
|
3928 |
|
3929 void |
|
3930 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
3931 { |
|
3932 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes); |
|
3933 appendElement(elt, stack[currentPtr]->node); |
|
3934 if (nsHtml5ElementName::ELT_TEMPLATE == elementName) { |
|
3935 elt = getDocumentFragmentForTemplate(elt); |
|
3936 } |
|
3937 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt); |
|
3938 push(node); |
|
3939 } |
|
3940 |
|
3941 void |
|
3942 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
3943 { |
|
3944 nsIAtom* popName = elementName->name; |
|
3945 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes); |
|
3946 nsHtml5StackNode* current = stack[currentPtr]; |
|
3947 if (current->isFosterParenting()) { |
|
3948 |
|
3949 insertIntoFosterParent(elt); |
|
3950 } else { |
|
3951 appendElement(elt, current->node); |
|
3952 } |
|
3953 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName); |
|
3954 push(node); |
|
3955 } |
|
3956 |
|
3957 void |
|
3958 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
3959 { |
|
3960 nsIAtom* popName = elementName->name; |
|
3961 bool markAsHtmlIntegrationPoint = false; |
|
3962 if (nsHtml5ElementName::ELT_ANNOTATION_XML == elementName && annotationXmlEncodingPermitsHtml(attributes)) { |
|
3963 markAsHtmlIntegrationPoint = true; |
|
3964 } |
|
3965 nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes); |
|
3966 nsHtml5StackNode* current = stack[currentPtr]; |
|
3967 if (current->isFosterParenting()) { |
|
3968 |
|
3969 insertIntoFosterParent(elt); |
|
3970 } else { |
|
3971 appendElement(elt, current->node); |
|
3972 } |
|
3973 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName, markAsHtmlIntegrationPoint); |
|
3974 push(node); |
|
3975 } |
|
3976 |
|
3977 bool |
|
3978 nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes) |
|
3979 { |
|
3980 nsString* encoding = attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING); |
|
3981 if (!encoding) { |
|
3982 return false; |
|
3983 } |
|
3984 return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("application/xhtml+xml", encoding) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("text/html", encoding); |
|
3985 } |
|
3986 |
|
3987 void |
|
3988 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
3989 { |
|
3990 nsIAtom* popName = elementName->camelCaseName; |
|
3991 nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes); |
|
3992 nsHtml5StackNode* current = stack[currentPtr]; |
|
3993 if (current->isFosterParenting()) { |
|
3994 |
|
3995 insertIntoFosterParent(elt); |
|
3996 } else { |
|
3997 appendElement(elt, current->node); |
|
3998 } |
|
3999 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt); |
|
4000 push(node); |
|
4001 } |
|
4002 |
|
4003 void |
|
4004 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form) |
|
4005 { |
|
4006 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, !form || fragment || isTemplateContents() ? nullptr : form); |
|
4007 nsHtml5StackNode* current = stack[currentPtr]; |
|
4008 if (current->isFosterParenting()) { |
|
4009 |
|
4010 insertIntoFosterParent(elt); |
|
4011 } else { |
|
4012 appendElement(elt, current->node); |
|
4013 } |
|
4014 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt); |
|
4015 push(node); |
|
4016 } |
|
4017 |
|
4018 void |
|
4019 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form) |
|
4020 { |
|
4021 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form); |
|
4022 nsHtml5StackNode* current = stack[currentPtr]; |
|
4023 if (current->isFosterParenting()) { |
|
4024 |
|
4025 insertIntoFosterParent(elt); |
|
4026 } else { |
|
4027 appendElement(elt, current->node); |
|
4028 } |
|
4029 elementPushed(kNameSpaceID_XHTML, name, elt); |
|
4030 elementPopped(kNameSpaceID_XHTML, name, elt); |
|
4031 } |
|
4032 |
|
4033 void |
|
4034 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
4035 { |
|
4036 nsIAtom* popName = elementName->name; |
|
4037 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes); |
|
4038 nsHtml5StackNode* current = stack[currentPtr]; |
|
4039 if (current->isFosterParenting()) { |
|
4040 |
|
4041 insertIntoFosterParent(elt); |
|
4042 } else { |
|
4043 appendElement(elt, current->node); |
|
4044 } |
|
4045 elementPushed(kNameSpaceID_XHTML, popName, elt); |
|
4046 elementPopped(kNameSpaceID_XHTML, popName, elt); |
|
4047 } |
|
4048 |
|
4049 void |
|
4050 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
4051 { |
|
4052 nsIAtom* popName = elementName->camelCaseName; |
|
4053 nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes); |
|
4054 nsHtml5StackNode* current = stack[currentPtr]; |
|
4055 if (current->isFosterParenting()) { |
|
4056 |
|
4057 insertIntoFosterParent(elt); |
|
4058 } else { |
|
4059 appendElement(elt, current->node); |
|
4060 } |
|
4061 elementPushed(kNameSpaceID_SVG, popName, elt); |
|
4062 elementPopped(kNameSpaceID_SVG, popName, elt); |
|
4063 } |
|
4064 |
|
4065 void |
|
4066 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) |
|
4067 { |
|
4068 nsIAtom* popName = elementName->name; |
|
4069 nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes); |
|
4070 nsHtml5StackNode* current = stack[currentPtr]; |
|
4071 if (current->isFosterParenting()) { |
|
4072 |
|
4073 insertIntoFosterParent(elt); |
|
4074 } else { |
|
4075 appendElement(elt, current->node); |
|
4076 } |
|
4077 elementPushed(kNameSpaceID_MathML, popName, elt); |
|
4078 elementPopped(kNameSpaceID_MathML, popName, elt); |
|
4079 } |
|
4080 |
|
4081 void |
|
4082 nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form) |
|
4083 { |
|
4084 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form); |
|
4085 nsHtml5StackNode* current = stack[currentPtr]; |
|
4086 appendElement(elt, current->node); |
|
4087 elementPushed(kNameSpaceID_XHTML, name, elt); |
|
4088 elementPopped(kNameSpaceID_XHTML, name, elt); |
|
4089 } |
|
4090 |
|
4091 void |
|
4092 nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes) |
|
4093 { |
|
4094 nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes); |
|
4095 formPointer = elt; |
|
4096 nsHtml5StackNode* current = stack[currentPtr]; |
|
4097 appendElement(elt, current->node); |
|
4098 elementPushed(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt); |
|
4099 elementPopped(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt); |
|
4100 } |
|
4101 |
|
4102 void |
|
4103 nsHtml5TreeBuilder::requestSuspension() |
|
4104 { |
|
4105 tokenizer->requestSuspension(); |
|
4106 } |
|
4107 |
|
4108 bool |
|
4109 nsHtml5TreeBuilder::isInForeign() |
|
4110 { |
|
4111 return currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML; |
|
4112 } |
|
4113 |
|
4114 bool |
|
4115 nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint() |
|
4116 { |
|
4117 if (currentPtr < 0) { |
|
4118 return false; |
|
4119 } |
|
4120 return !isSpecialParentInForeign(stack[currentPtr]); |
|
4121 } |
|
4122 |
|
4123 void |
|
4124 nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks) |
|
4125 { |
|
4126 this->contextName = context; |
|
4127 this->contextNamespace = ns; |
|
4128 this->contextNode = node; |
|
4129 this->fragment = (!!contextName); |
|
4130 this->quirks = quirks; |
|
4131 } |
|
4132 |
|
4133 nsIContentHandle* |
|
4134 nsHtml5TreeBuilder::currentNode() |
|
4135 { |
|
4136 return stack[currentPtr]->node; |
|
4137 } |
|
4138 |
|
4139 bool |
|
4140 nsHtml5TreeBuilder::isScriptingEnabled() |
|
4141 { |
|
4142 return scriptingEnabled; |
|
4143 } |
|
4144 |
|
4145 void |
|
4146 nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled) |
|
4147 { |
|
4148 this->scriptingEnabled = scriptingEnabled; |
|
4149 } |
|
4150 |
|
4151 void |
|
4152 nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument) |
|
4153 { |
|
4154 this->isSrcdocDocument = isSrcdocDocument; |
|
4155 } |
|
4156 |
|
4157 void |
|
4158 nsHtml5TreeBuilder::flushCharacters() |
|
4159 { |
|
4160 if (charBufferLen > 0) { |
|
4161 if ((mode == NS_HTML5TREE_BUILDER_IN_TABLE || mode == NS_HTML5TREE_BUILDER_IN_TABLE_BODY || mode == NS_HTML5TREE_BUILDER_IN_ROW) && charBufferContainsNonWhitespace()) { |
|
4162 errNonSpaceInTable(); |
|
4163 reconstructTheActiveFormattingElements(); |
|
4164 if (!stack[currentPtr]->isFosterParenting()) { |
|
4165 appendCharacters(currentNode(), charBuffer, 0, charBufferLen); |
|
4166 charBufferLen = 0; |
|
4167 return; |
|
4168 } |
|
4169 int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE); |
|
4170 int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE); |
|
4171 if (templatePos >= tablePos) { |
|
4172 appendCharacters(stack[templatePos]->node, charBuffer, 0, charBufferLen); |
|
4173 charBufferLen = 0; |
|
4174 return; |
|
4175 } |
|
4176 nsHtml5StackNode* tableElt = stack[tablePos]; |
|
4177 insertFosterParentedCharacters(charBuffer, 0, charBufferLen, tableElt->node, stack[tablePos - 1]->node); |
|
4178 charBufferLen = 0; |
|
4179 return; |
|
4180 } |
|
4181 appendCharacters(currentNode(), charBuffer, 0, charBufferLen); |
|
4182 charBufferLen = 0; |
|
4183 } |
|
4184 } |
|
4185 |
|
4186 bool |
|
4187 nsHtml5TreeBuilder::charBufferContainsNonWhitespace() |
|
4188 { |
|
4189 for (int32_t i = 0; i < charBufferLen; i++) { |
|
4190 switch(charBuffer[i]) { |
|
4191 case ' ': |
|
4192 case '\t': |
|
4193 case '\n': |
|
4194 case '\r': |
|
4195 case '\f': { |
|
4196 continue; |
|
4197 } |
|
4198 default: { |
|
4199 return true; |
|
4200 } |
|
4201 } |
|
4202 } |
|
4203 return false; |
|
4204 } |
|
4205 |
|
4206 nsAHtml5TreeBuilderState* |
|
4207 nsHtml5TreeBuilder::newSnapshot() |
|
4208 { |
|
4209 jArray<nsHtml5StackNode*,int32_t> listCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(listPtr + 1); |
|
4210 for (int32_t i = 0; i < listCopy.length; i++) { |
|
4211 nsHtml5StackNode* node = listOfActiveFormattingElements[i]; |
|
4212 if (node) { |
|
4213 nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, node->attributes->cloneAttributes(nullptr)); |
|
4214 listCopy[i] = newNode; |
|
4215 } else { |
|
4216 listCopy[i] = nullptr; |
|
4217 } |
|
4218 } |
|
4219 jArray<nsHtml5StackNode*,int32_t> stackCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(currentPtr + 1); |
|
4220 for (int32_t i = 0; i < stackCopy.length; i++) { |
|
4221 nsHtml5StackNode* node = stack[i]; |
|
4222 int32_t listIndex = findInListOfActiveFormattingElements(node); |
|
4223 if (listIndex == -1) { |
|
4224 nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, nullptr); |
|
4225 stackCopy[i] = newNode; |
|
4226 } else { |
|
4227 stackCopy[i] = listCopy[listIndex]; |
|
4228 stackCopy[i]->retain(); |
|
4229 } |
|
4230 } |
|
4231 jArray<int32_t,int32_t> templateModeStackCopy = jArray<int32_t,int32_t>::newJArray(templateModePtr + 1); |
|
4232 nsHtml5ArrayCopy::arraycopy(templateModeStack, templateModeStackCopy, templateModeStackCopy.length); |
|
4233 return new nsHtml5StateSnapshot(stackCopy, listCopy, templateModeStackCopy, formPointer, headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk, needToDropLF, quirks); |
|
4234 } |
|
4235 |
|
4236 bool |
|
4237 nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState* snapshot) |
|
4238 { |
|
4239 jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack(); |
|
4240 int32_t stackLen = snapshot->getStackLength(); |
|
4241 jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements(); |
|
4242 int32_t listLen = snapshot->getListOfActiveFormattingElementsLength(); |
|
4243 jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack(); |
|
4244 int32_t templateModeStackLen = snapshot->getTemplateModeStackLength(); |
|
4245 if (stackLen != currentPtr + 1 || listLen != listPtr + 1 || templateModeStackLen != templateModePtr + 1 || formPointer != snapshot->getFormPointer() || headPointer != snapshot->getHeadPointer() || deepTreeSurrogateParent != snapshot->getDeepTreeSurrogateParent() || mode != snapshot->getMode() || originalMode != snapshot->getOriginalMode() || framesetOk != snapshot->isFramesetOk() || needToDropLF != snapshot->isNeedToDropLF() || quirks != snapshot->isQuirks()) { |
|
4246 return false; |
|
4247 } |
|
4248 for (int32_t i = listLen - 1; i >= 0; i--) { |
|
4249 if (!listCopy[i] && !listOfActiveFormattingElements[i]) { |
|
4250 continue; |
|
4251 } else if (!listCopy[i] || !listOfActiveFormattingElements[i]) { |
|
4252 return false; |
|
4253 } |
|
4254 if (listCopy[i]->node != listOfActiveFormattingElements[i]->node) { |
|
4255 return false; |
|
4256 } |
|
4257 } |
|
4258 for (int32_t i = stackLen - 1; i >= 0; i--) { |
|
4259 if (stackCopy[i]->node != stack[i]->node) { |
|
4260 return false; |
|
4261 } |
|
4262 } |
|
4263 for (int32_t i = templateModeStackLen - 1; i >= 0; i--) { |
|
4264 if (templateModeStackCopy[i] != templateModeStack[i]) { |
|
4265 return false; |
|
4266 } |
|
4267 } |
|
4268 return true; |
|
4269 } |
|
4270 |
|
4271 void |
|
4272 nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner) |
|
4273 { |
|
4274 jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack(); |
|
4275 int32_t stackLen = snapshot->getStackLength(); |
|
4276 jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements(); |
|
4277 int32_t listLen = snapshot->getListOfActiveFormattingElementsLength(); |
|
4278 jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack(); |
|
4279 int32_t templateModeStackLen = snapshot->getTemplateModeStackLength(); |
|
4280 for (int32_t i = 0; i <= listPtr; i++) { |
|
4281 if (listOfActiveFormattingElements[i]) { |
|
4282 listOfActiveFormattingElements[i]->release(); |
|
4283 } |
|
4284 } |
|
4285 if (listOfActiveFormattingElements.length < listLen) { |
|
4286 listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(listLen); |
|
4287 } |
|
4288 listPtr = listLen - 1; |
|
4289 for (int32_t i = 0; i <= currentPtr; i++) { |
|
4290 stack[i]->release(); |
|
4291 } |
|
4292 if (stack.length < stackLen) { |
|
4293 stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stackLen); |
|
4294 } |
|
4295 currentPtr = stackLen - 1; |
|
4296 if (templateModeStack.length < templateModeStackLen) { |
|
4297 templateModeStack = jArray<int32_t,int32_t>::newJArray(templateModeStackLen); |
|
4298 } |
|
4299 templateModePtr = templateModeStackLen - 1; |
|
4300 for (int32_t i = 0; i < listLen; i++) { |
|
4301 nsHtml5StackNode* node = listCopy[i]; |
|
4302 if (node) { |
|
4303 nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), node->attributes->cloneAttributes(nullptr)); |
|
4304 listOfActiveFormattingElements[i] = newNode; |
|
4305 } else { |
|
4306 listOfActiveFormattingElements[i] = nullptr; |
|
4307 } |
|
4308 } |
|
4309 for (int32_t i = 0; i < stackLen; i++) { |
|
4310 nsHtml5StackNode* node = stackCopy[i]; |
|
4311 int32_t listIndex = findInArray(node, listCopy); |
|
4312 if (listIndex == -1) { |
|
4313 nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), nullptr); |
|
4314 stack[i] = newNode; |
|
4315 } else { |
|
4316 stack[i] = listOfActiveFormattingElements[listIndex]; |
|
4317 stack[i]->retain(); |
|
4318 } |
|
4319 } |
|
4320 nsHtml5ArrayCopy::arraycopy(templateModeStackCopy, templateModeStack, templateModeStackLen); |
|
4321 formPointer = snapshot->getFormPointer(); |
|
4322 headPointer = snapshot->getHeadPointer(); |
|
4323 deepTreeSurrogateParent = snapshot->getDeepTreeSurrogateParent(); |
|
4324 mode = snapshot->getMode(); |
|
4325 originalMode = snapshot->getOriginalMode(); |
|
4326 framesetOk = snapshot->isFramesetOk(); |
|
4327 needToDropLF = snapshot->isNeedToDropLF(); |
|
4328 quirks = snapshot->isQuirks(); |
|
4329 } |
|
4330 |
|
4331 int32_t |
|
4332 nsHtml5TreeBuilder::findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr) |
|
4333 { |
|
4334 for (int32_t i = listPtr; i >= 0; i--) { |
|
4335 if (node == arr[i]) { |
|
4336 return i; |
|
4337 } |
|
4338 } |
|
4339 return -1; |
|
4340 } |
|
4341 |
|
4342 nsIContentHandle* |
|
4343 nsHtml5TreeBuilder::getFormPointer() |
|
4344 { |
|
4345 return formPointer; |
|
4346 } |
|
4347 |
|
4348 nsIContentHandle* |
|
4349 nsHtml5TreeBuilder::getHeadPointer() |
|
4350 { |
|
4351 return headPointer; |
|
4352 } |
|
4353 |
|
4354 nsIContentHandle* |
|
4355 nsHtml5TreeBuilder::getDeepTreeSurrogateParent() |
|
4356 { |
|
4357 return deepTreeSurrogateParent; |
|
4358 } |
|
4359 |
|
4360 jArray<nsHtml5StackNode*,int32_t> |
|
4361 nsHtml5TreeBuilder::getListOfActiveFormattingElements() |
|
4362 { |
|
4363 return listOfActiveFormattingElements; |
|
4364 } |
|
4365 |
|
4366 jArray<nsHtml5StackNode*,int32_t> |
|
4367 nsHtml5TreeBuilder::getStack() |
|
4368 { |
|
4369 return stack; |
|
4370 } |
|
4371 |
|
4372 jArray<int32_t,int32_t> |
|
4373 nsHtml5TreeBuilder::getTemplateModeStack() |
|
4374 { |
|
4375 return templateModeStack; |
|
4376 } |
|
4377 |
|
4378 int32_t |
|
4379 nsHtml5TreeBuilder::getMode() |
|
4380 { |
|
4381 return mode; |
|
4382 } |
|
4383 |
|
4384 int32_t |
|
4385 nsHtml5TreeBuilder::getOriginalMode() |
|
4386 { |
|
4387 return originalMode; |
|
4388 } |
|
4389 |
|
4390 bool |
|
4391 nsHtml5TreeBuilder::isFramesetOk() |
|
4392 { |
|
4393 return framesetOk; |
|
4394 } |
|
4395 |
|
4396 bool |
|
4397 nsHtml5TreeBuilder::isNeedToDropLF() |
|
4398 { |
|
4399 return needToDropLF; |
|
4400 } |
|
4401 |
|
4402 bool |
|
4403 nsHtml5TreeBuilder::isQuirks() |
|
4404 { |
|
4405 return quirks; |
|
4406 } |
|
4407 |
|
4408 int32_t |
|
4409 nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength() |
|
4410 { |
|
4411 return listPtr + 1; |
|
4412 } |
|
4413 |
|
4414 int32_t |
|
4415 nsHtml5TreeBuilder::getStackLength() |
|
4416 { |
|
4417 return currentPtr + 1; |
|
4418 } |
|
4419 |
|
4420 int32_t |
|
4421 nsHtml5TreeBuilder::getTemplateModeStackLength() |
|
4422 { |
|
4423 return templateModePtr + 1; |
|
4424 } |
|
4425 |
|
4426 void |
|
4427 nsHtml5TreeBuilder::initializeStatics() |
|
4428 { |
|
4429 } |
|
4430 |
|
4431 void |
|
4432 nsHtml5TreeBuilder::releaseStatics() |
|
4433 { |
|
4434 } |
|
4435 |
|
4436 |
|
4437 #include "nsHtml5TreeBuilderCppSupplement.h" |
|
4438 |