2 * Copyright (c) 2007 Henri Sivonen
3 * Copyright (c) 2007-2017 Mozilla Foundation
4 * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
5 * Foundation, and Opera Software ASA.
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
28 * Please edit TreeBuilder.java instead and regenerate.
31 #define nsHtml5TreeBuilder_cpp__
33 #include "nsContentUtils.h"
35 #include "nsHtml5AtomTable.h"
36 #include "nsHtml5String.h"
37 #include "nsNameSpaceManager.h"
38 #include "nsIContent.h"
39 #include "nsTraceRefcnt.h"
41 #include "nsHtml5DocumentMode.h"
42 #include "nsHtml5ArrayCopy.h"
43 #include "nsHtml5Parser.h"
44 #include "nsGkAtoms.h"
45 #include "nsHtml5TreeOperation.h"
46 #include "nsHtml5StateSnapshot.h"
47 #include "nsHtml5StackNode.h"
48 #include "nsHtml5TreeOpExecutor.h"
49 #include "nsHtml5StreamParser.h"
50 #include "nsAHtml5TreeBuilderState.h"
51 #include "nsHtml5Highlighter.h"
52 #include "nsHtml5PlainTextUtils.h"
53 #include "nsHtml5ViewSourceUtils.h"
54 #include "mozilla/ImportScanner.h"
55 #include "mozilla/Likely.h"
56 #include "nsIContentHandle.h"
57 #include "nsHtml5OplessBuilder.h"
59 #include "nsHtml5AttributeName.h"
60 #include "nsHtml5ElementName.h"
61 #include "nsHtml5Tokenizer.h"
62 #include "nsHtml5MetaScanner.h"
63 #include "nsHtml5StackNode.h"
64 #include "nsHtml5UTF16Buffer.h"
65 #include "nsHtml5StateSnapshot.h"
66 #include "nsHtml5Portability.h"
68 #include "nsHtml5TreeBuilder.h"
70 char16_t
nsHtml5TreeBuilder::REPLACEMENT_CHARACTER
[] = {0xfffd};
71 static const char* const QUIRKY_PUBLIC_IDS_DATA
[] = {
72 "+//silmaril//dtd html pro v0r11 19970101//",
73 "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
74 "-//as//dtd html 3.0 aswedit + extensions//",
75 "-//ietf//dtd html 2.0 level 1//",
76 "-//ietf//dtd html 2.0 level 2//",
77 "-//ietf//dtd html 2.0 strict level 1//",
78 "-//ietf//dtd html 2.0 strict level 2//",
79 "-//ietf//dtd html 2.0 strict//",
80 "-//ietf//dtd html 2.0//",
81 "-//ietf//dtd html 2.1e//",
82 "-//ietf//dtd html 3.0//",
83 "-//ietf//dtd html 3.2 final//",
84 "-//ietf//dtd html 3.2//",
85 "-//ietf//dtd html 3//",
86 "-//ietf//dtd html level 0//",
87 "-//ietf//dtd html level 1//",
88 "-//ietf//dtd html level 2//",
89 "-//ietf//dtd html level 3//",
90 "-//ietf//dtd html strict level 0//",
91 "-//ietf//dtd html strict level 1//",
92 "-//ietf//dtd html strict level 2//",
93 "-//ietf//dtd html strict level 3//",
94 "-//ietf//dtd html strict//",
95 "-//ietf//dtd html//",
96 "-//metrius//dtd metrius presentational//",
97 "-//microsoft//dtd internet explorer 2.0 html strict//",
98 "-//microsoft//dtd internet explorer 2.0 html//",
99 "-//microsoft//dtd internet explorer 2.0 tables//",
100 "-//microsoft//dtd internet explorer 3.0 html strict//",
101 "-//microsoft//dtd internet explorer 3.0 html//",
102 "-//microsoft//dtd internet explorer 3.0 tables//",
103 "-//netscape comm. corp.//dtd html//",
104 "-//netscape comm. corp.//dtd strict html//",
105 "-//o'reilly and associates//dtd html 2.0//",
106 "-//o'reilly and associates//dtd html extended 1.0//",
107 "-//o'reilly and associates//dtd html extended relaxed 1.0//",
108 "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html "
110 "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
111 "-//spyglass//dtd html 2.0 extended//",
112 "-//sq//dtd html 2.0 hotmetal + extensions//",
113 "-//sun microsystems corp.//dtd hotjava html//",
114 "-//sun microsystems corp.//dtd hotjava strict html//",
115 "-//w3c//dtd html 3 1995-03-24//",
116 "-//w3c//dtd html 3.2 draft//",
117 "-//w3c//dtd html 3.2 final//",
118 "-//w3c//dtd html 3.2//",
119 "-//w3c//dtd html 3.2s draft//",
120 "-//w3c//dtd html 4.0 frameset//",
121 "-//w3c//dtd html 4.0 transitional//",
122 "-//w3c//dtd html experimental 19960712//",
123 "-//w3c//dtd html experimental 970421//",
124 "-//w3c//dtd w3 html//",
125 "-//w3o//dtd w3 html 3.0//",
126 "-//webtechs//dtd mozilla html 2.0//",
127 "-//webtechs//dtd mozilla html//"};
128 staticJArray
<const char*, int32_t> nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
= {
129 QUIRKY_PUBLIC_IDS_DATA
, MOZ_ARRAY_LENGTH(QUIRKY_PUBLIC_IDS_DATA
)};
130 void nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer
* self
) {
132 stackNodes
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
133 stack
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
134 templateModeStack
= jArray
<int32_t, int32_t>::newJArray(64);
135 listOfActiveFormattingElements
=
136 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
137 needToDropLF
= false;
138 originalMode
= INITIAL
;
139 templateModePtr
= -1;
144 formPointer
= nullptr;
145 headPointer
= nullptr;
148 charBuffer
= nullptr;
151 nsIContentHandle
* elt
;
155 elt
= createHtmlElementSetAsRoot(tokenizer
->emptyAttributes());
157 if (contextNamespace
== kNameSpaceID_SVG
) {
158 nsHtml5ElementName
* elementName
= nsHtml5ElementName::ELT_SVG
;
159 if (nsGkAtoms::title
== contextName
|| nsGkAtoms::desc
== contextName
||
160 nsGkAtoms::foreignObject
== contextName
) {
161 elementName
= nsHtml5ElementName::ELT_FOREIGNOBJECT
;
163 nsHtml5StackNode
* node
=
164 createStackNode(elementName
, elementName
->getCamelCaseName(), elt
);
166 stack
[currentPtr
] = node
;
167 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
169 } else if (contextNamespace
== kNameSpaceID_MathML
) {
170 nsHtml5ElementName
* elementName
= nsHtml5ElementName::ELT_MATH
;
171 if (nsGkAtoms::mi_
== contextName
|| nsGkAtoms::mo_
== contextName
||
172 nsGkAtoms::mn_
== contextName
|| nsGkAtoms::ms_
== contextName
||
173 nsGkAtoms::mtext_
== contextName
) {
174 elementName
= nsHtml5ElementName::ELT_MTEXT
;
175 } else if (nsGkAtoms::annotation_xml_
== contextName
) {
176 elementName
= nsHtml5ElementName::ELT_ANNOTATION_XML
;
178 nsHtml5StackNode
* node
=
179 createStackNode(elementName
, elt
, elementName
->getName(), false);
181 stack
[currentPtr
] = node
;
182 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
185 nsHtml5StackNode
* node
=
186 createStackNode(nsHtml5ElementName::ELT_HTML
, elt
);
188 stack
[currentPtr
] = node
;
189 if (nsGkAtoms::_template
== contextName
) {
190 pushTemplateMode(IN_TEMPLATE
);
192 resetTheInsertionMode();
193 formPointer
= getFormPointerForContext(contextNode
);
194 if (nsGkAtoms::title
== contextName
||
195 nsGkAtoms::textarea
== contextName
) {
196 tokenizer
->setState(nsHtml5Tokenizer::RCDATA
);
197 } else if (nsGkAtoms::style
== contextName
||
198 nsGkAtoms::xmp
== contextName
||
199 nsGkAtoms::iframe
== contextName
||
200 nsGkAtoms::noembed
== contextName
||
201 nsGkAtoms::noframes
== contextName
||
202 (scriptingEnabled
&& nsGkAtoms::noscript
== contextName
)) {
203 tokenizer
->setState(nsHtml5Tokenizer::RAWTEXT
);
204 } else if (nsGkAtoms::plaintext
== contextName
) {
205 tokenizer
->setState(nsHtml5Tokenizer::PLAINTEXT
);
206 } else if (nsGkAtoms::script
== contextName
) {
207 tokenizer
->setState(nsHtml5Tokenizer::SCRIPT_DATA
);
209 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
214 if (tokenizer
->isViewingXmlSource()) {
215 nsIContentHandle
* elt
= createElement(
216 kNameSpaceID_SVG
, nsGkAtoms::svg
, tokenizer
->emptyAttributes(),
217 nullptr, svgCreator(NS_NewSVGSVGElement
));
218 nsHtml5StackNode
* node
=
219 createStackNode(nsHtml5ElementName::ELT_SVG
, nsGkAtoms::svg
, elt
);
221 stack
[currentPtr
] = node
;
226 void nsHtml5TreeBuilder::doctype(nsAtom
* name
, nsHtml5String publicIdentifier
,
227 nsHtml5String systemIdentifier
,
229 needToDropLF
= false;
230 if (!isInForeign() && mode
== INITIAL
) {
231 nsHtml5String emptyString
= nsHtml5Portability::newEmptyString();
232 appendDoctypeToDocument(!name
? nsGkAtoms::_empty
: name
,
233 !publicIdentifier
? emptyString
: publicIdentifier
,
234 !systemIdentifier
? emptyString
: systemIdentifier
);
235 emptyString
.Release();
236 if (isQuirky(name
, publicIdentifier
, systemIdentifier
, forceQuirks
)) {
238 documentModeInternal(QUIRKS_MODE
, publicIdentifier
, systemIdentifier
);
239 } else if (isAlmostStandards(publicIdentifier
, systemIdentifier
)) {
240 errAlmostStandardsDoctype();
241 documentModeInternal(ALMOST_STANDARDS_MODE
, publicIdentifier
,
244 documentModeInternal(STANDARDS_MODE
, publicIdentifier
, systemIdentifier
);
253 void nsHtml5TreeBuilder::comment(char16_t
* buf
, int32_t start
, int32_t length
) {
254 needToDropLF
= false;
255 if (!isInForeign()) {
259 case AFTER_AFTER_BODY
:
260 case AFTER_AFTER_FRAMESET
: {
261 appendCommentToDocument(buf
, start
, length
);
266 appendComment(stack
[0]->node
, buf
, start
, length
);
275 appendComment(stack
[currentPtr
]->node
, buf
, start
, length
);
279 void nsHtml5TreeBuilder::characters(const char16_t
* buf
, int32_t start
,
281 if (tokenizer
->isViewingXmlSource()) {
285 needToDropLF
= false;
286 if (buf
[start
] == '\n') {
298 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
299 reconstructTheActiveFormattingElements();
304 accumulateCharacters(buf
, start
, length
);
310 accumulateCharactersForced(buf
, start
, length
);
314 int32_t end
= start
+ length
;
315 for (int32_t i
= start
; i
< end
; i
++) {
330 case IN_HEAD_NOSCRIPT
:
332 case IN_COLUMN_GROUP
:
334 case AFTER_FRAMESET
: {
343 accumulateCharacters(buf
, start
, i
- start
);
346 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
348 reconstructTheActiveFormattingElements();
350 NS_HTML5_BREAK(charactersloop
);
353 case IN_SELECT_IN_TABLE
: {
354 NS_HTML5_BREAK(charactersloop
);
359 accumulateCharactersForced(buf
, i
, 1);
364 case AFTER_AFTER_BODY
:
365 case AFTER_AFTER_FRAMESET
: {
367 accumulateCharacters(buf
, start
, i
- start
);
371 reconstructTheActiveFormattingElements();
375 MOZ_FALLTHROUGH_ASSERT();
380 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
386 appendHtmlElementToDocumentAndPush();
393 accumulateCharacters(buf
, start
, i
- start
);
397 appendToCurrentNodeAndPushHeadElement(
398 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
405 accumulateCharacters(buf
, start
, i
- start
);
414 case IN_HEAD_NOSCRIPT
: {
416 accumulateCharacters(buf
, start
, i
- start
);
419 errNonSpaceInNoscriptInHead();
428 accumulateCharacters(buf
, start
, i
- start
);
432 appendToCurrentNodeAndPushBodyElement();
448 accumulateCharacters(buf
, start
, i
- start
);
451 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
453 reconstructTheActiveFormattingElements();
455 NS_HTML5_BREAK(charactersloop
);
460 accumulateCharactersForced(buf
, i
, 1);
464 case IN_COLUMN_GROUP
: {
466 accumulateCharacters(buf
, start
, i
- start
);
469 if (!currentPtr
|| stack
[currentPtr
]->getGroup() ==
470 nsHtml5TreeBuilder::TEMPLATE
) {
471 errNonSpaceInColgroupInFragment();
482 case IN_SELECT_IN_TABLE
: {
483 NS_HTML5_BREAK(charactersloop
);
486 errNonSpaceAfterBody();
488 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
494 accumulateCharacters(buf
, start
, i
- start
);
496 errNonSpaceInFrameset();
500 case AFTER_FRAMESET
: {
502 accumulateCharacters(buf
, start
, i
- start
);
504 errNonSpaceAfterFrameset();
508 case AFTER_AFTER_BODY
: {
509 errNonSpaceInTrailer();
510 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
514 case AFTER_AFTER_FRAMESET
: {
516 accumulateCharacters(buf
, start
, i
- start
);
518 errNonSpaceInTrailer();
528 accumulateCharacters(buf
, start
, end
- start
);
534 void nsHtml5TreeBuilder::zeroOriginatingReplacementCharacter() {
536 accumulateCharacters(REPLACEMENT_CHARACTER
, 0, 1);
539 if (currentPtr
>= 0) {
540 if (isSpecialParentInForeign(stack
[currentPtr
])) {
543 accumulateCharacters(REPLACEMENT_CHARACTER
, 0, 1);
547 void nsHtml5TreeBuilder::eof() {
552 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
557 appendHtmlElementToDocumentAndPush();
562 appendToCurrentNodeAndPushHeadElement(
563 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
568 while (currentPtr
> 0) {
574 case IN_HEAD_NOSCRIPT
: {
575 while (currentPtr
> 1) {
582 appendToCurrentNodeAndPushBodyElement();
589 case IN_SELECT_IN_TABLE
:
591 case IN_COLUMN_GROUP
:
596 if (isTemplateModeStackEmpty()) {
597 NS_HTML5_BREAK(eofloop
);
602 int32_t eltPos
= findLast(nsGkAtoms::_template
);
603 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
604 MOZ_ASSERT(fragment
);
605 NS_HTML5_BREAK(eofloop
);
607 if (MOZ_UNLIKELY(mViewSource
)) {
608 errUnclosedElements(eltPos
, nsGkAtoms::_template
);
610 while (currentPtr
>= eltPos
) {
613 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
615 resetTheInsertionMode();
619 if (originalMode
== AFTER_HEAD
) {
627 NS_HTML5_BREAK(eofloop
);
631 case AFTER_AFTER_BODY
:
632 case AFTER_AFTER_FRAMESET
:
634 NS_HTML5_BREAK(eofloop
);
639 while (currentPtr
> 0) {
647 void nsHtml5TreeBuilder::endTokenization() {
648 formPointer
= nullptr;
649 headPointer
= nullptr;
650 contextName
= nullptr;
651 contextNode
= nullptr;
652 templateModeStack
= nullptr;
654 while (currentPtr
> -1) {
655 stack
[currentPtr
]->release(this);
660 if (listOfActiveFormattingElements
) {
661 while (listPtr
> -1) {
662 if (listOfActiveFormattingElements
[listPtr
]) {
663 listOfActiveFormattingElements
[listPtr
]->release(this);
667 listOfActiveFormattingElements
= nullptr;
670 for (int32_t i
= 0; i
< numStackNodes
; i
++) {
671 MOZ_ASSERT(stackNodes
[i
]->isUnused());
672 delete stackNodes
[i
];
676 stackNodes
= nullptr;
678 charBuffer
= nullptr;
682 void nsHtml5TreeBuilder::startTag(nsHtml5ElementName
* elementName
,
683 nsHtml5HtmlAttributes
* attributes
,
687 needToDropLF
= false;
690 int32_t group
= elementName
->getGroup();
691 nsAtom
* name
= elementName
->getName();
693 nsHtml5StackNode
* currentNode
= stack
[currentPtr
];
694 int32_t currNs
= currentNode
->ns
;
695 if (!(currentNode
->isHtmlIntegrationPoint() ||
696 (currNs
== kNameSpaceID_MathML
&&
697 ((currentNode
->getGroup() == MI_MO_MN_MS_MTEXT
&&
698 group
!= MGLYPH_OR_MALIGNMARK
) ||
699 (currentNode
->getGroup() == ANNOTATION_XML
&& group
== SVG
))))) {
701 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
702 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
705 case RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR
:
710 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
:
720 if (!(group
== FONT
&&
721 !(attributes
->contains(nsHtml5AttributeName::ATTR_COLOR
) ||
722 attributes
->contains(nsHtml5AttributeName::ATTR_FACE
) ||
723 attributes
->contains(nsHtml5AttributeName::ATTR_SIZE
)))) {
724 errHtmlStartTagInForeignContext(name
);
726 while (!isSpecialParentInForeign(stack
[currentPtr
])) {
729 NS_HTML5_CONTINUE(starttagloop
);
735 if (kNameSpaceID_SVG
== currNs
) {
736 attributes
->adjustForSvg();
738 appendVoidElementToCurrentMayFosterSVG(elementName
, attributes
);
741 appendToCurrentNodeAndPushElementMayFosterSVG(elementName
,
744 attributes
= nullptr;
745 NS_HTML5_BREAK(starttagloop
);
747 attributes
->adjustForMath();
749 appendVoidElementToCurrentMayFosterMathML(elementName
,
753 appendToCurrentNodeAndPushElementMayFosterMathML(elementName
,
756 attributes
= nullptr;
757 NS_HTML5_BREAK(starttagloop
);
768 pushTemplateMode(IN_COLUMN_GROUP
);
769 mode
= IN_COLUMN_GROUP
;
774 case TBODY_OR_THEAD_OR_TFOOT
: {
776 pushTemplateMode(IN_TABLE
);
782 pushTemplateMode(IN_TABLE_BODY
);
783 mode
= IN_TABLE_BODY
;
788 pushTemplateMode(IN_ROW
);
793 checkMetaCharset(attributes
);
794 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
796 attributes
= nullptr;
797 NS_HTML5_BREAK(starttagloop
);
800 startTagTitleInHead(elementName
, attributes
);
801 attributes
= nullptr;
802 NS_HTML5_BREAK(starttagloop
);
805 case LINK_OR_BASEFONT_OR_BGSOUND
: {
806 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
808 attributes
= nullptr;
809 NS_HTML5_BREAK(starttagloop
);
812 startTagScriptInHead(elementName
, attributes
);
813 attributes
= nullptr;
814 NS_HTML5_BREAK(starttagloop
);
818 startTagGenericRawText(elementName
, attributes
);
819 attributes
= nullptr;
820 NS_HTML5_BREAK(starttagloop
);
823 startTagTemplateInHead(elementName
, attributes
);
824 attributes
= nullptr;
825 NS_HTML5_BREAK(starttagloop
);
829 pushTemplateMode(IN_BODY
);
838 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TR
));
839 appendToCurrentNodeAndPushElement(elementName
, attributes
);
842 attributes
= nullptr;
843 NS_HTML5_BREAK(starttagloop
);
848 case TBODY_OR_THEAD_OR_TFOOT
:
850 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
852 MOZ_ASSERT(fragment
|| isTemplateContents());
853 errNoTableRowToClose();
854 NS_HTML5_BREAK(starttagloop
);
856 clearStackBackTo(eltPos
);
858 mode
= IN_TABLE_BODY
;
861 default:; // fall through
865 case IN_TABLE_BODY
: {
869 findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
870 appendToCurrentNodeAndPushElement(elementName
, attributes
);
872 attributes
= nullptr;
873 NS_HTML5_BREAK(starttagloop
);
876 errStartTagInTableBody(name
);
878 findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
879 appendToCurrentNodeAndPushElement(
880 nsHtml5ElementName::ELT_TR
,
881 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
888 case TBODY_OR_THEAD_OR_TFOOT
: {
889 eltPos
= findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
890 if (!eltPos
|| stack
[eltPos
]->getGroup() == TEMPLATE
) {
891 MOZ_ASSERT(fragment
|| isTemplateContents());
892 errStrayStartTag(name
);
893 NS_HTML5_BREAK(starttagloop
);
895 clearStackBackTo(eltPos
);
901 default:; // fall through
909 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
911 appendToCurrentNodeAndPushElement(elementName
, attributes
);
913 attributes
= nullptr;
914 NS_HTML5_BREAK(starttagloop
);
917 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
918 appendToCurrentNodeAndPushElement(elementName
, attributes
);
919 mode
= IN_COLUMN_GROUP
;
920 attributes
= nullptr;
921 NS_HTML5_BREAK(starttagloop
);
924 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
925 appendToCurrentNodeAndPushElement(
926 nsHtml5ElementName::ELT_COLGROUP
,
927 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
928 mode
= IN_COLUMN_GROUP
;
929 NS_HTML5_CONTINUE(starttagloop
);
931 case TBODY_OR_THEAD_OR_TFOOT
: {
932 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
933 appendToCurrentNodeAndPushElement(elementName
, attributes
);
934 mode
= IN_TABLE_BODY
;
935 attributes
= nullptr;
936 NS_HTML5_BREAK(starttagloop
);
940 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
941 appendToCurrentNodeAndPushElement(
942 nsHtml5ElementName::ELT_TBODY
,
943 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
944 mode
= IN_TABLE_BODY
;
945 NS_HTML5_CONTINUE(starttagloop
);
948 NS_HTML5_BREAK(intableloop
);
951 errTableSeenWhileTableOpen();
952 eltPos
= findLastInTableScope(name
);
953 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
954 MOZ_ASSERT(fragment
|| isTemplateContents());
955 NS_HTML5_BREAK(starttagloop
);
957 generateImpliedEndTags();
958 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(nsGkAtoms::table
)) {
959 errNoCheckUnclosedElementsOnStack();
961 while (currentPtr
>= eltPos
) {
964 resetTheInsertionMode();
965 NS_HTML5_CONTINUE(starttagloop
);
968 appendToCurrentNodeAndPushElement(elementName
, attributes
);
971 tokenizer
->setStateAndEndTagExpectation(
972 nsHtml5Tokenizer::SCRIPT_DATA
, elementName
);
973 attributes
= nullptr;
974 NS_HTML5_BREAK(starttagloop
);
977 appendToCurrentNodeAndPushElement(elementName
, attributes
);
980 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
982 attributes
= nullptr;
983 NS_HTML5_BREAK(starttagloop
);
986 errStartTagInTable(name
);
987 if (!nsHtml5Portability::
988 lowerCaseLiteralEqualsIgnoreAsciiCaseString(
989 "hidden", attributes
->getValue(
990 nsHtml5AttributeName::ATTR_TYPE
))) {
991 NS_HTML5_BREAK(intableloop
);
993 appendVoidInputToCurrent(attributes
, formPointer
);
995 attributes
= nullptr;
996 NS_HTML5_BREAK(starttagloop
);
999 if (!!formPointer
|| isTemplateContents()) {
1000 errFormWhenFormOpen();
1001 NS_HTML5_BREAK(starttagloop
);
1003 errStartTagInTable(name
);
1004 appendVoidFormToCurrent(attributes
);
1005 attributes
= nullptr;
1006 NS_HTML5_BREAK(starttagloop
);
1010 errStartTagInTable(name
);
1011 NS_HTML5_BREAK(intableloop
);
1023 case TBODY_OR_THEAD_OR_TFOOT
:
1026 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
1027 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1028 MOZ_ASSERT(fragment
|| isTemplateContents());
1029 errStrayStartTag(name
);
1030 NS_HTML5_BREAK(starttagloop
);
1032 generateImpliedEndTags();
1033 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
1034 errNoCheckUnclosedElementsOnStack();
1036 while (currentPtr
>= eltPos
) {
1039 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
1043 default:; // fall through
1052 case TBODY_OR_THEAD_OR_TFOOT
:
1055 eltPos
= findLastInTableScopeTdTh();
1056 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1058 NS_HTML5_BREAK(starttagloop
);
1060 closeTheCell(eltPos
);
1064 default:; // fall through
1071 if (mode
== FRAMESET_OK
) {
1072 if (!currentPtr
|| stack
[1]->getGroup() != BODY
) {
1073 MOZ_ASSERT(fragment
|| isTemplateContents());
1074 errStrayStartTag(name
);
1075 NS_HTML5_BREAK(starttagloop
);
1078 detachFromParent(stack
[1]->node
);
1079 while (currentPtr
> 0) {
1082 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1084 attributes
= nullptr;
1085 NS_HTML5_BREAK(starttagloop
);
1088 errStrayStartTag(name
);
1089 NS_HTML5_BREAK(starttagloop
);
1092 case PRE_OR_LISTING
:
1096 case MARQUEE_OR_APPLET
:
1110 if (mode
== FRAMESET_OK
&&
1112 nsHtml5Portability::
1113 lowerCaseLiteralEqualsIgnoreAsciiCaseString(
1114 "hidden", attributes
->getValue(
1115 nsHtml5AttributeName::ATTR_TYPE
)))) {
1121 default:; // fall through
1129 errStrayStartTag(name
);
1130 if (!fragment
&& !isTemplateContents()) {
1131 addAttributesToHtml(attributes
);
1132 attributes
= nullptr;
1134 NS_HTML5_BREAK(starttagloop
);
1137 case LINK_OR_BASEFONT_OR_BGSOUND
:
1143 NS_HTML5_BREAK(inbodyloop
);
1146 if (!currentPtr
|| stack
[1]->getGroup() != BODY
||
1147 isTemplateContents()) {
1148 MOZ_ASSERT(fragment
|| isTemplateContents());
1149 errStrayStartTag(name
);
1150 NS_HTML5_BREAK(starttagloop
);
1152 errFooSeenWhenFooOpen(name
);
1154 if (mode
== FRAMESET_OK
) {
1157 if (addAttributesToBody(attributes
)) {
1158 attributes
= nullptr;
1160 NS_HTML5_BREAK(starttagloop
);
1163 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
1164 case UL_OR_OL_OR_DL
:
1165 case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY
: {
1167 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1169 attributes
= nullptr;
1170 NS_HTML5_BREAK(starttagloop
);
1172 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
: {
1174 if (stack
[currentPtr
]->getGroup() ==
1175 H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
) {
1176 errHeadingWhenHeadingOpen();
1179 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1181 attributes
= nullptr;
1182 NS_HTML5_BREAK(starttagloop
);
1186 appendToCurrentNodeAndPushElementMayFoster(
1187 elementName
, attributes
, formPointer
);
1188 attributes
= nullptr;
1189 NS_HTML5_BREAK(starttagloop
);
1191 case PRE_OR_LISTING
: {
1193 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1195 needToDropLF
= true;
1196 attributes
= nullptr;
1197 NS_HTML5_BREAK(starttagloop
);
1200 if (!!formPointer
&& !isTemplateContents()) {
1201 errFormWhenFormOpen();
1202 NS_HTML5_BREAK(starttagloop
);
1205 appendToCurrentNodeAndPushFormElementMayFoster(attributes
);
1206 attributes
= nullptr;
1207 NS_HTML5_BREAK(starttagloop
);
1212 eltPos
= currentPtr
;
1214 nsHtml5StackNode
* node
= stack
[eltPos
];
1215 if (node
->getGroup() == group
) {
1216 generateImpliedEndTagsExceptFor(node
->name
);
1217 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
1218 errUnclosedElementsImplied(eltPos
, name
);
1220 while (currentPtr
>= eltPos
) {
1224 } else if (!eltPos
|| (node
->isSpecial() &&
1225 (node
->ns
!= kNameSpaceID_XHTML
||
1226 (node
->name
!= nsGkAtoms::p
&&
1227 node
->name
!= nsGkAtoms::address
&&
1228 node
->name
!= nsGkAtoms::div
)))) {
1234 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1236 attributes
= nullptr;
1237 NS_HTML5_BREAK(starttagloop
);
1241 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1243 tokenizer
->setStateAndEndTagExpectation(
1244 nsHtml5Tokenizer::PLAINTEXT
, elementName
);
1245 attributes
= nullptr;
1246 NS_HTML5_BREAK(starttagloop
);
1249 int32_t activeAPos
=
1250 findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(
1252 if (activeAPos
!= -1) {
1253 errFooSeenWhenFooOpen(name
);
1254 nsHtml5StackNode
* activeA
=
1255 listOfActiveFormattingElements
[activeAPos
];
1257 adoptionAgencyEndTag(nsGkAtoms::a
);
1258 removeFromStack(activeA
);
1259 activeAPos
= findInListOfActiveFormattingElements(activeA
);
1260 if (activeAPos
!= -1) {
1261 removeFromListOfActiveFormattingElements(activeAPos
);
1263 activeA
->release(this);
1265 reconstructTheActiveFormattingElements();
1266 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1268 attributes
= nullptr;
1269 NS_HTML5_BREAK(starttagloop
);
1271 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
1273 reconstructTheActiveFormattingElements();
1274 maybeForgetEarlierDuplicateFormattingElement(
1275 elementName
->getName(), attributes
);
1276 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1278 attributes
= nullptr;
1279 NS_HTML5_BREAK(starttagloop
);
1282 reconstructTheActiveFormattingElements();
1283 if (nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
!=
1284 findLastInScope(nsGkAtoms::nobr
)) {
1285 errFooSeenWhenFooOpen(name
);
1286 adoptionAgencyEndTag(nsGkAtoms::nobr
);
1287 reconstructTheActiveFormattingElements();
1289 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1291 attributes
= nullptr;
1292 NS_HTML5_BREAK(starttagloop
);
1295 eltPos
= findLastInScope(name
);
1296 if (eltPos
!= nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1297 errFooSeenWhenFooOpen(name
);
1298 generateImpliedEndTags();
1299 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
1300 errUnclosedElementsImplied(eltPos
, name
);
1302 while (currentPtr
>= eltPos
) {
1305 NS_HTML5_CONTINUE(starttagloop
);
1307 reconstructTheActiveFormattingElements();
1308 appendToCurrentNodeAndPushElementMayFoster(
1309 elementName
, attributes
, formPointer
);
1310 attributes
= nullptr;
1311 NS_HTML5_BREAK(starttagloop
);
1315 reconstructTheActiveFormattingElements();
1316 appendToCurrentNodeAndPushElementMayFoster(
1317 elementName
, attributes
, formPointer
);
1319 attributes
= nullptr;
1320 NS_HTML5_BREAK(starttagloop
);
1322 case MARQUEE_OR_APPLET
: {
1323 reconstructTheActiveFormattingElements();
1324 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1327 attributes
= nullptr;
1328 NS_HTML5_BREAK(starttagloop
);
1334 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1337 attributes
= nullptr;
1338 NS_HTML5_BREAK(starttagloop
);
1344 reconstructTheActiveFormattingElements();
1347 #ifdef ENABLE_VOID_MENUITEM
1350 case PARAM_OR_SOURCE_OR_TRACK
: {
1351 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1352 selfClosing
= false;
1353 attributes
= nullptr;
1354 NS_HTML5_BREAK(starttagloop
);
1358 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1359 selfClosing
= false;
1360 attributes
= nullptr;
1361 NS_HTML5_BREAK(starttagloop
);
1365 elementName
= nsHtml5ElementName::ELT_IMG
;
1366 NS_HTML5_CONTINUE(starttagloop
);
1370 reconstructTheActiveFormattingElements();
1371 appendVoidElementToCurrentMayFoster(elementName
, attributes
,
1373 selfClosing
= false;
1374 attributes
= nullptr;
1375 NS_HTML5_BREAK(starttagloop
);
1378 appendToCurrentNodeAndPushElementMayFoster(
1379 elementName
, attributes
, formPointer
);
1380 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
1382 originalMode
= mode
;
1384 needToDropLF
= true;
1385 attributes
= nullptr;
1386 NS_HTML5_BREAK(starttagloop
);
1390 reconstructTheActiveFormattingElements();
1391 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1393 originalMode
= mode
;
1395 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1397 attributes
= nullptr;
1398 NS_HTML5_BREAK(starttagloop
);
1401 if (!scriptingEnabled
) {
1402 reconstructTheActiveFormattingElements();
1403 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1405 attributes
= nullptr;
1406 NS_HTML5_BREAK(starttagloop
);
1413 startTagGenericRawText(elementName
, attributes
);
1414 attributes
= nullptr;
1415 NS_HTML5_BREAK(starttagloop
);
1418 reconstructTheActiveFormattingElements();
1419 appendToCurrentNodeAndPushElementMayFoster(
1420 elementName
, attributes
, formPointer
);
1424 case IN_COLUMN_GROUP
:
1428 mode
= IN_SELECT_IN_TABLE
;
1436 attributes
= nullptr;
1437 NS_HTML5_BREAK(starttagloop
);
1441 if (isCurrent(nsGkAtoms::option
)) {
1444 reconstructTheActiveFormattingElements();
1445 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1447 attributes
= nullptr;
1448 NS_HTML5_BREAK(starttagloop
);
1451 eltPos
= findLastInScope(nsGkAtoms::ruby
);
1452 if (eltPos
!= NOT_FOUND_ON_STACK
) {
1453 generateImpliedEndTags();
1455 if (eltPos
!= currentPtr
) {
1456 if (eltPos
== NOT_FOUND_ON_STACK
) {
1457 errStartTagSeenWithoutRuby(name
);
1459 errUnclosedChildrenInRuby();
1462 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1464 attributes
= nullptr;
1465 NS_HTML5_BREAK(starttagloop
);
1468 eltPos
= findLastInScope(nsGkAtoms::ruby
);
1469 if (eltPos
!= NOT_FOUND_ON_STACK
) {
1470 generateImpliedEndTagsExceptFor(nsGkAtoms::rtc
);
1472 if (eltPos
!= currentPtr
) {
1473 if (!isCurrent(nsGkAtoms::rtc
)) {
1474 if (eltPos
== NOT_FOUND_ON_STACK
) {
1475 errStartTagSeenWithoutRuby(name
);
1477 errUnclosedChildrenInRuby();
1481 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1483 attributes
= nullptr;
1484 NS_HTML5_BREAK(starttagloop
);
1487 reconstructTheActiveFormattingElements();
1488 attributes
->adjustForMath();
1490 appendVoidElementToCurrentMayFosterMathML(elementName
,
1492 selfClosing
= false;
1494 appendToCurrentNodeAndPushElementMayFosterMathML(elementName
,
1497 attributes
= nullptr;
1498 NS_HTML5_BREAK(starttagloop
);
1501 reconstructTheActiveFormattingElements();
1502 attributes
->adjustForSvg();
1504 appendVoidElementToCurrentMayFosterSVG(elementName
, attributes
);
1505 selfClosing
= false;
1507 appendToCurrentNodeAndPushElementMayFosterSVG(elementName
,
1510 attributes
= nullptr;
1511 NS_HTML5_BREAK(starttagloop
);
1516 case TBODY_OR_THEAD_OR_TFOOT
:
1522 errStrayStartTag(name
);
1523 NS_HTML5_BREAK(starttagloop
);
1526 reconstructTheActiveFormattingElements();
1527 appendToCurrentNodeAndPushElementMayFoster(
1528 elementName
, attributes
, formPointer
);
1529 attributes
= nullptr;
1530 NS_HTML5_BREAK(starttagloop
);
1533 reconstructTheActiveFormattingElements();
1534 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1536 attributes
= nullptr;
1537 NS_HTML5_BREAK(starttagloop
);
1548 errStrayStartTag(name
);
1549 if (!fragment
&& !isTemplateContents()) {
1550 addAttributesToHtml(attributes
);
1551 attributes
= nullptr;
1553 NS_HTML5_BREAK(starttagloop
);
1556 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1557 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1558 selfClosing
= false;
1559 attributes
= nullptr;
1560 NS_HTML5_BREAK(starttagloop
);
1563 NS_HTML5_BREAK(inheadloop
);
1566 startTagTitleInHead(elementName
, attributes
);
1567 attributes
= nullptr;
1568 NS_HTML5_BREAK(starttagloop
);
1571 if (scriptingEnabled
) {
1572 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1573 originalMode
= mode
;
1575 tokenizer
->setStateAndEndTagExpectation(
1576 nsHtml5Tokenizer::RAWTEXT
, elementName
);
1578 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1580 mode
= IN_HEAD_NOSCRIPT
;
1582 attributes
= nullptr;
1583 NS_HTML5_BREAK(starttagloop
);
1586 startTagScriptInHead(elementName
, attributes
);
1587 attributes
= nullptr;
1588 NS_HTML5_BREAK(starttagloop
);
1592 startTagGenericRawText(elementName
, attributes
);
1593 attributes
= nullptr;
1594 NS_HTML5_BREAK(starttagloop
);
1597 errFooSeenWhenFooOpen(name
);
1598 NS_HTML5_BREAK(starttagloop
);
1601 startTagTemplateInHead(elementName
, attributes
);
1602 attributes
= nullptr;
1603 NS_HTML5_BREAK(starttagloop
);
1608 NS_HTML5_CONTINUE(starttagloop
);
1615 case IN_HEAD_NOSCRIPT
: {
1618 errStrayStartTag(name
);
1619 if (!fragment
&& !isTemplateContents()) {
1620 addAttributesToHtml(attributes
);
1621 attributes
= nullptr;
1623 NS_HTML5_BREAK(starttagloop
);
1625 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1626 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1627 selfClosing
= false;
1628 attributes
= nullptr;
1629 NS_HTML5_BREAK(starttagloop
);
1632 checkMetaCharset(attributes
);
1633 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1634 selfClosing
= false;
1635 attributes
= nullptr;
1636 NS_HTML5_BREAK(starttagloop
);
1640 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1641 originalMode
= mode
;
1643 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1645 attributes
= nullptr;
1646 NS_HTML5_BREAK(starttagloop
);
1649 errFooSeenWhenFooOpen(name
);
1650 NS_HTML5_BREAK(starttagloop
);
1653 errFooSeenWhenFooOpen(name
);
1654 NS_HTML5_BREAK(starttagloop
);
1657 errBadStartTagInNoscriptInHead(name
);
1664 case IN_COLUMN_GROUP
: {
1667 errStrayStartTag(name
);
1668 if (!fragment
&& !isTemplateContents()) {
1669 addAttributesToHtml(attributes
);
1670 attributes
= nullptr;
1672 NS_HTML5_BREAK(starttagloop
);
1675 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1676 selfClosing
= false;
1677 attributes
= nullptr;
1678 NS_HTML5_BREAK(starttagloop
);
1681 startTagTemplateInHead(elementName
, attributes
);
1682 attributes
= nullptr;
1683 NS_HTML5_BREAK(starttagloop
);
1686 if (!currentPtr
|| stack
[currentPtr
]->getGroup() == TEMPLATE
) {
1687 MOZ_ASSERT(fragment
|| isTemplateContents());
1688 errGarbageInColgroup();
1689 NS_HTML5_BREAK(starttagloop
);
1697 case IN_SELECT_IN_TABLE
: {
1700 case TBODY_OR_THEAD_OR_TFOOT
:
1704 errStartTagWithSelectOpen(name
);
1705 eltPos
= findLastInTableScope(nsGkAtoms::select
);
1706 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1707 MOZ_ASSERT(fragment
);
1708 NS_HTML5_BREAK(starttagloop
);
1710 while (currentPtr
>= eltPos
) {
1713 resetTheInsertionMode();
1716 default:; // fall through
1723 errStrayStartTag(name
);
1725 addAttributesToHtml(attributes
);
1726 attributes
= nullptr;
1728 NS_HTML5_BREAK(starttagloop
);
1731 if (isCurrent(nsGkAtoms::option
)) {
1734 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1735 attributes
= nullptr;
1736 NS_HTML5_BREAK(starttagloop
);
1739 if (isCurrent(nsGkAtoms::option
)) {
1742 if (isCurrent(nsGkAtoms::optgroup
)) {
1745 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1746 attributes
= nullptr;
1747 NS_HTML5_BREAK(starttagloop
);
1750 errStartSelectWhereEndSelectExpected();
1751 eltPos
= findLastInTableScope(name
);
1752 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1753 MOZ_ASSERT(fragment
);
1754 errNoSelectInTableScope();
1755 NS_HTML5_BREAK(starttagloop
);
1757 while (currentPtr
>= eltPos
) {
1760 resetTheInsertionMode();
1761 NS_HTML5_BREAK(starttagloop
);
1766 errStartTagWithSelectOpen(name
);
1767 eltPos
= findLastInTableScope(nsGkAtoms::select
);
1768 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1769 MOZ_ASSERT(fragment
);
1770 NS_HTML5_BREAK(starttagloop
);
1772 while (currentPtr
>= eltPos
) {
1775 resetTheInsertionMode();
1779 startTagScriptInHead(elementName
, attributes
);
1780 attributes
= nullptr;
1781 NS_HTML5_BREAK(starttagloop
);
1784 startTagTemplateInHead(elementName
, attributes
);
1785 attributes
= nullptr;
1786 NS_HTML5_BREAK(starttagloop
);
1789 errStrayStartTag(name
);
1790 NS_HTML5_BREAK(starttagloop
);
1797 errStrayStartTag(name
);
1798 if (!fragment
&& !isTemplateContents()) {
1799 addAttributesToHtml(attributes
);
1800 attributes
= nullptr;
1802 NS_HTML5_BREAK(starttagloop
);
1805 errStrayStartTag(name
);
1806 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
1814 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1815 attributes
= nullptr;
1816 NS_HTML5_BREAK(starttagloop
);
1819 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1820 selfClosing
= false;
1821 attributes
= nullptr;
1822 NS_HTML5_BREAK(starttagloop
);
1824 default:; // fall through
1828 case AFTER_FRAMESET
: {
1831 errStrayStartTag(name
);
1832 if (!fragment
&& !isTemplateContents()) {
1833 addAttributesToHtml(attributes
);
1834 attributes
= nullptr;
1836 NS_HTML5_BREAK(starttagloop
);
1839 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1840 originalMode
= mode
;
1842 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1844 attributes
= nullptr;
1845 NS_HTML5_BREAK(starttagloop
);
1848 errStrayStartTag(name
);
1849 NS_HTML5_BREAK(starttagloop
);
1854 errStartTagWithoutDoctype();
1855 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
1862 if (attributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
1863 appendHtmlElementToDocumentAndPush();
1865 appendHtmlElementToDocumentAndPush(attributes
);
1868 attributes
= nullptr;
1869 NS_HTML5_BREAK(starttagloop
);
1872 appendHtmlElementToDocumentAndPush();
1881 errStrayStartTag(name
);
1882 if (!fragment
&& !isTemplateContents()) {
1883 addAttributesToHtml(attributes
);
1884 attributes
= nullptr;
1886 NS_HTML5_BREAK(starttagloop
);
1889 appendToCurrentNodeAndPushHeadElement(attributes
);
1891 attributes
= nullptr;
1892 NS_HTML5_BREAK(starttagloop
);
1895 appendToCurrentNodeAndPushHeadElement(
1896 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
1905 errStrayStartTag(name
);
1906 if (!fragment
&& !isTemplateContents()) {
1907 addAttributesToHtml(attributes
);
1908 attributes
= nullptr;
1910 NS_HTML5_BREAK(starttagloop
);
1913 if (!attributes
->getLength()) {
1914 appendToCurrentNodeAndPushBodyElement();
1916 appendToCurrentNodeAndPushBodyElement(attributes
);
1920 attributes
= nullptr;
1921 NS_HTML5_BREAK(starttagloop
);
1924 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1926 attributes
= nullptr;
1927 NS_HTML5_BREAK(starttagloop
);
1930 errFooBetweenHeadAndBody(name
);
1931 pushHeadPointerOntoStack();
1932 nsHtml5StackNode
* headOnStack
= stack
[currentPtr
];
1933 startTagTemplateInHead(elementName
, attributes
);
1934 removeFromStack(headOnStack
);
1935 attributes
= nullptr;
1936 NS_HTML5_BREAK(starttagloop
);
1939 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1940 errFooBetweenHeadAndBody(name
);
1941 pushHeadPointerOntoStack();
1942 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1943 selfClosing
= false;
1945 attributes
= nullptr;
1946 NS_HTML5_BREAK(starttagloop
);
1949 errFooBetweenHeadAndBody(name
);
1950 checkMetaCharset(attributes
);
1951 pushHeadPointerOntoStack();
1952 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1953 selfClosing
= false;
1955 attributes
= nullptr;
1956 NS_HTML5_BREAK(starttagloop
);
1959 errFooBetweenHeadAndBody(name
);
1960 pushHeadPointerOntoStack();
1961 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1962 originalMode
= mode
;
1964 tokenizer
->setStateAndEndTagExpectation(
1965 nsHtml5Tokenizer::SCRIPT_DATA
, elementName
);
1966 attributes
= nullptr;
1967 NS_HTML5_BREAK(starttagloop
);
1971 errFooBetweenHeadAndBody(name
);
1972 pushHeadPointerOntoStack();
1973 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1974 originalMode
= mode
;
1976 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1978 attributes
= nullptr;
1979 NS_HTML5_BREAK(starttagloop
);
1982 errFooBetweenHeadAndBody(name
);
1983 pushHeadPointerOntoStack();
1984 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1985 originalMode
= mode
;
1987 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
1989 attributes
= nullptr;
1990 NS_HTML5_BREAK(starttagloop
);
1993 errStrayStartTag(name
);
1994 NS_HTML5_BREAK(starttagloop
);
1997 appendToCurrentNodeAndPushBodyElement();
2003 case AFTER_AFTER_BODY
: {
2006 errStrayStartTag(name
);
2007 if (!fragment
&& !isTemplateContents()) {
2008 addAttributesToHtml(attributes
);
2009 attributes
= nullptr;
2011 NS_HTML5_BREAK(starttagloop
);
2014 errStrayStartTag(name
);
2016 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
2021 case AFTER_AFTER_FRAMESET
: {
2024 errStrayStartTag(name
);
2025 if (!fragment
&& !isTemplateContents()) {
2026 addAttributesToHtml(attributes
);
2027 attributes
= nullptr;
2029 NS_HTML5_BREAK(starttagloop
);
2032 startTagGenericRawText(elementName
, attributes
);
2033 attributes
= nullptr;
2034 NS_HTML5_BREAK(starttagloop
);
2037 errStrayStartTag(name
);
2038 NS_HTML5_BREAK(starttagloop
);
2044 NS_HTML5_BREAK(starttagloop
);
2052 if (!mBuilder
&& attributes
!= nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
2057 void nsHtml5TreeBuilder::startTagTitleInHead(
2058 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2059 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2060 originalMode
= mode
;
2062 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
2066 void nsHtml5TreeBuilder::startTagGenericRawText(
2067 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2068 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2069 originalMode
= mode
;
2071 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
2075 void nsHtml5TreeBuilder::startTagScriptInHead(
2076 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2077 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2078 originalMode
= mode
;
2080 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::SCRIPT_DATA
,
2084 void nsHtml5TreeBuilder::startTagTemplateInHead(
2085 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2086 appendToCurrentNodeAndPushElement(elementName
, attributes
);
2089 originalMode
= mode
;
2091 pushTemplateMode(IN_TEMPLATE
);
2094 bool nsHtml5TreeBuilder::isTemplateContents() {
2095 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
!=
2096 findLast(nsGkAtoms::_template
);
2099 bool nsHtml5TreeBuilder::isTemplateModeStackEmpty() {
2100 return templateModePtr
== -1;
2103 bool nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode
* stackNode
) {
2104 int32_t ns
= stackNode
->ns
;
2105 return (kNameSpaceID_XHTML
== ns
) || (stackNode
->isHtmlIntegrationPoint()) ||
2106 ((kNameSpaceID_MathML
== ns
) &&
2107 (stackNode
->getGroup() == MI_MO_MN_MS_MTEXT
));
2110 nsHtml5String
nsHtml5TreeBuilder::extractCharsetFromContent(
2111 nsHtml5String attributeValue
, nsHtml5TreeBuilder
* tb
) {
2112 int32_t charsetState
= CHARSET_INITIAL
;
2115 autoJArray
<char16_t
, int32_t> buffer
=
2116 nsHtml5Portability::newCharArrayFromString(attributeValue
);
2117 for (int32_t i
= 0; i
< buffer
.length
; i
++) {
2118 char16_t c
= buffer
[i
];
2119 switch (charsetState
) {
2120 case CHARSET_INITIAL
: {
2124 charsetState
= CHARSET_C
;
2136 charsetState
= CHARSET_H
;
2140 charsetState
= CHARSET_INITIAL
;
2149 charsetState
= CHARSET_A
;
2153 charsetState
= CHARSET_INITIAL
;
2162 charsetState
= CHARSET_R
;
2166 charsetState
= CHARSET_INITIAL
;
2175 charsetState
= CHARSET_S
;
2179 charsetState
= CHARSET_INITIAL
;
2188 charsetState
= CHARSET_E
;
2192 charsetState
= CHARSET_INITIAL
;
2201 charsetState
= CHARSET_T
;
2205 charsetState
= CHARSET_INITIAL
;
2220 charsetState
= CHARSET_EQUALS
;
2228 case CHARSET_EQUALS
: {
2239 charsetState
= CHARSET_SINGLE_QUOTED
;
2244 charsetState
= CHARSET_DOUBLE_QUOTED
;
2249 charsetState
= CHARSET_UNQUOTED
;
2254 case CHARSET_SINGLE_QUOTED
: {
2258 NS_HTML5_BREAK(charsetloop
);
2265 case CHARSET_DOUBLE_QUOTED
: {
2269 NS_HTML5_BREAK(charsetloop
);
2276 case CHARSET_UNQUOTED
: {
2285 NS_HTML5_BREAK(charsetloop
);
2297 if (charsetState
== CHARSET_UNQUOTED
) {
2298 end
= buffer
.length
;
2303 return nsHtml5Portability::newStringFromBuffer(buffer
, start
, end
- start
,
2309 void nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes
* attributes
) {
2310 nsHtml5String charset
=
2311 attributes
->getValue(nsHtml5AttributeName::ATTR_CHARSET
);
2313 if (tokenizer
->internalEncodingDeclaration(charset
)) {
2314 requestSuspension();
2319 if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
2321 attributes
->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV
))) {
2324 nsHtml5String content
=
2325 attributes
->getValue(nsHtml5AttributeName::ATTR_CONTENT
);
2327 nsHtml5String extract
=
2328 nsHtml5TreeBuilder::extractCharsetFromContent(content
, this);
2330 if (tokenizer
->internalEncodingDeclaration(extract
)) {
2331 requestSuspension();
2338 void nsHtml5TreeBuilder::endTag(nsHtml5ElementName
* elementName
) {
2340 needToDropLF
= false;
2342 int32_t group
= elementName
->getGroup();
2343 nsAtom
* name
= elementName
->getName();
2345 if (isInForeign()) {
2346 if (stack
[currentPtr
]->name
!= name
) {
2348 errStrayEndTag(name
);
2350 errEndTagDidNotMatchCurrentOpenElement(name
,
2351 stack
[currentPtr
]->popName
);
2354 eltPos
= currentPtr
;
2355 int32_t origPos
= currentPtr
;
2358 MOZ_ASSERT(fragment
,
2359 "We can get this close to the root of the stack in "
2360 "foreign content only in the fragment case.");
2361 NS_HTML5_BREAK(endtagloop
);
2363 if (stack
[eltPos
]->name
== name
) {
2364 while (currentPtr
>= eltPos
) {
2365 popForeign(origPos
, eltPos
);
2367 NS_HTML5_BREAK(endtagloop
);
2369 if (stack
[--eltPos
]->ns
== kNameSpaceID_XHTML
) {
2381 errStrayEndTag(name
);
2382 NS_HTML5_BREAK(endtagloop
);
2390 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2392 MOZ_ASSERT(fragment
|| isTemplateContents());
2393 errNoTableRowToClose();
2394 NS_HTML5_BREAK(endtagloop
);
2396 clearStackBackTo(eltPos
);
2398 mode
= IN_TABLE_BODY
;
2399 NS_HTML5_BREAK(endtagloop
);
2402 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2404 MOZ_ASSERT(fragment
|| isTemplateContents());
2405 errNoTableRowToClose();
2406 NS_HTML5_BREAK(endtagloop
);
2408 clearStackBackTo(eltPos
);
2410 mode
= IN_TABLE_BODY
;
2413 case TBODY_OR_THEAD_OR_TFOOT
: {
2414 if (findLastInTableScope(name
) ==
2415 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2416 errStrayEndTag(name
);
2417 NS_HTML5_BREAK(endtagloop
);
2419 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2421 MOZ_ASSERT(fragment
|| isTemplateContents());
2422 errNoTableRowToClose();
2423 NS_HTML5_BREAK(endtagloop
);
2425 clearStackBackTo(eltPos
);
2427 mode
= IN_TABLE_BODY
;
2436 errStrayEndTag(name
);
2437 NS_HTML5_BREAK(endtagloop
);
2439 default:; // fall through
2443 case IN_TABLE_BODY
: {
2445 case TBODY_OR_THEAD_OR_TFOOT
: {
2446 eltPos
= findLastOrRoot(name
);
2448 errStrayEndTag(name
);
2449 NS_HTML5_BREAK(endtagloop
);
2451 clearStackBackTo(eltPos
);
2454 NS_HTML5_BREAK(endtagloop
);
2457 eltPos
= findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
2458 if (!eltPos
|| stack
[eltPos
]->getGroup() == TEMPLATE
) {
2459 MOZ_ASSERT(fragment
|| isTemplateContents());
2460 errStrayEndTag(name
);
2461 NS_HTML5_BREAK(endtagloop
);
2463 clearStackBackTo(eltPos
);
2475 errStrayEndTag(name
);
2476 NS_HTML5_BREAK(endtagloop
);
2478 default:; // fall through
2485 eltPos
= findLast(nsGkAtoms::table
);
2486 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2487 MOZ_ASSERT(fragment
|| isTemplateContents());
2488 errStrayEndTag(name
);
2489 NS_HTML5_BREAK(endtagloop
);
2491 while (currentPtr
>= eltPos
) {
2494 resetTheInsertionMode();
2495 NS_HTML5_BREAK(endtagloop
);
2502 case TBODY_OR_THEAD_OR_TFOOT
:
2505 errStrayEndTag(name
);
2506 NS_HTML5_BREAK(endtagloop
);
2512 errStrayEndTag(name
);
2520 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
2521 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2522 NS_HTML5_BREAK(endtagloop
);
2524 generateImpliedEndTags();
2525 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
2526 errUnclosedElements(eltPos
, name
);
2528 while (currentPtr
>= eltPos
) {
2531 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2533 NS_HTML5_BREAK(endtagloop
);
2536 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
2537 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2538 MOZ_ASSERT(fragment
|| isTemplateContents());
2539 errStrayEndTag(name
);
2540 NS_HTML5_BREAK(endtagloop
);
2542 generateImpliedEndTags();
2543 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
2544 errUnclosedElements(eltPos
, name
);
2546 while (currentPtr
>= eltPos
) {
2549 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2557 case TBODY_OR_THEAD_OR_TFOOT
:
2560 errStrayEndTag(name
);
2561 NS_HTML5_BREAK(endtagloop
);
2563 default:; // fall through
2570 eltPos
= findLastInTableScope(name
);
2571 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2572 errStrayEndTag(name
);
2573 NS_HTML5_BREAK(endtagloop
);
2575 generateImpliedEndTags();
2576 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2577 errUnclosedElements(eltPos
, name
);
2579 while (currentPtr
>= eltPos
) {
2582 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2584 NS_HTML5_BREAK(endtagloop
);
2587 case TBODY_OR_THEAD_OR_TFOOT
:
2589 if (findLastInTableScope(name
) ==
2590 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2591 MOZ_ASSERT(name
== nsGkAtoms::tbody
|| name
== nsGkAtoms::tfoot
||
2592 name
== nsGkAtoms::thead
|| fragment
||
2593 isTemplateContents());
2594 errStrayEndTag(name
);
2595 NS_HTML5_BREAK(endtagloop
);
2597 closeTheCell(findLastInTableScopeTdTh());
2605 errStrayEndTag(name
);
2606 NS_HTML5_BREAK(endtagloop
);
2608 default:; // fall through
2616 if (!isSecondOnStackBody()) {
2617 MOZ_ASSERT(fragment
|| isTemplateContents());
2618 errStrayEndTag(name
);
2619 NS_HTML5_BREAK(endtagloop
);
2621 MOZ_ASSERT(currentPtr
>= 1);
2622 if (MOZ_UNLIKELY(mViewSource
)) {
2623 for (int32_t i
= 2; i
<= currentPtr
; i
++) {
2624 switch (stack
[i
]->getGroup()) {
2633 case TBODY_OR_THEAD_OR_TFOOT
: {
2637 errEndWithUnclosedElements(name
);
2638 NS_HTML5_BREAK(uncloseloop1
);
2645 NS_HTML5_BREAK(endtagloop
);
2648 if (!isSecondOnStackBody()) {
2649 MOZ_ASSERT(fragment
|| isTemplateContents());
2650 errStrayEndTag(name
);
2651 NS_HTML5_BREAK(endtagloop
);
2653 if (MOZ_UNLIKELY(mViewSource
)) {
2654 for (int32_t i
= 0; i
<= currentPtr
; i
++) {
2655 switch (stack
[i
]->getGroup()) {
2661 case TBODY_OR_THEAD_OR_TFOOT
:
2668 errEndWithUnclosedElements(name
);
2669 NS_HTML5_BREAK(uncloseloop2
);
2678 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
2679 case UL_OR_OL_OR_DL
:
2680 case PRE_OR_LISTING
:
2683 case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY
: {
2684 eltPos
= findLastInScope(name
);
2685 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2686 errStrayEndTag(name
);
2688 generateImpliedEndTags();
2689 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2690 errUnclosedElements(eltPos
, name
);
2692 while (currentPtr
>= eltPos
) {
2696 NS_HTML5_BREAK(endtagloop
);
2699 if (!isTemplateContents()) {
2701 errStrayEndTag(name
);
2702 NS_HTML5_BREAK(endtagloop
);
2704 formPointer
= nullptr;
2705 eltPos
= findLastInScope(name
);
2706 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2707 errStrayEndTag(name
);
2708 NS_HTML5_BREAK(endtagloop
);
2710 generateImpliedEndTags();
2711 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2712 errUnclosedElements(eltPos
, name
);
2714 removeFromStack(eltPos
);
2715 NS_HTML5_BREAK(endtagloop
);
2717 eltPos
= findLastInScope(name
);
2718 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2719 errStrayEndTag(name
);
2720 NS_HTML5_BREAK(endtagloop
);
2722 generateImpliedEndTags();
2723 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2724 errUnclosedElements(eltPos
, name
);
2726 while (currentPtr
>= eltPos
) {
2729 NS_HTML5_BREAK(endtagloop
);
2733 eltPos
= findLastInButtonScope(nsGkAtoms::p
);
2734 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2735 errNoElementToCloseButEndTagSeen(nsGkAtoms::p
);
2736 if (isInForeign()) {
2737 errHtmlStartTagInForeignContext(name
);
2738 while (currentPtr
>= 0 &&
2739 stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
) {
2743 appendVoidElementToCurrentMayFoster(
2744 elementName
, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
2745 NS_HTML5_BREAK(endtagloop
);
2747 generateImpliedEndTagsExceptFor(nsGkAtoms::p
);
2748 MOZ_ASSERT(eltPos
!= nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
);
2749 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2750 errUnclosedElements(eltPos
, name
);
2752 while (currentPtr
>= eltPos
) {
2755 NS_HTML5_BREAK(endtagloop
);
2758 eltPos
= findLastInListScope(name
);
2759 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2760 errNoElementToCloseButEndTagSeen(name
);
2762 generateImpliedEndTagsExceptFor(name
);
2763 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2764 errUnclosedElements(eltPos
, name
);
2766 while (currentPtr
>= eltPos
) {
2770 NS_HTML5_BREAK(endtagloop
);
2773 eltPos
= findLastInScope(name
);
2774 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2775 errNoElementToCloseButEndTagSeen(name
);
2777 generateImpliedEndTagsExceptFor(name
);
2778 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2779 errUnclosedElements(eltPos
, name
);
2781 while (currentPtr
>= eltPos
) {
2785 NS_HTML5_BREAK(endtagloop
);
2787 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
: {
2788 eltPos
= findLastInScopeHn();
2789 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2790 errStrayEndTag(name
);
2792 generateImpliedEndTags();
2793 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2794 errUnclosedElements(eltPos
, name
);
2796 while (currentPtr
>= eltPos
) {
2800 NS_HTML5_BREAK(endtagloop
);
2803 case MARQUEE_OR_APPLET
: {
2804 eltPos
= findLastInScope(name
);
2805 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2806 errStrayEndTag(name
);
2808 generateImpliedEndTags();
2809 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2810 errUnclosedElements(eltPos
, name
);
2812 while (currentPtr
>= eltPos
) {
2815 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2817 NS_HTML5_BREAK(endtagloop
);
2821 if (isInForeign()) {
2822 errHtmlStartTagInForeignContext(name
);
2823 while (currentPtr
>= 0 &&
2824 stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
) {
2828 reconstructTheActiveFormattingElements();
2829 appendVoidElementToCurrentMayFoster(
2830 elementName
, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
2831 NS_HTML5_BREAK(endtagloop
);
2838 #ifdef ENABLE_VOID_MENUITEM
2841 case PARAM_OR_SOURCE_OR_TRACK
:
2853 errStrayEndTag(name
);
2854 NS_HTML5_BREAK(endtagloop
);
2857 if (scriptingEnabled
) {
2858 errStrayEndTag(name
);
2859 NS_HTML5_BREAK(endtagloop
);
2864 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
2867 if (adoptionAgencyEndTag(name
)) {
2868 NS_HTML5_BREAK(endtagloop
);
2873 if (isCurrent(name
)) {
2875 NS_HTML5_BREAK(endtagloop
);
2877 eltPos
= currentPtr
;
2879 nsHtml5StackNode
* node
= stack
[eltPos
];
2880 if (node
->ns
== kNameSpaceID_XHTML
&& node
->name
== name
) {
2881 generateImpliedEndTags();
2882 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2883 errUnclosedElements(eltPos
, name
);
2885 while (currentPtr
>= eltPos
) {
2888 NS_HTML5_BREAK(endtagloop
);
2889 } else if (!eltPos
|| node
->isSpecial()) {
2890 errStrayEndTag(name
);
2891 NS_HTML5_BREAK(endtagloop
);
2904 NS_HTML5_BREAK(endtagloop
);
2914 endTagTemplateInHead();
2915 NS_HTML5_BREAK(endtagloop
);
2918 errStrayEndTag(name
);
2919 NS_HTML5_BREAK(endtagloop
);
2923 case IN_HEAD_NOSCRIPT
: {
2928 NS_HTML5_BREAK(endtagloop
);
2931 errStrayEndTag(name
);
2937 errStrayEndTag(name
);
2938 NS_HTML5_BREAK(endtagloop
);
2942 case IN_COLUMN_GROUP
: {
2946 stack
[currentPtr
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
) {
2947 MOZ_ASSERT(fragment
|| isTemplateContents());
2948 errGarbageInColgroup();
2949 NS_HTML5_BREAK(endtagloop
);
2953 NS_HTML5_BREAK(endtagloop
);
2956 errStrayEndTag(name
);
2957 NS_HTML5_BREAK(endtagloop
);
2960 endTagTemplateInHead();
2961 NS_HTML5_BREAK(endtagloop
);
2965 stack
[currentPtr
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
) {
2966 MOZ_ASSERT(fragment
|| isTemplateContents());
2967 errGarbageInColgroup();
2968 NS_HTML5_BREAK(endtagloop
);
2976 case IN_SELECT_IN_TABLE
: {
2980 case TBODY_OR_THEAD_OR_TFOOT
:
2983 errEndTagSeenWithSelectOpen(name
);
2984 if (findLastInTableScope(name
) !=
2985 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2986 eltPos
= findLastInTableScope(nsGkAtoms::select
);
2987 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2988 MOZ_ASSERT(fragment
);
2989 NS_HTML5_BREAK(endtagloop
);
2991 while (currentPtr
>= eltPos
) {
2994 resetTheInsertionMode();
2997 NS_HTML5_BREAK(endtagloop
);
3000 default:; // fall through
3007 if (isCurrent(nsGkAtoms::option
)) {
3009 NS_HTML5_BREAK(endtagloop
);
3011 errStrayEndTag(name
);
3012 NS_HTML5_BREAK(endtagloop
);
3016 if (isCurrent(nsGkAtoms::option
) &&
3017 nsGkAtoms::optgroup
== stack
[currentPtr
- 1]->name
) {
3020 if (isCurrent(nsGkAtoms::optgroup
)) {
3023 errStrayEndTag(name
);
3025 NS_HTML5_BREAK(endtagloop
);
3028 eltPos
= findLastInTableScope(nsGkAtoms::select
);
3029 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3030 MOZ_ASSERT(fragment
);
3031 errStrayEndTag(name
);
3032 NS_HTML5_BREAK(endtagloop
);
3034 while (currentPtr
>= eltPos
) {
3037 resetTheInsertionMode();
3038 NS_HTML5_BREAK(endtagloop
);
3041 endTagTemplateInHead();
3042 NS_HTML5_BREAK(endtagloop
);
3045 errStrayEndTag(name
);
3046 NS_HTML5_BREAK(endtagloop
);
3054 errStrayEndTag(name
);
3055 NS_HTML5_BREAK(endtagloop
);
3057 mode
= AFTER_AFTER_BODY
;
3058 NS_HTML5_BREAK(endtagloop
);
3062 errEndTagAfterBody();
3063 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3072 MOZ_ASSERT(fragment
);
3073 errStrayEndTag(name
);
3074 NS_HTML5_BREAK(endtagloop
);
3077 if ((!fragment
) && !isCurrent(nsGkAtoms::frameset
)) {
3078 mode
= AFTER_FRAMESET
;
3080 NS_HTML5_BREAK(endtagloop
);
3083 errStrayEndTag(name
);
3084 NS_HTML5_BREAK(endtagloop
);
3088 case AFTER_FRAMESET
: {
3091 mode
= AFTER_AFTER_FRAMESET
;
3092 NS_HTML5_BREAK(endtagloop
);
3095 errStrayEndTag(name
);
3096 NS_HTML5_BREAK(endtagloop
);
3101 errEndTagSeenWithoutDoctype();
3102 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
3112 appendHtmlElementToDocumentAndPush();
3117 errStrayEndTag(name
);
3118 NS_HTML5_BREAK(endtagloop
);
3128 appendToCurrentNodeAndPushHeadElement(
3129 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
3134 errStrayEndTag(name
);
3135 NS_HTML5_BREAK(endtagloop
);
3142 endTagTemplateInHead();
3143 NS_HTML5_BREAK(endtagloop
);
3148 appendToCurrentNodeAndPushBodyElement();
3153 errStrayEndTag(name
);
3154 NS_HTML5_BREAK(endtagloop
);
3158 case AFTER_AFTER_BODY
: {
3159 errStrayEndTag(name
);
3160 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3163 case AFTER_AFTER_FRAMESET
: {
3164 errStrayEndTag(name
);
3165 NS_HTML5_BREAK(endtagloop
);
3169 if (originalMode
== AFTER_HEAD
) {
3172 mode
= originalMode
;
3173 NS_HTML5_BREAK(endtagloop
);
3180 void nsHtml5TreeBuilder::endTagTemplateInHead() {
3181 int32_t eltPos
= findLast(nsGkAtoms::_template
);
3182 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3183 errStrayEndTag(nsGkAtoms::_template
);
3186 generateImpliedEndTags();
3187 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(nsGkAtoms::_template
)) {
3188 errUnclosedElements(eltPos
, nsGkAtoms::_template
);
3190 while (currentPtr
>= eltPos
) {
3193 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
3195 resetTheInsertionMode();
3199 nsHtml5TreeBuilder::findLastInTableScopeOrRootTemplateTbodyTheadTfoot() {
3200 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3201 if (stack
[i
]->getGroup() == nsHtml5TreeBuilder::TBODY_OR_THEAD_OR_TFOOT
||
3202 stack
[i
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
) {
3209 int32_t nsHtml5TreeBuilder::findLast(nsAtom
* name
) {
3210 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3211 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3215 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3218 int32_t nsHtml5TreeBuilder::findLastInTableScope(nsAtom
* name
) {
3219 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3220 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3221 if (stack
[i
]->name
== name
) {
3223 } else if (stack
[i
]->name
== nsGkAtoms::table
||
3224 stack
[i
]->name
== nsGkAtoms::_template
) {
3225 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3229 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3232 int32_t nsHtml5TreeBuilder::findLastInButtonScope(nsAtom
* name
) {
3233 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3234 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3235 if (stack
[i
]->name
== name
) {
3237 } else if (stack
[i
]->name
== nsGkAtoms::button
) {
3238 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3241 if (stack
[i
]->isScoping()) {
3242 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3245 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3248 int32_t nsHtml5TreeBuilder::findLastInScope(nsAtom
* name
) {
3249 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3250 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3252 } else if (stack
[i
]->isScoping()) {
3253 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3256 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3259 int32_t nsHtml5TreeBuilder::findLastInListScope(nsAtom
* name
) {
3260 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3261 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3262 if (stack
[i
]->name
== name
) {
3264 } else if (stack
[i
]->name
== nsGkAtoms::ul
||
3265 stack
[i
]->name
== nsGkAtoms::ol
) {
3266 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3269 if (stack
[i
]->isScoping()) {
3270 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3273 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3276 int32_t nsHtml5TreeBuilder::findLastInScopeHn() {
3277 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3278 if (stack
[i
]->getGroup() ==
3279 nsHtml5TreeBuilder::H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
) {
3281 } else if (stack
[i
]->isScoping()) {
3282 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3285 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3288 void nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsAtom
* name
) {
3290 nsHtml5StackNode
* node
= stack
[currentPtr
];
3291 switch (node
->getGroup()) {
3299 if (node
->ns
== kNameSpaceID_XHTML
&& node
->name
== name
) {
3312 void nsHtml5TreeBuilder::generateImpliedEndTags() {
3314 switch (stack
[currentPtr
]->getGroup()) {
3332 bool nsHtml5TreeBuilder::isSecondOnStackBody() {
3333 return currentPtr
>= 1 && stack
[1]->getGroup() == nsHtml5TreeBuilder::BODY
;
3336 void nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m
,
3337 nsHtml5String publicIdentifier
,
3338 nsHtml5String systemIdentifier
) {
3339 if (isSrcdocDocument
) {
3341 this->documentMode(STANDARDS_MODE
);
3344 quirks
= (m
== QUIRKS_MODE
);
3345 this->documentMode(m
);
3348 bool nsHtml5TreeBuilder::isAlmostStandards(nsHtml5String publicIdentifier
,
3349 nsHtml5String systemIdentifier
) {
3350 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3351 "-//w3c//dtd xhtml 1.0 transitional//", publicIdentifier
)) {
3354 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3355 "-//w3c//dtd xhtml 1.0 frameset//", publicIdentifier
)) {
3358 if (systemIdentifier
) {
3359 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3360 "-//w3c//dtd html 4.01 transitional//", publicIdentifier
)) {
3363 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3364 "-//w3c//dtd html 4.01 frameset//", publicIdentifier
)) {
3371 bool nsHtml5TreeBuilder::isQuirky(nsAtom
* name
, nsHtml5String publicIdentifier
,
3372 nsHtml5String systemIdentifier
,
3377 if (name
!= nsGkAtoms::html
) {
3380 if (publicIdentifier
) {
3381 for (int32_t i
= 0; i
< nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
.length
; i
++) {
3382 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3383 nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
[i
], publicIdentifier
)) {
3387 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3388 "-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier
) ||
3389 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3390 "-/w3c/dtd html 4.0 transitional/en", publicIdentifier
) ||
3391 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3392 "html", publicIdentifier
)) {
3396 if (!systemIdentifier
) {
3397 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3398 "-//w3c//dtd html 4.01 transitional//", publicIdentifier
)) {
3400 } else if (nsHtml5Portability::
3401 lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3402 "-//w3c//dtd html 4.01 frameset//", publicIdentifier
)) {
3405 } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3406 "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd",
3407 systemIdentifier
)) {
3413 void nsHtml5TreeBuilder::closeTheCell(int32_t eltPos
) {
3414 generateImpliedEndTags();
3415 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
3416 errUnclosedElementsCell(eltPos
);
3418 while (currentPtr
>= eltPos
) {
3421 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
3426 int32_t nsHtml5TreeBuilder::findLastInTableScopeTdTh() {
3427 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3428 nsAtom
* name
= stack
[i
]->name
;
3429 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3430 if (nsGkAtoms::td
== name
|| nsGkAtoms::th
== name
) {
3432 } else if (name
== nsGkAtoms::table
|| name
== nsGkAtoms::_template
) {
3433 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3437 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3440 void nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos
) {
3441 int32_t eltGroup
= stack
[eltPos
]->getGroup();
3442 while (currentPtr
> eltPos
) {
3443 if (stack
[currentPtr
]->ns
== kNameSpaceID_XHTML
&&
3444 stack
[currentPtr
]->getGroup() == TEMPLATE
&&
3445 (eltGroup
== TABLE
|| eltGroup
== TBODY_OR_THEAD_OR_TFOOT
||
3446 eltGroup
== TR
|| !eltPos
)) {
3453 void nsHtml5TreeBuilder::resetTheInsertionMode() {
3454 nsHtml5StackNode
* node
;
3457 for (int32_t i
= currentPtr
; i
>= 0; i
--) {
3462 if (!(contextNamespace
== kNameSpaceID_XHTML
&&
3463 (contextName
== nsGkAtoms::td
|| contextName
== nsGkAtoms::th
))) {
3466 ns
= contextNamespace
;
3469 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3473 if (nsGkAtoms::select
== name
) {
3474 int32_t ancestorIndex
= i
;
3475 while (ancestorIndex
> 0) {
3476 nsHtml5StackNode
* ancestor
= stack
[ancestorIndex
--];
3477 if (kNameSpaceID_XHTML
== ancestor
->ns
) {
3478 if (nsGkAtoms::_template
== ancestor
->name
) {
3481 if (nsGkAtoms::table
== ancestor
->name
) {
3482 mode
= IN_SELECT_IN_TABLE
;
3489 } else if (nsGkAtoms::td
== name
|| nsGkAtoms::th
== name
) {
3492 } else if (nsGkAtoms::tr
== name
) {
3495 } else if (nsGkAtoms::tbody
== name
|| nsGkAtoms::thead
== name
||
3496 nsGkAtoms::tfoot
== name
) {
3497 mode
= IN_TABLE_BODY
;
3499 } else if (nsGkAtoms::caption
== name
) {
3502 } else if (nsGkAtoms::colgroup
== name
) {
3503 mode
= IN_COLUMN_GROUP
;
3505 } else if (nsGkAtoms::table
== name
) {
3508 } else if (kNameSpaceID_XHTML
!= ns
) {
3509 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3511 } else if (nsGkAtoms::_template
== name
) {
3512 MOZ_ASSERT(templateModePtr
>= 0);
3513 mode
= templateModeStack
[templateModePtr
];
3515 } else if (nsGkAtoms::head
== name
) {
3516 if (name
== contextName
) {
3517 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3522 } else if (nsGkAtoms::body
== name
) {
3523 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3525 } else if (nsGkAtoms::frameset
== name
) {
3528 } else if (nsGkAtoms::html
== name
) {
3536 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3542 void nsHtml5TreeBuilder::implicitlyCloseP() {
3543 int32_t eltPos
= findLastInButtonScope(nsGkAtoms::p
);
3544 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3547 generateImpliedEndTagsExceptFor(nsGkAtoms::p
);
3548 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
3549 errUnclosedElementsImplied(eltPos
, nsGkAtoms::p
);
3551 while (currentPtr
>= eltPos
) {
3556 bool nsHtml5TreeBuilder::debugOnlyClearLastStackSlot() {
3557 stack
[currentPtr
] = nullptr;
3561 bool nsHtml5TreeBuilder::debugOnlyClearLastListSlot() {
3562 listOfActiveFormattingElements
[listPtr
] = nullptr;
3566 void nsHtml5TreeBuilder::pushTemplateMode(int32_t mode
) {
3568 if (templateModePtr
== templateModeStack
.length
) {
3569 jArray
<int32_t, int32_t> newStack
=
3570 jArray
<int32_t, int32_t>::newJArray(templateModeStack
.length
+ 64);
3571 nsHtml5ArrayCopy::arraycopy(templateModeStack
, newStack
,
3572 templateModeStack
.length
);
3573 templateModeStack
= newStack
;
3575 templateModeStack
[templateModePtr
] = mode
;
3578 void nsHtml5TreeBuilder::push(nsHtml5StackNode
* node
) {
3580 if (currentPtr
== stack
.length
) {
3581 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
3582 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stack
.length
+ 64);
3583 nsHtml5ArrayCopy::arraycopy(stack
, newStack
, stack
.length
);
3586 stack
[currentPtr
] = node
;
3587 elementPushed(node
->ns
, node
->popName
, node
->node
);
3590 void nsHtml5TreeBuilder::silentPush(nsHtml5StackNode
* node
) {
3592 if (currentPtr
== stack
.length
) {
3593 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
3594 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stack
.length
+ 64);
3595 nsHtml5ArrayCopy::arraycopy(stack
, newStack
, stack
.length
);
3598 stack
[currentPtr
] = node
;
3601 void nsHtml5TreeBuilder::append(nsHtml5StackNode
* node
) {
3603 if (listPtr
== listOfActiveFormattingElements
.length
) {
3604 jArray
<nsHtml5StackNode
*, int32_t> newList
=
3605 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(
3606 listOfActiveFormattingElements
.length
+ 64);
3607 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, newList
,
3608 listOfActiveFormattingElements
.length
);
3609 listOfActiveFormattingElements
= newList
;
3611 listOfActiveFormattingElements
[listPtr
] = node
;
3614 void nsHtml5TreeBuilder::
3615 clearTheListOfActiveFormattingElementsUpToTheLastMarker() {
3616 while (listPtr
> -1) {
3617 if (!listOfActiveFormattingElements
[listPtr
]) {
3621 listOfActiveFormattingElements
[listPtr
]->release(this);
3626 void nsHtml5TreeBuilder::removeFromStack(int32_t pos
) {
3627 if (currentPtr
== pos
) {
3630 stack
[pos
]->release(this);
3631 nsHtml5ArrayCopy::arraycopy(stack
, pos
+ 1, pos
, currentPtr
- pos
);
3632 MOZ_ASSERT(debugOnlyClearLastStackSlot());
3637 void nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode
* node
) {
3638 if (stack
[currentPtr
] == node
) {
3641 int32_t pos
= currentPtr
- 1;
3642 while (pos
>= 0 && stack
[pos
] != node
) {
3649 node
->release(this);
3650 nsHtml5ArrayCopy::arraycopy(stack
, pos
+ 1, pos
, currentPtr
- pos
);
3655 void nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos
) {
3656 MOZ_ASSERT(!!listOfActiveFormattingElements
[pos
]);
3657 listOfActiveFormattingElements
[pos
]->release(this);
3658 if (pos
== listPtr
) {
3659 MOZ_ASSERT(debugOnlyClearLastListSlot());
3663 MOZ_ASSERT(pos
< listPtr
);
3664 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, pos
+ 1, pos
,
3666 MOZ_ASSERT(debugOnlyClearLastListSlot());
3670 bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom
* name
) {
3671 if (stack
[currentPtr
]->ns
== kNameSpaceID_XHTML
&&
3672 stack
[currentPtr
]->name
== name
&&
3673 findInListOfActiveFormattingElements(stack
[currentPtr
]) == -1) {
3677 for (int32_t i
= 0; i
< 8; ++i
) {
3678 int32_t formattingEltListPos
= listPtr
;
3679 while (formattingEltListPos
> -1) {
3680 nsHtml5StackNode
* listNode
=
3681 listOfActiveFormattingElements
[formattingEltListPos
];
3683 formattingEltListPos
= -1;
3685 } else if (listNode
->name
== name
) {
3688 formattingEltListPos
--;
3690 if (formattingEltListPos
== -1) {
3693 nsHtml5StackNode
* formattingElt
=
3694 listOfActiveFormattingElements
[formattingEltListPos
];
3695 int32_t formattingEltStackPos
= currentPtr
;
3696 bool inScope
= true;
3697 while (formattingEltStackPos
> -1) {
3698 nsHtml5StackNode
* node
= stack
[formattingEltStackPos
];
3699 if (node
== formattingElt
) {
3701 } else if (node
->isScoping()) {
3704 formattingEltStackPos
--;
3706 if (formattingEltStackPos
== -1) {
3707 errNoElementToCloseButEndTagSeen(name
);
3708 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3712 errNoElementToCloseButEndTagSeen(name
);
3715 if (formattingEltStackPos
!= currentPtr
) {
3716 errEndTagViolatesNestingRules(name
);
3718 int32_t furthestBlockPos
= formattingEltStackPos
+ 1;
3719 while (furthestBlockPos
<= currentPtr
) {
3720 nsHtml5StackNode
* node
= stack
[furthestBlockPos
];
3721 MOZ_ASSERT(furthestBlockPos
> 0,
3722 "How is formattingEltStackPos + 1 not > 0?");
3723 if (node
->isSpecial()) {
3728 if (furthestBlockPos
> currentPtr
) {
3729 while (currentPtr
>= formattingEltStackPos
) {
3732 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3735 nsHtml5StackNode
* commonAncestor
= stack
[formattingEltStackPos
- 1];
3736 nsIContentHandle
* insertionCommonAncestor
=
3737 nodeFromStackWithBlinkCompat(formattingEltStackPos
- 1);
3738 nsHtml5StackNode
* furthestBlock
= stack
[furthestBlockPos
];
3739 int32_t bookmark
= formattingEltListPos
;
3740 int32_t nodePos
= furthestBlockPos
;
3741 nsHtml5StackNode
* lastNode
= furthestBlock
;
3746 if (nodePos
== formattingEltStackPos
) {
3749 nsHtml5StackNode
* node
= stack
[nodePos
];
3750 int32_t nodeListPos
= findInListOfActiveFormattingElements(node
);
3751 if (j
> 3 && nodeListPos
!= -1) {
3752 removeFromListOfActiveFormattingElements(nodeListPos
);
3753 if (nodeListPos
<= formattingEltListPos
) {
3754 formattingEltListPos
--;
3756 if (nodeListPos
<= bookmark
) {
3761 if (nodeListPos
== -1) {
3762 MOZ_ASSERT(formattingEltStackPos
< nodePos
);
3763 MOZ_ASSERT(bookmark
< nodePos
);
3764 MOZ_ASSERT(furthestBlockPos
> nodePos
);
3765 removeFromStack(nodePos
);
3769 if (nodePos
== furthestBlockPos
) {
3770 bookmark
= nodeListPos
+ 1;
3772 MOZ_ASSERT(node
== listOfActiveFormattingElements
[nodeListPos
]);
3773 MOZ_ASSERT(node
== stack
[nodePos
]);
3774 nsIContentHandle
* clone
= createElement(
3775 kNameSpaceID_XHTML
, node
->name
, node
->attributes
->cloneAttributes(),
3776 insertionCommonAncestor
, htmlCreator(node
->getHtmlCreator()));
3777 nsHtml5StackNode
* newNode
= createStackNode(
3778 node
->getFlags(), node
->ns
, node
->name
, clone
, node
->popName
,
3779 node
->attributes
, node
->getHtmlCreator());
3780 node
->dropAttributes();
3781 stack
[nodePos
] = newNode
;
3783 listOfActiveFormattingElements
[nodeListPos
] = newNode
;
3784 node
->release(this);
3785 node
->release(this);
3787 detachFromParent(lastNode
->node
);
3788 appendElement(lastNode
->node
, nodeFromStackWithBlinkCompat(nodePos
));
3791 if (commonAncestor
->isFosterParenting()) {
3792 detachFromParent(lastNode
->node
);
3793 insertIntoFosterParent(lastNode
->node
);
3795 detachFromParent(lastNode
->node
);
3796 appendElement(lastNode
->node
, insertionCommonAncestor
);
3798 nsIContentHandle
* clone
= createElement(
3799 kNameSpaceID_XHTML
, formattingElt
->name
,
3800 formattingElt
->attributes
->cloneAttributes(), furthestBlock
->node
,
3801 htmlCreator(formattingElt
->getHtmlCreator()));
3802 nsHtml5StackNode
* formattingClone
= createStackNode(
3803 formattingElt
->getFlags(), formattingElt
->ns
, formattingElt
->name
,
3804 clone
, formattingElt
->popName
, formattingElt
->attributes
,
3805 formattingElt
->getHtmlCreator());
3806 formattingElt
->dropAttributes();
3807 appendChildrenToNewParent(furthestBlock
->node
, clone
);
3808 appendElement(clone
, furthestBlock
->node
);
3809 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3810 insertIntoListOfActiveFormattingElements(formattingClone
, bookmark
);
3811 MOZ_ASSERT(formattingEltStackPos
< furthestBlockPos
);
3812 removeFromStack(formattingEltStackPos
);
3813 insertIntoStack(formattingClone
, furthestBlockPos
);
3818 void nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode
* node
,
3820 MOZ_ASSERT(currentPtr
+ 1 < stack
.length
);
3821 MOZ_ASSERT(position
<= currentPtr
+ 1);
3822 if (position
== currentPtr
+ 1) {
3825 nsHtml5ArrayCopy::arraycopy(stack
, position
, position
+ 1,
3826 (currentPtr
- position
) + 1);
3828 stack
[position
] = node
;
3832 void nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(
3833 nsHtml5StackNode
* formattingClone
, int32_t bookmark
) {
3834 formattingClone
->retain();
3835 MOZ_ASSERT(listPtr
+ 1 < listOfActiveFormattingElements
.length
);
3836 if (bookmark
<= listPtr
) {
3837 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, bookmark
,
3838 bookmark
+ 1, (listPtr
- bookmark
) + 1);
3841 listOfActiveFormattingElements
[bookmark
] = formattingClone
;
3844 int32_t nsHtml5TreeBuilder::findInListOfActiveFormattingElements(
3845 nsHtml5StackNode
* node
) {
3846 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3847 if (node
== listOfActiveFormattingElements
[i
]) {
3854 int32_t nsHtml5TreeBuilder::
3855 findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(
3857 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3858 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
3861 } else if (node
->name
== name
) {
3868 void nsHtml5TreeBuilder::maybeForgetEarlierDuplicateFormattingElement(
3869 nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
) {
3870 int32_t candidate
= -1;
3872 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3873 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
3877 if (node
->name
== name
&& node
->attributes
->equalsAnother(attributes
)) {
3883 removeFromListOfActiveFormattingElements(candidate
);
3887 int32_t nsHtml5TreeBuilder::findLastOrRoot(nsAtom
* name
) {
3888 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3889 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3896 int32_t nsHtml5TreeBuilder::findLastOrRoot(int32_t group
) {
3897 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3898 if (stack
[i
]->getGroup() == group
) {
3905 bool nsHtml5TreeBuilder::addAttributesToBody(
3906 nsHtml5HtmlAttributes
* attributes
) {
3907 if (currentPtr
>= 1) {
3908 nsHtml5StackNode
* body
= stack
[1];
3909 if (body
->getGroup() == nsHtml5TreeBuilder::BODY
) {
3910 addAttributesToElement(body
->node
, attributes
);
3917 void nsHtml5TreeBuilder::addAttributesToHtml(
3918 nsHtml5HtmlAttributes
* attributes
) {
3919 addAttributesToElement(stack
[0]->node
, attributes
);
3922 void nsHtml5TreeBuilder::pushHeadPointerOntoStack() {
3923 MOZ_ASSERT(!!headPointer
);
3924 MOZ_ASSERT(mode
== AFTER_HEAD
);
3926 silentPush(createStackNode(nsHtml5ElementName::ELT_HEAD
, headPointer
));
3929 void nsHtml5TreeBuilder::reconstructTheActiveFormattingElements() {
3930 if (listPtr
== -1) {
3933 nsHtml5StackNode
* mostRecent
= listOfActiveFormattingElements
[listPtr
];
3934 if (!mostRecent
|| isInStack(mostRecent
)) {
3937 int32_t entryPos
= listPtr
;
3940 if (entryPos
== -1) {
3943 if (!listOfActiveFormattingElements
[entryPos
]) {
3946 if (isInStack(listOfActiveFormattingElements
[entryPos
])) {
3950 while (entryPos
< listPtr
) {
3952 nsHtml5StackNode
* entry
= listOfActiveFormattingElements
[entryPos
];
3953 nsHtml5StackNode
* current
= stack
[currentPtr
];
3954 nsIContentHandle
* clone
;
3955 if (current
->isFosterParenting()) {
3956 clone
= createAndInsertFosterParentedElement(
3957 kNameSpaceID_XHTML
, entry
->name
, entry
->attributes
->cloneAttributes(),
3958 htmlCreator(entry
->getHtmlCreator()));
3960 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
3961 clone
= createElement(kNameSpaceID_XHTML
, entry
->name
,
3962 entry
->attributes
->cloneAttributes(), currentNode
,
3963 htmlCreator(entry
->getHtmlCreator()));
3964 appendElement(clone
, currentNode
);
3966 nsHtml5StackNode
* entryClone
= createStackNode(
3967 entry
->getFlags(), entry
->ns
, entry
->name
, clone
, entry
->popName
,
3968 entry
->attributes
, entry
->getHtmlCreator());
3969 entry
->dropAttributes();
3971 listOfActiveFormattingElements
[entryPos
] = entryClone
;
3972 entry
->release(this);
3973 entryClone
->retain();
3977 void nsHtml5TreeBuilder::notifyUnusedStackNode(int32_t idxInStackNodes
) {
3978 if (idxInStackNodes
< stackNodesIdx
) {
3979 stackNodesIdx
= idxInStackNodes
;
3983 nsHtml5StackNode
* nsHtml5TreeBuilder::getUnusedStackNode() {
3984 while (stackNodesIdx
< numStackNodes
) {
3985 if (stackNodes
[stackNodesIdx
]->isUnused()) {
3986 return stackNodes
[stackNodesIdx
++];
3990 if (stackNodesIdx
< stackNodes
.length
) {
3991 stackNodes
[stackNodesIdx
] = new nsHtml5StackNode(stackNodesIdx
);
3993 return stackNodes
[stackNodesIdx
++];
3995 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
3996 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stackNodes
.length
+ 64);
3997 nsHtml5ArrayCopy::arraycopy(stackNodes
, newStack
, stackNodes
.length
);
3998 stackNodes
= newStack
;
3999 stackNodes
[stackNodesIdx
] = new nsHtml5StackNode(stackNodesIdx
);
4001 return stackNodes
[stackNodesIdx
++];
4004 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4005 int32_t flags
, int32_t ns
, nsAtom
* name
, nsIContentHandle
* node
,
4006 nsAtom
* popName
, nsHtml5HtmlAttributes
* attributes
,
4007 mozilla::dom::HTMLContentCreatorFunction htmlCreator
) {
4008 nsHtml5StackNode
* instance
= getUnusedStackNode();
4009 instance
->setValues(flags
, ns
, name
, node
, popName
, attributes
, htmlCreator
);
4013 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4014 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
) {
4015 nsHtml5StackNode
* instance
= getUnusedStackNode();
4016 instance
->setValues(elementName
, node
);
4020 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4021 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
,
4022 nsHtml5HtmlAttributes
* attributes
) {
4023 nsHtml5StackNode
* instance
= getUnusedStackNode();
4024 instance
->setValues(elementName
, node
, attributes
);
4028 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4029 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
, nsAtom
* popName
) {
4030 nsHtml5StackNode
* instance
= getUnusedStackNode();
4031 instance
->setValues(elementName
, node
, popName
);
4035 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4036 nsHtml5ElementName
* elementName
, nsAtom
* popName
, nsIContentHandle
* node
) {
4037 nsHtml5StackNode
* instance
= getUnusedStackNode();
4038 instance
->setValues(elementName
, popName
, node
);
4042 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4043 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
, nsAtom
* popName
,
4044 bool markAsIntegrationPoint
) {
4045 nsHtml5StackNode
* instance
= getUnusedStackNode();
4046 instance
->setValues(elementName
, node
, popName
, markAsIntegrationPoint
);
4050 void nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle
* child
) {
4051 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4052 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4053 if (templatePos
>= tablePos
) {
4054 appendElement(child
, stack
[templatePos
]->node
);
4057 nsHtml5StackNode
* node
= stack
[tablePos
];
4058 insertFosterParentedChild(child
, node
->node
, stack
[tablePos
- 1]->node
);
4061 nsIContentHandle
* nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
4062 int32_t ns
, nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
,
4063 nsHtml5ContentCreatorFunction creator
) {
4064 return createAndInsertFosterParentedElement(ns
, name
, attributes
, nullptr,
4068 nsIContentHandle
* nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
4069 int32_t ns
, nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
,
4070 nsIContentHandle
* form
, nsHtml5ContentCreatorFunction creator
) {
4071 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4072 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4073 if (templatePos
>= tablePos
) {
4074 nsIContentHandle
* child
= createElement(ns
, name
, attributes
, form
,
4075 stack
[templatePos
]->node
, creator
);
4076 appendElement(child
, stack
[templatePos
]->node
);
4079 nsHtml5StackNode
* node
= stack
[tablePos
];
4080 return createAndInsertFosterParentedElement(
4081 ns
, name
, attributes
, form
, node
->node
, stack
[tablePos
- 1]->node
,
4085 bool nsHtml5TreeBuilder::isInStack(nsHtml5StackNode
* node
) {
4086 for (int32_t i
= currentPtr
; i
>= 0; i
--) {
4087 if (stack
[i
] == node
) {
4094 void nsHtml5TreeBuilder::popTemplateMode() { templateModePtr
--; }
4096 void nsHtml5TreeBuilder::pop() {
4097 nsHtml5StackNode
* node
= stack
[currentPtr
];
4098 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4100 elementPopped(node
->ns
, node
->popName
, node
->node
);
4101 node
->release(this);
4104 void nsHtml5TreeBuilder::popForeign(int32_t origPos
, int32_t eltPos
) {
4105 nsHtml5StackNode
* node
= stack
[currentPtr
];
4106 if (origPos
!= currentPtr
|| eltPos
!= currentPtr
) {
4107 markMalformedIfScript(node
->node
);
4109 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4111 elementPopped(node
->ns
, node
->popName
, node
->node
);
4112 node
->release(this);
4115 void nsHtml5TreeBuilder::silentPop() {
4116 nsHtml5StackNode
* node
= stack
[currentPtr
];
4117 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4119 node
->release(this);
4122 void nsHtml5TreeBuilder::popOnEof() {
4123 nsHtml5StackNode
* node
= stack
[currentPtr
];
4124 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4126 markMalformedIfScript(node
->node
);
4127 elementPopped(node
->ns
, node
->popName
, node
->node
);
4128 node
->release(this);
4131 void nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(
4132 nsHtml5HtmlAttributes
* attributes
) {
4133 nsIContentHandle
* elt
= createHtmlElementSetAsRoot(attributes
);
4134 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_HTML
, elt
);
4138 void nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush() {
4139 appendHtmlElementToDocumentAndPush(tokenizer
->emptyAttributes());
4142 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(
4143 nsHtml5HtmlAttributes
* attributes
) {
4144 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4145 nsIContentHandle
* elt
=
4146 createElement(kNameSpaceID_XHTML
, nsGkAtoms::head
, attributes
,
4147 currentNode
, htmlCreator(NS_NewHTMLSharedElement
));
4148 appendElement(elt
, currentNode
);
4150 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_HEAD
, elt
);
4154 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(
4155 nsHtml5HtmlAttributes
* attributes
) {
4156 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY
, attributes
);
4159 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement() {
4160 appendToCurrentNodeAndPushBodyElement(tokenizer
->emptyAttributes());
4163 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(
4164 nsHtml5HtmlAttributes
* attributes
) {
4165 nsIContentHandle
* elt
;
4166 nsHtml5StackNode
* current
= stack
[currentPtr
];
4167 if (current
->isFosterParenting()) {
4168 elt
= createAndInsertFosterParentedElement(
4169 kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4170 htmlCreator(NS_NewHTMLFormElement
));
4172 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4173 elt
= createElement(kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4174 currentNode
, htmlCreator(NS_NewHTMLFormElement
));
4175 appendElement(elt
, currentNode
);
4177 if (!isTemplateContents()) {
4180 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_FORM
, elt
);
4184 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(
4185 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4186 nsHtml5HtmlAttributes
* clone
= attributes
->cloneAttributes();
4187 nsIContentHandle
* elt
;
4188 nsHtml5StackNode
* current
= stack
[currentPtr
];
4189 if (current
->isFosterParenting()) {
4190 elt
= createAndInsertFosterParentedElement(
4191 kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4192 htmlCreator(elementName
->getHtmlCreator()));
4194 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4196 createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4197 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4198 appendElement(elt
, currentNode
);
4200 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
, clone
);
4206 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(
4207 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4208 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4209 nsIContentHandle
* elt
=
4210 createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4211 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4212 appendElement(elt
, currentNode
);
4213 if (nsHtml5ElementName::ELT_TEMPLATE
== elementName
) {
4214 elt
= getDocumentFragmentForTemplate(elt
);
4216 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
);
4220 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
4221 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4222 nsAtom
* popName
= elementName
->getName();
4223 nsIContentHandle
* elt
;
4224 nsHtml5StackNode
* current
= stack
[currentPtr
];
4225 if (current
->isFosterParenting()) {
4226 elt
= createAndInsertFosterParentedElement(
4227 kNameSpaceID_XHTML
, popName
, attributes
,
4228 htmlCreator(elementName
->getHtmlCreator()));
4230 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4231 elt
= createElement(kNameSpaceID_XHTML
, popName
, attributes
, currentNode
,
4232 htmlCreator(elementName
->getHtmlCreator()));
4233 appendElement(elt
, currentNode
);
4235 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
, popName
);
4239 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(
4240 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4241 nsAtom
* popName
= elementName
->getName();
4242 bool markAsHtmlIntegrationPoint
= false;
4243 if (nsHtml5ElementName::ELT_ANNOTATION_XML
== elementName
&&
4244 annotationXmlEncodingPermitsHtml(attributes
)) {
4245 markAsHtmlIntegrationPoint
= true;
4247 nsIContentHandle
* elt
;
4248 nsHtml5StackNode
* current
= stack
[currentPtr
];
4249 if (current
->isFosterParenting()) {
4250 elt
= createAndInsertFosterParentedElement(
4251 kNameSpaceID_MathML
, popName
, attributes
, htmlCreator(nullptr));
4253 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4254 elt
= createElement(kNameSpaceID_MathML
, popName
, attributes
, currentNode
,
4255 htmlCreator(nullptr));
4256 appendElement(elt
, currentNode
);
4258 nsHtml5StackNode
* node
=
4259 createStackNode(elementName
, elt
, popName
, markAsHtmlIntegrationPoint
);
4263 bool nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(
4264 nsHtml5HtmlAttributes
* attributes
) {
4265 nsHtml5String encoding
=
4266 attributes
->getValue(nsHtml5AttributeName::ATTR_ENCODING
);
4270 return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
4271 "application/xhtml+xml", encoding
) ||
4272 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
4273 "text/html", encoding
);
4276 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(
4277 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4278 nsAtom
* popName
= elementName
->getCamelCaseName();
4279 nsIContentHandle
* elt
;
4280 nsHtml5StackNode
* current
= stack
[currentPtr
];
4281 if (current
->isFosterParenting()) {
4282 elt
= createAndInsertFosterParentedElement(
4283 kNameSpaceID_SVG
, popName
, attributes
,
4284 svgCreator(elementName
->getSvgCreator()));
4286 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4287 elt
= createElement(kNameSpaceID_SVG
, popName
, attributes
, currentNode
,
4288 svgCreator(elementName
->getSvgCreator()));
4289 appendElement(elt
, currentNode
);
4291 nsHtml5StackNode
* node
= createStackNode(elementName
, popName
, elt
);
4295 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
4296 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
,
4297 nsIContentHandle
* form
) {
4298 nsIContentHandle
* elt
;
4299 nsIContentHandle
* formOwner
=
4300 !form
|| fragment
|| isTemplateContents() ? nullptr : form
;
4301 nsHtml5StackNode
* current
= stack
[currentPtr
];
4302 if (current
->isFosterParenting()) {
4303 elt
= createAndInsertFosterParentedElement(
4304 kNameSpaceID_XHTML
, elementName
->getName(), attributes
, formOwner
,
4305 htmlCreator(elementName
->getHtmlCreator()));
4307 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4308 elt
= createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4309 formOwner
, currentNode
,
4310 htmlCreator(elementName
->getHtmlCreator()));
4311 appendElement(elt
, currentNode
);
4313 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
);
4317 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
4318 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
,
4319 nsIContentHandle
* form
) {
4320 nsAtom
* name
= elementName
->getName();
4321 nsIContentHandle
* elt
;
4322 nsIContentHandle
* formOwner
=
4323 !form
|| fragment
|| isTemplateContents() ? nullptr : form
;
4324 nsHtml5StackNode
* current
= stack
[currentPtr
];
4325 if (current
->isFosterParenting()) {
4326 elt
= createAndInsertFosterParentedElement(
4327 kNameSpaceID_XHTML
, name
, attributes
, formOwner
,
4328 htmlCreator(elementName
->getHtmlCreator()));
4330 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4332 createElement(kNameSpaceID_XHTML
, name
, attributes
, formOwner
,
4333 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4334 appendElement(elt
, currentNode
);
4336 elementPushed(kNameSpaceID_XHTML
, name
, elt
);
4337 elementPopped(kNameSpaceID_XHTML
, name
, elt
);
4340 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
4341 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4342 nsAtom
* popName
= elementName
->getName();
4343 nsIContentHandle
* elt
;
4344 nsHtml5StackNode
* current
= stack
[currentPtr
];
4345 if (current
->isFosterParenting()) {
4346 elt
= createAndInsertFosterParentedElement(
4347 kNameSpaceID_XHTML
, popName
, attributes
,
4348 htmlCreator(elementName
->getHtmlCreator()));
4350 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4351 elt
= createElement(kNameSpaceID_XHTML
, popName
, attributes
, currentNode
,
4352 htmlCreator(elementName
->getHtmlCreator()));
4353 appendElement(elt
, currentNode
);
4355 elementPushed(kNameSpaceID_XHTML
, popName
, elt
);
4356 elementPopped(kNameSpaceID_XHTML
, popName
, elt
);
4359 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(
4360 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4361 nsAtom
* popName
= elementName
->getCamelCaseName();
4362 nsIContentHandle
* elt
;
4363 nsHtml5StackNode
* current
= stack
[currentPtr
];
4364 if (current
->isFosterParenting()) {
4365 elt
= createAndInsertFosterParentedElement(
4366 kNameSpaceID_SVG
, popName
, attributes
,
4367 svgCreator(elementName
->getSvgCreator()));
4369 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4370 elt
= createElement(kNameSpaceID_SVG
, popName
, attributes
, currentNode
,
4371 svgCreator(elementName
->getSvgCreator()));
4372 appendElement(elt
, currentNode
);
4374 elementPushed(kNameSpaceID_SVG
, popName
, elt
);
4375 elementPopped(kNameSpaceID_SVG
, popName
, elt
);
4378 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(
4379 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4380 nsAtom
* popName
= elementName
->getName();
4381 nsIContentHandle
* elt
;
4382 nsHtml5StackNode
* current
= stack
[currentPtr
];
4383 if (current
->isFosterParenting()) {
4384 elt
= createAndInsertFosterParentedElement(
4385 kNameSpaceID_MathML
, popName
, attributes
, htmlCreator(nullptr));
4387 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4388 elt
= createElement(kNameSpaceID_MathML
, popName
, attributes
, currentNode
,
4389 htmlCreator(nullptr));
4390 appendElement(elt
, currentNode
);
4392 elementPushed(kNameSpaceID_MathML
, popName
, elt
);
4393 elementPopped(kNameSpaceID_MathML
, popName
, elt
);
4396 void nsHtml5TreeBuilder::appendVoidInputToCurrent(
4397 nsHtml5HtmlAttributes
* attributes
, nsIContentHandle
* form
) {
4398 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4399 nsIContentHandle
* elt
=
4400 createElement(kNameSpaceID_XHTML
, nsGkAtoms::input
, attributes
,
4401 !form
|| fragment
|| isTemplateContents() ? nullptr : form
,
4402 currentNode
, htmlCreator(NS_NewHTMLInputElement
));
4403 appendElement(elt
, currentNode
);
4404 elementPushed(kNameSpaceID_XHTML
, nsGkAtoms::input
, elt
);
4405 elementPopped(kNameSpaceID_XHTML
, nsGkAtoms::input
, elt
);
4408 void nsHtml5TreeBuilder::appendVoidFormToCurrent(
4409 nsHtml5HtmlAttributes
* attributes
) {
4410 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4411 nsIContentHandle
* elt
=
4412 createElement(kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4413 currentNode
, htmlCreator(NS_NewHTMLFormElement
));
4415 appendElement(elt
, currentNode
);
4416 elementPushed(kNameSpaceID_XHTML
, nsGkAtoms::form
, elt
);
4417 elementPopped(kNameSpaceID_XHTML
, nsGkAtoms::form
, elt
);
4420 void nsHtml5TreeBuilder::requestSuspension() {
4421 tokenizer
->requestSuspension();
4425 bool nsHtml5TreeBuilder::isInForeign() {
4426 return currentPtr
>= 0 && stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
;
4429 bool nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint() {
4430 if (currentPtr
< 0) {
4433 return !isSpecialParentInForeign(stack
[currentPtr
]);
4436 void nsHtml5TreeBuilder::setFragmentContext(nsAtom
* context
, int32_t ns
,
4437 nsIContentHandle
* node
,
4439 this->contextName
= context
;
4440 this->contextNamespace
= ns
;
4441 this->contextNode
= node
;
4442 this->fragment
= (!!contextName
);
4443 this->quirks
= quirks
;
4446 nsIContentHandle
* nsHtml5TreeBuilder::currentNode() {
4447 return stack
[currentPtr
]->node
;
4450 bool nsHtml5TreeBuilder::isScriptingEnabled() { return scriptingEnabled
; }
4452 void nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled
) {
4453 this->scriptingEnabled
= scriptingEnabled
;
4456 void nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument
) {
4457 this->isSrcdocDocument
= isSrcdocDocument
;
4460 void nsHtml5TreeBuilder::flushCharacters() {
4461 if (charBufferLen
> 0) {
4462 if ((mode
== IN_TABLE
|| mode
== IN_TABLE_BODY
|| mode
== IN_ROW
) &&
4463 charBufferContainsNonWhitespace()) {
4464 errNonSpaceInTable();
4465 reconstructTheActiveFormattingElements();
4466 if (!stack
[currentPtr
]->isFosterParenting()) {
4467 appendCharacters(currentNode(), charBuffer
, 0, charBufferLen
);
4471 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4472 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4473 if (templatePos
>= tablePos
) {
4474 appendCharacters(stack
[templatePos
]->node
, charBuffer
, 0,
4479 nsHtml5StackNode
* tableElt
= stack
[tablePos
];
4480 insertFosterParentedCharacters(charBuffer
, 0, charBufferLen
,
4481 tableElt
->node
, stack
[tablePos
- 1]->node
);
4485 appendCharacters(currentNode(), charBuffer
, 0, charBufferLen
);
4490 bool nsHtml5TreeBuilder::charBufferContainsNonWhitespace() {
4491 for (int32_t i
= 0; i
< charBufferLen
; i
++) {
4492 switch (charBuffer
[i
]) {
4508 nsAHtml5TreeBuilderState
* nsHtml5TreeBuilder::newSnapshot() {
4509 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4510 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(listPtr
+ 1);
4511 for (int32_t i
= 0; i
< listCopy
.length
; i
++) {
4512 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
4514 nsHtml5StackNode
* newNode
= new nsHtml5StackNode(-1);
4515 newNode
->setValues(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4516 node
->popName
, node
->attributes
->cloneAttributes(),
4517 node
->getHtmlCreator());
4518 listCopy
[i
] = newNode
;
4520 listCopy
[i
] = nullptr;
4523 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
=
4524 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(currentPtr
+ 1);
4525 for (int32_t i
= 0; i
< stackCopy
.length
; i
++) {
4526 nsHtml5StackNode
* node
= stack
[i
];
4527 int32_t listIndex
= findInListOfActiveFormattingElements(node
);
4528 if (listIndex
== -1) {
4529 nsHtml5StackNode
* newNode
= new nsHtml5StackNode(-1);
4530 newNode
->setValues(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4531 node
->popName
, nullptr, node
->getHtmlCreator());
4532 stackCopy
[i
] = newNode
;
4534 stackCopy
[i
] = listCopy
[listIndex
];
4535 stackCopy
[i
]->retain();
4538 jArray
<int32_t, int32_t> templateModeStackCopy
=
4539 jArray
<int32_t, int32_t>::newJArray(templateModePtr
+ 1);
4540 nsHtml5ArrayCopy::arraycopy(templateModeStack
, templateModeStackCopy
,
4541 templateModeStackCopy
.length
);
4542 return new nsHtml5StateSnapshot(stackCopy
, listCopy
, templateModeStackCopy
,
4543 formPointer
, headPointer
, mode
, originalMode
,
4544 framesetOk
, needToDropLF
, quirks
);
4547 bool nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState
* snapshot
) {
4548 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
= snapshot
->getStack();
4549 int32_t stackLen
= snapshot
->getStackLength();
4550 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4551 snapshot
->getListOfActiveFormattingElements();
4552 int32_t listLen
= snapshot
->getListOfActiveFormattingElementsLength();
4553 jArray
<int32_t, int32_t> templateModeStackCopy
=
4554 snapshot
->getTemplateModeStack();
4555 int32_t templateModeStackLen
= snapshot
->getTemplateModeStackLength();
4556 if (stackLen
!= currentPtr
+ 1 || listLen
!= listPtr
+ 1 ||
4557 templateModeStackLen
!= templateModePtr
+ 1 ||
4558 formPointer
!= snapshot
->getFormPointer() ||
4559 headPointer
!= snapshot
->getHeadPointer() ||
4560 mode
!= snapshot
->getMode() ||
4561 originalMode
!= snapshot
->getOriginalMode() ||
4562 framesetOk
!= snapshot
->isFramesetOk() ||
4563 needToDropLF
!= snapshot
->isNeedToDropLF() ||
4564 quirks
!= snapshot
->isQuirks()) {
4567 for (int32_t i
= listLen
- 1; i
>= 0; i
--) {
4568 if (!listCopy
[i
] && !listOfActiveFormattingElements
[i
]) {
4570 } else if (!listCopy
[i
] || !listOfActiveFormattingElements
[i
]) {
4573 if (listCopy
[i
]->node
!= listOfActiveFormattingElements
[i
]->node
) {
4577 for (int32_t i
= stackLen
- 1; i
>= 0; i
--) {
4578 if (stackCopy
[i
]->node
!= stack
[i
]->node
) {
4582 for (int32_t i
= templateModeStackLen
- 1; i
>= 0; i
--) {
4583 if (templateModeStackCopy
[i
] != templateModeStack
[i
]) {
4590 void nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState
* snapshot
) {
4591 mCurrentHtmlScriptIsAsyncOrDefer
= false;
4592 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
= snapshot
->getStack();
4593 int32_t stackLen
= snapshot
->getStackLength();
4594 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4595 snapshot
->getListOfActiveFormattingElements();
4596 int32_t listLen
= snapshot
->getListOfActiveFormattingElementsLength();
4597 jArray
<int32_t, int32_t> templateModeStackCopy
=
4598 snapshot
->getTemplateModeStack();
4599 int32_t templateModeStackLen
= snapshot
->getTemplateModeStackLength();
4600 for (int32_t i
= 0; i
<= listPtr
; i
++) {
4601 if (listOfActiveFormattingElements
[i
]) {
4602 listOfActiveFormattingElements
[i
]->release(this);
4605 if (listOfActiveFormattingElements
.length
< listLen
) {
4606 listOfActiveFormattingElements
=
4607 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(listLen
);
4609 listPtr
= listLen
- 1;
4610 for (int32_t i
= 0; i
<= currentPtr
; i
++) {
4611 stack
[i
]->release(this);
4613 if (stack
.length
< stackLen
) {
4614 stack
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stackLen
);
4616 currentPtr
= stackLen
- 1;
4617 if (templateModeStack
.length
< templateModeStackLen
) {
4619 jArray
<int32_t, int32_t>::newJArray(templateModeStackLen
);
4621 templateModePtr
= templateModeStackLen
- 1;
4622 for (int32_t i
= 0; i
< listLen
; i
++) {
4623 nsHtml5StackNode
* node
= listCopy
[i
];
4625 nsHtml5StackNode
* newNode
= createStackNode(
4626 node
->getFlags(), node
->ns
, node
->name
, node
->node
, node
->popName
,
4627 node
->attributes
->cloneAttributes(), node
->getHtmlCreator());
4628 listOfActiveFormattingElements
[i
] = newNode
;
4630 listOfActiveFormattingElements
[i
] = nullptr;
4633 for (int32_t i
= 0; i
< stackLen
; i
++) {
4634 nsHtml5StackNode
* node
= stackCopy
[i
];
4635 int32_t listIndex
= findInArray(node
, listCopy
);
4636 if (listIndex
== -1) {
4637 nsHtml5StackNode
* newNode
=
4638 createStackNode(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4639 node
->popName
, nullptr, node
->getHtmlCreator());
4642 stack
[i
] = listOfActiveFormattingElements
[listIndex
];
4646 nsHtml5ArrayCopy::arraycopy(templateModeStackCopy
, templateModeStack
,
4647 templateModeStackLen
);
4648 formPointer
= snapshot
->getFormPointer();
4649 headPointer
= snapshot
->getHeadPointer();
4650 mode
= snapshot
->getMode();
4651 originalMode
= snapshot
->getOriginalMode();
4652 framesetOk
= snapshot
->isFramesetOk();
4653 needToDropLF
= snapshot
->isNeedToDropLF();
4654 quirks
= snapshot
->isQuirks();
4657 int32_t nsHtml5TreeBuilder::findInArray(
4658 nsHtml5StackNode
* node
, jArray
<nsHtml5StackNode
*, int32_t> arr
) {
4659 for (int32_t i
= listPtr
; i
>= 0; i
--) {
4660 if (node
== arr
[i
]) {
4667 nsIContentHandle
* nsHtml5TreeBuilder::nodeFromStackWithBlinkCompat(
4669 if (stackPos
> 511) {
4671 return stack
[511]->node
;
4673 return stack
[stackPos
]->node
;
4676 nsIContentHandle
* nsHtml5TreeBuilder::getFormPointer() { return formPointer
; }
4678 nsIContentHandle
* nsHtml5TreeBuilder::getHeadPointer() { return headPointer
; }
4680 jArray
<nsHtml5StackNode
*, int32_t>
4681 nsHtml5TreeBuilder::getListOfActiveFormattingElements() {
4682 return listOfActiveFormattingElements
;
4685 jArray
<nsHtml5StackNode
*, int32_t> nsHtml5TreeBuilder::getStack() {
4689 jArray
<int32_t, int32_t> nsHtml5TreeBuilder::getTemplateModeStack() {
4690 return templateModeStack
;
4693 int32_t nsHtml5TreeBuilder::getMode() { return mode
; }
4695 int32_t nsHtml5TreeBuilder::getOriginalMode() { return originalMode
; }
4697 bool nsHtml5TreeBuilder::isFramesetOk() { return framesetOk
; }
4699 bool nsHtml5TreeBuilder::isNeedToDropLF() { return needToDropLF
; }
4701 bool nsHtml5TreeBuilder::isQuirks() { return quirks
; }
4703 int32_t nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength() {
4707 int32_t nsHtml5TreeBuilder::getStackLength() { return currentPtr
+ 1; }
4709 int32_t nsHtml5TreeBuilder::getTemplateModeStackLength() {
4710 return templateModePtr
+ 1;
4713 void nsHtml5TreeBuilder::initializeStatics() {}
4715 void nsHtml5TreeBuilder::releaseStatics() {}
4717 #include "nsHtml5TreeBuilderCppSupplement.h"