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 "nsHtml5AttributeName.h"
34 #include "nsHtml5ElementName.h"
35 #include "nsHtml5Tokenizer.h"
36 #include "nsHtml5StackNode.h"
37 #include "nsHtml5UTF16Buffer.h"
38 #include "nsHtml5StateSnapshot.h"
39 #include "nsHtml5Portability.h"
41 #include "nsHtml5TreeBuilder.h"
43 char16_t
nsHtml5TreeBuilder::REPLACEMENT_CHARACTER
[] = {0xfffd};
44 static const char* const QUIRKY_PUBLIC_IDS_DATA
[] = {
45 "+//silmaril//dtd html pro v0r11 19970101//",
46 "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
47 "-//as//dtd html 3.0 aswedit + extensions//",
48 "-//ietf//dtd html 2.0 level 1//",
49 "-//ietf//dtd html 2.0 level 2//",
50 "-//ietf//dtd html 2.0 strict level 1//",
51 "-//ietf//dtd html 2.0 strict level 2//",
52 "-//ietf//dtd html 2.0 strict//",
53 "-//ietf//dtd html 2.0//",
54 "-//ietf//dtd html 2.1e//",
55 "-//ietf//dtd html 3.0//",
56 "-//ietf//dtd html 3.2 final//",
57 "-//ietf//dtd html 3.2//",
58 "-//ietf//dtd html 3//",
59 "-//ietf//dtd html level 0//",
60 "-//ietf//dtd html level 1//",
61 "-//ietf//dtd html level 2//",
62 "-//ietf//dtd html level 3//",
63 "-//ietf//dtd html strict level 0//",
64 "-//ietf//dtd html strict level 1//",
65 "-//ietf//dtd html strict level 2//",
66 "-//ietf//dtd html strict level 3//",
67 "-//ietf//dtd html strict//",
68 "-//ietf//dtd html//",
69 "-//metrius//dtd metrius presentational//",
70 "-//microsoft//dtd internet explorer 2.0 html strict//",
71 "-//microsoft//dtd internet explorer 2.0 html//",
72 "-//microsoft//dtd internet explorer 2.0 tables//",
73 "-//microsoft//dtd internet explorer 3.0 html strict//",
74 "-//microsoft//dtd internet explorer 3.0 html//",
75 "-//microsoft//dtd internet explorer 3.0 tables//",
76 "-//netscape comm. corp.//dtd html//",
77 "-//netscape comm. corp.//dtd strict html//",
78 "-//o'reilly and associates//dtd html 2.0//",
79 "-//o'reilly and associates//dtd html extended 1.0//",
80 "-//o'reilly and associates//dtd html extended relaxed 1.0//",
81 "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html "
83 "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
84 "-//spyglass//dtd html 2.0 extended//",
85 "-//sq//dtd html 2.0 hotmetal + extensions//",
86 "-//sun microsystems corp.//dtd hotjava html//",
87 "-//sun microsystems corp.//dtd hotjava strict html//",
88 "-//w3c//dtd html 3 1995-03-24//",
89 "-//w3c//dtd html 3.2 draft//",
90 "-//w3c//dtd html 3.2 final//",
91 "-//w3c//dtd html 3.2//",
92 "-//w3c//dtd html 3.2s draft//",
93 "-//w3c//dtd html 4.0 frameset//",
94 "-//w3c//dtd html 4.0 transitional//",
95 "-//w3c//dtd html experimental 19960712//",
96 "-//w3c//dtd html experimental 970421//",
97 "-//w3c//dtd w3 html//",
98 "-//w3o//dtd w3 html 3.0//",
99 "-//webtechs//dtd mozilla html 2.0//",
100 "-//webtechs//dtd mozilla html//"};
101 staticJArray
<const char*, int32_t> nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
= {
102 QUIRKY_PUBLIC_IDS_DATA
, std::size(QUIRKY_PUBLIC_IDS_DATA
)};
103 void nsHtml5TreeBuilder::setKeepBuffer(bool keepBuffer
) {
104 this->keepBuffer
= keepBuffer
;
107 bool nsHtml5TreeBuilder::dropBufferIfLongerThan(int32_t length
) {
108 if (charBuffer
.length
> length
) {
109 charBuffer
= nullptr;
115 void nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer
* self
) {
117 stackNodes
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
118 stack
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
119 templateModeStack
= jArray
<int32_t, int32_t>::newJArray(64);
120 listOfActiveFormattingElements
=
121 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(64);
122 needToDropLF
= false;
123 originalMode
= INITIAL
;
124 templateModePtr
= -1;
129 formPointer
= nullptr;
130 headPointer
= nullptr;
134 charBuffer
= nullptr;
138 nsIContentHandle
* elt
;
142 elt
= createHtmlElementSetAsRoot(tokenizer
->emptyAttributes());
144 if (contextNamespace
== kNameSpaceID_SVG
) {
145 nsHtml5ElementName
* elementName
= nsHtml5ElementName::ELT_SVG
;
146 if (nsGkAtoms::title
== contextName
|| nsGkAtoms::desc
== contextName
||
147 nsGkAtoms::foreignObject
== contextName
) {
148 elementName
= nsHtml5ElementName::ELT_FOREIGNOBJECT
;
150 nsHtml5StackNode
* node
=
151 createStackNode(elementName
, elementName
->getCamelCaseName(), elt
);
153 stack
[currentPtr
] = node
;
154 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
156 } else if (contextNamespace
== kNameSpaceID_MathML
) {
157 nsHtml5ElementName
* elementName
= nsHtml5ElementName::ELT_MATH
;
158 if (nsGkAtoms::mi_
== contextName
|| nsGkAtoms::mo_
== contextName
||
159 nsGkAtoms::mn_
== contextName
|| nsGkAtoms::ms_
== contextName
||
160 nsGkAtoms::mtext_
== contextName
) {
161 elementName
= nsHtml5ElementName::ELT_MTEXT
;
162 } else if (nsGkAtoms::annotation_xml_
== contextName
) {
163 elementName
= nsHtml5ElementName::ELT_ANNOTATION_XML
;
165 nsHtml5StackNode
* node
=
166 createStackNode(elementName
, elt
, elementName
->getName(), false);
168 stack
[currentPtr
] = node
;
169 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
172 nsHtml5StackNode
* node
=
173 createStackNode(nsHtml5ElementName::ELT_HTML
, elt
);
175 stack
[currentPtr
] = node
;
176 if (nsGkAtoms::_template
== contextName
) {
177 pushTemplateMode(IN_TEMPLATE
);
179 resetTheInsertionMode();
180 formPointer
= getFormPointerForContext(contextNode
);
181 if (nsGkAtoms::title
== contextName
||
182 nsGkAtoms::textarea
== contextName
) {
183 tokenizer
->setState(nsHtml5Tokenizer::RCDATA
);
184 } else if (nsGkAtoms::style
== contextName
||
185 nsGkAtoms::xmp
== contextName
||
186 nsGkAtoms::iframe
== contextName
||
187 nsGkAtoms::noembed
== contextName
||
188 nsGkAtoms::noframes
== contextName
||
189 (scriptingEnabled
&& nsGkAtoms::noscript
== contextName
)) {
190 tokenizer
->setState(nsHtml5Tokenizer::RAWTEXT
);
191 } else if (nsGkAtoms::plaintext
== contextName
) {
192 tokenizer
->setState(nsHtml5Tokenizer::PLAINTEXT
);
193 } else if (nsGkAtoms::script
== contextName
) {
194 tokenizer
->setState(nsHtml5Tokenizer::SCRIPT_DATA
);
196 tokenizer
->setState(nsHtml5Tokenizer::DATA
);
201 if (tokenizer
->isViewingXmlSource()) {
202 nsIContentHandle
* elt
= createElement(
203 kNameSpaceID_SVG
, nsGkAtoms::svg
, tokenizer
->emptyAttributes(),
204 nullptr, svgCreator(NS_NewSVGSVGElement
));
205 nsHtml5StackNode
* node
=
206 createStackNode(nsHtml5ElementName::ELT_SVG
, nsGkAtoms::svg
, elt
);
208 stack
[currentPtr
] = node
;
213 void nsHtml5TreeBuilder::doctype(nsAtom
* name
, nsHtml5String publicIdentifier
,
214 nsHtml5String systemIdentifier
,
216 needToDropLF
= false;
217 if (!isInForeign() && mode
== INITIAL
) {
218 nsHtml5String emptyString
= nsHtml5Portability::newEmptyString();
219 appendDoctypeToDocument(!name
? nsGkAtoms::_empty
: name
,
220 !publicIdentifier
? emptyString
: publicIdentifier
,
221 !systemIdentifier
? emptyString
: systemIdentifier
);
222 emptyString
.Release();
223 if (isQuirky(name
, publicIdentifier
, systemIdentifier
, forceQuirks
)) {
225 documentModeInternal(QUIRKS_MODE
, publicIdentifier
, systemIdentifier
);
226 } else if (isAlmostStandards(publicIdentifier
, systemIdentifier
)) {
227 errAlmostStandardsDoctype();
228 documentModeInternal(ALMOST_STANDARDS_MODE
, publicIdentifier
,
231 documentModeInternal(STANDARDS_MODE
, publicIdentifier
, systemIdentifier
);
240 void nsHtml5TreeBuilder::comment(char16_t
* buf
, int32_t start
, int32_t length
) {
241 needToDropLF
= false;
242 if (!isInForeign()) {
246 case AFTER_AFTER_BODY
:
247 case AFTER_AFTER_FRAMESET
: {
248 appendCommentToDocument(buf
, start
, length
);
253 appendComment(stack
[0]->node
, buf
, start
, length
);
262 appendComment(stack
[currentPtr
]->node
, buf
, start
, length
);
266 void nsHtml5TreeBuilder::characters(const char16_t
* buf
, int32_t start
,
268 if (tokenizer
->isViewingXmlSource()) {
272 needToDropLF
= false;
273 if (buf
[start
] == '\n') {
285 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
286 reconstructTheActiveFormattingElements();
291 accumulateCharacters(buf
, start
, length
);
297 accumulateCharactersForced(buf
, start
, length
);
301 int32_t end
= start
+ length
;
302 for (int32_t i
= start
; i
< end
; i
++) {
317 case IN_HEAD_NOSCRIPT
:
319 case IN_COLUMN_GROUP
:
321 case AFTER_FRAMESET
: {
330 accumulateCharacters(buf
, start
, i
- start
);
333 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
335 reconstructTheActiveFormattingElements();
337 NS_HTML5_BREAK(charactersloop
);
340 case IN_SELECT_IN_TABLE
: {
341 NS_HTML5_BREAK(charactersloop
);
346 accumulateCharactersForced(buf
, i
, 1);
351 case AFTER_AFTER_BODY
:
352 case AFTER_AFTER_FRAMESET
: {
354 accumulateCharacters(buf
, start
, i
- start
);
358 reconstructTheActiveFormattingElements();
362 MOZ_FALLTHROUGH_ASSERT();
367 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
373 appendHtmlElementToDocumentAndPush();
380 accumulateCharacters(buf
, start
, i
- start
);
384 appendToCurrentNodeAndPushHeadElement(
385 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
392 accumulateCharacters(buf
, start
, i
- start
);
401 case IN_HEAD_NOSCRIPT
: {
403 accumulateCharacters(buf
, start
, i
- start
);
406 errNonSpaceInNoscriptInHead();
415 accumulateCharacters(buf
, start
, i
- start
);
419 appendToCurrentNodeAndPushBodyElement();
435 accumulateCharacters(buf
, start
, i
- start
);
438 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
440 reconstructTheActiveFormattingElements();
442 NS_HTML5_BREAK(charactersloop
);
447 accumulateCharactersForced(buf
, i
, 1);
451 case IN_COLUMN_GROUP
: {
453 accumulateCharacters(buf
, start
, i
- start
);
456 if (!currentPtr
|| stack
[currentPtr
]->getGroup() ==
457 nsHtml5TreeBuilder::TEMPLATE
) {
458 errNonSpaceInColgroupInFragment();
469 case IN_SELECT_IN_TABLE
: {
470 NS_HTML5_BREAK(charactersloop
);
473 errNonSpaceAfterBody();
475 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
481 accumulateCharacters(buf
, start
, i
- start
);
483 errNonSpaceInFrameset();
487 case AFTER_FRAMESET
: {
489 accumulateCharacters(buf
, start
, i
- start
);
491 errNonSpaceAfterFrameset();
495 case AFTER_AFTER_BODY
: {
496 errNonSpaceInTrailer();
497 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
501 case AFTER_AFTER_FRAMESET
: {
503 accumulateCharacters(buf
, start
, i
- start
);
505 errNonSpaceInTrailer();
515 accumulateCharacters(buf
, start
, end
- start
);
521 void nsHtml5TreeBuilder::zeroOriginatingReplacementCharacter() {
523 accumulateCharacters(REPLACEMENT_CHARACTER
, 0, 1);
526 if (currentPtr
>= 0) {
527 if (isSpecialParentInForeign(stack
[currentPtr
])) {
530 accumulateCharacters(REPLACEMENT_CHARACTER
, 0, 1);
534 void nsHtml5TreeBuilder::zeroOrReplacementCharacter() {
535 zeroOriginatingReplacementCharacter();
538 void nsHtml5TreeBuilder::eof() {
543 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
548 appendHtmlElementToDocumentAndPush();
553 appendToCurrentNodeAndPushHeadElement(
554 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
559 while (currentPtr
> 0) {
565 case IN_HEAD_NOSCRIPT
: {
566 while (currentPtr
> 1) {
573 appendToCurrentNodeAndPushBodyElement();
580 case IN_SELECT_IN_TABLE
:
582 case IN_COLUMN_GROUP
:
587 if (isTemplateModeStackEmpty()) {
588 NS_HTML5_BREAK(eofloop
);
593 int32_t eltPos
= findLast(nsGkAtoms::_template
);
594 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
595 MOZ_ASSERT(fragment
);
596 NS_HTML5_BREAK(eofloop
);
598 if (MOZ_UNLIKELY(mViewSource
)) {
599 errListUnclosedStartTags(0);
601 while (currentPtr
>= eltPos
) {
604 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
606 resetTheInsertionMode();
610 if (originalMode
== AFTER_HEAD
) {
618 NS_HTML5_BREAK(eofloop
);
622 case AFTER_AFTER_BODY
:
623 case AFTER_AFTER_FRAMESET
:
625 NS_HTML5_BREAK(eofloop
);
630 while (currentPtr
> 0) {
638 void nsHtml5TreeBuilder::endTokenization() {
639 formPointer
= nullptr;
640 headPointer
= nullptr;
641 contextName
= nullptr;
642 contextNode
= nullptr;
643 templateModeStack
= nullptr;
645 while (currentPtr
> -1) {
646 stack
[currentPtr
]->release(this);
651 if (listOfActiveFormattingElements
) {
652 while (listPtr
> -1) {
653 if (listOfActiveFormattingElements
[listPtr
]) {
654 listOfActiveFormattingElements
[listPtr
]->release(this);
658 listOfActiveFormattingElements
= nullptr;
661 for (int32_t i
= 0; i
< numStackNodes
; i
++) {
662 MOZ_ASSERT(stackNodes
[i
]->isUnused());
663 delete stackNodes
[i
];
667 stackNodes
= nullptr;
670 charBuffer
= nullptr;
675 void nsHtml5TreeBuilder::startTag(nsHtml5ElementName
* elementName
,
676 nsHtml5HtmlAttributes
* attributes
,
680 needToDropLF
= false;
683 int32_t group
= elementName
->getGroup();
684 nsAtom
* name
= elementName
->getName();
686 nsHtml5StackNode
* currentNode
= stack
[currentPtr
];
687 int32_t currNs
= currentNode
->ns
;
688 if (!(currentNode
->isHtmlIntegrationPoint() ||
689 (currNs
== kNameSpaceID_MathML
&&
690 ((currentNode
->getGroup() == MI_MO_MN_MS_MTEXT
&&
691 group
!= MGLYPH_OR_MALIGNMARK
) ||
692 (currentNode
->getGroup() == ANNOTATION_XML
&& group
== SVG
))))) {
694 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
695 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
698 case RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR
:
703 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
:
713 if (!(group
== FONT
&&
714 !(attributes
->contains(nsHtml5AttributeName::ATTR_COLOR
) ||
715 attributes
->contains(nsHtml5AttributeName::ATTR_FACE
) ||
716 attributes
->contains(nsHtml5AttributeName::ATTR_SIZE
)))) {
717 errHtmlStartTagInForeignContext(name
);
719 while (!isSpecialParentInForeign(stack
[currentPtr
])) {
722 NS_HTML5_CONTINUE(starttagloop
);
728 if (kNameSpaceID_SVG
== currNs
) {
729 attributes
->adjustForSvg();
731 appendVoidElementToCurrentMayFosterSVG(elementName
, attributes
);
734 appendToCurrentNodeAndPushElementMayFosterSVG(elementName
,
737 attributes
= nullptr;
738 NS_HTML5_BREAK(starttagloop
);
740 attributes
->adjustForMath();
742 appendVoidElementToCurrentMayFosterMathML(elementName
,
746 appendToCurrentNodeAndPushElementMayFosterMathML(elementName
,
749 attributes
= nullptr;
750 NS_HTML5_BREAK(starttagloop
);
761 pushTemplateMode(IN_COLUMN_GROUP
);
762 mode
= IN_COLUMN_GROUP
;
767 case TBODY_OR_THEAD_OR_TFOOT
: {
769 pushTemplateMode(IN_TABLE
);
775 pushTemplateMode(IN_TABLE_BODY
);
776 mode
= IN_TABLE_BODY
;
781 pushTemplateMode(IN_ROW
);
786 checkMetaCharset(attributes
);
787 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
789 attributes
= nullptr;
790 NS_HTML5_BREAK(starttagloop
);
793 startTagTitleInHead(elementName
, attributes
);
794 attributes
= nullptr;
795 NS_HTML5_BREAK(starttagloop
);
798 case LINK_OR_BASEFONT_OR_BGSOUND
: {
799 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
801 attributes
= nullptr;
802 NS_HTML5_BREAK(starttagloop
);
805 startTagScriptInHead(elementName
, attributes
);
806 attributes
= nullptr;
807 NS_HTML5_BREAK(starttagloop
);
811 startTagGenericRawText(elementName
, attributes
);
812 attributes
= nullptr;
813 NS_HTML5_BREAK(starttagloop
);
816 startTagTemplateInHead(elementName
, attributes
);
817 attributes
= nullptr;
818 NS_HTML5_BREAK(starttagloop
);
822 pushTemplateMode(IN_BODY
);
831 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TR
));
832 appendToCurrentNodeAndPushElement(elementName
, attributes
);
835 attributes
= nullptr;
836 NS_HTML5_BREAK(starttagloop
);
841 case TBODY_OR_THEAD_OR_TFOOT
:
843 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
845 MOZ_ASSERT(fragment
|| isTemplateContents());
846 errNoTableRowToClose();
847 NS_HTML5_BREAK(starttagloop
);
849 clearStackBackTo(eltPos
);
851 mode
= IN_TABLE_BODY
;
854 default:; // fall through
858 case IN_TABLE_BODY
: {
862 findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
863 appendToCurrentNodeAndPushElement(elementName
, attributes
);
865 attributes
= nullptr;
866 NS_HTML5_BREAK(starttagloop
);
869 errStartTagInTableBody(name
);
871 findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
872 appendToCurrentNodeAndPushElement(
873 nsHtml5ElementName::ELT_TR
,
874 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
881 case TBODY_OR_THEAD_OR_TFOOT
: {
882 eltPos
= findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
883 if (!eltPos
|| stack
[eltPos
]->getGroup() == TEMPLATE
) {
884 MOZ_ASSERT(fragment
|| isTemplateContents());
885 errStrayStartTag(name
);
886 NS_HTML5_BREAK(starttagloop
);
888 clearStackBackTo(eltPos
);
894 default:; // fall through
902 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
904 appendToCurrentNodeAndPushElement(elementName
, attributes
);
906 attributes
= nullptr;
907 NS_HTML5_BREAK(starttagloop
);
910 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
911 appendToCurrentNodeAndPushElement(elementName
, attributes
);
912 mode
= IN_COLUMN_GROUP
;
913 attributes
= nullptr;
914 NS_HTML5_BREAK(starttagloop
);
917 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
918 appendToCurrentNodeAndPushElement(
919 nsHtml5ElementName::ELT_COLGROUP
,
920 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
921 mode
= IN_COLUMN_GROUP
;
922 NS_HTML5_CONTINUE(starttagloop
);
924 case TBODY_OR_THEAD_OR_TFOOT
: {
925 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
926 appendToCurrentNodeAndPushElement(elementName
, attributes
);
927 mode
= IN_TABLE_BODY
;
928 attributes
= nullptr;
929 NS_HTML5_BREAK(starttagloop
);
933 clearStackBackTo(findLastOrRoot(nsHtml5TreeBuilder::TABLE
));
934 appendToCurrentNodeAndPushElement(
935 nsHtml5ElementName::ELT_TBODY
,
936 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
937 mode
= IN_TABLE_BODY
;
938 NS_HTML5_CONTINUE(starttagloop
);
941 NS_HTML5_BREAK(intableloop
);
944 errTableSeenWhileTableOpen();
945 eltPos
= findLastInTableScope(name
);
946 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
947 MOZ_ASSERT(fragment
|| isTemplateContents());
948 NS_HTML5_BREAK(starttagloop
);
950 generateImpliedEndTags();
951 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(nsGkAtoms::table
)) {
952 errNoCheckUnclosedElementsOnStack();
954 while (currentPtr
>= eltPos
) {
957 resetTheInsertionMode();
958 NS_HTML5_CONTINUE(starttagloop
);
961 appendToCurrentNodeAndPushElement(elementName
, attributes
);
964 tokenizer
->setStateAndEndTagExpectation(
965 nsHtml5Tokenizer::SCRIPT_DATA
, elementName
);
966 attributes
= nullptr;
967 NS_HTML5_BREAK(starttagloop
);
970 appendToCurrentNodeAndPushElement(elementName
, attributes
);
973 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
975 attributes
= nullptr;
976 NS_HTML5_BREAK(starttagloop
);
979 errStartTagInTable(name
);
980 if (!nsHtml5Portability::
981 lowerCaseLiteralEqualsIgnoreAsciiCaseString(
982 "hidden", attributes
->getValue(
983 nsHtml5AttributeName::ATTR_TYPE
))) {
984 NS_HTML5_BREAK(intableloop
);
986 appendVoidInputToCurrent(attributes
, formPointer
);
988 attributes
= nullptr;
989 NS_HTML5_BREAK(starttagloop
);
992 if (!!formPointer
|| isTemplateContents()) {
993 errFormWhenFormOpen();
994 NS_HTML5_BREAK(starttagloop
);
996 errStartTagInTable(name
);
997 appendVoidFormToCurrent(attributes
);
998 attributes
= nullptr;
999 NS_HTML5_BREAK(starttagloop
);
1003 errStartTagInTable(name
);
1004 NS_HTML5_BREAK(intableloop
);
1016 case TBODY_OR_THEAD_OR_TFOOT
:
1019 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
1020 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1021 MOZ_ASSERT(fragment
|| isTemplateContents());
1022 errStrayStartTag(name
);
1023 NS_HTML5_BREAK(starttagloop
);
1025 generateImpliedEndTags();
1026 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
1027 errNoCheckUnclosedElementsOnStack();
1029 while (currentPtr
>= eltPos
) {
1032 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
1036 default:; // fall through
1045 case TBODY_OR_THEAD_OR_TFOOT
:
1048 eltPos
= findLastInTableScopeTdTh();
1049 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1051 NS_HTML5_BREAK(starttagloop
);
1053 closeTheCell(eltPos
);
1057 default:; // fall through
1064 if (mode
== FRAMESET_OK
) {
1065 if (!currentPtr
|| stack
[1]->getGroup() != BODY
) {
1066 MOZ_ASSERT(fragment
|| isTemplateContents());
1067 errStrayStartTag(name
);
1068 NS_HTML5_BREAK(starttagloop
);
1071 detachFromParent(stack
[1]->node
);
1072 while (currentPtr
> 0) {
1075 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1077 attributes
= nullptr;
1078 NS_HTML5_BREAK(starttagloop
);
1081 errStrayStartTag(name
);
1082 NS_HTML5_BREAK(starttagloop
);
1085 case PRE_OR_LISTING
:
1089 case MARQUEE_OR_APPLET
:
1103 if (mode
== FRAMESET_OK
&&
1105 nsHtml5Portability::
1106 lowerCaseLiteralEqualsIgnoreAsciiCaseString(
1107 "hidden", attributes
->getValue(
1108 nsHtml5AttributeName::ATTR_TYPE
)))) {
1114 default:; // fall through
1122 errStrayStartTag(name
);
1123 if (!fragment
&& !isTemplateContents()) {
1124 addAttributesToHtml(attributes
);
1125 attributes
= nullptr;
1127 NS_HTML5_BREAK(starttagloop
);
1130 case LINK_OR_BASEFONT_OR_BGSOUND
:
1136 NS_HTML5_BREAK(inbodyloop
);
1139 if (!currentPtr
|| stack
[1]->getGroup() != BODY
||
1140 isTemplateContents()) {
1141 MOZ_ASSERT(fragment
|| isTemplateContents());
1142 errStrayStartTag(name
);
1143 NS_HTML5_BREAK(starttagloop
);
1145 errFooSeenWhenFooOpen(name
);
1147 if (mode
== FRAMESET_OK
) {
1150 if (addAttributesToBody(attributes
)) {
1151 attributes
= nullptr;
1153 NS_HTML5_BREAK(starttagloop
);
1156 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
1157 case UL_OR_OL_OR_DL
:
1158 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_SEARCH_OR_SECTION_OR_SUMMARY
: {
1160 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1162 attributes
= nullptr;
1163 NS_HTML5_BREAK(starttagloop
);
1165 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
: {
1167 if (stack
[currentPtr
]->getGroup() ==
1168 H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
) {
1169 errHeadingWhenHeadingOpen();
1172 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1174 attributes
= nullptr;
1175 NS_HTML5_BREAK(starttagloop
);
1179 appendToCurrentNodeAndPushElementMayFoster(
1180 elementName
, attributes
, formPointer
);
1181 attributes
= nullptr;
1182 NS_HTML5_BREAK(starttagloop
);
1184 case PRE_OR_LISTING
: {
1186 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1188 needToDropLF
= true;
1189 attributes
= nullptr;
1190 NS_HTML5_BREAK(starttagloop
);
1193 if (!!formPointer
&& !isTemplateContents()) {
1194 errFormWhenFormOpen();
1195 NS_HTML5_BREAK(starttagloop
);
1198 appendToCurrentNodeAndPushFormElementMayFoster(attributes
);
1199 attributes
= nullptr;
1200 NS_HTML5_BREAK(starttagloop
);
1205 eltPos
= currentPtr
;
1207 nsHtml5StackNode
* node
= stack
[eltPos
];
1208 if (node
->getGroup() == group
) {
1209 generateImpliedEndTagsExceptFor(node
->name
);
1210 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
1211 errUnclosedElementsImplied(eltPos
, name
);
1213 while (currentPtr
>= eltPos
) {
1217 } else if (!eltPos
|| (node
->isSpecial() &&
1218 (node
->ns
!= kNameSpaceID_XHTML
||
1219 (node
->name
!= nsGkAtoms::p
&&
1220 node
->name
!= nsGkAtoms::address
&&
1221 node
->name
!= nsGkAtoms::div
)))) {
1227 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1229 attributes
= nullptr;
1230 NS_HTML5_BREAK(starttagloop
);
1234 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1236 tokenizer
->setStateAndEndTagExpectation(
1237 nsHtml5Tokenizer::PLAINTEXT
, elementName
);
1238 attributes
= nullptr;
1239 NS_HTML5_BREAK(starttagloop
);
1242 int32_t activeAPos
=
1243 findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(
1245 if (activeAPos
!= -1) {
1246 errFooSeenWhenFooOpen(name
);
1247 nsHtml5StackNode
* activeA
=
1248 listOfActiveFormattingElements
[activeAPos
];
1250 adoptionAgencyEndTag(nsGkAtoms::a
);
1251 removeFromStack(activeA
);
1252 activeAPos
= findInListOfActiveFormattingElements(activeA
);
1253 if (activeAPos
!= -1) {
1254 removeFromListOfActiveFormattingElements(activeAPos
);
1256 activeA
->release(this);
1258 reconstructTheActiveFormattingElements();
1259 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1261 attributes
= nullptr;
1262 NS_HTML5_BREAK(starttagloop
);
1264 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
1266 reconstructTheActiveFormattingElements();
1267 maybeForgetEarlierDuplicateFormattingElement(
1268 elementName
->getName(), attributes
);
1269 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1271 attributes
= nullptr;
1272 NS_HTML5_BREAK(starttagloop
);
1275 reconstructTheActiveFormattingElements();
1276 if (nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
!=
1277 findLastInScope(nsGkAtoms::nobr
)) {
1278 errFooSeenWhenFooOpen(name
);
1279 adoptionAgencyEndTag(nsGkAtoms::nobr
);
1280 reconstructTheActiveFormattingElements();
1282 appendToCurrentNodeAndPushFormattingElementMayFoster(elementName
,
1284 attributes
= nullptr;
1285 NS_HTML5_BREAK(starttagloop
);
1288 eltPos
= findLastInScope(name
);
1289 if (eltPos
!= nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1290 errFooSeenWhenFooOpen(name
);
1291 generateImpliedEndTags();
1292 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
1293 errUnclosedElementsImplied(eltPos
, name
);
1295 while (currentPtr
>= eltPos
) {
1298 NS_HTML5_CONTINUE(starttagloop
);
1300 reconstructTheActiveFormattingElements();
1301 appendToCurrentNodeAndPushElementMayFoster(
1302 elementName
, attributes
, formPointer
);
1303 attributes
= nullptr;
1304 NS_HTML5_BREAK(starttagloop
);
1308 reconstructTheActiveFormattingElements();
1309 appendToCurrentNodeAndPushElementMayFoster(
1310 elementName
, attributes
, formPointer
);
1312 attributes
= nullptr;
1313 NS_HTML5_BREAK(starttagloop
);
1315 case MARQUEE_OR_APPLET
: {
1316 reconstructTheActiveFormattingElements();
1317 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1320 attributes
= nullptr;
1321 NS_HTML5_BREAK(starttagloop
);
1327 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1330 attributes
= nullptr;
1331 NS_HTML5_BREAK(starttagloop
);
1337 reconstructTheActiveFormattingElements();
1340 case PARAM_OR_SOURCE_OR_TRACK
: {
1341 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1342 selfClosing
= false;
1343 attributes
= nullptr;
1344 NS_HTML5_BREAK(starttagloop
);
1348 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1349 selfClosing
= false;
1350 attributes
= nullptr;
1351 NS_HTML5_BREAK(starttagloop
);
1355 elementName
= nsHtml5ElementName::ELT_IMG
;
1356 NS_HTML5_CONTINUE(starttagloop
);
1360 reconstructTheActiveFormattingElements();
1361 appendVoidElementToCurrentMayFoster(elementName
, attributes
,
1363 selfClosing
= false;
1364 attributes
= nullptr;
1365 NS_HTML5_BREAK(starttagloop
);
1368 appendToCurrentNodeAndPushElementMayFoster(
1369 elementName
, attributes
, formPointer
);
1370 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
1372 originalMode
= mode
;
1374 needToDropLF
= true;
1375 attributes
= nullptr;
1376 NS_HTML5_BREAK(starttagloop
);
1380 reconstructTheActiveFormattingElements();
1381 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1383 originalMode
= mode
;
1385 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1387 attributes
= nullptr;
1388 NS_HTML5_BREAK(starttagloop
);
1391 if (!scriptingEnabled
) {
1392 reconstructTheActiveFormattingElements();
1393 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1395 attributes
= nullptr;
1396 NS_HTML5_BREAK(starttagloop
);
1403 startTagGenericRawText(elementName
, attributes
);
1404 attributes
= nullptr;
1405 NS_HTML5_BREAK(starttagloop
);
1408 reconstructTheActiveFormattingElements();
1409 appendToCurrentNodeAndPushElementMayFoster(
1410 elementName
, attributes
, formPointer
);
1414 case IN_COLUMN_GROUP
:
1418 mode
= IN_SELECT_IN_TABLE
;
1426 attributes
= nullptr;
1427 NS_HTML5_BREAK(starttagloop
);
1431 if (isCurrent(nsGkAtoms::option
)) {
1434 reconstructTheActiveFormattingElements();
1435 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1437 attributes
= nullptr;
1438 NS_HTML5_BREAK(starttagloop
);
1441 eltPos
= findLastInScope(nsGkAtoms::ruby
);
1442 if (eltPos
!= NOT_FOUND_ON_STACK
) {
1443 generateImpliedEndTags();
1445 if (eltPos
!= currentPtr
) {
1446 if (eltPos
== NOT_FOUND_ON_STACK
) {
1447 errStartTagSeenWithoutRuby(name
);
1449 errUnclosedChildrenInRuby();
1452 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1454 attributes
= nullptr;
1455 NS_HTML5_BREAK(starttagloop
);
1458 eltPos
= findLastInScope(nsGkAtoms::ruby
);
1459 if (eltPos
!= NOT_FOUND_ON_STACK
) {
1460 generateImpliedEndTagsExceptFor(nsGkAtoms::rtc
);
1462 if (eltPos
!= currentPtr
) {
1463 if (!isCurrent(nsGkAtoms::rtc
)) {
1464 if (eltPos
== NOT_FOUND_ON_STACK
) {
1465 errStartTagSeenWithoutRuby(name
);
1467 errUnclosedChildrenInRuby();
1471 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1473 attributes
= nullptr;
1474 NS_HTML5_BREAK(starttagloop
);
1477 reconstructTheActiveFormattingElements();
1478 attributes
->adjustForMath();
1480 appendVoidElementToCurrentMayFosterMathML(elementName
,
1482 selfClosing
= false;
1484 appendToCurrentNodeAndPushElementMayFosterMathML(elementName
,
1487 attributes
= nullptr;
1488 NS_HTML5_BREAK(starttagloop
);
1491 reconstructTheActiveFormattingElements();
1492 attributes
->adjustForSvg();
1494 appendVoidElementToCurrentMayFosterSVG(elementName
, attributes
);
1495 selfClosing
= false;
1497 appendToCurrentNodeAndPushElementMayFosterSVG(elementName
,
1500 attributes
= nullptr;
1501 NS_HTML5_BREAK(starttagloop
);
1506 case TBODY_OR_THEAD_OR_TFOOT
:
1512 errStrayStartTag(name
);
1513 NS_HTML5_BREAK(starttagloop
);
1516 reconstructTheActiveFormattingElements();
1517 appendToCurrentNodeAndPushElementMayFoster(
1518 elementName
, attributes
, formPointer
);
1519 attributes
= nullptr;
1520 NS_HTML5_BREAK(starttagloop
);
1523 reconstructTheActiveFormattingElements();
1524 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1526 attributes
= nullptr;
1527 NS_HTML5_BREAK(starttagloop
);
1538 errStrayStartTag(name
);
1539 if (!fragment
&& !isTemplateContents()) {
1540 addAttributesToHtml(attributes
);
1541 attributes
= nullptr;
1543 NS_HTML5_BREAK(starttagloop
);
1546 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1547 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1548 selfClosing
= false;
1549 attributes
= nullptr;
1550 NS_HTML5_BREAK(starttagloop
);
1553 NS_HTML5_BREAK(inheadloop
);
1556 startTagTitleInHead(elementName
, attributes
);
1557 attributes
= nullptr;
1558 NS_HTML5_BREAK(starttagloop
);
1561 if (scriptingEnabled
) {
1562 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1563 originalMode
= mode
;
1565 tokenizer
->setStateAndEndTagExpectation(
1566 nsHtml5Tokenizer::RAWTEXT
, elementName
);
1568 appendToCurrentNodeAndPushElementMayFoster(elementName
,
1570 mode
= IN_HEAD_NOSCRIPT
;
1572 attributes
= nullptr;
1573 NS_HTML5_BREAK(starttagloop
);
1576 startTagScriptInHead(elementName
, attributes
);
1577 attributes
= nullptr;
1578 NS_HTML5_BREAK(starttagloop
);
1582 startTagGenericRawText(elementName
, attributes
);
1583 attributes
= nullptr;
1584 NS_HTML5_BREAK(starttagloop
);
1587 errFooSeenWhenFooOpen(name
);
1588 NS_HTML5_BREAK(starttagloop
);
1591 startTagTemplateInHead(elementName
, attributes
);
1592 attributes
= nullptr;
1593 NS_HTML5_BREAK(starttagloop
);
1598 NS_HTML5_CONTINUE(starttagloop
);
1605 case IN_HEAD_NOSCRIPT
: {
1608 errStrayStartTag(name
);
1609 if (!fragment
&& !isTemplateContents()) {
1610 addAttributesToHtml(attributes
);
1611 attributes
= nullptr;
1613 NS_HTML5_BREAK(starttagloop
);
1615 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1616 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1617 selfClosing
= false;
1618 attributes
= nullptr;
1619 NS_HTML5_BREAK(starttagloop
);
1622 checkMetaCharset(attributes
);
1623 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1624 selfClosing
= false;
1625 attributes
= nullptr;
1626 NS_HTML5_BREAK(starttagloop
);
1630 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1631 originalMode
= mode
;
1633 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1635 attributes
= nullptr;
1636 NS_HTML5_BREAK(starttagloop
);
1639 errFooSeenWhenFooOpen(name
);
1640 NS_HTML5_BREAK(starttagloop
);
1643 errFooSeenWhenFooOpen(name
);
1644 NS_HTML5_BREAK(starttagloop
);
1647 errBadStartTagInNoscriptInHead(name
);
1654 case IN_COLUMN_GROUP
: {
1657 errStrayStartTag(name
);
1658 if (!fragment
&& !isTemplateContents()) {
1659 addAttributesToHtml(attributes
);
1660 attributes
= nullptr;
1662 NS_HTML5_BREAK(starttagloop
);
1665 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1666 selfClosing
= false;
1667 attributes
= nullptr;
1668 NS_HTML5_BREAK(starttagloop
);
1671 startTagTemplateInHead(elementName
, attributes
);
1672 attributes
= nullptr;
1673 NS_HTML5_BREAK(starttagloop
);
1676 if (!currentPtr
|| stack
[currentPtr
]->getGroup() == TEMPLATE
) {
1677 MOZ_ASSERT(fragment
|| isTemplateContents());
1678 errGarbageInColgroup();
1679 NS_HTML5_BREAK(starttagloop
);
1687 case IN_SELECT_IN_TABLE
: {
1690 case TBODY_OR_THEAD_OR_TFOOT
:
1694 errStartTagWithSelectOpen(name
);
1695 eltPos
= findLastInTableScope(nsGkAtoms::select
);
1696 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1697 MOZ_ASSERT(fragment
);
1698 NS_HTML5_BREAK(starttagloop
);
1700 while (currentPtr
>= eltPos
) {
1703 resetTheInsertionMode();
1706 default:; // fall through
1713 errStrayStartTag(name
);
1715 addAttributesToHtml(attributes
);
1716 attributes
= nullptr;
1718 NS_HTML5_BREAK(starttagloop
);
1721 if (isCurrent(nsGkAtoms::option
)) {
1724 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1725 attributes
= nullptr;
1726 NS_HTML5_BREAK(starttagloop
);
1729 if (isCurrent(nsGkAtoms::option
)) {
1732 if (isCurrent(nsGkAtoms::optgroup
)) {
1735 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1736 attributes
= nullptr;
1737 NS_HTML5_BREAK(starttagloop
);
1740 errStartSelectWhereEndSelectExpected();
1741 eltPos
= findLastInTableScope(name
);
1742 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1743 MOZ_ASSERT(fragment
);
1744 errNoSelectInTableScope();
1745 NS_HTML5_BREAK(starttagloop
);
1747 while (currentPtr
>= eltPos
) {
1750 resetTheInsertionMode();
1751 NS_HTML5_BREAK(starttagloop
);
1756 errStartTagWithSelectOpen(name
);
1757 eltPos
= findLastInTableScope(nsGkAtoms::select
);
1758 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
1759 MOZ_ASSERT(fragment
);
1760 NS_HTML5_BREAK(starttagloop
);
1762 while (currentPtr
>= eltPos
) {
1765 resetTheInsertionMode();
1769 startTagScriptInHead(elementName
, attributes
);
1770 attributes
= nullptr;
1771 NS_HTML5_BREAK(starttagloop
);
1774 startTagTemplateInHead(elementName
, attributes
);
1775 attributes
= nullptr;
1776 NS_HTML5_BREAK(starttagloop
);
1779 if (isCurrent(nsGkAtoms::option
)) {
1782 if (isCurrent(nsGkAtoms::optgroup
)) {
1785 appendVoidElementToCurrent(elementName
, attributes
);
1786 selfClosing
= false;
1787 attributes
= nullptr;
1788 NS_HTML5_BREAK(starttagloop
);
1791 errStrayStartTag(name
);
1792 NS_HTML5_BREAK(starttagloop
);
1799 errStrayStartTag(name
);
1800 if (!fragment
&& !isTemplateContents()) {
1801 addAttributesToHtml(attributes
);
1802 attributes
= nullptr;
1804 NS_HTML5_BREAK(starttagloop
);
1807 errStrayStartTag(name
);
1808 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
1816 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1817 attributes
= nullptr;
1818 NS_HTML5_BREAK(starttagloop
);
1821 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1822 selfClosing
= false;
1823 attributes
= nullptr;
1824 NS_HTML5_BREAK(starttagloop
);
1826 default:; // fall through
1830 case AFTER_FRAMESET
: {
1833 errStrayStartTag(name
);
1834 if (!fragment
&& !isTemplateContents()) {
1835 addAttributesToHtml(attributes
);
1836 attributes
= nullptr;
1838 NS_HTML5_BREAK(starttagloop
);
1841 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1842 originalMode
= mode
;
1844 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1846 attributes
= nullptr;
1847 NS_HTML5_BREAK(starttagloop
);
1850 errStrayStartTag(name
);
1851 NS_HTML5_BREAK(starttagloop
);
1856 errStartTagWithoutDoctype();
1857 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
1864 if (attributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
1865 appendHtmlElementToDocumentAndPush();
1867 appendHtmlElementToDocumentAndPush(attributes
);
1870 attributes
= nullptr;
1871 NS_HTML5_BREAK(starttagloop
);
1874 appendHtmlElementToDocumentAndPush();
1883 errStrayStartTag(name
);
1884 if (!fragment
&& !isTemplateContents()) {
1885 addAttributesToHtml(attributes
);
1886 attributes
= nullptr;
1888 NS_HTML5_BREAK(starttagloop
);
1891 appendToCurrentNodeAndPushHeadElement(attributes
);
1893 attributes
= nullptr;
1894 NS_HTML5_BREAK(starttagloop
);
1897 appendToCurrentNodeAndPushHeadElement(
1898 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
1907 errStrayStartTag(name
);
1908 if (!fragment
&& !isTemplateContents()) {
1909 addAttributesToHtml(attributes
);
1910 attributes
= nullptr;
1912 NS_HTML5_BREAK(starttagloop
);
1915 if (!attributes
->getLength()) {
1916 appendToCurrentNodeAndPushBodyElement();
1918 appendToCurrentNodeAndPushBodyElement(attributes
);
1922 attributes
= nullptr;
1923 NS_HTML5_BREAK(starttagloop
);
1926 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1928 attributes
= nullptr;
1929 NS_HTML5_BREAK(starttagloop
);
1932 errFooBetweenHeadAndBody(name
);
1933 pushHeadPointerOntoStack();
1934 nsHtml5StackNode
* headOnStack
= stack
[currentPtr
];
1935 startTagTemplateInHead(elementName
, attributes
);
1936 removeFromStack(headOnStack
);
1937 attributes
= nullptr;
1938 NS_HTML5_BREAK(starttagloop
);
1941 case LINK_OR_BASEFONT_OR_BGSOUND
: {
1942 errFooBetweenHeadAndBody(name
);
1943 pushHeadPointerOntoStack();
1944 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1945 selfClosing
= false;
1947 attributes
= nullptr;
1948 NS_HTML5_BREAK(starttagloop
);
1951 errFooBetweenHeadAndBody(name
);
1952 checkMetaCharset(attributes
);
1953 pushHeadPointerOntoStack();
1954 appendVoidElementToCurrentMayFoster(elementName
, attributes
);
1955 selfClosing
= false;
1957 attributes
= nullptr;
1958 NS_HTML5_BREAK(starttagloop
);
1961 errFooBetweenHeadAndBody(name
);
1962 pushHeadPointerOntoStack();
1963 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1964 originalMode
= mode
;
1966 tokenizer
->setStateAndEndTagExpectation(
1967 nsHtml5Tokenizer::SCRIPT_DATA
, elementName
);
1968 attributes
= nullptr;
1969 NS_HTML5_BREAK(starttagloop
);
1973 errFooBetweenHeadAndBody(name
);
1974 pushHeadPointerOntoStack();
1975 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1976 originalMode
= mode
;
1978 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
1980 attributes
= nullptr;
1981 NS_HTML5_BREAK(starttagloop
);
1984 errFooBetweenHeadAndBody(name
);
1985 pushHeadPointerOntoStack();
1986 appendToCurrentNodeAndPushElement(elementName
, attributes
);
1987 originalMode
= mode
;
1989 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
1991 attributes
= nullptr;
1992 NS_HTML5_BREAK(starttagloop
);
1995 errStrayStartTag(name
);
1996 NS_HTML5_BREAK(starttagloop
);
1999 appendToCurrentNodeAndPushBodyElement();
2005 case AFTER_AFTER_BODY
: {
2008 errStrayStartTag(name
);
2009 if (!fragment
&& !isTemplateContents()) {
2010 addAttributesToHtml(attributes
);
2011 attributes
= nullptr;
2013 NS_HTML5_BREAK(starttagloop
);
2016 errStrayStartTag(name
);
2018 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
2023 case AFTER_AFTER_FRAMESET
: {
2026 errStrayStartTag(name
);
2027 if (!fragment
&& !isTemplateContents()) {
2028 addAttributesToHtml(attributes
);
2029 attributes
= nullptr;
2031 NS_HTML5_BREAK(starttagloop
);
2034 startTagGenericRawText(elementName
, attributes
);
2035 attributes
= nullptr;
2036 NS_HTML5_BREAK(starttagloop
);
2039 errStrayStartTag(name
);
2040 NS_HTML5_BREAK(starttagloop
);
2046 NS_HTML5_BREAK(starttagloop
);
2054 if (!mBuilder
&& attributes
!= nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
2059 void nsHtml5TreeBuilder::startTagTitleInHead(
2060 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2061 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2062 originalMode
= mode
;
2064 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RCDATA
,
2068 void nsHtml5TreeBuilder::startTagGenericRawText(
2069 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2070 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2071 originalMode
= mode
;
2073 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::RAWTEXT
,
2077 void nsHtml5TreeBuilder::startTagScriptInHead(
2078 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2079 appendToCurrentNodeAndPushElementMayFoster(elementName
, attributes
);
2080 originalMode
= mode
;
2082 tokenizer
->setStateAndEndTagExpectation(nsHtml5Tokenizer::SCRIPT_DATA
,
2086 void nsHtml5TreeBuilder::startTagTemplateInHead(
2087 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
2088 appendToCurrentNodeAndPushElement(elementName
, attributes
);
2091 originalMode
= mode
;
2093 pushTemplateMode(IN_TEMPLATE
);
2096 bool nsHtml5TreeBuilder::isTemplateContents() {
2097 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
!=
2098 findLast(nsGkAtoms::_template
);
2101 bool nsHtml5TreeBuilder::isTemplateModeStackEmpty() {
2102 return templateModePtr
== -1;
2105 bool nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode
* stackNode
) {
2106 int32_t ns
= stackNode
->ns
;
2107 return (kNameSpaceID_XHTML
== ns
) || (stackNode
->isHtmlIntegrationPoint()) ||
2108 ((kNameSpaceID_MathML
== ns
) &&
2109 (stackNode
->getGroup() == MI_MO_MN_MS_MTEXT
));
2112 nsIContentHandle
* nsHtml5TreeBuilder::getDeclarativeShadowRoot(
2113 nsIContentHandle
* currentNode
, nsIContentHandle
* templateNode
,
2114 nsHtml5HtmlAttributes
* attributes
) {
2115 if (!isAllowDeclarativeShadowRoots()) {
2118 nsHtml5String shadowRootMode
=
2119 attributes
->getValue(nsHtml5AttributeName::ATTR_SHADOWROOTMODE
);
2120 if (!shadowRootMode
) {
2123 bool shadowRootIsClonable
=
2124 attributes
->contains(nsHtml5AttributeName::ATTR_SHADOWROOTCLONABLE
);
2125 bool shadowRootIsSerializable
=
2126 attributes
->contains(nsHtml5AttributeName::ATTR_SHADOWROOTSERIALIZABLE
);
2127 bool shadowRootDelegatesFocus
=
2128 attributes
->contains(nsHtml5AttributeName::ATTR_SHADOWROOTDELEGATESFOCUS
);
2129 return getShadowRootFromHost(currentNode
, templateNode
, shadowRootMode
,
2130 shadowRootIsClonable
, shadowRootIsSerializable
,
2131 shadowRootDelegatesFocus
);
2134 nsHtml5String
nsHtml5TreeBuilder::extractCharsetFromContent(
2135 nsHtml5String attributeValue
, nsHtml5TreeBuilder
* tb
) {
2136 int32_t charsetState
= CHARSET_INITIAL
;
2139 autoJArray
<char16_t
, int32_t> buffer
=
2140 nsHtml5Portability::newCharArrayFromString(attributeValue
);
2141 for (int32_t i
= 0; i
< buffer
.length
; i
++) {
2142 char16_t c
= buffer
[i
];
2143 switch (charsetState
) {
2144 case CHARSET_INITIAL
: {
2148 charsetState
= CHARSET_C
;
2160 charsetState
= CHARSET_H
;
2164 charsetState
= CHARSET_INITIAL
;
2173 charsetState
= CHARSET_A
;
2177 charsetState
= CHARSET_INITIAL
;
2186 charsetState
= CHARSET_R
;
2190 charsetState
= CHARSET_INITIAL
;
2199 charsetState
= CHARSET_S
;
2203 charsetState
= CHARSET_INITIAL
;
2212 charsetState
= CHARSET_E
;
2216 charsetState
= CHARSET_INITIAL
;
2225 charsetState
= CHARSET_T
;
2229 charsetState
= CHARSET_INITIAL
;
2244 charsetState
= CHARSET_EQUALS
;
2252 case CHARSET_EQUALS
: {
2263 charsetState
= CHARSET_SINGLE_QUOTED
;
2268 charsetState
= CHARSET_DOUBLE_QUOTED
;
2273 charsetState
= CHARSET_UNQUOTED
;
2278 case CHARSET_SINGLE_QUOTED
: {
2282 NS_HTML5_BREAK(charsetloop
);
2289 case CHARSET_DOUBLE_QUOTED
: {
2293 NS_HTML5_BREAK(charsetloop
);
2300 case CHARSET_UNQUOTED
: {
2309 NS_HTML5_BREAK(charsetloop
);
2321 if (charsetState
== CHARSET_UNQUOTED
) {
2322 end
= buffer
.length
;
2327 return nsHtml5Portability::newStringFromBuffer(buffer
, start
, end
- start
,
2333 void nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes
* attributes
) {
2334 nsHtml5String charset
=
2335 attributes
->getValue(nsHtml5AttributeName::ATTR_CHARSET
);
2337 if (tokenizer
->internalEncodingDeclaration(charset
)) {
2338 requestSuspension();
2343 if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
2345 attributes
->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV
))) {
2348 nsHtml5String content
=
2349 attributes
->getValue(nsHtml5AttributeName::ATTR_CONTENT
);
2351 nsHtml5String extract
=
2352 nsHtml5TreeBuilder::extractCharsetFromContent(content
, this);
2354 if (tokenizer
->internalEncodingDeclaration(extract
)) {
2355 requestSuspension();
2362 void nsHtml5TreeBuilder::endTag(nsHtml5ElementName
* elementName
) {
2364 needToDropLF
= false;
2366 int32_t group
= elementName
->getGroup();
2367 nsAtom
* name
= elementName
->getName();
2369 if (isInForeign()) {
2370 if (stack
[currentPtr
]->name
!= name
) {
2372 errStrayEndTag(name
);
2374 errEndTagDidNotMatchCurrentOpenElement(name
,
2375 stack
[currentPtr
]->popName
);
2378 eltPos
= currentPtr
;
2379 int32_t origPos
= currentPtr
;
2382 MOZ_ASSERT(fragment
,
2383 "We can get this close to the root of the stack in "
2384 "foreign content only in the fragment case.");
2385 NS_HTML5_BREAK(endtagloop
);
2387 if (stack
[eltPos
]->name
== name
) {
2388 while (currentPtr
>= eltPos
) {
2389 popForeign(origPos
, eltPos
);
2391 NS_HTML5_BREAK(endtagloop
);
2393 if (stack
[--eltPos
]->ns
== kNameSpaceID_XHTML
) {
2405 errStrayEndTag(name
);
2406 NS_HTML5_BREAK(endtagloop
);
2414 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2416 MOZ_ASSERT(fragment
|| isTemplateContents());
2417 errNoTableRowToClose();
2418 NS_HTML5_BREAK(endtagloop
);
2420 clearStackBackTo(eltPos
);
2422 mode
= IN_TABLE_BODY
;
2423 NS_HTML5_BREAK(endtagloop
);
2426 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2428 MOZ_ASSERT(fragment
|| isTemplateContents());
2429 errNoTableRowToClose();
2430 NS_HTML5_BREAK(endtagloop
);
2432 clearStackBackTo(eltPos
);
2434 mode
= IN_TABLE_BODY
;
2437 case TBODY_OR_THEAD_OR_TFOOT
: {
2438 if (findLastInTableScope(name
) ==
2439 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2440 errStrayEndTag(name
);
2441 NS_HTML5_BREAK(endtagloop
);
2443 eltPos
= findLastOrRoot(nsHtml5TreeBuilder::TR
);
2445 MOZ_ASSERT(fragment
|| isTemplateContents());
2446 errNoTableRowToClose();
2447 NS_HTML5_BREAK(endtagloop
);
2449 clearStackBackTo(eltPos
);
2451 mode
= IN_TABLE_BODY
;
2460 errStrayEndTag(name
);
2461 NS_HTML5_BREAK(endtagloop
);
2463 default:; // fall through
2467 case IN_TABLE_BODY
: {
2469 case TBODY_OR_THEAD_OR_TFOOT
: {
2470 eltPos
= findLastOrRoot(name
);
2472 errStrayEndTag(name
);
2473 NS_HTML5_BREAK(endtagloop
);
2475 clearStackBackTo(eltPos
);
2478 NS_HTML5_BREAK(endtagloop
);
2481 eltPos
= findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
2482 if (!eltPos
|| stack
[eltPos
]->getGroup() == TEMPLATE
) {
2483 MOZ_ASSERT(fragment
|| isTemplateContents());
2484 errStrayEndTag(name
);
2485 NS_HTML5_BREAK(endtagloop
);
2487 clearStackBackTo(eltPos
);
2499 errStrayEndTag(name
);
2500 NS_HTML5_BREAK(endtagloop
);
2502 default:; // fall through
2509 eltPos
= findLast(nsGkAtoms::table
);
2510 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2511 MOZ_ASSERT(fragment
|| isTemplateContents());
2512 errStrayEndTag(name
);
2513 NS_HTML5_BREAK(endtagloop
);
2515 while (currentPtr
>= eltPos
) {
2518 resetTheInsertionMode();
2519 NS_HTML5_BREAK(endtagloop
);
2526 case TBODY_OR_THEAD_OR_TFOOT
:
2529 errStrayEndTag(name
);
2530 NS_HTML5_BREAK(endtagloop
);
2536 errStrayEndTag(name
);
2544 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
2545 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2546 NS_HTML5_BREAK(endtagloop
);
2548 generateImpliedEndTags();
2549 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
2550 errUnclosedElements(eltPos
, name
);
2552 while (currentPtr
>= eltPos
) {
2555 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2557 NS_HTML5_BREAK(endtagloop
);
2560 eltPos
= findLastInTableScope(nsGkAtoms::caption
);
2561 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2562 MOZ_ASSERT(fragment
|| isTemplateContents());
2563 errStrayEndTag(name
);
2564 NS_HTML5_BREAK(endtagloop
);
2566 generateImpliedEndTags();
2567 if (!!MOZ_UNLIKELY(mViewSource
) && currentPtr
!= eltPos
) {
2568 errUnclosedElements(eltPos
, name
);
2570 while (currentPtr
>= eltPos
) {
2573 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2581 case TBODY_OR_THEAD_OR_TFOOT
:
2584 errStrayEndTag(name
);
2585 NS_HTML5_BREAK(endtagloop
);
2587 default:; // fall through
2594 eltPos
= findLastInTableScope(name
);
2595 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2596 errStrayEndTag(name
);
2597 NS_HTML5_BREAK(endtagloop
);
2599 generateImpliedEndTags();
2600 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2601 errUnclosedElements(eltPos
, name
);
2603 while (currentPtr
>= eltPos
) {
2606 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2608 NS_HTML5_BREAK(endtagloop
);
2611 case TBODY_OR_THEAD_OR_TFOOT
:
2613 if (findLastInTableScope(name
) ==
2614 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2615 MOZ_ASSERT(name
== nsGkAtoms::tbody
|| name
== nsGkAtoms::tfoot
||
2616 name
== nsGkAtoms::thead
|| fragment
||
2617 isTemplateContents());
2618 errStrayEndTag(name
);
2619 NS_HTML5_BREAK(endtagloop
);
2621 closeTheCell(findLastInTableScopeTdTh());
2629 errStrayEndTag(name
);
2630 NS_HTML5_BREAK(endtagloop
);
2632 default:; // fall through
2640 if (!isSecondOnStackBody()) {
2641 MOZ_ASSERT(fragment
|| isTemplateContents());
2642 errStrayEndTag(name
);
2643 NS_HTML5_BREAK(endtagloop
);
2645 MOZ_ASSERT(currentPtr
>= 1);
2646 if (MOZ_UNLIKELY(mViewSource
)) {
2647 for (int32_t i
= 2; i
<= currentPtr
; i
++) {
2648 switch (stack
[i
]->getGroup()) {
2657 case TBODY_OR_THEAD_OR_TFOOT
: {
2661 errEndWithUnclosedElements(name
);
2662 NS_HTML5_BREAK(uncloseloop1
);
2669 NS_HTML5_BREAK(endtagloop
);
2672 if (!isSecondOnStackBody()) {
2673 MOZ_ASSERT(fragment
|| isTemplateContents());
2674 errStrayEndTag(name
);
2675 NS_HTML5_BREAK(endtagloop
);
2677 if (MOZ_UNLIKELY(mViewSource
)) {
2678 for (int32_t i
= 0; i
<= currentPtr
; i
++) {
2679 switch (stack
[i
]->getGroup()) {
2685 case TBODY_OR_THEAD_OR_TFOOT
:
2692 errEndWithUnclosedElements(name
);
2693 NS_HTML5_BREAK(uncloseloop2
);
2702 case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU
:
2703 case UL_OR_OL_OR_DL
:
2704 case PRE_OR_LISTING
:
2707 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_SEARCH_OR_SECTION_OR_SUMMARY
: {
2708 eltPos
= findLastInScope(name
);
2709 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2710 errStrayEndTag(name
);
2712 generateImpliedEndTags();
2713 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2714 errUnclosedElements(eltPos
, name
);
2716 while (currentPtr
>= eltPos
) {
2720 NS_HTML5_BREAK(endtagloop
);
2723 if (!isTemplateContents()) {
2725 errStrayEndTag(name
);
2726 NS_HTML5_BREAK(endtagloop
);
2728 formPointer
= nullptr;
2729 eltPos
= findLastInScope(name
);
2730 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2731 errStrayEndTag(name
);
2732 NS_HTML5_BREAK(endtagloop
);
2734 generateImpliedEndTags();
2735 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2736 errUnclosedElements(eltPos
, name
);
2738 removeFromStack(eltPos
);
2739 NS_HTML5_BREAK(endtagloop
);
2741 eltPos
= findLastInScope(name
);
2742 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2743 errStrayEndTag(name
);
2744 NS_HTML5_BREAK(endtagloop
);
2746 generateImpliedEndTags();
2747 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2748 errUnclosedElements(eltPos
, name
);
2750 while (currentPtr
>= eltPos
) {
2753 NS_HTML5_BREAK(endtagloop
);
2757 eltPos
= findLastInButtonScope(nsGkAtoms::p
);
2758 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2759 errNoElementToCloseButEndTagSeen(nsGkAtoms::p
);
2760 if (isInForeign()) {
2761 errHtmlStartTagInForeignContext(name
);
2762 while (currentPtr
>= 0 &&
2763 stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
) {
2767 appendVoidElementToCurrentMayFoster(
2768 elementName
, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
2769 NS_HTML5_BREAK(endtagloop
);
2771 generateImpliedEndTagsExceptFor(nsGkAtoms::p
);
2772 MOZ_ASSERT(eltPos
!= nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
);
2773 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2774 errUnclosedElements(eltPos
, name
);
2776 while (currentPtr
>= eltPos
) {
2779 NS_HTML5_BREAK(endtagloop
);
2782 eltPos
= findLastInListScope(name
);
2783 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2784 errNoElementToCloseButEndTagSeen(name
);
2786 generateImpliedEndTagsExceptFor(name
);
2787 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2788 errUnclosedElements(eltPos
, name
);
2790 while (currentPtr
>= eltPos
) {
2794 NS_HTML5_BREAK(endtagloop
);
2797 eltPos
= findLastInScope(name
);
2798 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2799 errNoElementToCloseButEndTagSeen(name
);
2801 generateImpliedEndTagsExceptFor(name
);
2802 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
2803 errUnclosedElements(eltPos
, name
);
2805 while (currentPtr
>= eltPos
) {
2809 NS_HTML5_BREAK(endtagloop
);
2811 case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
: {
2812 eltPos
= findLastInScopeHn();
2813 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2814 errStrayEndTag(name
);
2816 generateImpliedEndTags();
2817 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2818 errUnclosedElements(eltPos
, name
);
2820 while (currentPtr
>= eltPos
) {
2824 NS_HTML5_BREAK(endtagloop
);
2827 case MARQUEE_OR_APPLET
: {
2828 eltPos
= findLastInScope(name
);
2829 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
2830 errStrayEndTag(name
);
2832 generateImpliedEndTags();
2833 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2834 errUnclosedElements(eltPos
, name
);
2836 while (currentPtr
>= eltPos
) {
2839 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
2841 NS_HTML5_BREAK(endtagloop
);
2845 if (isInForeign()) {
2846 errHtmlStartTagInForeignContext(name
);
2847 while (currentPtr
>= 0 &&
2848 stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
) {
2852 reconstructTheActiveFormattingElements();
2853 appendVoidElementToCurrentMayFoster(
2854 elementName
, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
2855 NS_HTML5_BREAK(endtagloop
);
2862 case PARAM_OR_SOURCE_OR_TRACK
:
2874 errStrayEndTag(name
);
2875 NS_HTML5_BREAK(endtagloop
);
2878 if (scriptingEnabled
) {
2879 errStrayEndTag(name
);
2880 NS_HTML5_BREAK(endtagloop
);
2885 case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U
:
2888 if (adoptionAgencyEndTag(name
)) {
2889 NS_HTML5_BREAK(endtagloop
);
2894 if (isCurrent(name
)) {
2896 NS_HTML5_BREAK(endtagloop
);
2898 eltPos
= currentPtr
;
2900 nsHtml5StackNode
* node
= stack
[eltPos
];
2901 if (node
->ns
== kNameSpaceID_XHTML
&& node
->name
== name
) {
2902 generateImpliedEndTags();
2903 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(name
)) {
2904 errUnclosedElements(eltPos
, name
);
2906 while (currentPtr
>= eltPos
) {
2909 NS_HTML5_BREAK(endtagloop
);
2910 } else if (!eltPos
|| node
->isSpecial()) {
2911 errStrayEndTag(name
);
2912 NS_HTML5_BREAK(endtagloop
);
2925 NS_HTML5_BREAK(endtagloop
);
2935 endTagTemplateInHead();
2936 NS_HTML5_BREAK(endtagloop
);
2939 errStrayEndTag(name
);
2940 NS_HTML5_BREAK(endtagloop
);
2944 case IN_HEAD_NOSCRIPT
: {
2949 NS_HTML5_BREAK(endtagloop
);
2952 errStrayEndTag(name
);
2958 errStrayEndTag(name
);
2959 NS_HTML5_BREAK(endtagloop
);
2963 case IN_COLUMN_GROUP
: {
2967 stack
[currentPtr
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
) {
2968 MOZ_ASSERT(fragment
|| isTemplateContents());
2969 errGarbageInColgroup();
2970 NS_HTML5_BREAK(endtagloop
);
2974 NS_HTML5_BREAK(endtagloop
);
2977 errStrayEndTag(name
);
2978 NS_HTML5_BREAK(endtagloop
);
2981 endTagTemplateInHead();
2982 NS_HTML5_BREAK(endtagloop
);
2986 stack
[currentPtr
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
) {
2987 MOZ_ASSERT(fragment
|| isTemplateContents());
2988 errGarbageInColgroup();
2989 NS_HTML5_BREAK(endtagloop
);
2997 case IN_SELECT_IN_TABLE
: {
3001 case TBODY_OR_THEAD_OR_TFOOT
:
3004 errEndTagSeenWithSelectOpen(name
);
3005 if (findLastInTableScope(name
) !=
3006 nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3007 eltPos
= findLastInTableScope(nsGkAtoms::select
);
3008 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3009 MOZ_ASSERT(fragment
);
3010 NS_HTML5_BREAK(endtagloop
);
3012 while (currentPtr
>= eltPos
) {
3015 resetTheInsertionMode();
3018 NS_HTML5_BREAK(endtagloop
);
3021 default:; // fall through
3028 if (isCurrent(nsGkAtoms::option
)) {
3030 NS_HTML5_BREAK(endtagloop
);
3032 errStrayEndTag(name
);
3033 NS_HTML5_BREAK(endtagloop
);
3037 if (isCurrent(nsGkAtoms::option
) &&
3038 nsGkAtoms::optgroup
== stack
[currentPtr
- 1]->name
) {
3041 if (isCurrent(nsGkAtoms::optgroup
)) {
3044 errStrayEndTag(name
);
3046 NS_HTML5_BREAK(endtagloop
);
3049 eltPos
= findLastInTableScope(nsGkAtoms::select
);
3050 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3051 MOZ_ASSERT(fragment
);
3052 errStrayEndTag(name
);
3053 NS_HTML5_BREAK(endtagloop
);
3055 while (currentPtr
>= eltPos
) {
3058 resetTheInsertionMode();
3059 NS_HTML5_BREAK(endtagloop
);
3062 endTagTemplateInHead();
3063 NS_HTML5_BREAK(endtagloop
);
3066 errStrayEndTag(name
);
3067 NS_HTML5_BREAK(endtagloop
);
3075 errStrayEndTag(name
);
3076 NS_HTML5_BREAK(endtagloop
);
3078 mode
= AFTER_AFTER_BODY
;
3079 NS_HTML5_BREAK(endtagloop
);
3083 errEndTagAfterBody();
3084 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3093 MOZ_ASSERT(fragment
);
3094 errStrayEndTag(name
);
3095 NS_HTML5_BREAK(endtagloop
);
3098 if ((!fragment
) && !isCurrent(nsGkAtoms::frameset
)) {
3099 mode
= AFTER_FRAMESET
;
3101 NS_HTML5_BREAK(endtagloop
);
3104 errStrayEndTag(name
);
3105 NS_HTML5_BREAK(endtagloop
);
3109 case AFTER_FRAMESET
: {
3112 mode
= AFTER_AFTER_FRAMESET
;
3113 NS_HTML5_BREAK(endtagloop
);
3116 errStrayEndTag(name
);
3117 NS_HTML5_BREAK(endtagloop
);
3122 errEndTagSeenWithoutDoctype();
3123 documentModeInternal(QUIRKS_MODE
, nullptr, nullptr);
3133 appendHtmlElementToDocumentAndPush();
3138 errStrayEndTag(name
);
3139 NS_HTML5_BREAK(endtagloop
);
3149 appendToCurrentNodeAndPushHeadElement(
3150 nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
);
3155 errStrayEndTag(name
);
3156 NS_HTML5_BREAK(endtagloop
);
3163 endTagTemplateInHead();
3164 NS_HTML5_BREAK(endtagloop
);
3169 appendToCurrentNodeAndPushBodyElement();
3174 errStrayEndTag(name
);
3175 NS_HTML5_BREAK(endtagloop
);
3179 case AFTER_AFTER_BODY
: {
3180 errStrayEndTag(name
);
3181 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3184 case AFTER_AFTER_FRAMESET
: {
3185 errStrayEndTag(name
);
3186 NS_HTML5_BREAK(endtagloop
);
3190 if (originalMode
== AFTER_HEAD
) {
3193 mode
= originalMode
;
3194 NS_HTML5_BREAK(endtagloop
);
3201 void nsHtml5TreeBuilder::endTagTemplateInHead() {
3202 int32_t eltPos
= findLast(nsGkAtoms::_template
);
3203 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3204 errStrayEndTag(nsGkAtoms::_template
);
3207 generateImpliedEndTagsThoroughly();
3208 if (!!MOZ_UNLIKELY(mViewSource
) && !isCurrent(nsGkAtoms::_template
)) {
3209 errUnclosedElements(eltPos
, nsGkAtoms::_template
);
3211 while (currentPtr
>= eltPos
) {
3214 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
3216 resetTheInsertionMode();
3220 nsHtml5TreeBuilder::findLastInTableScopeOrRootTemplateTbodyTheadTfoot() {
3221 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3222 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&&
3223 (stack
[i
]->getGroup() == nsHtml5TreeBuilder::TBODY_OR_THEAD_OR_TFOOT
||
3224 stack
[i
]->getGroup() == nsHtml5TreeBuilder::TEMPLATE
)) {
3231 int32_t nsHtml5TreeBuilder::findLast(nsAtom
* name
) {
3232 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3233 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3237 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3240 int32_t nsHtml5TreeBuilder::findLastInTableScope(nsAtom
* name
) {
3241 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3242 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3243 if (stack
[i
]->name
== name
) {
3245 } else if (stack
[i
]->name
== nsGkAtoms::table
||
3246 stack
[i
]->name
== nsGkAtoms::_template
) {
3247 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3251 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3254 int32_t nsHtml5TreeBuilder::findLastInButtonScope(nsAtom
* name
) {
3255 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3256 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3257 if (stack
[i
]->name
== name
) {
3259 } else if (stack
[i
]->name
== nsGkAtoms::button
) {
3260 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3263 if (stack
[i
]->isScoping()) {
3264 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3267 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3270 int32_t nsHtml5TreeBuilder::findLastInScope(nsAtom
* name
) {
3271 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3272 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3274 } else if (stack
[i
]->isScoping()) {
3275 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3278 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3281 int32_t nsHtml5TreeBuilder::findLastInListScope(nsAtom
* name
) {
3282 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3283 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3284 if (stack
[i
]->name
== name
) {
3286 } else if (stack
[i
]->name
== nsGkAtoms::ul
||
3287 stack
[i
]->name
== nsGkAtoms::ol
) {
3288 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3291 if (stack
[i
]->isScoping()) {
3292 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3295 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3298 int32_t nsHtml5TreeBuilder::findLastInScopeHn() {
3299 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3300 if (stack
[i
]->getGroup() ==
3301 nsHtml5TreeBuilder::H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6
) {
3303 } else if (stack
[i
]->isScoping()) {
3304 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3307 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3310 void nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsAtom
* name
) {
3312 nsHtml5StackNode
* node
= stack
[currentPtr
];
3313 switch (node
->getGroup()) {
3321 if (node
->ns
== kNameSpaceID_XHTML
&& node
->name
== name
) {
3334 void nsHtml5TreeBuilder::generateImpliedEndTags() {
3336 switch (stack
[currentPtr
]->getGroup()) {
3354 void nsHtml5TreeBuilder::generateImpliedEndTagsThoroughly() {
3356 switch (stack
[currentPtr
]->getGroup()) {
3366 case TBODY_OR_THEAD_OR_TFOOT
:
3379 bool nsHtml5TreeBuilder::isSecondOnStackBody() {
3380 return currentPtr
>= 1 && stack
[1]->getGroup() == nsHtml5TreeBuilder::BODY
;
3383 void nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m
,
3384 nsHtml5String publicIdentifier
,
3385 nsHtml5String systemIdentifier
) {
3386 if (forceNoQuirks
) {
3388 this->documentMode(STANDARDS_MODE
);
3391 quirks
= (m
== QUIRKS_MODE
);
3392 this->documentMode(m
);
3395 bool nsHtml5TreeBuilder::isAlmostStandards(nsHtml5String publicIdentifier
,
3396 nsHtml5String systemIdentifier
) {
3397 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3398 "-//w3c//dtd xhtml 1.0 transitional//", publicIdentifier
)) {
3401 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3402 "-//w3c//dtd xhtml 1.0 frameset//", publicIdentifier
)) {
3405 if (systemIdentifier
) {
3406 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3407 "-//w3c//dtd html 4.01 transitional//", publicIdentifier
)) {
3410 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3411 "-//w3c//dtd html 4.01 frameset//", publicIdentifier
)) {
3418 bool nsHtml5TreeBuilder::isQuirky(nsAtom
* name
, nsHtml5String publicIdentifier
,
3419 nsHtml5String systemIdentifier
,
3424 if (name
!= nsGkAtoms::html
) {
3427 if (publicIdentifier
) {
3428 for (int32_t i
= 0; i
< nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
.length
; i
++) {
3429 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3430 nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS
[i
], publicIdentifier
)) {
3434 if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3435 "-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier
) ||
3436 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3437 "-/w3c/dtd html 4.0 transitional/en", publicIdentifier
) ||
3438 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3439 "html", publicIdentifier
)) {
3443 if (!systemIdentifier
) {
3444 if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3445 "-//w3c//dtd html 4.01 transitional//", publicIdentifier
)) {
3447 } else if (nsHtml5Portability::
3448 lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
3449 "-//w3c//dtd html 4.01 frameset//", publicIdentifier
)) {
3452 } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
3453 "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd",
3454 systemIdentifier
)) {
3460 void nsHtml5TreeBuilder::closeTheCell(int32_t eltPos
) {
3461 generateImpliedEndTags();
3462 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
3463 errUnclosedElementsCell(eltPos
);
3465 while (currentPtr
>= eltPos
) {
3468 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
3473 int32_t nsHtml5TreeBuilder::findLastInTableScopeTdTh() {
3474 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3475 nsAtom
* name
= stack
[i
]->name
;
3476 if (stack
[i
]->ns
== kNameSpaceID_XHTML
) {
3477 if (nsGkAtoms::td
== name
|| nsGkAtoms::th
== name
) {
3479 } else if (name
== nsGkAtoms::table
|| name
== nsGkAtoms::_template
) {
3480 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3484 return nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
;
3487 void nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos
) {
3488 int32_t eltGroup
= stack
[eltPos
]->getGroup();
3489 while (currentPtr
> eltPos
) {
3490 if (stack
[currentPtr
]->ns
== kNameSpaceID_XHTML
&&
3491 stack
[currentPtr
]->getGroup() == TEMPLATE
&&
3492 (eltGroup
== TABLE
|| eltGroup
== TBODY_OR_THEAD_OR_TFOOT
||
3493 eltGroup
== TR
|| !eltPos
)) {
3500 void nsHtml5TreeBuilder::resetTheInsertionMode() {
3501 nsHtml5StackNode
* node
;
3504 for (int32_t i
= currentPtr
; i
>= 0; i
--) {
3509 if (!(contextNamespace
== kNameSpaceID_XHTML
&&
3510 (contextName
== nsGkAtoms::td
|| contextName
== nsGkAtoms::th
))) {
3513 ns
= contextNamespace
;
3516 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3520 if (nsGkAtoms::select
== name
) {
3521 int32_t ancestorIndex
= i
;
3522 while (ancestorIndex
> 0) {
3523 nsHtml5StackNode
* ancestor
= stack
[ancestorIndex
--];
3524 if (kNameSpaceID_XHTML
== ancestor
->ns
) {
3525 if (nsGkAtoms::_template
== ancestor
->name
) {
3528 if (nsGkAtoms::table
== ancestor
->name
) {
3529 mode
= IN_SELECT_IN_TABLE
;
3536 } else if (nsGkAtoms::td
== name
|| nsGkAtoms::th
== name
) {
3539 } else if (nsGkAtoms::tr
== name
) {
3542 } else if (nsGkAtoms::tbody
== name
|| nsGkAtoms::thead
== name
||
3543 nsGkAtoms::tfoot
== name
) {
3544 mode
= IN_TABLE_BODY
;
3546 } else if (nsGkAtoms::caption
== name
) {
3549 } else if (nsGkAtoms::colgroup
== name
) {
3550 mode
= IN_COLUMN_GROUP
;
3552 } else if (nsGkAtoms::table
== name
) {
3555 } else if (kNameSpaceID_XHTML
!= ns
) {
3556 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3558 } else if (nsGkAtoms::_template
== name
) {
3559 MOZ_ASSERT(templateModePtr
>= 0);
3560 mode
= templateModeStack
[templateModePtr
];
3562 } else if (nsGkAtoms::head
== name
) {
3563 if (name
== contextName
) {
3564 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3569 } else if (nsGkAtoms::body
== name
) {
3570 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3572 } else if (nsGkAtoms::frameset
== name
) {
3575 } else if (nsGkAtoms::html
== name
) {
3583 mode
= framesetOk
? FRAMESET_OK
: IN_BODY
;
3589 void nsHtml5TreeBuilder::implicitlyCloseP() {
3590 int32_t eltPos
= findLastInButtonScope(nsGkAtoms::p
);
3591 if (eltPos
== nsHtml5TreeBuilder::NOT_FOUND_ON_STACK
) {
3594 generateImpliedEndTagsExceptFor(nsGkAtoms::p
);
3595 if (!!MOZ_UNLIKELY(mViewSource
) && eltPos
!= currentPtr
) {
3596 errUnclosedElementsImplied(eltPos
, nsGkAtoms::p
);
3598 while (currentPtr
>= eltPos
) {
3603 bool nsHtml5TreeBuilder::debugOnlyClearLastStackSlot() {
3604 stack
[currentPtr
] = nullptr;
3608 bool nsHtml5TreeBuilder::debugOnlyClearLastListSlot() {
3609 listOfActiveFormattingElements
[listPtr
] = nullptr;
3613 void nsHtml5TreeBuilder::pushTemplateMode(int32_t mode
) {
3615 if (templateModePtr
== templateModeStack
.length
) {
3616 jArray
<int32_t, int32_t> newStack
=
3617 jArray
<int32_t, int32_t>::newJArray(templateModeStack
.length
+ 64);
3618 nsHtml5ArrayCopy::arraycopy(templateModeStack
, newStack
,
3619 templateModeStack
.length
);
3620 templateModeStack
= newStack
;
3622 templateModeStack
[templateModePtr
] = mode
;
3625 void nsHtml5TreeBuilder::push(nsHtml5StackNode
* node
) {
3627 if (currentPtr
== stack
.length
) {
3628 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
3629 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stack
.length
+ 64);
3630 nsHtml5ArrayCopy::arraycopy(stack
, newStack
, stack
.length
);
3633 stack
[currentPtr
] = node
;
3634 elementPushed(node
->ns
, node
->popName
, node
->node
);
3637 void nsHtml5TreeBuilder::silentPush(nsHtml5StackNode
* node
) {
3639 if (currentPtr
== stack
.length
) {
3640 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
3641 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stack
.length
+ 64);
3642 nsHtml5ArrayCopy::arraycopy(stack
, newStack
, stack
.length
);
3645 stack
[currentPtr
] = node
;
3648 void nsHtml5TreeBuilder::append(nsHtml5StackNode
* node
) {
3650 if (listPtr
== listOfActiveFormattingElements
.length
) {
3651 jArray
<nsHtml5StackNode
*, int32_t> newList
=
3652 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(
3653 listOfActiveFormattingElements
.length
+ 64);
3654 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, newList
,
3655 listOfActiveFormattingElements
.length
);
3656 listOfActiveFormattingElements
= newList
;
3658 listOfActiveFormattingElements
[listPtr
] = node
;
3661 void nsHtml5TreeBuilder::
3662 clearTheListOfActiveFormattingElementsUpToTheLastMarker() {
3663 while (listPtr
> -1) {
3664 if (!listOfActiveFormattingElements
[listPtr
]) {
3668 listOfActiveFormattingElements
[listPtr
]->release(this);
3673 void nsHtml5TreeBuilder::removeFromStack(int32_t pos
) {
3674 if (currentPtr
== pos
) {
3677 stack
[pos
]->release(this);
3678 nsHtml5ArrayCopy::arraycopy(stack
, pos
+ 1, pos
, currentPtr
- pos
);
3679 MOZ_ASSERT(debugOnlyClearLastStackSlot());
3684 void nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode
* node
) {
3685 if (stack
[currentPtr
] == node
) {
3688 int32_t pos
= currentPtr
- 1;
3689 while (pos
>= 0 && stack
[pos
] != node
) {
3696 node
->release(this);
3697 nsHtml5ArrayCopy::arraycopy(stack
, pos
+ 1, pos
, currentPtr
- pos
);
3702 void nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos
) {
3703 MOZ_ASSERT(!!listOfActiveFormattingElements
[pos
]);
3704 listOfActiveFormattingElements
[pos
]->release(this);
3705 if (pos
== listPtr
) {
3706 MOZ_ASSERT(debugOnlyClearLastListSlot());
3710 MOZ_ASSERT(pos
< listPtr
);
3711 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, pos
+ 1, pos
,
3713 MOZ_ASSERT(debugOnlyClearLastListSlot());
3717 bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom
* name
) {
3718 if (stack
[currentPtr
]->ns
== kNameSpaceID_XHTML
&&
3719 stack
[currentPtr
]->name
== name
&&
3720 findInListOfActiveFormattingElements(stack
[currentPtr
]) == -1) {
3724 for (int32_t i
= 0; i
< 8; ++i
) {
3725 int32_t formattingEltListPos
= listPtr
;
3726 while (formattingEltListPos
> -1) {
3727 nsHtml5StackNode
* listNode
=
3728 listOfActiveFormattingElements
[formattingEltListPos
];
3730 formattingEltListPos
= -1;
3732 } else if (listNode
->name
== name
) {
3735 formattingEltListPos
--;
3737 if (formattingEltListPos
== -1) {
3740 nsHtml5StackNode
* formattingElt
=
3741 listOfActiveFormattingElements
[formattingEltListPos
];
3742 int32_t formattingEltStackPos
= currentPtr
;
3743 bool inScope
= true;
3744 while (formattingEltStackPos
> -1) {
3745 nsHtml5StackNode
* node
= stack
[formattingEltStackPos
];
3746 if (node
== formattingElt
) {
3748 } else if (node
->isScoping()) {
3751 formattingEltStackPos
--;
3753 if (formattingEltStackPos
== -1) {
3754 errNoElementToCloseButEndTagSeen(name
);
3755 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3759 errNoElementToCloseButEndTagSeen(name
);
3762 if (formattingEltStackPos
!= currentPtr
) {
3763 errEndTagViolatesNestingRules(name
);
3765 int32_t furthestBlockPos
= formattingEltStackPos
+ 1;
3766 while (furthestBlockPos
<= currentPtr
) {
3767 nsHtml5StackNode
* node
= stack
[furthestBlockPos
];
3768 MOZ_ASSERT(furthestBlockPos
> 0,
3769 "How is formattingEltStackPos + 1 not > 0?");
3770 if (node
->isSpecial()) {
3775 if (furthestBlockPos
> currentPtr
) {
3776 while (currentPtr
>= formattingEltStackPos
) {
3779 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3782 nsHtml5StackNode
* commonAncestor
= stack
[formattingEltStackPos
- 1];
3783 nsIContentHandle
* insertionCommonAncestor
=
3784 nodeFromStackWithBlinkCompat(formattingEltStackPos
- 1);
3785 nsHtml5StackNode
* furthestBlock
= stack
[furthestBlockPos
];
3786 int32_t bookmark
= formattingEltListPos
;
3787 int32_t nodePos
= furthestBlockPos
;
3788 nsHtml5StackNode
* lastNode
= furthestBlock
;
3793 if (nodePos
== formattingEltStackPos
) {
3796 nsHtml5StackNode
* node
= stack
[nodePos
];
3797 int32_t nodeListPos
= findInListOfActiveFormattingElements(node
);
3798 if (j
> 3 && nodeListPos
!= -1) {
3799 removeFromListOfActiveFormattingElements(nodeListPos
);
3800 if (nodeListPos
<= formattingEltListPos
) {
3801 formattingEltListPos
--;
3803 if (nodeListPos
<= bookmark
) {
3808 if (nodeListPos
== -1) {
3809 MOZ_ASSERT(formattingEltStackPos
< nodePos
);
3810 MOZ_ASSERT(bookmark
< nodePos
);
3811 MOZ_ASSERT(furthestBlockPos
> nodePos
);
3812 removeFromStack(nodePos
);
3816 if (nodePos
== furthestBlockPos
) {
3817 bookmark
= nodeListPos
+ 1;
3819 MOZ_ASSERT(node
== listOfActiveFormattingElements
[nodeListPos
]);
3820 MOZ_ASSERT(node
== stack
[nodePos
]);
3821 nsIContentHandle
* clone
= createElement(
3822 kNameSpaceID_XHTML
, node
->name
, node
->attributes
->cloneAttributes(),
3823 insertionCommonAncestor
, htmlCreator(node
->getHtmlCreator()));
3824 nsHtml5StackNode
* newNode
= createStackNode(
3825 node
->getFlags(), node
->ns
, node
->name
, clone
, node
->popName
,
3826 node
->attributes
, node
->getHtmlCreator());
3827 node
->dropAttributes();
3828 stack
[nodePos
] = newNode
;
3830 listOfActiveFormattingElements
[nodeListPos
] = newNode
;
3831 node
->release(this);
3832 node
->release(this);
3834 detachFromParent(lastNode
->node
);
3835 appendElement(lastNode
->node
, nodeFromStackWithBlinkCompat(nodePos
));
3838 if (commonAncestor
->isFosterParenting()) {
3839 detachFromParent(lastNode
->node
);
3840 insertIntoFosterParent(lastNode
->node
);
3842 detachFromParent(lastNode
->node
);
3843 appendElement(lastNode
->node
, insertionCommonAncestor
);
3845 nsIContentHandle
* clone
= createElement(
3846 kNameSpaceID_XHTML
, formattingElt
->name
,
3847 formattingElt
->attributes
->cloneAttributes(), furthestBlock
->node
,
3848 htmlCreator(formattingElt
->getHtmlCreator()));
3849 nsHtml5StackNode
* formattingClone
= createStackNode(
3850 formattingElt
->getFlags(), formattingElt
->ns
, formattingElt
->name
,
3851 clone
, formattingElt
->popName
, formattingElt
->attributes
,
3852 formattingElt
->getHtmlCreator());
3853 formattingElt
->dropAttributes();
3854 appendChildrenToNewParent(furthestBlock
->node
, clone
);
3855 appendElement(clone
, furthestBlock
->node
);
3856 removeFromListOfActiveFormattingElements(formattingEltListPos
);
3857 insertIntoListOfActiveFormattingElements(formattingClone
, bookmark
);
3858 MOZ_ASSERT(formattingEltStackPos
< furthestBlockPos
);
3859 removeFromStack(formattingEltStackPos
);
3860 insertIntoStack(formattingClone
, furthestBlockPos
);
3865 void nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode
* node
,
3867 MOZ_ASSERT(currentPtr
+ 1 < stack
.length
);
3868 MOZ_ASSERT(position
<= currentPtr
+ 1);
3869 if (position
== currentPtr
+ 1) {
3872 nsHtml5ArrayCopy::arraycopy(stack
, position
, position
+ 1,
3873 (currentPtr
- position
) + 1);
3875 stack
[position
] = node
;
3879 void nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(
3880 nsHtml5StackNode
* formattingClone
, int32_t bookmark
) {
3881 formattingClone
->retain();
3882 MOZ_ASSERT(listPtr
+ 1 < listOfActiveFormattingElements
.length
);
3883 if (bookmark
<= listPtr
) {
3884 nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements
, bookmark
,
3885 bookmark
+ 1, (listPtr
- bookmark
) + 1);
3888 listOfActiveFormattingElements
[bookmark
] = formattingClone
;
3891 int32_t nsHtml5TreeBuilder::findInListOfActiveFormattingElements(
3892 nsHtml5StackNode
* node
) {
3893 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3894 if (node
== listOfActiveFormattingElements
[i
]) {
3901 int32_t nsHtml5TreeBuilder::
3902 findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(
3904 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3905 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
3908 } else if (node
->name
== name
) {
3915 void nsHtml5TreeBuilder::maybeForgetEarlierDuplicateFormattingElement(
3916 nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
) {
3917 int32_t candidate
= -1;
3919 for (int32_t i
= listPtr
; i
>= 0; i
--) {
3920 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
3924 if (node
->name
== name
&& node
->attributes
->equalsAnother(attributes
)) {
3930 removeFromListOfActiveFormattingElements(candidate
);
3934 int32_t nsHtml5TreeBuilder::findLastOrRoot(nsAtom
* name
) {
3935 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3936 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->name
== name
) {
3943 int32_t nsHtml5TreeBuilder::findLastOrRoot(int32_t group
) {
3944 for (int32_t i
= currentPtr
; i
> 0; i
--) {
3945 if (stack
[i
]->ns
== kNameSpaceID_XHTML
&& stack
[i
]->getGroup() == group
) {
3952 bool nsHtml5TreeBuilder::addAttributesToBody(
3953 nsHtml5HtmlAttributes
* attributes
) {
3954 if (currentPtr
>= 1) {
3955 nsHtml5StackNode
* body
= stack
[1];
3956 if (body
->getGroup() == nsHtml5TreeBuilder::BODY
) {
3957 addAttributesToElement(body
->node
, attributes
);
3964 void nsHtml5TreeBuilder::addAttributesToHtml(
3965 nsHtml5HtmlAttributes
* attributes
) {
3966 addAttributesToElement(stack
[0]->node
, attributes
);
3969 void nsHtml5TreeBuilder::pushHeadPointerOntoStack() {
3970 MOZ_ASSERT(!!headPointer
);
3971 MOZ_ASSERT(mode
== AFTER_HEAD
);
3973 silentPush(createStackNode(nsHtml5ElementName::ELT_HEAD
, headPointer
));
3976 void nsHtml5TreeBuilder::reconstructTheActiveFormattingElements() {
3977 if (listPtr
== -1) {
3980 nsHtml5StackNode
* mostRecent
= listOfActiveFormattingElements
[listPtr
];
3981 if (!mostRecent
|| isInStack(mostRecent
)) {
3984 int32_t entryPos
= listPtr
;
3987 if (entryPos
== -1) {
3990 if (!listOfActiveFormattingElements
[entryPos
]) {
3993 if (isInStack(listOfActiveFormattingElements
[entryPos
])) {
3997 while (entryPos
< listPtr
) {
3999 nsHtml5StackNode
* entry
= listOfActiveFormattingElements
[entryPos
];
4000 nsHtml5StackNode
* current
= stack
[currentPtr
];
4001 nsIContentHandle
* clone
;
4002 if (current
->isFosterParenting()) {
4003 clone
= createAndInsertFosterParentedElement(
4004 kNameSpaceID_XHTML
, entry
->name
, entry
->attributes
->cloneAttributes(),
4005 htmlCreator(entry
->getHtmlCreator()));
4007 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4008 clone
= createElement(kNameSpaceID_XHTML
, entry
->name
,
4009 entry
->attributes
->cloneAttributes(), currentNode
,
4010 htmlCreator(entry
->getHtmlCreator()));
4011 appendElement(clone
, currentNode
);
4013 nsHtml5StackNode
* entryClone
= createStackNode(
4014 entry
->getFlags(), entry
->ns
, entry
->name
, clone
, entry
->popName
,
4015 entry
->attributes
, entry
->getHtmlCreator());
4016 entry
->dropAttributes();
4018 listOfActiveFormattingElements
[entryPos
] = entryClone
;
4019 entry
->release(this);
4020 entryClone
->retain();
4024 void nsHtml5TreeBuilder::notifyUnusedStackNode(int32_t idxInStackNodes
) {
4025 if (idxInStackNodes
< stackNodesIdx
) {
4026 stackNodesIdx
= idxInStackNodes
;
4030 nsHtml5StackNode
* nsHtml5TreeBuilder::getUnusedStackNode() {
4031 while (stackNodesIdx
< numStackNodes
) {
4032 if (stackNodes
[stackNodesIdx
]->isUnused()) {
4033 return stackNodes
[stackNodesIdx
++];
4037 if (stackNodesIdx
< stackNodes
.length
) {
4038 stackNodes
[stackNodesIdx
] = new nsHtml5StackNode(stackNodesIdx
);
4040 return stackNodes
[stackNodesIdx
++];
4042 jArray
<nsHtml5StackNode
*, int32_t> newStack
=
4043 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stackNodes
.length
+ 64);
4044 nsHtml5ArrayCopy::arraycopy(stackNodes
, newStack
, stackNodes
.length
);
4045 stackNodes
= newStack
;
4046 stackNodes
[stackNodesIdx
] = new nsHtml5StackNode(stackNodesIdx
);
4048 return stackNodes
[stackNodesIdx
++];
4051 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4052 int32_t flags
, int32_t ns
, nsAtom
* name
, nsIContentHandle
* node
,
4053 nsAtom
* popName
, nsHtml5HtmlAttributes
* attributes
,
4054 mozilla::dom::HTMLContentCreatorFunction htmlCreator
) {
4055 nsHtml5StackNode
* instance
= getUnusedStackNode();
4056 instance
->setValues(flags
, ns
, name
, node
, popName
, attributes
, htmlCreator
);
4060 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4061 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
) {
4062 nsHtml5StackNode
* instance
= getUnusedStackNode();
4063 instance
->setValues(elementName
, node
);
4067 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4068 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
,
4069 nsHtml5HtmlAttributes
* attributes
) {
4070 nsHtml5StackNode
* instance
= getUnusedStackNode();
4071 instance
->setValues(elementName
, node
, attributes
);
4075 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4076 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
, nsAtom
* popName
) {
4077 nsHtml5StackNode
* instance
= getUnusedStackNode();
4078 instance
->setValues(elementName
, node
, popName
);
4082 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4083 nsHtml5ElementName
* elementName
, nsAtom
* popName
, nsIContentHandle
* node
) {
4084 nsHtml5StackNode
* instance
= getUnusedStackNode();
4085 instance
->setValues(elementName
, popName
, node
);
4089 nsHtml5StackNode
* nsHtml5TreeBuilder::createStackNode(
4090 nsHtml5ElementName
* elementName
, nsIContentHandle
* node
, nsAtom
* popName
,
4091 bool markAsIntegrationPoint
) {
4092 nsHtml5StackNode
* instance
= getUnusedStackNode();
4093 instance
->setValues(elementName
, node
, popName
, markAsIntegrationPoint
);
4097 void nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle
* child
) {
4098 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4099 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4100 if (templatePos
>= tablePos
) {
4101 appendElement(child
, stack
[templatePos
]->node
);
4104 nsHtml5StackNode
* node
= stack
[tablePos
];
4105 insertFosterParentedChild(child
, node
->node
, stack
[tablePos
- 1]->node
);
4108 nsIContentHandle
* nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
4109 int32_t ns
, nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
,
4110 nsHtml5ContentCreatorFunction creator
) {
4111 return createAndInsertFosterParentedElement(ns
, name
, attributes
, nullptr,
4115 nsIContentHandle
* nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
4116 int32_t ns
, nsAtom
* name
, nsHtml5HtmlAttributes
* attributes
,
4117 nsIContentHandle
* form
, nsHtml5ContentCreatorFunction creator
) {
4118 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4119 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4120 if (templatePos
>= tablePos
) {
4121 nsIContentHandle
* child
= createElement(ns
, name
, attributes
, form
,
4122 stack
[templatePos
]->node
, creator
);
4123 appendElement(child
, stack
[templatePos
]->node
);
4126 nsHtml5StackNode
* node
= stack
[tablePos
];
4127 return createAndInsertFosterParentedElement(
4128 ns
, name
, attributes
, form
, node
->node
, stack
[tablePos
- 1]->node
,
4132 bool nsHtml5TreeBuilder::isInStack(nsHtml5StackNode
* node
) {
4133 for (int32_t i
= currentPtr
; i
>= 0; i
--) {
4134 if (stack
[i
] == node
) {
4141 void nsHtml5TreeBuilder::popTemplateMode() { templateModePtr
--; }
4143 void nsHtml5TreeBuilder::pop() {
4144 nsHtml5StackNode
* node
= stack
[currentPtr
];
4145 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4147 elementPopped(node
->ns
, node
->popName
, node
->node
);
4148 node
->release(this);
4151 void nsHtml5TreeBuilder::popForeign(int32_t origPos
, int32_t eltPos
) {
4152 nsHtml5StackNode
* node
= stack
[currentPtr
];
4153 if (origPos
!= currentPtr
|| eltPos
!= currentPtr
) {
4154 markMalformedIfScript(node
->node
);
4156 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4158 elementPopped(node
->ns
, node
->popName
, node
->node
);
4159 node
->release(this);
4162 void nsHtml5TreeBuilder::silentPop() {
4163 nsHtml5StackNode
* node
= stack
[currentPtr
];
4164 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4166 node
->release(this);
4169 void nsHtml5TreeBuilder::popOnEof() {
4170 nsHtml5StackNode
* node
= stack
[currentPtr
];
4171 MOZ_ASSERT(debugOnlyClearLastStackSlot());
4173 markMalformedIfScript(node
->node
);
4174 elementPopped(node
->ns
, node
->popName
, node
->node
);
4175 node
->release(this);
4178 void nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(
4179 nsHtml5HtmlAttributes
* attributes
) {
4180 nsIContentHandle
* elt
= createHtmlElementSetAsRoot(attributes
);
4181 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_HTML
, elt
);
4185 void nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush() {
4186 appendHtmlElementToDocumentAndPush(tokenizer
->emptyAttributes());
4189 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(
4190 nsHtml5HtmlAttributes
* attributes
) {
4191 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4192 nsIContentHandle
* elt
=
4193 createElement(kNameSpaceID_XHTML
, nsGkAtoms::head
, attributes
,
4194 currentNode
, htmlCreator(NS_NewHTMLSharedElement
));
4195 appendElement(elt
, currentNode
);
4197 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_HEAD
, elt
);
4201 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(
4202 nsHtml5HtmlAttributes
* attributes
) {
4203 appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY
, attributes
);
4206 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement() {
4207 appendToCurrentNodeAndPushBodyElement(tokenizer
->emptyAttributes());
4210 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(
4211 nsHtml5HtmlAttributes
* attributes
) {
4212 nsIContentHandle
* elt
;
4213 nsHtml5StackNode
* current
= stack
[currentPtr
];
4214 if (current
->isFosterParenting()) {
4215 elt
= createAndInsertFosterParentedElement(
4216 kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4217 htmlCreator(NS_NewHTMLFormElement
));
4219 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4220 elt
= createElement(kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4221 currentNode
, htmlCreator(NS_NewHTMLFormElement
));
4222 appendElement(elt
, currentNode
);
4224 if (!isTemplateContents()) {
4227 nsHtml5StackNode
* node
= createStackNode(nsHtml5ElementName::ELT_FORM
, elt
);
4231 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(
4232 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4233 nsHtml5HtmlAttributes
* clone
= attributes
->cloneAttributes();
4234 nsIContentHandle
* elt
;
4235 nsHtml5StackNode
* current
= stack
[currentPtr
];
4236 if (current
->isFosterParenting()) {
4237 elt
= createAndInsertFosterParentedElement(
4238 kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4239 htmlCreator(elementName
->getHtmlCreator()));
4241 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4243 createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4244 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4245 appendElement(elt
, currentNode
);
4247 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
, clone
);
4253 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(
4254 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4255 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4256 nsIContentHandle
* elt
=
4257 createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4258 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4259 if (nsHtml5ElementName::ELT_TEMPLATE
== elementName
) {
4260 nsIContentHandle
* root
=
4261 getDeclarativeShadowRoot(currentNode
, elt
, attributes
);
4263 setDocumentFragmentForTemplate(elt
, root
);
4266 appendElement(elt
, currentNode
);
4267 elt
= getDocumentFragmentForTemplate(elt
);
4270 appendElement(elt
, currentNode
);
4272 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
);
4276 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
4277 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4278 nsAtom
* popName
= elementName
->getName();
4279 nsIContentHandle
* elt
;
4280 nsHtml5StackNode
* current
= stack
[currentPtr
];
4281 if (current
->isFosterParenting()) {
4282 elt
= createAndInsertFosterParentedElement(
4283 kNameSpaceID_XHTML
, popName
, attributes
,
4284 htmlCreator(elementName
->getHtmlCreator()));
4286 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4287 elt
= createElement(kNameSpaceID_XHTML
, popName
, attributes
, currentNode
,
4288 htmlCreator(elementName
->getHtmlCreator()));
4289 appendElement(elt
, currentNode
);
4291 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
, popName
);
4295 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(
4296 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4297 nsAtom
* popName
= elementName
->getName();
4298 bool markAsHtmlIntegrationPoint
= false;
4299 if (nsHtml5ElementName::ELT_ANNOTATION_XML
== elementName
&&
4300 annotationXmlEncodingPermitsHtml(attributes
)) {
4301 markAsHtmlIntegrationPoint
= true;
4303 nsIContentHandle
* elt
;
4304 nsHtml5StackNode
* current
= stack
[currentPtr
];
4305 if (current
->isFosterParenting()) {
4306 elt
= createAndInsertFosterParentedElement(
4307 kNameSpaceID_MathML
, popName
, attributes
, htmlCreator(nullptr));
4309 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4310 elt
= createElement(kNameSpaceID_MathML
, popName
, attributes
, currentNode
,
4311 htmlCreator(nullptr));
4312 appendElement(elt
, currentNode
);
4314 nsHtml5StackNode
* node
=
4315 createStackNode(elementName
, elt
, popName
, markAsHtmlIntegrationPoint
);
4319 bool nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(
4320 nsHtml5HtmlAttributes
* attributes
) {
4321 nsHtml5String encoding
=
4322 attributes
->getValue(nsHtml5AttributeName::ATTR_ENCODING
);
4326 return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
4327 "application/xhtml+xml", encoding
) ||
4328 nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
4329 "text/html", encoding
);
4332 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(
4333 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4334 nsAtom
* popName
= elementName
->getCamelCaseName();
4335 nsIContentHandle
* elt
;
4336 nsHtml5StackNode
* current
= stack
[currentPtr
];
4337 if (current
->isFosterParenting()) {
4338 elt
= createAndInsertFosterParentedElement(
4339 kNameSpaceID_SVG
, popName
, attributes
,
4340 svgCreator(elementName
->getSvgCreator()));
4342 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4343 elt
= createElement(kNameSpaceID_SVG
, popName
, attributes
, currentNode
,
4344 svgCreator(elementName
->getSvgCreator()));
4345 appendElement(elt
, currentNode
);
4347 nsHtml5StackNode
* node
= createStackNode(elementName
, popName
, elt
);
4351 void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
4352 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
,
4353 nsIContentHandle
* form
) {
4354 nsIContentHandle
* elt
;
4355 nsIContentHandle
* formOwner
=
4356 !form
|| fragment
|| isTemplateContents() ? nullptr : form
;
4357 nsHtml5StackNode
* current
= stack
[currentPtr
];
4358 if (current
->isFosterParenting()) {
4359 elt
= createAndInsertFosterParentedElement(
4360 kNameSpaceID_XHTML
, elementName
->getName(), attributes
, formOwner
,
4361 htmlCreator(elementName
->getHtmlCreator()));
4363 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4364 elt
= createElement(kNameSpaceID_XHTML
, elementName
->getName(), attributes
,
4365 formOwner
, currentNode
,
4366 htmlCreator(elementName
->getHtmlCreator()));
4367 appendElement(elt
, currentNode
);
4369 nsHtml5StackNode
* node
= createStackNode(elementName
, elt
);
4373 void nsHtml5TreeBuilder::appendVoidElementToCurrent(
4374 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4375 nsAtom
* popName
= elementName
->getName();
4376 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4377 nsIContentHandle
* elt
=
4378 createElement(kNameSpaceID_XHTML
, popName
, attributes
, currentNode
,
4379 htmlCreator(elementName
->getHtmlCreator()));
4380 appendElement(elt
, currentNode
);
4381 elementPushed(kNameSpaceID_XHTML
, popName
, elt
);
4382 elementPopped(kNameSpaceID_XHTML
, popName
, elt
);
4385 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
4386 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
,
4387 nsIContentHandle
* form
) {
4388 nsAtom
* name
= elementName
->getName();
4389 nsIContentHandle
* elt
;
4390 nsIContentHandle
* formOwner
=
4391 !form
|| fragment
|| isTemplateContents() ? nullptr : form
;
4392 nsHtml5StackNode
* current
= stack
[currentPtr
];
4393 if (current
->isFosterParenting()) {
4394 elt
= createAndInsertFosterParentedElement(
4395 kNameSpaceID_XHTML
, name
, attributes
, formOwner
,
4396 htmlCreator(elementName
->getHtmlCreator()));
4398 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4400 createElement(kNameSpaceID_XHTML
, name
, attributes
, formOwner
,
4401 currentNode
, htmlCreator(elementName
->getHtmlCreator()));
4402 appendElement(elt
, currentNode
);
4404 elementPushed(kNameSpaceID_XHTML
, name
, elt
);
4405 elementPopped(kNameSpaceID_XHTML
, name
, elt
);
4408 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
4409 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4410 nsAtom
* popName
= elementName
->getName();
4411 nsIContentHandle
* elt
;
4412 nsHtml5StackNode
* current
= stack
[currentPtr
];
4413 if (current
->isFosterParenting()) {
4414 elt
= createAndInsertFosterParentedElement(
4415 kNameSpaceID_XHTML
, popName
, attributes
,
4416 htmlCreator(elementName
->getHtmlCreator()));
4418 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4419 elt
= createElement(kNameSpaceID_XHTML
, popName
, attributes
, currentNode
,
4420 htmlCreator(elementName
->getHtmlCreator()));
4421 appendElement(elt
, currentNode
);
4423 elementPushed(kNameSpaceID_XHTML
, popName
, elt
);
4424 elementPopped(kNameSpaceID_XHTML
, popName
, elt
);
4427 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(
4428 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4429 nsAtom
* popName
= elementName
->getCamelCaseName();
4430 nsIContentHandle
* elt
;
4431 nsHtml5StackNode
* current
= stack
[currentPtr
];
4432 if (current
->isFosterParenting()) {
4433 elt
= createAndInsertFosterParentedElement(
4434 kNameSpaceID_SVG
, popName
, attributes
,
4435 svgCreator(elementName
->getSvgCreator()));
4437 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4438 elt
= createElement(kNameSpaceID_SVG
, popName
, attributes
, currentNode
,
4439 svgCreator(elementName
->getSvgCreator()));
4440 appendElement(elt
, currentNode
);
4442 elementPushed(kNameSpaceID_SVG
, popName
, elt
);
4443 elementPopped(kNameSpaceID_SVG
, popName
, elt
);
4446 void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(
4447 nsHtml5ElementName
* elementName
, nsHtml5HtmlAttributes
* attributes
) {
4448 nsAtom
* popName
= elementName
->getName();
4449 nsIContentHandle
* elt
;
4450 nsHtml5StackNode
* current
= stack
[currentPtr
];
4451 if (current
->isFosterParenting()) {
4452 elt
= createAndInsertFosterParentedElement(
4453 kNameSpaceID_MathML
, popName
, attributes
, htmlCreator(nullptr));
4455 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4456 elt
= createElement(kNameSpaceID_MathML
, popName
, attributes
, currentNode
,
4457 htmlCreator(nullptr));
4458 appendElement(elt
, currentNode
);
4460 elementPushed(kNameSpaceID_MathML
, popName
, elt
);
4461 elementPopped(kNameSpaceID_MathML
, popName
, elt
);
4464 void nsHtml5TreeBuilder::appendVoidInputToCurrent(
4465 nsHtml5HtmlAttributes
* attributes
, nsIContentHandle
* form
) {
4466 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4467 nsIContentHandle
* elt
=
4468 createElement(kNameSpaceID_XHTML
, nsGkAtoms::input
, attributes
,
4469 !form
|| fragment
|| isTemplateContents() ? nullptr : form
,
4470 currentNode
, htmlCreator(NS_NewHTMLInputElement
));
4471 appendElement(elt
, currentNode
);
4472 elementPushed(kNameSpaceID_XHTML
, nsGkAtoms::input
, elt
);
4473 elementPopped(kNameSpaceID_XHTML
, nsGkAtoms::input
, elt
);
4476 void nsHtml5TreeBuilder::appendVoidFormToCurrent(
4477 nsHtml5HtmlAttributes
* attributes
) {
4478 nsIContentHandle
* currentNode
= nodeFromStackWithBlinkCompat(currentPtr
);
4479 nsIContentHandle
* elt
=
4480 createElement(kNameSpaceID_XHTML
, nsGkAtoms::form
, attributes
,
4481 currentNode
, htmlCreator(NS_NewHTMLFormElement
));
4483 appendElement(elt
, currentNode
);
4484 elementPushed(kNameSpaceID_XHTML
, nsGkAtoms::form
, elt
);
4485 elementPopped(kNameSpaceID_XHTML
, nsGkAtoms::form
, elt
);
4488 void nsHtml5TreeBuilder::requestSuspension() {
4489 tokenizer
->requestSuspension();
4493 bool nsHtml5TreeBuilder::isInForeign() {
4494 return currentPtr
>= 0 && stack
[currentPtr
]->ns
!= kNameSpaceID_XHTML
;
4497 bool nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint() {
4498 if (currentPtr
< 0) {
4501 return !isSpecialParentInForeign(stack
[currentPtr
]);
4504 void nsHtml5TreeBuilder::setFragmentContext(nsAtom
* context
, int32_t ns
,
4505 nsIContentHandle
* node
,
4507 this->contextName
= context
;
4508 this->contextNamespace
= ns
;
4509 this->contextNode
= node
;
4510 this->fragment
= (!!contextName
);
4511 this->quirks
= quirks
;
4514 nsIContentHandle
* nsHtml5TreeBuilder::currentNode() {
4515 return stack
[currentPtr
]->node
;
4518 bool nsHtml5TreeBuilder::isScriptingEnabled() { return scriptingEnabled
; }
4520 void nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled
) {
4521 this->scriptingEnabled
= scriptingEnabled
;
4524 void nsHtml5TreeBuilder::setForceNoQuirks(bool forceNoQuirks
) {
4525 this->forceNoQuirks
= forceNoQuirks
;
4528 void nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument
) {
4529 this->setForceNoQuirks(isSrcdocDocument
);
4532 bool nsHtml5TreeBuilder::isAllowDeclarativeShadowRoots() {
4533 return allowDeclarativeShadowRoots
;
4536 void nsHtml5TreeBuilder::setAllowDeclarativeShadowRoots(bool allow
) {
4537 allowDeclarativeShadowRoots
= allow
;
4540 void nsHtml5TreeBuilder::flushCharacters() {
4541 if (charBufferLen
> 0) {
4542 if ((mode
== IN_TABLE
|| mode
== IN_TABLE_BODY
|| mode
== IN_ROW
) &&
4543 charBufferContainsNonWhitespace()) {
4544 errNonSpaceInTable();
4545 reconstructTheActiveFormattingElements();
4546 if (!stack
[currentPtr
]->isFosterParenting()) {
4547 appendCharacters(currentNode(), charBuffer
, 0, charBufferLen
);
4551 int32_t tablePos
= findLastOrRoot(nsHtml5TreeBuilder::TABLE
);
4552 int32_t templatePos
= findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE
);
4553 if (templatePos
>= tablePos
) {
4554 appendCharacters(stack
[templatePos
]->node
, charBuffer
, 0,
4559 nsHtml5StackNode
* tableElt
= stack
[tablePos
];
4560 insertFosterParentedCharacters(charBuffer
, 0, charBufferLen
,
4561 tableElt
->node
, stack
[tablePos
- 1]->node
);
4565 appendCharacters(currentNode(), charBuffer
, 0, charBufferLen
);
4570 bool nsHtml5TreeBuilder::charBufferContainsNonWhitespace() {
4571 for (int32_t i
= 0; i
< charBufferLen
; i
++) {
4572 switch (charBuffer
[i
]) {
4588 nsAHtml5TreeBuilderState
* nsHtml5TreeBuilder::newSnapshot() {
4589 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4590 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(listPtr
+ 1);
4591 for (int32_t i
= 0; i
< listCopy
.length
; i
++) {
4592 nsHtml5StackNode
* node
= listOfActiveFormattingElements
[i
];
4594 nsHtml5StackNode
* newNode
= new nsHtml5StackNode(-1);
4595 newNode
->setValues(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4596 node
->popName
, node
->attributes
->cloneAttributes(),
4597 node
->getHtmlCreator());
4598 listCopy
[i
] = newNode
;
4600 listCopy
[i
] = nullptr;
4603 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
=
4604 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(currentPtr
+ 1);
4605 for (int32_t i
= 0; i
< stackCopy
.length
; i
++) {
4606 nsHtml5StackNode
* node
= stack
[i
];
4607 int32_t listIndex
= findInListOfActiveFormattingElements(node
);
4608 if (listIndex
== -1) {
4609 nsHtml5StackNode
* newNode
= new nsHtml5StackNode(-1);
4610 newNode
->setValues(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4611 node
->popName
, nullptr, node
->getHtmlCreator());
4612 stackCopy
[i
] = newNode
;
4614 stackCopy
[i
] = listCopy
[listIndex
];
4615 stackCopy
[i
]->retain();
4618 jArray
<int32_t, int32_t> templateModeStackCopy
=
4619 jArray
<int32_t, int32_t>::newJArray(templateModePtr
+ 1);
4620 nsHtml5ArrayCopy::arraycopy(templateModeStack
, templateModeStackCopy
,
4621 templateModeStackCopy
.length
);
4622 return new nsHtml5StateSnapshot(stackCopy
, listCopy
, templateModeStackCopy
,
4623 formPointer
, headPointer
, mode
, originalMode
,
4624 framesetOk
, needToDropLF
, quirks
);
4627 bool nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState
* snapshot
) {
4628 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
= snapshot
->getStack();
4629 int32_t stackLen
= snapshot
->getStackLength();
4630 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4631 snapshot
->getListOfActiveFormattingElements();
4632 int32_t listLen
= snapshot
->getListOfActiveFormattingElementsLength();
4633 jArray
<int32_t, int32_t> templateModeStackCopy
=
4634 snapshot
->getTemplateModeStack();
4635 int32_t templateModeStackLen
= snapshot
->getTemplateModeStackLength();
4636 if (stackLen
!= currentPtr
+ 1 || listLen
!= listPtr
+ 1 ||
4637 templateModeStackLen
!= templateModePtr
+ 1 ||
4638 formPointer
!= snapshot
->getFormPointer() ||
4639 headPointer
!= snapshot
->getHeadPointer() ||
4640 mode
!= snapshot
->getMode() ||
4641 originalMode
!= snapshot
->getOriginalMode() ||
4642 framesetOk
!= snapshot
->isFramesetOk() ||
4643 needToDropLF
!= snapshot
->isNeedToDropLF() ||
4644 quirks
!= snapshot
->isQuirks()) {
4647 for (int32_t i
= listLen
- 1; i
>= 0; i
--) {
4648 if (!listCopy
[i
] && !listOfActiveFormattingElements
[i
]) {
4650 } else if (!listCopy
[i
] || !listOfActiveFormattingElements
[i
]) {
4653 if (listCopy
[i
]->node
!= listOfActiveFormattingElements
[i
]->node
) {
4657 for (int32_t i
= stackLen
- 1; i
>= 0; i
--) {
4658 if (stackCopy
[i
]->node
!= stack
[i
]->node
) {
4662 for (int32_t i
= templateModeStackLen
- 1; i
>= 0; i
--) {
4663 if (templateModeStackCopy
[i
] != templateModeStack
[i
]) {
4670 void nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState
* snapshot
) {
4671 mCurrentHtmlScriptCannotDocumentWriteOrBlock
= false;
4672 jArray
<nsHtml5StackNode
*, int32_t> stackCopy
= snapshot
->getStack();
4673 int32_t stackLen
= snapshot
->getStackLength();
4674 jArray
<nsHtml5StackNode
*, int32_t> listCopy
=
4675 snapshot
->getListOfActiveFormattingElements();
4676 int32_t listLen
= snapshot
->getListOfActiveFormattingElementsLength();
4677 jArray
<int32_t, int32_t> templateModeStackCopy
=
4678 snapshot
->getTemplateModeStack();
4679 int32_t templateModeStackLen
= snapshot
->getTemplateModeStackLength();
4680 for (int32_t i
= 0; i
<= listPtr
; i
++) {
4681 if (listOfActiveFormattingElements
[i
]) {
4682 listOfActiveFormattingElements
[i
]->release(this);
4685 if (listOfActiveFormattingElements
.length
< listLen
) {
4686 listOfActiveFormattingElements
=
4687 jArray
<nsHtml5StackNode
*, int32_t>::newJArray(listLen
);
4689 listPtr
= listLen
- 1;
4690 for (int32_t i
= 0; i
<= currentPtr
; i
++) {
4691 stack
[i
]->release(this);
4693 if (stack
.length
< stackLen
) {
4694 stack
= jArray
<nsHtml5StackNode
*, int32_t>::newJArray(stackLen
);
4696 currentPtr
= stackLen
- 1;
4697 if (templateModeStack
.length
< templateModeStackLen
) {
4699 jArray
<int32_t, int32_t>::newJArray(templateModeStackLen
);
4701 templateModePtr
= templateModeStackLen
- 1;
4702 for (int32_t i
= 0; i
< listLen
; i
++) {
4703 nsHtml5StackNode
* node
= listCopy
[i
];
4705 nsHtml5StackNode
* newNode
= createStackNode(
4706 node
->getFlags(), node
->ns
, node
->name
, node
->node
, node
->popName
,
4707 node
->attributes
->cloneAttributes(), node
->getHtmlCreator());
4708 listOfActiveFormattingElements
[i
] = newNode
;
4710 listOfActiveFormattingElements
[i
] = nullptr;
4713 for (int32_t i
= 0; i
< stackLen
; i
++) {
4714 nsHtml5StackNode
* node
= stackCopy
[i
];
4715 int32_t listIndex
= findInArray(node
, listCopy
);
4716 if (listIndex
== -1) {
4717 nsHtml5StackNode
* newNode
=
4718 createStackNode(node
->getFlags(), node
->ns
, node
->name
, node
->node
,
4719 node
->popName
, nullptr, node
->getHtmlCreator());
4722 stack
[i
] = listOfActiveFormattingElements
[listIndex
];
4726 nsHtml5ArrayCopy::arraycopy(templateModeStackCopy
, templateModeStack
,
4727 templateModeStackLen
);
4728 formPointer
= snapshot
->getFormPointer();
4729 headPointer
= snapshot
->getHeadPointer();
4730 mode
= snapshot
->getMode();
4731 originalMode
= snapshot
->getOriginalMode();
4732 framesetOk
= snapshot
->isFramesetOk();
4733 needToDropLF
= snapshot
->isNeedToDropLF();
4734 quirks
= snapshot
->isQuirks();
4737 int32_t nsHtml5TreeBuilder::findInArray(
4738 nsHtml5StackNode
* node
, jArray
<nsHtml5StackNode
*, int32_t> arr
) {
4739 for (int32_t i
= listPtr
; i
>= 0; i
--) {
4740 if (node
== arr
[i
]) {
4747 nsIContentHandle
* nsHtml5TreeBuilder::nodeFromStackWithBlinkCompat(
4749 if (stackPos
> 511) {
4751 return stack
[511]->node
;
4753 return stack
[stackPos
]->node
;
4756 nsIContentHandle
* nsHtml5TreeBuilder::getFormPointer() { return formPointer
; }
4758 nsIContentHandle
* nsHtml5TreeBuilder::getHeadPointer() { return headPointer
; }
4760 jArray
<nsHtml5StackNode
*, int32_t>
4761 nsHtml5TreeBuilder::getListOfActiveFormattingElements() {
4762 return listOfActiveFormattingElements
;
4765 jArray
<nsHtml5StackNode
*, int32_t> nsHtml5TreeBuilder::getStack() {
4769 jArray
<int32_t, int32_t> nsHtml5TreeBuilder::getTemplateModeStack() {
4770 return templateModeStack
;
4773 int32_t nsHtml5TreeBuilder::getMode() { return mode
; }
4775 int32_t nsHtml5TreeBuilder::getOriginalMode() { return originalMode
; }
4777 bool nsHtml5TreeBuilder::isFramesetOk() { return framesetOk
; }
4779 bool nsHtml5TreeBuilder::isNeedToDropLF() { return needToDropLF
; }
4781 bool nsHtml5TreeBuilder::isQuirks() { return quirks
; }
4783 int32_t nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength() {
4787 int32_t nsHtml5TreeBuilder::getStackLength() { return currentPtr
+ 1; }
4789 int32_t nsHtml5TreeBuilder::getTemplateModeStackLength() {
4790 return templateModePtr
+ 1;
4793 void nsHtml5TreeBuilder::initializeStatics() {}
4795 void nsHtml5TreeBuilder::releaseStatics() {}
4797 #include "nsHtml5TreeBuilderCppSupplement.h"