Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
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 */
26 /*
27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
28 * Please edit TreeBuilder.java instead and regenerate.
29 */
31 #define nsHtml5TreeBuilder_cpp__
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"
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"
70 #include "nsHtml5TreeBuilder.h"
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 }
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 }
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 }
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();
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 }
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 }
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 }
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 }
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);
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 }
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 }
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 }
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 }
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 }
1937 bool
1938 nsHtml5TreeBuilder::isTemplateContents()
1939 {
1940 return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_);
1941 }
1943 bool
1944 nsHtml5TreeBuilder::isTemplateModeStackEmpty()
1945 {
1946 return templateModePtr == -1;
1947 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
3154 bool
3155 nsHtml5TreeBuilder::isSecondOnStackBody()
3156 {
3157 return currentPtr >= 1 && stack[1]->getGroup() == NS_HTML5TREE_BUILDER_BODY;
3158 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
3375 bool
3376 nsHtml5TreeBuilder::debugOnlyClearLastStackSlot()
3377 {
3378 stack[currentPtr] = nullptr;
3379 return true;
3380 }
3382 bool
3383 nsHtml5TreeBuilder::debugOnlyClearLastListSlot()
3384 {
3385 listOfActiveFormattingElements[listPtr] = nullptr;
3386 return true;
3387 }
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 }
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 }
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 }
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 }
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 }
3451 void
3452 nsHtml5TreeBuilder::removeFromStack(int32_t pos)
3453 {
3454 if (currentPtr == pos) {
3455 pop();
3456 } else {
3458 stack[pos]->release();
3459 nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
3460 MOZ_ASSERT(debugOnlyClearLastStackSlot());
3461 currentPtr--;
3462 }
3463 }
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 }
3479 node->release();
3480 nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
3481 currentPtr--;
3482 }
3483 }
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 }
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()) {
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
3740 void
3741 nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes)
3742 {
3743 addAttributesToElement(stack[0]->node, attributes);
3744 }
3746 void
3747 nsHtml5TreeBuilder::pushHeadPointerOntoStack()
3748 {
3749 MOZ_ASSERT(!!headPointer);
3750 MOZ_ASSERT(mode == NS_HTML5TREE_BUILDER_AFTER_HEAD);
3752 silentPush(new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, headPointer));
3753 }
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 }
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 }
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 }
3821 void
3822 nsHtml5TreeBuilder::popTemplateMode()
3823 {
3824 templateModePtr--;
3825 }
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 }
3837 void
3838 nsHtml5TreeBuilder::silentPop()
3839 {
3840 nsHtml5StackNode* node = stack[currentPtr];
3841 MOZ_ASSERT(debugOnlyClearLastStackSlot());
3842 currentPtr--;
3843 node->release();
3844 }
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 }
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 }
3865 void
3866 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush()
3867 {
3868 appendHtmlElementToDocumentAndPush(tokenizer->emptyAttributes());
3869 }
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 }
3881 void
3882 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes)
3883 {
3884 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY, attributes);
3885 }
3887 void
3888 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement()
3889 {
3890 appendToCurrentNodeAndPushBodyElement(tokenizer->emptyAttributes());
3891 }
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()) {
3903 insertIntoFosterParent(elt);
3904 } else {
3905 appendElement(elt, current->node);
3906 }
3907 nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt);
3908 push(node);
3909 }
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()) {
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 }
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 }
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()) {
3949 insertIntoFosterParent(elt);
3950 } else {
3951 appendElement(elt, current->node);
3952 }
3953 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName);
3954 push(node);
3955 }
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()) {
3969 insertIntoFosterParent(elt);
3970 } else {
3971 appendElement(elt, current->node);
3972 }
3973 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName, markAsHtmlIntegrationPoint);
3974 push(node);
3975 }
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 }
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()) {
3995 insertIntoFosterParent(elt);
3996 } else {
3997 appendElement(elt, current->node);
3998 }
3999 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt);
4000 push(node);
4001 }
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()) {
4010 insertIntoFosterParent(elt);
4011 } else {
4012 appendElement(elt, current->node);
4013 }
4014 nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
4015 push(node);
4016 }
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()) {
4025 insertIntoFosterParent(elt);
4026 } else {
4027 appendElement(elt, current->node);
4028 }
4029 elementPushed(kNameSpaceID_XHTML, name, elt);
4030 elementPopped(kNameSpaceID_XHTML, name, elt);
4031 }
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()) {
4041 insertIntoFosterParent(elt);
4042 } else {
4043 appendElement(elt, current->node);
4044 }
4045 elementPushed(kNameSpaceID_XHTML, popName, elt);
4046 elementPopped(kNameSpaceID_XHTML, popName, elt);
4047 }
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()) {
4057 insertIntoFosterParent(elt);
4058 } else {
4059 appendElement(elt, current->node);
4060 }
4061 elementPushed(kNameSpaceID_SVG, popName, elt);
4062 elementPopped(kNameSpaceID_SVG, popName, elt);
4063 }
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()) {
4073 insertIntoFosterParent(elt);
4074 } else {
4075 appendElement(elt, current->node);
4076 }
4077 elementPushed(kNameSpaceID_MathML, popName, elt);
4078 elementPopped(kNameSpaceID_MathML, popName, elt);
4079 }
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 }
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 }
4102 void
4103 nsHtml5TreeBuilder::requestSuspension()
4104 {
4105 tokenizer->requestSuspension();
4106 }
4108 bool
4109 nsHtml5TreeBuilder::isInForeign()
4110 {
4111 return currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML;
4112 }
4114 bool
4115 nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint()
4116 {
4117 if (currentPtr < 0) {
4118 return false;
4119 }
4120 return !isSpecialParentInForeign(stack[currentPtr]);
4121 }
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 }
4133 nsIContentHandle*
4134 nsHtml5TreeBuilder::currentNode()
4135 {
4136 return stack[currentPtr]->node;
4137 }
4139 bool
4140 nsHtml5TreeBuilder::isScriptingEnabled()
4141 {
4142 return scriptingEnabled;
4143 }
4145 void
4146 nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled)
4147 {
4148 this->scriptingEnabled = scriptingEnabled;
4149 }
4151 void
4152 nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument)
4153 {
4154 this->isSrcdocDocument = isSrcdocDocument;
4155 }
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 }
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 }
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 }
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 }
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 }
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 }
4342 nsIContentHandle*
4343 nsHtml5TreeBuilder::getFormPointer()
4344 {
4345 return formPointer;
4346 }
4348 nsIContentHandle*
4349 nsHtml5TreeBuilder::getHeadPointer()
4350 {
4351 return headPointer;
4352 }
4354 nsIContentHandle*
4355 nsHtml5TreeBuilder::getDeepTreeSurrogateParent()
4356 {
4357 return deepTreeSurrogateParent;
4358 }
4360 jArray<nsHtml5StackNode*,int32_t>
4361 nsHtml5TreeBuilder::getListOfActiveFormattingElements()
4362 {
4363 return listOfActiveFormattingElements;
4364 }
4366 jArray<nsHtml5StackNode*,int32_t>
4367 nsHtml5TreeBuilder::getStack()
4368 {
4369 return stack;
4370 }
4372 jArray<int32_t,int32_t>
4373 nsHtml5TreeBuilder::getTemplateModeStack()
4374 {
4375 return templateModeStack;
4376 }
4378 int32_t
4379 nsHtml5TreeBuilder::getMode()
4380 {
4381 return mode;
4382 }
4384 int32_t
4385 nsHtml5TreeBuilder::getOriginalMode()
4386 {
4387 return originalMode;
4388 }
4390 bool
4391 nsHtml5TreeBuilder::isFramesetOk()
4392 {
4393 return framesetOk;
4394 }
4396 bool
4397 nsHtml5TreeBuilder::isNeedToDropLF()
4398 {
4399 return needToDropLF;
4400 }
4402 bool
4403 nsHtml5TreeBuilder::isQuirks()
4404 {
4405 return quirks;
4406 }
4408 int32_t
4409 nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength()
4410 {
4411 return listPtr + 1;
4412 }
4414 int32_t
4415 nsHtml5TreeBuilder::getStackLength()
4416 {
4417 return currentPtr + 1;
4418 }
4420 int32_t
4421 nsHtml5TreeBuilder::getTemplateModeStackLength()
4422 {
4423 return templateModePtr + 1;
4424 }
4426 void
4427 nsHtml5TreeBuilder::initializeStatics()
4428 {
4429 }
4431 void
4432 nsHtml5TreeBuilder::releaseStatics()
4433 {
4434 }
4437 #include "nsHtml5TreeBuilderCppSupplement.h"