Modernize and streamline HTMLStackItem
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 17:11:40 +0000 (17:11 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 17:11:40 +0000 (17:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140056

Reviewed by Anders Carlsson.

* html/HTMLHtmlElement.cpp:
(WebCore::HTMLHtmlElement::create): Changed to return Ref.
* html/HTMLHtmlElement.h: Ditto.

* html/parser/HTMLConstructionSite.cpp:
(WebCore::hasImpliedEndTag): Update to use reference instead of pointer.
(WebCore::causesFosterParenting): Moved here from HTMLStackItem.h.
(WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML): Update
for references instead of pointers.
(WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagInBody): Ditto.
(WebCore::HTMLConstructionSite::insertHTMLBodyStartTagInBody): Ditto.
(WebCore::HTMLConstructionSite::insertComment): Ditto.
(WebCore::HTMLConstructionSite::insertCommentOnHTMLHtmlElement): Ditto.
(WebCore::HTMLConstructionSite::insertHTMLHeadElement): Ditto.
(WebCore::HTMLConstructionSite::insertHTMLBodyElement): Ditto.
(WebCore::HTMLConstructionSite::insertHTMLFormElement): Ditto.
(WebCore::HTMLConstructionSite::insertHTMLElement): Ditto.
(WebCore::HTMLConstructionSite::insertSelfClosingHTMLElement): Ditto.
(WebCore::HTMLConstructionSite::insertFormattingElement): Ditto.
(WebCore::HTMLConstructionSite::insertScriptElement): Ditto.
(WebCore::HTMLConstructionSite::insertForeignElement): Ditto.
(WebCore::HTMLConstructionSite::insertTextNode): Ditto.
(WebCore::HTMLConstructionSite::reparent): Ditto.
(WebCore::HTMLConstructionSite::insertAlreadyParsedChild): Ditto.
(WebCore::HTMLConstructionSite::takeAllChildren): Ditto.
(WebCore::HTMLConstructionSite::ownerDocumentForCurrentNode): Ditto.
(WebCore::HTMLConstructionSite::createElementFromSavedToken): Ditto.
(WebCore::HTMLConstructionSite::indexOfFirstUnopenFormattingElement): Ditto.
(WebCore::HTMLConstructionSite::reconstructTheActiveFormattingElements): Ditto.
(WebCore::HTMLConstructionSite::generateImpliedEndTagsWithExclusion): Ditto.
(WebCore::HTMLConstructionSite::findFosterSite): Ditto.
(WebCore::HTMLConstructionSite::shouldFosterParent): Removed unneeded
isElementNode check, since causesFosterParenting will return false for a
document fragment node.

* html/parser/HTMLConstructionSite.h: Updated to use references instead of
pointers. Also removed the unneeded currentElementRecord function.

* html/parser/HTMLElementStack.cpp:
(WebCore::HTMLNames::isRootNode): Updated to use references instead of pointers.
(WebCore::HTMLNames::isScopeMarker): Ditto.
(WebCore::HTMLNames::isListItemScopeMarker): Ditto.
(WebCore::HTMLNames::isTableScopeMarker): Ditto.
(WebCore::HTMLNames::isTableBodyScopeMarker): Ditto.
(WebCore::HTMLNames::isTableRowScopeMarker): Ditto.
(WebCore::HTMLNames::isForeignContentScopeMarker): Ditto.
(WebCore::HTMLNames::isButtonScopeMarker): Ditto.
(WebCore::HTMLNames::isSelectScopeMarker): Ditto.
(WebCore::HTMLElementStack::ElementRecord::replaceElement): Ditto.
(WebCore::HTMLElementStack::hasOnlyOneElement): Ditto.
(WebCore::HTMLElementStack::popHTMLHeadElement): Ditto.
(WebCore::HTMLElementStack::popHTMLBodyElement): Ditto.
(WebCore::HTMLElementStack::popAll): Ditto.
(WebCore::HTMLElementStack::pop): Ditto.
(WebCore::HTMLElementStack::popUntil): Ditto.
(WebCore::HTMLElementStack::popUntilNumberedHeaderElementPopped): Ditto.
(WebCore::HTMLElementStack::isMathMLTextIntegrationPoint): Ditto. Also removed
unneeded isElementNode check.
(WebCore::HTMLElementStack::isHTMLIntegrationPoint): Ditto.
(WebCore::HTMLElementStack::pushRootNode): Ditto.
(WebCore::HTMLElementStack::pushRootNodeCommon): Ditto.
(WebCore::HTMLElementStack::pushHTMLHeadElement): Ditto.
(WebCore::HTMLElementStack::pushHTMLBodyElement): Ditto.
(WebCore::HTMLElementStack::insertAbove): Ditto.
(WebCore::HTMLElementStack::topRecord): Ditto.
(WebCore::HTMLElementStack::oneBelowTop): Ditto.
(WebCore::HTMLElementStack::removeHTMLHeadElement): Ditto.
(WebCore::HTMLElementStack::remove): Ditto.
(WebCore::HTMLElementStack::find): Ditto.
(WebCore::HTMLElementStack::topmost): Ditto.
(WebCore::inScopeCommon): Ditto.
(WebCore::HTMLElementStack::hasNumberedHeaderElementInScope): Ditto.
(WebCore::HTMLElementStack::inScope): Ditto.
(WebCore::HTMLElementStack::htmlElement): Ditto.
(WebCore::HTMLElementStack::headElement): Ditto.
(WebCore::HTMLElementStack::bodyElement): Ditto.
(WebCore::HTMLElementStack::rootNode): Ditto.
(WebCore::HTMLElementStack::popCommon): Ditto.
(WebCore::HTMLElementStack::removeNonTopCommon): Ditto.
(WebCore::HTMLElementStack::furthestBlockForFormattingElement): Ditto.
(WebCore::HTMLElementStack::show): Ditto.

* html/parser/HTMLElementStack.h: Use reference instead of pointer.

* html/parser/HTMLFormattingElementList.cpp:
(WebCore::HTMLFormattingElementList::closestElementInScopeWithName): Update
to use references instead of pointer.
(WebCore::HTMLFormattingElementList::swapTo): Ditto.
(WebCore::HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly): Ditto.
(WebCore::HTMLFormattingElementList::ensureNoahsArkCondition): Ditto.
(WebCore::HTMLFormattingElementList::show): Ditto.

* html/parser/HTMLFormattingElementList.h: Use reference instead of pointer
and a raw pointer instead of a RefPtr.

* html/parser/HTMLStackItem.h: Removed unneeded includes. Got rid of "type"
concept and simply overload the create functions and constructors for both
Element and DOcumentFragment. Renamed isElementNode and isDocumentFragmentNode
to remove the "Node" suffix. Removed unused getAttributeItem, hasLocalName, and
one of the overloads of matchesHTMLTag. Moved all the policy functions such as
causesFosterParenting out of this class into free functions or into other
source files. Got rid of m_isDocumentFragmentNode boolean. Moved function
bodies out of the class definition. Marked all data members const since they
are all initialized in the constructor and never touched again. Restructured
the isSpecialNode function to avoid the repeated checks of the namespace.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::isParsingTemplateContents): Use reference instead of
pointer and free functions instead of member functions.
(WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Ditto.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext): Ditto.
(WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement): Ditto.
(WebCore::HTMLTreeBuilder::constructTree): Ditto.
(WebCore::HTMLTreeBuilder::processFakePEndTagIfPInButtonScope): Ditto.
(WebCore::HTMLTreeBuilder::processCloseWhenNestedTag): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processTemplateStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processTemplateEndTag): Ditto.
(WebCore::HTMLTreeBuilder::processColgroupEndTagForInColumnGroup): Ditto.
(WebCore::HTMLTreeBuilder::closeTheCell): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processHtmlStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processBodyEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::callTheAdoptionAgency): Ditto.
(WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
(WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processCaptionEndTagForInCaption): Ditto.
(WebCore::HTMLTreeBuilder::processTrEndTagForInRow): Ditto.
(WebCore::HTMLTreeBuilder::processTableEndTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTag): Ditto.
(WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
(WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
(WebCore::HTMLTreeBuilder::adjustedCurrentStackItem): Ditto.
(WebCore::HTMLTreeBuilder::shouldProcessTokenInForeignContent): Ditto.
(WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177910 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/html/HTMLHtmlElement.cpp
Source/WebCore/html/HTMLHtmlElement.h
Source/WebCore/html/parser/HTMLConstructionSite.cpp
Source/WebCore/html/parser/HTMLConstructionSite.h
Source/WebCore/html/parser/HTMLElementStack.cpp
Source/WebCore/html/parser/HTMLElementStack.h
Source/WebCore/html/parser/HTMLFormattingElementList.cpp
Source/WebCore/html/parser/HTMLFormattingElementList.h
Source/WebCore/html/parser/HTMLStackItem.h
Source/WebCore/html/parser/HTMLTreeBuilder.cpp

index acc5188..b609d4d 100644 (file)
@@ -1,3 +1,151 @@
+2015-01-05  Darin Adler  <darin@apple.com>
+
+        Modernize and streamline HTMLStackItem
+        https://bugs.webkit.org/show_bug.cgi?id=140056
+
+        Reviewed by Anders Carlsson.
+
+        * html/HTMLHtmlElement.cpp:
+        (WebCore::HTMLHtmlElement::create): Changed to return Ref.
+        * html/HTMLHtmlElement.h: Ditto.
+
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::hasImpliedEndTag): Update to use reference instead of pointer.
+        (WebCore::causesFosterParenting): Moved here from HTMLStackItem.h.
+        (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML): Update
+        for references instead of pointers.
+        (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagInBody): Ditto.
+        (WebCore::HTMLConstructionSite::insertHTMLBodyStartTagInBody): Ditto.
+        (WebCore::HTMLConstructionSite::insertComment): Ditto.
+        (WebCore::HTMLConstructionSite::insertCommentOnHTMLHtmlElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertHTMLHeadElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertHTMLBodyElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertHTMLFormElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertHTMLElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertSelfClosingHTMLElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertFormattingElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertScriptElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertForeignElement): Ditto.
+        (WebCore::HTMLConstructionSite::insertTextNode): Ditto.
+        (WebCore::HTMLConstructionSite::reparent): Ditto.
+        (WebCore::HTMLConstructionSite::insertAlreadyParsedChild): Ditto.
+        (WebCore::HTMLConstructionSite::takeAllChildren): Ditto.
+        (WebCore::HTMLConstructionSite::ownerDocumentForCurrentNode): Ditto.
+        (WebCore::HTMLConstructionSite::createElementFromSavedToken): Ditto.
+        (WebCore::HTMLConstructionSite::indexOfFirstUnopenFormattingElement): Ditto.
+        (WebCore::HTMLConstructionSite::reconstructTheActiveFormattingElements): Ditto.
+        (WebCore::HTMLConstructionSite::generateImpliedEndTagsWithExclusion): Ditto.
+        (WebCore::HTMLConstructionSite::findFosterSite): Ditto.
+        (WebCore::HTMLConstructionSite::shouldFosterParent): Removed unneeded
+        isElementNode check, since causesFosterParenting will return false for a
+        document fragment node.
+
+        * html/parser/HTMLConstructionSite.h: Updated to use references instead of
+        pointers. Also removed the unneeded currentElementRecord function.
+
+        * html/parser/HTMLElementStack.cpp:
+        (WebCore::HTMLNames::isRootNode): Updated to use references instead of pointers.
+        (WebCore::HTMLNames::isScopeMarker): Ditto.
+        (WebCore::HTMLNames::isListItemScopeMarker): Ditto.
+        (WebCore::HTMLNames::isTableScopeMarker): Ditto.
+        (WebCore::HTMLNames::isTableBodyScopeMarker): Ditto.
+        (WebCore::HTMLNames::isTableRowScopeMarker): Ditto.
+        (WebCore::HTMLNames::isForeignContentScopeMarker): Ditto.
+        (WebCore::HTMLNames::isButtonScopeMarker): Ditto.
+        (WebCore::HTMLNames::isSelectScopeMarker): Ditto.
+        (WebCore::HTMLElementStack::ElementRecord::replaceElement): Ditto.
+        (WebCore::HTMLElementStack::hasOnlyOneElement): Ditto.
+        (WebCore::HTMLElementStack::popHTMLHeadElement): Ditto.
+        (WebCore::HTMLElementStack::popHTMLBodyElement): Ditto.
+        (WebCore::HTMLElementStack::popAll): Ditto.
+        (WebCore::HTMLElementStack::pop): Ditto.
+        (WebCore::HTMLElementStack::popUntil): Ditto.
+        (WebCore::HTMLElementStack::popUntilNumberedHeaderElementPopped): Ditto.
+        (WebCore::HTMLElementStack::isMathMLTextIntegrationPoint): Ditto. Also removed
+        unneeded isElementNode check.
+        (WebCore::HTMLElementStack::isHTMLIntegrationPoint): Ditto.
+        (WebCore::HTMLElementStack::pushRootNode): Ditto.
+        (WebCore::HTMLElementStack::pushRootNodeCommon): Ditto.
+        (WebCore::HTMLElementStack::pushHTMLHeadElement): Ditto.
+        (WebCore::HTMLElementStack::pushHTMLBodyElement): Ditto.
+        (WebCore::HTMLElementStack::insertAbove): Ditto.
+        (WebCore::HTMLElementStack::topRecord): Ditto.
+        (WebCore::HTMLElementStack::oneBelowTop): Ditto.
+        (WebCore::HTMLElementStack::removeHTMLHeadElement): Ditto.
+        (WebCore::HTMLElementStack::remove): Ditto.
+        (WebCore::HTMLElementStack::find): Ditto.
+        (WebCore::HTMLElementStack::topmost): Ditto.
+        (WebCore::inScopeCommon): Ditto.
+        (WebCore::HTMLElementStack::hasNumberedHeaderElementInScope): Ditto.
+        (WebCore::HTMLElementStack::inScope): Ditto.
+        (WebCore::HTMLElementStack::htmlElement): Ditto.
+        (WebCore::HTMLElementStack::headElement): Ditto.
+        (WebCore::HTMLElementStack::bodyElement): Ditto.
+        (WebCore::HTMLElementStack::rootNode): Ditto.
+        (WebCore::HTMLElementStack::popCommon): Ditto.
+        (WebCore::HTMLElementStack::removeNonTopCommon): Ditto.
+        (WebCore::HTMLElementStack::furthestBlockForFormattingElement): Ditto.
+        (WebCore::HTMLElementStack::show): Ditto.
+
+        * html/parser/HTMLElementStack.h: Use reference instead of pointer.
+
+        * html/parser/HTMLFormattingElementList.cpp:
+        (WebCore::HTMLFormattingElementList::closestElementInScopeWithName): Update
+        to use references instead of pointer.
+        (WebCore::HTMLFormattingElementList::swapTo): Ditto.
+        (WebCore::HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly): Ditto.
+        (WebCore::HTMLFormattingElementList::ensureNoahsArkCondition): Ditto.
+        (WebCore::HTMLFormattingElementList::show): Ditto.
+
+        * html/parser/HTMLFormattingElementList.h: Use reference instead of pointer
+        and a raw pointer instead of a RefPtr.
+
+        * html/parser/HTMLStackItem.h: Removed unneeded includes. Got rid of "type"
+        concept and simply overload the create functions and constructors for both
+        Element and DOcumentFragment. Renamed isElementNode and isDocumentFragmentNode
+        to remove the "Node" suffix. Removed unused getAttributeItem, hasLocalName, and
+        one of the overloads of matchesHTMLTag. Moved all the policy functions such as
+        causesFosterParenting out of this class into free functions or into other
+        source files. Got rid of m_isDocumentFragmentNode boolean. Moved function
+        bodies out of the class definition. Marked all data members const since they
+        are all initialized in the constructor and never touched again. Restructured
+        the isSpecialNode function to avoid the repeated checks of the namespace.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::isParsingTemplateContents): Use reference instead of
+        pointer and free functions instead of member functions.
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Ditto.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext): Ditto.
+        (WebCore::HTMLTreeBuilder::FragmentParsingContext::contextElement): Ditto.
+        (WebCore::HTMLTreeBuilder::constructTree): Ditto.
+        (WebCore::HTMLTreeBuilder::processFakePEndTagIfPInButtonScope): Ditto.
+        (WebCore::HTMLTreeBuilder::processCloseWhenNestedTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processTemplateStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processTemplateEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processColgroupEndTagForInColumnGroup): Ditto.
+        (WebCore::HTMLTreeBuilder::closeTheCell): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processHtmlStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processBodyEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::callTheAdoptionAgency): Ditto.
+        (WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processCaptionEndTagForInCaption): Ditto.
+        (WebCore::HTMLTreeBuilder::processTrEndTagForInRow): Ditto.
+        (WebCore::HTMLTreeBuilder::processTableEndTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
+        (WebCore::HTMLTreeBuilder::adjustedCurrentStackItem): Ditto.
+        (WebCore::HTMLTreeBuilder::shouldProcessTokenInForeignContent): Ditto.
+        (WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.
+
 2015-01-05  peavo@outlook.com  <peavo@outlook.com>
 
         [WinCairo] Crash when font data pointer is null.
index 783e9b2..c7f517a 100644 (file)
@@ -42,14 +42,14 @@ HTMLHtmlElement::HTMLHtmlElement(const QualifiedName& tagName, Document& documen
     ASSERT(hasTagName(htmlTag));
 }
 
-RefPtr<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
+Ref<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
 {
-    return adoptRef(new HTMLHtmlElement(htmlTag, document));
+    return adoptRef(*new HTMLHtmlElement(htmlTag, document));
 }
 
-RefPtr<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName, Document& document)
+Ref<HTMLHtmlElement> HTMLHtmlElement::create(const QualifiedName& tagName, Document& document)
 {
-    return adoptRef(new HTMLHtmlElement(tagName, document));
+    return adoptRef(*new HTMLHtmlElement(tagName, document));
 }
 
 bool HTMLHtmlElement::isURLAttribute(const Attribute& attribute) const
index 549e08b..44d6d60 100644 (file)
@@ -30,8 +30,8 @@ namespace WebCore {
 
 class HTMLHtmlElement final : public HTMLElement {
 public:
-    static RefPtr<HTMLHtmlElement> create(Document&);
-    static RefPtr<HTMLHtmlElement> create(const QualifiedName&, Document&);
+    static Ref<HTMLHtmlElement> create(Document&);
+    static Ref<HTMLHtmlElement> create(const QualifiedName&, Document&);
 
     void insertedByParser();
 
index 350819b..1f4358f 100644 (file)
@@ -56,18 +56,18 @@ static inline void setAttributes(Element* element, AtomicHTMLToken* token, Parse
     element->parserSetAttributes(token->attributes());
 }
 
-static bool hasImpliedEndTag(const HTMLStackItem* item)
+static bool hasImpliedEndTag(const HTMLStackItem& item)
 {
-    return item->hasTagName(ddTag)
-        || item->hasTagName(dtTag)
-        || item->hasTagName(liTag)
-        || is<HTMLOptionElement>(*item->node())
-        || is<HTMLOptGroupElement>(*item->node())
-        || item->hasTagName(pTag)
-        || item->hasTagName(rbTag)
-        || item->hasTagName(rpTag)
-        || item->hasTagName(rtTag)
-        || item->hasTagName(rtcTag);
+    return item.hasTagName(ddTag)
+        || item.hasTagName(dtTag)
+        || item.hasTagName(liTag)
+        || is<HTMLOptionElement>(item.node())
+        || is<HTMLOptGroupElement>(item.node())
+        || item.hasTagName(pTag)
+        || item.hasTagName(rbTag)
+        || item.hasTagName(rpTag)
+        || item.hasTagName(rtTag)
+        || item.hasTagName(rtcTag);
 }
 
 static bool shouldUseLengthLimit(const ContainerNode* node)
@@ -77,6 +77,15 @@ static bool shouldUseLengthLimit(const ContainerNode* node)
         && !node->hasTagName(SVGNames::scriptTag);
 }
 
+static inline bool causesFosterParenting(const HTMLStackItem& item)
+{
+    return item.hasTagName(HTMLNames::tableTag)
+        || item.hasTagName(HTMLNames::tbodyTag)
+        || item.hasTagName(HTMLNames::tfootTag)
+        || item.hasTagName(HTMLNames::theadTag)
+        || item.hasTagName(HTMLNames::trTag);
+}
+
 static inline bool isAllWhitespace(const String& string)
 {
     return string.isAllSpecialCharacters<isHTMLSpace>();
@@ -250,10 +259,10 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
 
 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
 {
-    RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
-    setAttributes(element.get(), token, m_parserContentPolicy);
-    attachLater(m_attachmentRoot, element);
-    m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(elementtoken));
+    Ref<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
+    setAttributes(element.ptr(), token, m_parserContentPolicy);
+    attachLater(m_attachmentRoot, element.ptr());
+    m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element.copyRef(), *token));
 
     executeQueuedTasks();
     element->insertedByParser();
@@ -279,12 +288,12 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken* token)
     if (m_isParsingFragment)
         return;
 
-    mergeAttributesFromTokenIntoElement(token, m_openElements.htmlElement());
+    mergeAttributesFromTokenIntoElement(token, &m_openElements.htmlElement());
 }
 
 void HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken* token)
 {
-    mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement());
+    mergeAttributesFromTokenIntoElement(token, &m_openElements.bodyElement());
 }
 
 void HTMLConstructionSite::setDefaultCompatibilityMode()
@@ -423,7 +432,7 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token)
 void HTMLConstructionSite::insertComment(AtomicHTMLToken* token)
 {
     ASSERT(token->type() == HTMLToken::Comment);
-    attachLater(currentNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
+    attachLater(&currentNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
 }
 
 void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token)
@@ -435,15 +444,15 @@ void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token)
 void HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken* token)
 {
     ASSERT(token->type() == HTMLToken::Comment);
-    ContainerNode* parent = m_openElements.rootNode();
-    attachLater(parent, Comment::create(parent->document(), token->comment()));
+    ContainerNode& parent = m_openElements.rootNode();
+    attachLater(&parent, Comment::create(parent.document(), token->comment()));
 }
 
 void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token)
 {
     ASSERT(!shouldFosterParent());
-    m_head = HTMLStackItem::create(createHTMLElement(token), token);
-    attachLater(currentNode(), m_head->element());
+    m_head = HTMLStackItem::create(*createHTMLElement(token), *token);
+    attachLater(&currentNode(), &m_head->element());
     m_openElements.pushHTMLHeadElement(m_head);
 }
 
@@ -451,8 +460,8 @@ void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
 {
     ASSERT(!shouldFosterParent());
     RefPtr<Element> body = createHTMLElement(token);
-    attachLater(currentNode(), body);
-    m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
+    attachLater(&currentNode(), body.get());
+    m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.releaseNonNull(), *token));
 }
 
 void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
@@ -461,15 +470,15 @@ void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool is
     ASSERT(is<HTMLFormElement>(*element));
     m_form = static_pointer_cast<HTMLFormElement>(element.release());
     m_form->setDemoted(isDemoted);
-    attachLater(currentNode(), m_form);
-    m_openElements.push(HTMLStackItem::create(m_form, token));
+    attachLater(&currentNode(), m_form);
+    m_openElements.push(HTMLStackItem::create(*m_form, *token));
 }
 
 void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
 {
     RefPtr<Element> element = createHTMLElement(token);
-    attachLater(currentNode(), element);
-    m_openElements.push(HTMLStackItem::create(element.release(), token));
+    attachLater(&currentNode(), element);
+    m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
 }
 
 void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
@@ -478,7 +487,7 @@ void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
     // Normally HTMLElementStack is responsible for calling finishParsingChildren,
     // but self-closing elements are never in the element stack so the stack
     // doesn't get a chance to tell them that we're done parsing their children.
-    attachLater(currentNode(), createHTMLElement(token), true);
+    attachLater(&currentNode(), createHTMLElement(token), true);
     // FIXME: Do we want to acknowledge the token's self-closing flag?
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#acknowledge-self-closing-flag
 }
@@ -489,7 +498,7 @@ void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken* token)
     // Possible active formatting elements include:
     // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
     insertHTMLElement(token);
-    m_activeFormattingElements.append(currentElementRecord()->stackItem());
+    m_activeFormattingElements.append(&currentStackItem());
 }
 
 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
@@ -504,8 +513,8 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
     RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
     setAttributes(element.get(), token, m_parserContentPolicy);
     if (scriptingContentIsAllowed(m_parserContentPolicy))
-        attachLater(currentNode(), element);
-    m_openElements.push(HTMLStackItem::create(element.release(), token));
+        attachLater(&currentNode(), element);
+    m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
 }
 
 void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
@@ -515,15 +524,15 @@ void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At
 
     RefPtr<Element> element = createElement(token, namespaceURI);
     if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptElementIfPossible(element.get()))
-        attachLater(currentNode(), element, token->selfClosing());
+        attachLater(&currentNode(), element, token->selfClosing());
     if (!token->selfClosing())
-        m_openElements.push(HTMLStackItem::create(element.release(), token, namespaceURI));
+        m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token, namespaceURI));
 }
 
 void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMode whitespaceMode)
 {
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
-    task.parent = currentNode();
+    task.parent = &currentNode();
 
     if (shouldFosterParent())
         findFosterSite(task);
@@ -571,37 +580,37 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo
 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord& newParent, HTMLElementStack::ElementRecord& child)
 {
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
-    task.parent = newParent.node();
-    task.child = child.element();
+    task.parent = &newParent.node();
+    task.child = &child.element();
     m_taskQueue.append(task);
 }
 
 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord& newParent, HTMLStackItem& child)
 {
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
-    task.parent = newParent.node();
-    task.child = child.element();
+    task.parent = &newParent.node();
+    task.child = &child.element();
     m_taskQueue.append(task);
 }
 
 void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& child)
 {
-    if (newParent.causesFosterParenting()) {
-        fosterParent(child.element());
+    if (causesFosterParenting(newParent)) {
+        fosterParent(&child.element());
         return;
     }
 
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertAlreadyParsedChild);
-    task.parent = newParent.node();
-    task.child = child.element();
+    task.parent = &newParent.node();
+    task.child = &child.element();
     m_taskQueue.append(task);
 }
 
 void HTMLConstructionSite::takeAllChildren(HTMLStackItem& newParent, HTMLElementStack::ElementRecord& oldParent)
 {
     HTMLConstructionSiteTask task(HTMLConstructionSiteTask::TakeAllChildren);
-    task.parent = newParent.node();
-    task.child = oldParent.node();
+    task.parent = &newParent.node();
+    task.child = &oldParent.node();
     m_taskQueue.append(task);
 }
 
@@ -616,10 +625,10 @@ PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token,
 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
 {
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (is<HTMLTemplateElement>(*currentNode()))
-        return downcast<HTMLTemplateElement>(*currentElement()).content()->document();
+    if (is<HTMLTemplateElement>(currentNode()))
+        return downcast<HTMLTemplateElement>(currentNode()).content()->document();
 #endif
-    return currentNode()->document();
+    return currentNode().document();
 }
 
 PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
@@ -646,7 +655,7 @@ PassRefPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTML
         element = createHTMLElement(&fakeToken);
     else
         element = createElement(&fakeToken, item->namespaceURI());
-    return HTMLStackItem::create(element.release(), &fakeToken, item->namespaceURI());
+    return HTMLStackItem::create(element.releaseNonNull(), fakeToken, item->namespaceURI());
 }
 
 bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
@@ -657,7 +666,7 @@ bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUn
     do {
         --index;
         const HTMLFormattingElementList::Entry& entry = m_activeFormattingElements.at(index);
-        if (entry.isMarker() || m_openElements.contains(entry.element())) {
+        if (entry.isMarker() || m_openElements.contains(&entry.element())) {
             firstUnopenElementIndex = index + 1;
             return firstUnopenElementIndex < m_activeFormattingElements.size();
         }
@@ -676,8 +685,8 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
     ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
     for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
         HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
-        RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
-        attachLater(currentNode(), reconstructed->node());
+        RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem());
+        attachLater(&currentNode(), &reconstructed->node());
         m_openElements.push(reconstructed);
         unopenedEntry.replaceElement(reconstructed.release());
     }
@@ -685,7 +694,7 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
 
 void HTMLConstructionSite::generateImpliedEndTagsWithExclusion(const AtomicString& tagName)
 {
-    while (hasImpliedEndTag(currentStackItem()) && !currentStackItem()->matchesHTMLTag(tagName))
+    while (hasImpliedEndTag(currentStackItem()) && !currentStackItem().matchesHTMLTag(tagName))
         m_openElements.pop();
 }
 
@@ -706,7 +715,7 @@ void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task)
     // When a node is to be foster parented, the last template element with no table element is below it in the stack of open elements is the foster parent element (NOT the template's parent!)
     HTMLElementStack::ElementRecord* lastTemplateElement = m_openElements.topmost(templateTag.localName());
     if (lastTemplateElement && !m_openElements.inTableScope(tableTag)) {
-        task.parent = lastTemplateElement->element();
+        task.parent = &lastTemplateElement->element();
         return;
     }
 
@@ -714,31 +723,30 @@ void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task)
 
     HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName());
     if (lastTableElementRecord) {
-        Element* lastTableElement = lastTableElementRecord->element();
-        ContainerNode* parent = lastTableElement->parentNode();
+        Element& lastTableElement = lastTableElementRecord->element();
+        ContainerNode* parent = lastTableElement.parentNode();
         // When parsing HTML fragments, we skip step 4.2 ("Let root be a new html element with no attributes") for efficiency,
         // and instead use the DocumentFragment as a root node. So we must treat the root node (DocumentFragment) as if it is a html element here.
-        bool parentCanBeFosterParent = parent && (parent->isElementNode() || (m_isParsingFragment && parent == m_openElements.rootNode()));
+        bool parentCanBeFosterParent = parent && (parent->isElementNode() || (m_isParsingFragment && parent == &m_openElements.rootNode()));
 #if ENABLE(TEMPLATE_ELEMENT)
         parentCanBeFosterParent = parentCanBeFosterParent || (is<DocumentFragment>(parent) && downcast<DocumentFragment>(parent)->isTemplateContent());
 #endif
         if (parentCanBeFosterParent) {
             task.parent = parent;
-            task.nextChild = lastTableElement;
+            task.nextChild = &lastTableElement;
             return;
         }
-        task.parent = lastTableElementRecord->next()->element();
+        task.parent = &lastTableElementRecord->next()->element();
         return;
     }
     // Fragment case
-    task.parent = m_openElements.rootNode(); // DocumentFragment
+    task.parent = &m_openElements.rootNode(); // DocumentFragment
 }
 
 bool HTMLConstructionSite::shouldFosterParent() const
 {
     return m_redirectAttachToFosterParent
-        && currentStackItem()->isElementNode()
-        && currentStackItem()->causesFosterParenting();
+        && causesFosterParenting(currentStackItem());
 }
 
 void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
index 36adf2b..af73bec 100644 (file)
@@ -138,17 +138,16 @@ public:
     bool inQuirksMode();
 
     bool isEmpty() const { return !m_openElements.stackDepth(); }
-    HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
-    Element* currentElement() const { return m_openElements.top(); }
-    ContainerNode* currentNode() const { return m_openElements.topNode(); }
-    HTMLStackItem* currentStackItem() const { return m_openElements.topStackItem(); }
+    Element& currentElement() const { return m_openElements.top(); }
+    ContainerNode& currentNode() const { return m_openElements.topNode(); }
+    HTMLStackItem& currentStackItem() const { return m_openElements.topStackItem(); }
     HTMLStackItem* oneBelowTop() const { return m_openElements.oneBelowTop(); }
     Document& ownerDocumentForCurrentNode();
-    HTMLElementStack* openElements() const { return &m_openElements; }
-    HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
-    bool currentIsRootNode() { return m_openElements.topNode() == m_openElements.rootNode(); }
+    HTMLElementStack& openElements() const { return m_openElements; }
+    HTMLFormattingElementList& activeFormattingElements() const { return m_activeFormattingElements; }
+    bool currentIsRootNode() { return &m_openElements.topNode() == &m_openElements.rootNode(); }
 
-    Element* head() const { return m_head->element(); }
+    Element& head() const { return m_head->element(); }
     HTMLStackItem* headStackItem() const { return m_head.get(); }
 
     void setForm(HTMLFormElement*);
index 397d1e6..b2a0aea 100644 (file)
@@ -36,91 +36,90 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-
 namespace {
 
-inline bool isRootNode(HTMLStackItem* item)
-{
-    return item->isDocumentFragmentNode()
-        || item->hasTagName(htmlTag);
-}
-
-inline bool isScopeMarker(HTMLStackItem* item)
-{
-    return item->hasTagName(appletTag)
-        || item->hasTagName(captionTag)
-        || item->hasTagName(marqueeTag)
-        || item->hasTagName(objectTag)
-        || is<HTMLTableElement>(*item->node())
-        || item->hasTagName(tdTag)
-        || item->hasTagName(thTag)
-        || item->hasTagName(MathMLNames::miTag)
-        || item->hasTagName(MathMLNames::moTag)
-        || item->hasTagName(MathMLNames::mnTag)
-        || item->hasTagName(MathMLNames::msTag)
-        || item->hasTagName(MathMLNames::mtextTag)
-        || item->hasTagName(MathMLNames::annotation_xmlTag)
-        || item->hasTagName(SVGNames::foreignObjectTag)
-        || item->hasTagName(SVGNames::descTag)
-        || item->hasTagName(SVGNames::titleTag)
+inline bool isRootNode(HTMLStackItem& item)
+{
+    return item.isDocumentFragment()
+        || item.hasTagName(htmlTag);
+}
+
+inline bool isScopeMarker(HTMLStackItem& item)
+{
+    return item.hasTagName(appletTag)
+        || item.hasTagName(captionTag)
+        || item.hasTagName(marqueeTag)
+        || item.hasTagName(objectTag)
+        || is<HTMLTableElement>(item.node())
+        || item.hasTagName(tdTag)
+        || item.hasTagName(thTag)
+        || item.hasTagName(MathMLNames::miTag)
+        || item.hasTagName(MathMLNames::moTag)
+        || item.hasTagName(MathMLNames::mnTag)
+        || item.hasTagName(MathMLNames::msTag)
+        || item.hasTagName(MathMLNames::mtextTag)
+        || item.hasTagName(MathMLNames::annotation_xmlTag)
+        || item.hasTagName(SVGNames::foreignObjectTag)
+        || item.hasTagName(SVGNames::descTag)
+        || item.hasTagName(SVGNames::titleTag)
 #if ENABLE(TEMPLATE_ELEMENT)
-        || item->hasTagName(templateTag)
+        || item.hasTagName(templateTag)
 #endif
         || isRootNode(item);
 }
 
-inline bool isListItemScopeMarker(HTMLStackItem* item)
+inline bool isListItemScopeMarker(HTMLStackItem& item)
 {
     return isScopeMarker(item)
-        || item->hasTagName(olTag)
-        || item->hasTagName(ulTag);
+        || item.hasTagName(olTag)
+        || item.hasTagName(ulTag);
 }
 
-inline bool isTableScopeMarker(HTMLStackItem* item)
+inline bool isTableScopeMarker(HTMLStackItem& item)
 {
-    return is<HTMLTableElement>(*item->node())
+    return is<HTMLTableElement>(item.node())
 #if ENABLE(TEMPLATE_ELEMENT)
-        || item->hasTagName(templateTag)
+        || item.hasTagName(templateTag)
 #endif
         || isRootNode(item);
 }
 
-inline bool isTableBodyScopeMarker(HTMLStackItem* item)
+inline bool isTableBodyScopeMarker(HTMLStackItem& item)
 {
-    return item->hasTagName(tbodyTag)
-        || item->hasTagName(tfootTag)
-        || item->hasTagName(theadTag)
+    return item.hasTagName(tbodyTag)
+        || item.hasTagName(tfootTag)
+        || item.hasTagName(theadTag)
 #if ENABLE(TEMPLATE_ELEMENT)
-        || item->hasTagName(templateTag)
+        || item.hasTagName(templateTag)
 #endif
         || isRootNode(item);
 }
 
-inline bool isTableRowScopeMarker(HTMLStackItem* item)
+inline bool isTableRowScopeMarker(HTMLStackItem& item)
 {
-    return item->hasTagName(trTag)
+    return item.hasTagName(trTag)
 #if ENABLE(TEMPLATE_ELEMENT)
-        || item->hasTagName(templateTag)
+        || item.hasTagName(templateTag)
 #endif
         || isRootNode(item);
 }
 
-inline bool isForeignContentScopeMarker(HTMLStackItem* item)
+inline bool isForeignContentScopeMarker(HTMLStackItem& item)
 {
     return HTMLElementStack::isMathMLTextIntegrationPoint(item)
         || HTMLElementStack::isHTMLIntegrationPoint(item)
-        || item->isInHTMLNamespace();
+        || isInHTMLNamespace(item);
 }
 
-inline bool isButtonScopeMarker(HTMLStackItem* item)
+inline bool isButtonScopeMarker(HTMLStackItem& item)
 {
     return isScopeMarker(item)
-        || item->hasTagName(buttonTag);
+        || item.hasTagName(buttonTag);
 }
 
-inline bool isSelectScopeMarker(HTMLStackItem* item)
+inline bool isSelectScopeMarker(HTMLStackItem& item)
 {
-    return !is<HTMLOptGroupElement>(*item->node()) && !is<HTMLOptionElement>(*item->node());
+    return !is<HTMLOptGroupElement>(item.node()) && !is<HTMLOptionElement>(item.node());
 }
 
 }
@@ -139,7 +138,7 @@ HTMLElementStack::ElementRecord::~ElementRecord()
 void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<HTMLStackItem> item)
 {
     ASSERT(item);
-    ASSERT(!m_item || m_item->isElementNode());
+    ASSERT(!m_item || m_item->isElement());
     // FIXME: Should this call finishParsingChildren?
     m_item = item;
 }
@@ -167,7 +166,7 @@ HTMLElementStack::~HTMLElementStack()
 
 bool HTMLElementStack::hasOnlyOneElement() const
 {
-    return !topRecord()->next();
+    return !topRecord().next();
 }
 
 bool HTMLElementStack::secondElementIsHTMLBodyElement() const
@@ -184,15 +183,15 @@ bool HTMLElementStack::secondElementIsHTMLBodyElement() const
 
 void HTMLElementStack::popHTMLHeadElement()
 {
-    ASSERT(top() == m_headElement);
-    m_headElement = 0;
+    ASSERT(&top() == m_headElement);
+    m_headElement = nullptr;
     popCommon();
 }
 
 void HTMLElementStack::popHTMLBodyElement()
 {
-    ASSERT(top() == m_bodyElement);
-    m_bodyElement = 0;
+    ASSERT(&top() == m_bodyElement);
+    m_bodyElement = nullptr;
     popCommon();
 }
 
@@ -203,20 +202,20 @@ void HTMLElementStack::popAll()
     m_bodyElement = 0;
     m_stackDepth = 0;
     while (m_top) {
-        topNode()->finishParsingChildren();
+        topNode().finishParsingChildren();
         m_top = m_top->releaseNext();
     }
 }
 
 void HTMLElementStack::pop()
 {
-    ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag));
+    ASSERT(!topStackItem().hasTagName(HTMLNames::headTag));
     popCommon();
 }
 
 void HTMLElementStack::popUntil(const AtomicString& tagName)
 {
-    while (!topStackItem()->matchesHTMLTag(tagName)) {
+    while (!topStackItem().matchesHTMLTag(tagName)) {
         // pop() will ASSERT if a <body>, <head> or <html> will be popped.
         pop();
     }
@@ -230,14 +229,14 @@ void HTMLElementStack::popUntilPopped(const AtomicString& tagName)
 
 void HTMLElementStack::popUntilNumberedHeaderElementPopped()
 {
-    while (!topStackItem()->isNumberedHeaderElement())
+    while (!isNumberedHeaderElement(topStackItem()))
         pop();
     pop();
 }
 
 void HTMLElementStack::popUntil(Element* element)
 {
-    while (top() != element)
+    while (&top() != element)
         pop();
 }
 
@@ -269,24 +268,20 @@ void HTMLElementStack::popUntilTableRowScopeMarker()
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#mathml-text-integration-point
-bool HTMLElementStack::isMathMLTextIntegrationPoint(HTMLStackItem* item)
+bool HTMLElementStack::isMathMLTextIntegrationPoint(HTMLStackItem& item)
 {
-    if (!item->isElementNode())
-        return false;
-    return item->hasTagName(MathMLNames::miTag)
-        || item->hasTagName(MathMLNames::moTag)
-        || item->hasTagName(MathMLNames::mnTag)
-        || item->hasTagName(MathMLNames::msTag)
-        || item->hasTagName(MathMLNames::mtextTag);
+    return item.hasTagName(MathMLNames::miTag)
+        || item.hasTagName(MathMLNames::moTag)
+        || item.hasTagName(MathMLNames::mnTag)
+        || item.hasTagName(MathMLNames::msTag)
+        || item.hasTagName(MathMLNames::mtextTag);
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#html-integration-point
-bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem* item)
+bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem& item)
 {
-    if (!item->isElementNode())
-        return false;
-    if (item->hasTagName(MathMLNames::annotation_xmlTag)) {
-        Attribute* encodingAttr = item->getAttributeItem(MathMLNames::encodingAttr);
+    if (item.hasTagName(MathMLNames::annotation_xmlTag)) {
+        const Attribute* encodingAttr = item.findAttribute(MathMLNames::encodingAttr);
         if (encodingAttr) {
             const String& encoding = encodingAttr->value();
             return equalIgnoringCase(encoding, "text/html")
@@ -294,9 +289,9 @@ bool HTMLElementStack::isHTMLIntegrationPoint(HTMLStackItem* item)
         }
         return false;
     }
-    return item->hasTagName(SVGNames::foreignObjectTag)
-        || item->hasTagName(SVGNames::descTag)
-        || item->hasTagName(SVGNames::titleTag);
+    return item.hasTagName(SVGNames::foreignObjectTag)
+        || item.hasTagName(SVGNames::descTag)
+        || item.hasTagName(SVGNames::titleTag);
 }
 
 void HTMLElementStack::popUntilForeignContentScopeMarker()
@@ -307,7 +302,7 @@ void HTMLElementStack::popUntilForeignContentScopeMarker()
     
 void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
 {
-    ASSERT(rootItem->isDocumentFragmentNode());
+    ASSERT(rootItem->isDocumentFragment());
     pushRootNodeCommon(rootItem);
 }
 
@@ -321,7 +316,7 @@ void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
 {
     ASSERT(!m_top);
     ASSERT(!m_rootNode);
-    m_rootNode = rootItem->node();
+    m_rootNode = &rootItem->node();
     pushCommon(rootItem);
 }
 
@@ -329,7 +324,7 @@ void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
 {
     ASSERT(item->hasTagName(HTMLNames::headTag));
     ASSERT(!m_headElement);
-    m_headElement = item->element();
+    m_headElement = &item->element();
     pushCommon(item);
 }
 
@@ -337,7 +332,7 @@ void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
 {
     ASSERT(item->hasTagName(HTMLNames::bodyTag));
     ASSERT(!m_bodyElement);
-    m_bodyElement = item->element();
+    m_bodyElement = &item->element();
     pushCommon(item);
 }
 
@@ -370,16 +365,16 @@ void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord
 
         m_stackDepth++;
         recordAbove->setNext(std::make_unique<ElementRecord>(item, recordAbove->releaseNext()));
-        recordAbove->next()->element()->beginParsingChildren();
+        recordAbove->next()->element().beginParsingChildren();
         return;
     }
     ASSERT_NOT_REACHED();
 }
 
-HTMLElementStack::ElementRecord* HTMLElementStack::topRecord() const
+HTMLElementStack::ElementRecord& HTMLElementStack::topRecord() const
 {
     ASSERT(m_top);
-    return m_top.get();
+    return *m_top;
 }
 
 HTMLStackItem* HTMLElementStack::oneBelowTop() const
@@ -387,26 +382,26 @@ HTMLStackItem* HTMLElementStack::oneBelowTop() const
     // We should never call this if there are fewer than 2 elements on the stack.
     ASSERT(m_top);
     ASSERT(m_top->next());
-    if (m_top->next()->stackItem()->isElementNode())
-        return m_top->next()->stackItem().get();
-    return 0;
+    if (m_top->next()->stackItem().isElement())
+        return &m_top->next()->stackItem();
+    return nullptr;
 }
 
 void HTMLElementStack::removeHTMLHeadElement(Element* element)
 {
     ASSERT(m_headElement == element);
-    if (m_top->element() == element) {
+    if (&m_top->element() == element) {
         popHTMLHeadElement();
         return;
     }
-    m_headElement = 0;
+    m_headElement = nullptr;
     removeNonTopCommon(element);
 }
 
 void HTMLElementStack::remove(Element* element)
 {
     ASSERT(!element->hasTagName(HTMLNames::headTag));
-    if (m_top->element() == element) {
+    if (&m_top->element() == element) {
         pop();
         return;
     }
@@ -415,20 +410,20 @@ void HTMLElementStack::remove(Element* element)
 
 HTMLElementStack::ElementRecord* HTMLElementStack::find(Element* element) const
 {
-    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-        if (pos->node() == element)
-            return pos;
+    for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+        if (&record->node() == element)
+            return record;
     }
-    return 0;
+    return nullptr;
 }
 
 HTMLElementStack::ElementRecord* HTMLElementStack::topmost(const AtomicString& tagName) const
 {
-    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-        if (pos->stackItem()->matchesHTMLTag(tagName))
-            return pos;
+    for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+        if (record->stackItem().matchesHTMLTag(tagName))
+            return record;
     }
-    return 0;
+    return nullptr;
 }
 
 bool HTMLElementStack::contains(Element* element) const
@@ -441,12 +436,11 @@ bool HTMLElementStack::contains(const AtomicString& tagName) const
     return !!topmost(tagName);
 }
 
-template <bool isMarker(HTMLStackItem*)>
-bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag)
+template <bool isMarker(HTMLStackItem&)> bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag)
 {
-    for (HTMLElementStack::ElementRecord* pos = top; pos; pos = pos->next()) {
-        HTMLStackItem* item = pos->stackItem().get();
-        if (item->matchesHTMLTag(targetTag))
+    for (auto* record = top; record; record = record->next()) {
+        HTMLStackItem& item = record->stackItem();
+        if (item.matchesHTMLTag(targetTag))
             return true;
         if (isMarker(item))
             return false;
@@ -458,8 +452,8 @@ bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& tar
 bool HTMLElementStack::hasNumberedHeaderElementInScope() const
 {
     for (ElementRecord* record = m_top.get(); record; record = record->next()) {
-        HTMLStackItem* item = record->stackItem().get();
-        if (item->isNumberedHeaderElement())
+        HTMLStackItem& item = record->stackItem();
+        if (isNumberedHeaderElement(item))
             return true;
         if (isScopeMarker(item))
             return false;
@@ -470,9 +464,9 @@ bool HTMLElementStack::hasNumberedHeaderElementInScope() const
 
 bool HTMLElementStack::inScope(Element* targetElement) const
 {
-    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-        HTMLStackItem* item = pos->stackItem().get();
-        if (item->node() == targetElement)
+    for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+        HTMLStackItem& item = record->stackItem();
+        if (&item.node() == targetElement)
             return true;
         if (isScopeMarker(item))
             return false;
@@ -538,28 +532,27 @@ bool HTMLElementStack::hasTemplateInHTMLScope() const
 }
 #endif
 
-Element* HTMLElementStack::htmlElement() const
+Element& HTMLElementStack::htmlElement() const
 {
-    ASSERT(m_rootNode);
-    return downcast<Element>(m_rootNode);
+    return downcast<Element>(rootNode());
 }
 
-Element* HTMLElementStack::headElement() const
+Element& HTMLElementStack::headElement() const
 {
     ASSERT(m_headElement);
-    return m_headElement;
+    return *m_headElement;
 }
 
-Element* HTMLElementStack::bodyElement() const
+Element& HTMLElementStack::bodyElement() const
 {
     ASSERT(m_bodyElement);
-    return m_bodyElement;
+    return *m_bodyElement;
 }
     
-ContainerNode* HTMLElementStack::rootNode() const
+ContainerNode& HTMLElementStack::rootNode() const
 {
     ASSERT(m_rootNode);
-    return m_rootNode;
+    return *m_rootNode;
 }
 
 void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
@@ -572,10 +565,11 @@ void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
 
 void HTMLElementStack::popCommon()
 {
-    ASSERT(!topStackItem()->hasTagName(HTMLNames::htmlTag));
-    ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag) || !m_headElement);
-    ASSERT(!topStackItem()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
-    top()->finishParsingChildren();
+    ASSERT(!topStackItem().hasTagName(HTMLNames::htmlTag));
+    ASSERT(!topStackItem().hasTagName(HTMLNames::headTag) || !m_headElement);
+    ASSERT(!topStackItem().hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
+
+    top().finishParsingChildren();
     m_top = m_top->releaseNext();
 
     m_stackDepth--;
@@ -585,13 +579,13 @@ void HTMLElementStack::removeNonTopCommon(Element* element)
 {
     ASSERT(!element->hasTagName(HTMLNames::htmlTag));
     ASSERT(!element->hasTagName(HTMLNames::bodyTag));
-    ASSERT(top() != element);
-    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-        if (pos->next()->element() == element) {
+    ASSERT(&top() != element);
+    for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+        if (&record->next()->element() == element) {
             // FIXME: Is it OK to call finishParsingChildren()
             // when the children aren't actually finished?
             element->finishParsingChildren();
-            pos->setNext(pos->next()->releaseNext());
+            record->setNext(record->next()->releaseNext());
             m_stackDepth--;
             return;
         }
@@ -601,15 +595,15 @@ void HTMLElementStack::removeNonTopCommon(Element* element)
 
 HTMLElementStack::ElementRecord* HTMLElementStack::furthestBlockForFormattingElement(Element* formattingElement) const
 {
-    ElementRecord* furthestBlock = 0;
-    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-        if (pos->element() == formattingElement)
+    ElementRecord* furthestBlock = nullptr;
+    for (ElementRecord* record = m_top.get(); record; record = record->next()) {
+        if (&record->element() == formattingElement)
             return furthestBlock;
-        if (pos->stackItem()->isSpecialNode())
-            furthestBlock = pos;
+        if (isSpecialNode(record->stackItem()))
+            furthestBlock = record;
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 #ifndef NDEBUG
@@ -617,7 +611,7 @@ HTMLElementStack::ElementRecord* HTMLElementStack::furthestBlockForFormattingEle
 void HTMLElementStack::show()
 {
     for (ElementRecord* record = m_top.get(); record; record = record->next())
-        record->element()->showNode();
+        record->element().showNode();
 }
 
 #endif
index 377d114..1335129 100644 (file)
@@ -53,15 +53,16 @@ public:
         ElementRecord(PassRefPtr<HTMLStackItem>, std::unique_ptr<ElementRecord>);
         ~ElementRecord();
     
-        Element* element() const { return m_item->element(); }
-        ContainerNode* node() const { return m_item->node(); }
+        Element& element() const { return m_item->element(); }
+        ContainerNode& node() const { return m_item->node(); }
         const AtomicString& namespaceURI() const { return m_item->namespaceURI(); }
-        PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
+        HTMLStackItem& stackItem() const { return *m_item; }
         void replaceElement(PassRefPtr<HTMLStackItem>);
 
         bool isAbove(ElementRecord*) const;
 
         ElementRecord* next() const { return m_next.get(); }
+
     private:
         friend class HTMLElementStack;
 
@@ -76,26 +77,23 @@ public:
 
     // Inlining this function is a (small) performance win on the parsing
     // benchmark.
-    Element* top() const
+    Element& top() const
     {
-        ASSERT(m_top->element());
         return m_top->element();
     }
 
-    ContainerNode* topNode() const
+    ContainerNode& topNode() const
     {
-        ASSERT(m_top->node());
         return m_top->node();
     }
 
-    HTMLStackItem* topStackItem() const
+    HTMLStackItem& topStackItem() const
     {
-        ASSERT(m_top->stackItem());
-        return m_top->stackItem().get();
+        return m_top->stackItem();
     }
 
     HTMLStackItem* oneBelowTop() const;
-    ElementRecord* topRecord() const;
+    ElementRecord& topRecord() const;
     ElementRecord* find(Element*) const;
     ElementRecord* furthestBlockForFormattingElement(Element*) const;
     ElementRecord* topmost(const AtomicString& tagName) const;
@@ -124,8 +122,8 @@ public:
     void popHTMLBodyElement();
     void popAll();
 
-    static bool isMathMLTextIntegrationPoint(HTMLStackItem*);
-    static bool isHTMLIntegrationPoint(HTMLStackItem*);
+    static bool isMathMLTextIntegrationPoint(HTMLStackItem&);
+    static bool isHTMLIntegrationPoint(HTMLStackItem&);
 
     void remove(Element*);
     void removeHTMLHeadElement(Element*);
@@ -152,11 +150,11 @@ public:
 #if ENABLE(TEMPLATE_ELEMENT)
     bool hasTemplateInHTMLScope() const;
 #endif
-    Element* htmlElement() const;
-    Element* headElement() const;
-    Element* bodyElement() const;
-    
-    ContainerNode* rootNode() const;
+    Element& htmlElement() const;
+    Element& headElement() const;
+    Element& bodyElement() const;
+
+    ContainerNode& rootNode() const;
 
 #ifndef NDEBUG
     void show();
index bd07ab1..4ff6858 100644 (file)
@@ -50,11 +50,11 @@ Element* HTMLFormattingElementList::closestElementInScopeWithName(const AtomicSt
     for (unsigned i = 1; i <= m_entries.size(); ++i) {
         const Entry& entry = m_entries[m_entries.size() - i];
         if (entry.isMarker())
-            return 0;
+            return nullptr;
         if (entry.stackItem()->matchesHTMLTag(targetName))
-            return entry.element();
+            return &entry.element();
     }
-    return 0;
+    return nullptr;
 }
 
 bool HTMLFormattingElementList::contains(Element* element)
@@ -82,9 +82,9 @@ HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Eleme
 void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
 {
     ASSERT(contains(oldElement));
-    ASSERT(!contains(newItem->element()));
+    ASSERT(!contains(&newItem->element()));
     if (!bookmark.hasBeenMoved()) {
-        ASSERT(bookmark.mark()->element() == oldElement);
+        ASSERT(&bookmark.mark()->element() == oldElement);
         bookmark.mark()->replaceElement(newItem);
         return;
     }
@@ -143,7 +143,7 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
             break;
 
         // Quickly reject obviously non-matching candidates.
-        HTMLStackItem* candidate = entry.stackItem().get();
+        HTMLStackItem* candidate = entry.stackItem();
         if (newItem->localName() != candidate->localName() || newItem->namespaceURI() != candidate->namespaceURI())
             continue;
         if (candidate->attributes().size() != newItemAttributeCount)
@@ -181,7 +181,7 @@ void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
             ASSERT(newItem->attributes().size() == candidate->attributes().size());
             ASSERT(newItem->localName() == candidate->localName() && newItem->namespaceURI() == candidate->namespaceURI());
 
-            Attribute* candidateAttribute = candidate->getAttributeItem(attribute.name());
+            const Attribute* candidateAttribute = candidate->findAttribute(attribute.name());
             if (candidateAttribute && candidateAttribute->value() == attribute.value())
                 remainingCandidates.append(candidate);
         }
@@ -197,7 +197,7 @@ void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
     // however, that we wil spin the loop more than once because of how the
     // formatting element list gets permuted.
     for (size_t i = kNoahsArkCapacity - 1; i < candidates.size(); ++i)
-        remove(candidates[i]->element());
+        remove(&candidates[i]->element());
 }
 
 #ifndef NDEBUG
@@ -209,7 +209,7 @@ void HTMLFormattingElementList::show()
         if (entry.isMarker())
             fprintf(stderr, "marker\n");
         else
-            entry.element()->showNode();
+            entry.element().showNode();
     }
 }
 
index 35ac17c..8439cc3 100644 (file)
@@ -61,8 +61,8 @@ public:
 
         bool isMarker() const { return !m_item; }
 
-        PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
-        Element* element() const
+        HTMLStackItem* stackItem() const { return m_item.get(); }
+        Element& element() const
         {
             // The fact that !m_item == isMarker() is an implementation detail
             // callers should check isMarker() before calling element().
@@ -72,8 +72,8 @@ public:
         void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
 
         // Needed for use with Vector.  These are super-hot and must be inline.
-        bool operator==(Element* element) const { return !m_item ? !element : m_item->element() == element; }
-        bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
+        bool operator==(Element* element) const { return !m_item ? !element : &m_item->element() == element; }
+        bool operator!=(Element* element) const { return !m_item ? !!element : &m_item->element() != element; }
 
     private:
         RefPtr<HTMLStackItem> m_item;
index 3d95511..dd6a227 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Company 100, Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define HTMLStackItem_h
 
 #include "AtomicHTMLToken.h"
+#include "DocumentFragment.h"
 #include "Element.h"
 #include "HTMLNames.h"
 #include "MathMLNames.h"
 #include "SVGNames.h"
 
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/AtomicString.h>
-
 namespace WebCore {
 
-class ContainerNode;
-
 class HTMLStackItem : public RefCounted<HTMLStackItem> {
 public:
-    enum ItemType {
-        ItemForContextElement,
-        ItemForDocumentFragmentNode
-    };
-
-    // Used by document fragment node and context element.
-    static RefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, ItemType type)
-    {
-        return adoptRef(new HTMLStackItem(node, type));
-    }
+    // Normal HTMLElementStack and HTMLFormattingElementList items.
+    static Ref<HTMLStackItem> create(Ref<Element>, AtomicHTMLToken&, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI);
 
-    // Used by HTMLElementStack and HTMLFormattingElementList.
-    static RefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
-    {
-        return adoptRef(new HTMLStackItem(node, token, namespaceURI));
-    }
+    // Document fragment or element for parsing context.
+    static Ref<HTMLStackItem> create(Element&);
+    static Ref<HTMLStackItem> create(DocumentFragment&);
 
-    Element* element() const { return downcast<Element>(m_node.get()); }
-    ContainerNode* node() const { return m_node.get(); }
+    bool isElement() const;
+    bool isDocumentFragment() const;
 
-    bool isDocumentFragmentNode() const { return m_isDocumentFragmentNode; }
-    bool isElementNode() const { return !m_isDocumentFragmentNode; }
+    ContainerNode& node() const;
+    Element& element() const;
 
-    const AtomicString& namespaceURI() const { return m_namespaceURI; }
-    const AtomicString& localName() const { return m_tokenLocalName; }
+    const AtomicString& namespaceURI() const;
+    const AtomicString& localName() const;
 
-    const Vector<Attribute>& attributes() const { ASSERT(m_tokenLocalName); return m_tokenAttributes; }
-    Attribute* getAttributeItem(const QualifiedName& attributeName)
-    {
-        ASSERT(m_tokenLocalName);
-        return findAttributeInVector(m_tokenAttributes, attributeName);
-    }
+    const Vector<Attribute>& attributes() const;
+    const Attribute* findAttribute(const QualifiedName& attributeName) const;
 
-    bool hasLocalName(const AtomicString& name) const { return m_tokenLocalName == name; }
-    bool hasTagName(const QualifiedName& name) const { return m_tokenLocalName == name.localName() && m_namespaceURI == name.namespaceURI(); }
+    bool hasTagName(const QualifiedName&) const;
+    bool matchesHTMLTag(const AtomicString&) const;
 
-    bool matchesHTMLTag(const AtomicString& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
-    bool matchesHTMLTag(const QualifiedName& name) const { return m_tokenLocalName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI; }
+private:
+    HTMLStackItem(Ref<Element>, AtomicHTMLToken&, const AtomicString& namespaceURI);
+    explicit HTMLStackItem(Element&);
+    explicit HTMLStackItem(DocumentFragment&);
 
-    bool causesFosterParenting()
-    {
-        return hasTagName(HTMLNames::tableTag)
-            || hasTagName(HTMLNames::tbodyTag)
-            || hasTagName(HTMLNames::tfootTag)
-            || hasTagName(HTMLNames::theadTag)
-            || hasTagName(HTMLNames::trTag);
-    }
+    const Ref<ContainerNode> m_node;
+    const AtomicString m_namespaceURI;
+    const AtomicString m_localName;
+    const Vector<Attribute> m_attributes;
+};
 
-    bool isInHTMLNamespace() const
-    {
-        // A DocumentFragment takes the place of the document element when parsing
-        // fragments and should be considered in the HTML namespace.
-        return namespaceURI() == HTMLNames::xhtmlNamespaceURI
-            || isDocumentFragmentNode(); // FIXME: Does this also apply to ShadowRoot?
-    }
+bool isInHTMLNamespace(const HTMLStackItem&);
+bool isNumberedHeaderElement(const HTMLStackItem&);
+bool isSpecialNode(const HTMLStackItem&);
 
-    bool isNumberedHeaderElement() const
-    {
-        return hasTagName(HTMLNames::h1Tag)
-            || hasTagName(HTMLNames::h2Tag)
-            || hasTagName(HTMLNames::h3Tag)
-            || hasTagName(HTMLNames::h4Tag)
-            || hasTagName(HTMLNames::h5Tag)
-            || hasTagName(HTMLNames::h6Tag);
-    }
+inline HTMLStackItem::HTMLStackItem(Ref<Element> element, AtomicHTMLToken& token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+    : m_node(WTF::move(element))
+    , m_namespaceURI(namespaceURI)
+    , m_localName(token.name())
+    , m_attributes(token.attributes())
+{
+    // FIXME: We should find a way to move the attributes vector in the normal code path instead of copying it.
+}
 
-    bool isTableBodyContextElement() const
-    {
-        return hasTagName(HTMLNames::tbodyTag)
-            || hasTagName(HTMLNames::tfootTag)
-            || hasTagName(HTMLNames::theadTag);
-    }
+inline Ref<HTMLStackItem> HTMLStackItem::create(Ref<Element> element, AtomicHTMLToken& token, const AtomicString& namespaceURI)
+{
+    return adoptRef(*new HTMLStackItem(WTF::move(element), token, namespaceURI));
+}
+
+inline HTMLStackItem::HTMLStackItem(Element& element)
+    : m_node(element)
+    , m_namespaceURI(element.namespaceURI())
+    , m_localName(element.localName())
+{
+}
+
+inline Ref<HTMLStackItem> HTMLStackItem::create(Element& element)
+{
+    return adoptRef(*new HTMLStackItem(element));
+}
+
+inline HTMLStackItem::HTMLStackItem(DocumentFragment& fragment)
+    : m_node(fragment)
+{
+}
+
+inline Ref<HTMLStackItem> HTMLStackItem::create(DocumentFragment& fragment)
+{
+    return adoptRef(*new HTMLStackItem(fragment));
+}
+
+inline ContainerNode& HTMLStackItem::node() const
+{
+    return const_cast<ContainerNode&>(m_node.get());
+}
+
+inline Element& HTMLStackItem::element() const
+{
+    return downcast<Element>(node());
+}
 
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
-    bool isSpecialNode() const
-    {
-        if (hasTagName(MathMLNames::miTag)
-            || hasTagName(MathMLNames::moTag)
-            || hasTagName(MathMLNames::mnTag)
-            || hasTagName(MathMLNames::msTag)
-            || hasTagName(MathMLNames::mtextTag)
-            || hasTagName(MathMLNames::annotation_xmlTag)
-            || hasTagName(SVGNames::foreignObjectTag)
-            || hasTagName(SVGNames::descTag)
-            || hasTagName(SVGNames::titleTag))
-            return true;
-        if (isDocumentFragmentNode())
-            return true;
-        if (!isInHTMLNamespace())
-            return false;
-        const AtomicString& tagName = localName();
+inline bool HTMLStackItem::isDocumentFragment() const
+{
+    return m_localName.isNull();
+}
+
+inline bool HTMLStackItem::isElement() const
+{
+    return !isDocumentFragment();
+}
+
+inline const AtomicString& HTMLStackItem::namespaceURI() const
+{
+    return m_namespaceURI;
+}
+
+inline const AtomicString& HTMLStackItem::localName() const
+{
+    return m_localName;
+}
+
+inline const Vector<Attribute>& HTMLStackItem::attributes() const
+{
+    ASSERT(isElement());
+    return m_attributes;
+}
+
+inline const Attribute* HTMLStackItem::findAttribute(const QualifiedName& attributeName) const
+{
+    return findAttributeInVector(const_cast<Vector<Attribute>&>(attributes()), attributeName);
+}
+
+inline bool HTMLStackItem::hasTagName(const QualifiedName& name) const
+{
+    return m_localName == name.localName() && m_namespaceURI == name.namespaceURI();
+}
+
+inline bool HTMLStackItem::matchesHTMLTag(const AtomicString& name) const
+{
+    return m_localName == name && m_namespaceURI == HTMLNames::xhtmlNamespaceURI;
+}
+
+inline bool isInHTMLNamespace(const HTMLStackItem& item)
+{
+    // A DocumentFragment takes the place of the document element when parsing
+    // fragments and thus should be treated as if it was in the HTML namespace.
+    // FIXME: Is this also needed for a ShadowRoot that might be a non-HTML element?
+    return item.namespaceURI() == HTMLNames::xhtmlNamespaceURI || item.isDocumentFragment();
+}
+
+inline bool isNumberedHeaderElement(const HTMLStackItem& item)
+{
+    return item.namespaceURI() == HTMLNames::xhtmlNamespaceURI
+        && (item.localName() == HTMLNames::h1Tag
+            || item.localName() == HTMLNames::h2Tag
+            || item.localName() == HTMLNames::h3Tag
+            || item.localName() == HTMLNames::h4Tag
+            || item.localName() == HTMLNames::h5Tag
+            || item.localName() == HTMLNames::h6Tag);
+}
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
+inline bool isSpecialNode(const HTMLStackItem& item)
+{
+    if (item.isDocumentFragment())
+        return true;
+    const AtomicString& tagName = item.localName();
+    if (item.namespaceURI() == HTMLNames::xhtmlNamespaceURI) {
         return tagName == HTMLNames::addressTag
             || tagName == HTMLNames::appletTag
             || tagName == HTMLNames::areaTag
@@ -164,7 +219,12 @@ public:
             || tagName == HTMLNames::formTag
             || tagName == HTMLNames::frameTag
             || tagName == HTMLNames::framesetTag
-            || isNumberedHeaderElement()
+            || tagName == HTMLNames::h1Tag
+            || tagName == HTMLNames::h2Tag
+            || tagName == HTMLNames::h3Tag
+            || tagName == HTMLNames::h4Tag
+            || tagName == HTMLNames::h5Tag
+            || tagName == HTMLNames::h6Tag
             || tagName == HTMLNames::headTag
             || tagName == HTMLNames::headerTag
             || tagName == HTMLNames::hgroupTag
@@ -197,52 +257,36 @@ public:
             || tagName == HTMLNames::styleTag
             || tagName == HTMLNames::summaryTag
             || tagName == HTMLNames::tableTag
-            || isTableBodyContextElement()
+            || tagName == HTMLNames::tbodyTag
             || tagName == HTMLNames::tdTag
 #if ENABLE(TEMPLATE_ELEMENT)
             || tagName == HTMLNames::templateTag
 #endif
             || tagName == HTMLNames::textareaTag
+            || tagName == HTMLNames::tfootTag
             || tagName == HTMLNames::thTag
+            || tagName == HTMLNames::theadTag
             || tagName == HTMLNames::titleTag
             || tagName == HTMLNames::trTag
             || tagName == HTMLNames::ulTag
             || tagName == HTMLNames::wbrTag
             || tagName == HTMLNames::xmpTag;
     }
-
-private:
-    HTMLStackItem(PassRefPtr<ContainerNode> node, ItemType type)
-        : m_node(node)
-    {
-        switch (type) {
-        case ItemForDocumentFragmentNode:
-            m_isDocumentFragmentNode = true;
-            break;
-        case ItemForContextElement:
-            m_tokenLocalName = m_node->localName();
-            m_namespaceURI = m_node->namespaceURI();
-            m_isDocumentFragmentNode = false;
-            break;
-        }
+    if (item.namespaceURI() == MathMLNames::mathmlNamespaceURI) {
+        return tagName == MathMLNames::annotation_xmlTag
+            || tagName == MathMLNames::miTag
+            || tagName == MathMLNames::moTag
+            || tagName == MathMLNames::mnTag
+            || tagName == MathMLNames::msTag
+            || tagName == MathMLNames::mtextTag;
     }
-
-    HTMLStackItem(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
-        : m_node(node)
-        , m_tokenLocalName(token->name())
-        , m_tokenAttributes(token->attributes())
-        , m_namespaceURI(namespaceURI)
-        , m_isDocumentFragmentNode(false)
-    {
+    if (item.namespaceURI() == SVGNames::svgNamespaceURI) {
+        return tagName == SVGNames::descTag
+            || tagName == SVGNames::foreignObjectTag
+            || tagName == SVGNames::titleTag;
     }
-
-    RefPtr<ContainerNode> m_node;
-
-    AtomicString m_tokenLocalName;
-    Vector<Attribute> m_tokenAttributes;
-    AtomicString m_namespaceURI;
-    bool m_isDocumentFragmentNode;
-};
+    return false;
+}
 
 } // namespace WebCore
 
index 881260c..8529972 100644 (file)
@@ -241,7 +241,7 @@ private:
 inline bool HTMLTreeBuilder::isParsingTemplateContents() const
 {
 #if ENABLE(TEMPLATE_ELEMENT)
-    return m_tree.openElements()->hasTemplateInHTMLScope();
+    return m_tree.openElements().hasTemplateInHTMLScope();
 #else
     return false;
 #endif
@@ -274,7 +274,7 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, DocumentFragment& f
 
     // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
     // For efficiency, we skip step 5 ("Let root be a new html element with no attributes") and instead use the DocumentFragment as a root node.
-    m_tree.openElements()->pushRootNode(HTMLStackItem::create(&fragment, HTMLStackItem::ItemForDocumentFragmentNode));
+    m_tree.openElements().pushRootNode(HTMLStackItem::create(fragment));
 
 #if ENABLE(TEMPLATE_ELEMENT)
     if (contextElement.hasTagName(templateTag))
@@ -298,12 +298,12 @@ HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
     : m_fragment(&fragment)
 {
     ASSERT(!fragment.hasChildNodes());
-    m_contextElementStackItem = HTMLStackItem::create(&contextElement, HTMLStackItem::ItemForContextElement);
+    m_contextElementStackItem = HTMLStackItem::create(contextElement);
 }
 
 inline Element& HTMLTreeBuilder::FragmentParsingContext::contextElement() const
 {
-    return *contextElementStackItem().element();
+    return contextElementStackItem().element();
 }
 
 inline HTMLStackItem& HTMLTreeBuilder::FragmentParsingContext::contextElementStackItem() const
@@ -341,7 +341,7 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken& token)
         processToken(token);
 
     bool inForeignContent = !m_tree.isEmpty()
-        && !adjustedCurrentStackItem().isInHTMLNamespace()
+        && !isInHTMLNamespace(adjustedCurrentStackItem())
         && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
         && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
 
@@ -432,7 +432,7 @@ void HTMLTreeBuilder::processFakeCharacters(const String& characters)
 
 void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
 {
-    if (!m_tree.openElements()->inButtonScope(pTag.localName()))
+    if (!m_tree.openElements().inButtonScope(pTag.localName()))
         return;
     AtomicHTMLToken endP(HTMLToken::EndTag, pTag.localName());
     processEndTag(endP);
@@ -494,14 +494,14 @@ bool isDdOrDt(const HTMLStackItem& item)
 template <bool shouldClose(const HTMLStackItem&)> void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
 {
     m_framesetOk = false;
-    for (auto* nodeRecord = m_tree.openElements()->topRecord(); ; nodeRecord = nodeRecord->next()) {
-        HTMLStackItem& item = *nodeRecord->stackItem();
+    for (auto* nodeRecord = &m_tree.openElements().topRecord(); ; nodeRecord = nodeRecord->next()) {
+        HTMLStackItem& item = nodeRecord->stackItem();
         if (shouldClose(item)) {
-            ASSERT(item.isElementNode());
+            ASSERT(item.isElement());
             processFakeEndTag(item.localName());
             break;
         }
-        if (item.isSpecialNode() && !item.hasTagName(addressTag) && !item.hasTagName(divTag) && !item.hasTagName(pTag))
+        if (isSpecialNode(item) && !item.hasTagName(addressTag) && !item.hasTagName(divTag) && !item.hasTagName(pTag))
             break;
     }
     processFakePEndTagIfPInButtonScope();
@@ -606,9 +606,9 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     }
     if (token.name() == bodyTag) {
         parseError(token);
-        bool fragmentOrTemplateCase = !m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement();
+        bool fragmentOrTemplateCase = !m_tree.openElements().secondElementIsHTMLBodyElement() || m_tree.openElements().hasOnlyOneElement();
 #if ENABLE(TEMPLATE_ELEMENT)
-        fragmentOrTemplateCase = fragmentOrTemplateCase || m_tree.openElements()->hasTemplateInHTMLScope();
+        fragmentOrTemplateCase = fragmentOrTemplateCase || m_tree.openElements().hasTemplateInHTMLScope();
 #endif
         if (fragmentOrTemplateCase) {
             ASSERT(isParsingFragmentOrTemplateContents());
@@ -620,16 +620,16 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     }
     if (token.name() == framesetTag) {
         parseError(token);
-        if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
+        if (!m_tree.openElements().secondElementIsHTMLBodyElement() || m_tree.openElements().hasOnlyOneElement()) {
             ASSERT(isParsingFragmentOrTemplateContents());
             return;
         }
         if (!m_framesetOk)
             return;
-        m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION);
-        m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
-        m_tree.openElements()->popHTMLBodyElement();
-        ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement());
+        m_tree.openElements().bodyElement().remove(ASSERT_NO_EXCEPTION);
+        m_tree.openElements().popUntil(&m_tree.openElements().bodyElement());
+        m_tree.openElements().popHTMLBodyElement();
+        ASSERT(&m_tree.openElements().top() == &m_tree.openElements().htmlElement());
         m_tree.insertHTMLElement(&token);
         m_insertionMode = InsertionMode::InFrameset;
         return;
@@ -663,9 +663,9 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     }
     if (isNumberedHeaderTag(token.name())) {
         processFakePEndTagIfPInButtonScope();
-        if (m_tree.currentStackItem()->isNumberedHeaderElement()) {
+        if (isNumberedHeaderElement(m_tree.currentStackItem())) {
             parseError(token);
-            m_tree.openElements()->pop();
+            m_tree.openElements().pop();
         }
         m_tree.insertHTMLElement(&token);
         return;
@@ -701,7 +701,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         return;
     }
     if (token.name() == buttonTag) {
-        if (m_tree.openElements()->inScope(buttonTag)) {
+        if (m_tree.openElements().inScope(buttonTag)) {
             parseError(token);
             processFakeEndTag(buttonTag);
             processStartTag(token); // FIXME: Could we just fall through here?
@@ -713,13 +713,13 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         return;
     }
     if (token.name() == aTag) {
-        Element* activeATag = m_tree.activeFormattingElements()->closestElementInScopeWithName(aTag.localName());
+        Element* activeATag = m_tree.activeFormattingElements().closestElementInScopeWithName(aTag.localName());
         if (activeATag) {
             parseError(token);
             processFakeEndTag(aTag);
-            m_tree.activeFormattingElements()->remove(activeATag);
-            if (m_tree.openElements()->contains(activeATag))
-                m_tree.openElements()->remove(activeATag);
+            m_tree.activeFormattingElements().remove(activeATag);
+            if (m_tree.openElements().contains(activeATag))
+                m_tree.openElements().remove(activeATag);
         }
         m_tree.reconstructTheActiveFormattingElements();
         m_tree.insertFormattingElement(&token);
@@ -732,7 +732,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     }
     if (token.name() == nobrTag) {
         m_tree.reconstructTheActiveFormattingElements();
-        if (m_tree.openElements()->inScope(nobrTag)) {
+        if (m_tree.openElements().inScope(nobrTag)) {
             parseError(token);
             processFakeEndTag(nobrTag);
             m_tree.reconstructTheActiveFormattingElements();
@@ -747,12 +747,12 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
         m_tree.reconstructTheActiveFormattingElements();
         m_tree.insertHTMLElement(&token);
-        m_tree.activeFormattingElements()->appendMarker();
+        m_tree.activeFormattingElements().appendMarker();
         m_framesetOk = false;
         return;
     }
     if (token.name() == tableTag) {
-        if (!m_tree.inQuirksMode() && m_tree.openElements()->inButtonScope(pTag))
+        if (!m_tree.inQuirksMode() && m_tree.openElements().inButtonScope(pTag))
             processFakeEndTag(pTag);
         m_tree.insertHTMLElement(&token);
         m_framesetOk = false;
@@ -845,7 +845,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         return;
     }
     if (token.name() == optgroupTag || token.name() == optionTag) {
-        if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
+        if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
             AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
             processEndTag(endOption);
         }
@@ -854,18 +854,18 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         return;
     }
     if (token.name() == rbTag || token.name() == rtcTag) {
-        if (m_tree.openElements()->inScope(rubyTag.localName())) {
+        if (m_tree.openElements().inScope(rubyTag.localName())) {
             m_tree.generateImpliedEndTags();
-            if (!m_tree.currentStackItem()->hasTagName(rubyTag))
+            if (!m_tree.currentStackItem().hasTagName(rubyTag))
                 parseError(token);
         }
         m_tree.insertHTMLElement(&token);
         return;
     }
     if (token.name() == rtTag || token.name() == rpTag) {
-        if (m_tree.openElements()->inScope(rubyTag.localName())) {
+        if (m_tree.openElements().inScope(rubyTag.localName())) {
             m_tree.generateImpliedEndTagsWithExclusion(rtcTag.localName());
-            if (!m_tree.currentStackItem()->hasTagName(rubyTag) && !m_tree.currentStackItem()->hasTagName(rtcTag))
+            if (!m_tree.currentStackItem().hasTagName(rubyTag) && !m_tree.currentStackItem().hasTagName(rtcTag))
                 parseError(token);
         }
         m_tree.insertHTMLElement(&token);
@@ -908,7 +908,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
 
 void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken& token)
 {
-    m_tree.activeFormattingElements()->appendMarker();
+    m_tree.activeFormattingElements().appendMarker();
     m_tree.insertHTMLElement(&token);
     m_templateInsertionModes.append(InsertionMode::TemplateContents);
     m_insertionMode = InsertionMode::TemplateContents;
@@ -917,16 +917,16 @@ void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken& token)
 bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken& token)
 {
     ASSERT(token.name() == templateTag.localName());
-    if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
+    if (!m_tree.openElements().hasTemplateInHTMLScope()) {
         ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement().hasTagName(templateTag)));
         parseError(token);
         return false;
     }
     m_tree.generateImpliedEndTags();
-    if (!m_tree.currentStackItem()->hasTagName(templateTag))
+    if (!m_tree.currentStackItem().hasTagName(templateTag))
         parseError(token);
-    m_tree.openElements()->popUntilPopped(templateTag);
-    m_tree.activeFormattingElements()->clearToLastMarker();
+    m_tree.openElements().popUntilPopped(templateTag);
+    m_tree.activeFormattingElements().clearToLastMarker();
     m_templateInsertionModes.removeLast();
     resetInsertionModeAppropriately();
     return true;
@@ -948,7 +948,7 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
 {
     bool ignoreFakeEndTag = m_tree.currentIsRootNode();
 #if ENABLE(TEMPLATE_ELEMENT)
-    ignoreFakeEndTag = ignoreFakeEndTag || m_tree.currentNode()->hasTagName(templateTag);
+    ignoreFakeEndTag = ignoreFakeEndTag || m_tree.currentNode().hasTagName(templateTag);
 #endif
 
     if (ignoreFakeEndTag) {
@@ -956,7 +956,7 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
         // FIXME: parse error
         return false;
     }
-    m_tree.openElements()->pop();
+    m_tree.openElements().pop();
     m_insertionMode = InsertionMode::InTable;
     return true;
 }
@@ -965,12 +965,12 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
 void HTMLTreeBuilder::closeTheCell()
 {
     ASSERT(m_insertionMode == InsertionMode::InCell);
-    if (m_tree.openElements()->inTableScope(tdTag)) {
-        ASSERT(!m_tree.openElements()->inTableScope(thTag));
+    if (m_tree.openElements().inTableScope(tdTag)) {
+        ASSERT(!m_tree.openElements().inTableScope(thTag));
         processFakeEndTag(tdTag);
         return;
     }
-    ASSERT(m_tree.openElements()->inTableScope(thTag));
+    ASSERT(m_tree.openElements().inTableScope(thTag));
     processFakeEndTag(thTag);
     ASSERT(m_insertionMode == InsertionMode::InRow);
 }
@@ -979,14 +979,14 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::StartTag);
     if (token.name() == captionTag) {
-        m_tree.openElements()->popUntilTableScopeMarker();
-        m_tree.activeFormattingElements()->appendMarker();
+        m_tree.openElements().popUntilTableScopeMarker();
+        m_tree.activeFormattingElements().appendMarker();
         m_tree.insertHTMLElement(&token);
         m_insertionMode = InsertionMode::InCaption;
         return;
     }
     if (token.name() == colgroupTag) {
-        m_tree.openElements()->popUntilTableScopeMarker();
+        m_tree.openElements().popUntilTableScopeMarker();
         m_tree.insertHTMLElement(&token);
         m_insertionMode = InsertionMode::InColumnGroup;
         return;
@@ -998,7 +998,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
         return;
     }
     if (isTableBodyContextTag(token.name())) {
-        m_tree.openElements()->popUntilTableScopeMarker();
+        m_tree.openElements().popUntilTableScopeMarker();
         m_tree.insertHTMLElement(&token);
         m_insertionMode = InsertionMode::InTableBody;
         return;
@@ -1036,7 +1036,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
         if (m_tree.form() && !isParsingTemplateContents())
             return;
         m_tree.insertHTMLFormElement(&token, true);
-        m_tree.openElements()->pop();
+        m_tree.openElements().pop();
         return;
     }
 #if ENABLE(TEMPLATE_ELEMENT)
@@ -1115,10 +1115,9 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
 #endif
             || token.name() == titleTag) {
             parseError(token);
-            ASSERT(m_tree.head());
-            m_tree.openElements()->pushHTMLHeadElement(m_tree.headStackItem());
+            m_tree.openElements().pushHTMLHeadElement(m_tree.headStackItem());
             processStartTagForInHead(token);
-            m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
+            m_tree.openElements().removeHTMLHeadElement(&m_tree.head());
             return;
         }
         if (token.name() == headTag) {
@@ -1172,7 +1171,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
         break;
     case InsertionMode::InTableBody:
         if (token.name() == trTag) {
-            m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
+            m_tree.openElements().popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
             m_tree.insertHTMLElement(&token);
             m_insertionMode = InsertionMode::InRow;
             return;
@@ -1186,14 +1185,14 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
         }
         if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
             // FIXME: This is slow.
-            if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
+            if (!m_tree.openElements().inTableScope(tbodyTag) && !m_tree.openElements().inTableScope(theadTag) && !m_tree.openElements().inTableScope(tfootTag)) {
                 ASSERT(isParsingFragmentOrTemplateContents());
                 parseError(token);
                 return;
             }
-            m_tree.openElements()->popUntilTableBodyScopeMarker();
-            ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
-            processFakeEndTag(m_tree.currentStackItem()->localName());
+            m_tree.openElements().popUntilTableBodyScopeMarker();
+            ASSERT(isTableBodyContextTag(m_tree.currentStackItem().localName()));
+            processFakeEndTag(m_tree.currentStackItem().localName());
             processStartTag(token);
             return;
         }
@@ -1201,10 +1200,10 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
         break;
     case InsertionMode::InRow:
         if (isTableCellContextTag(token.name())) {
-            m_tree.openElements()->popUntilTableRowScopeMarker();
+            m_tree.openElements().popUntilTableRowScopeMarker();
             m_tree.insertHTMLElement(&token);
             m_insertionMode = InsertionMode::InCell;
-            m_tree.activeFormattingElements()->appendMarker();
+            m_tree.activeFormattingElements().appendMarker();
             return;
         }
         if (token.name() == trTag
@@ -1226,7 +1225,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             || token.name() == trTag
             || isTableBodyContextTag(token.name())) {
             // FIXME: This could be more efficient.
-            if (!m_tree.openElements()->inTableScope(tdTag) && !m_tree.openElements()->inTableScope(thTag)) {
+            if (!m_tree.openElements().inTableScope(tdTag) && !m_tree.openElements().inTableScope(thTag)) {
                 ASSERT(isParsingFragment());
                 parseError(token);
                 return;
@@ -1324,7 +1323,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             return;
         }
         if (token.name() == optionTag) {
-            if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
+            if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
                 processEndTag(endOption);
             }
@@ -1332,11 +1331,11 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             return;
         }
         if (token.name() == optgroupTag) {
-            if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
+            if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
                 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
                 processEndTag(endOption);
             }
-            if (is<HTMLOptGroupElement>(*m_tree.currentStackItem()->node())) {
+            if (is<HTMLOptGroupElement>(m_tree.currentStackItem().node())) {
                 AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
                 processEndTag(endOptgroup);
             }
@@ -1351,7 +1350,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
         }
         if (token.name() == inputTag || token.name() == keygenTag || token.name() == textareaTag) {
             parseError(token);
-            if (!m_tree.openElements()->inSelectScope(selectTag)) {
+            if (!m_tree.openElements().inSelectScope(selectTag)) {
                 ASSERT(isParsingFragment());
                 return;
             }
@@ -1423,7 +1422,7 @@ void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken& token)
 {
     parseError(token);
 #if ENABLE(TEMPLATE_ELEMENT)
-    if (m_tree.openElements()->hasTemplateInHTMLScope()) {
+    if (m_tree.openElements().hasTemplateInHTMLScope()) {
         ASSERT(isParsingTemplateContents());
         return;
     }
@@ -1435,7 +1434,7 @@ bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::EndTag);
     ASSERT(token.name() == bodyTag);
-    if (!m_tree.openElements()->inScope(bodyTag.localName())) {
+    if (!m_tree.openElements().inScope(bodyTag.localName())) {
         parseError(token);
         return false;
     }
@@ -1447,16 +1446,16 @@ bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
 void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::EndTag);
-    for (auto* record = m_tree.openElements()->topRecord(); ; record = record->next()) {
-        HTMLStackItem& item = *record->stackItem();
+    for (auto* record = &m_tree.openElements().topRecord(); ; record = record->next()) {
+        HTMLStackItem& item = record->stackItem();
         if (item.matchesHTMLTag(token.name())) {
             m_tree.generateImpliedEndTagsWithExclusion(token.name());
-            if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+            if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
                 parseError(token);
-            m_tree.openElements()->popUntilPopped(item.element());
+            m_tree.openElements().popUntilPopped(&item.element());
             return;
         }
-        if (item.isSpecialNode()) {
+        if (isSpecialNode(item)) {
             parseError(token);
             return;
         }
@@ -1476,39 +1475,39 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
     // 1, 2, 3 and 16 are covered by the for() loop.
     for (int i = 0; i < outerIterationLimit; ++i) {
         // 4.
-        Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token.name());
+        Element* formattingElement = m_tree.activeFormattingElements().closestElementInScopeWithName(token.name());
         // 4.a
         if (!formattingElement)
             return processAnyOtherEndTagForInBody(token);
         // 4.c
-        if ((m_tree.openElements()->contains(formattingElement)) && !m_tree.openElements()->inScope(formattingElement)) {
+        if ((m_tree.openElements().contains(formattingElement)) && !m_tree.openElements().inScope(formattingElement)) {
             parseError(token);
             notImplemented(); // Check the stack of open elements for a more specific parse error.
             return;
         }
         // 4.b
-        auto* formattingElementRecord = m_tree.openElements()->find(formattingElement);
+        auto* formattingElementRecord = m_tree.openElements().find(formattingElement);
         if (!formattingElementRecord) {
             parseError(token);
-            m_tree.activeFormattingElements()->remove(formattingElement);
+            m_tree.activeFormattingElements().remove(formattingElement);
             return;
         }
         // 4.d
-        if (formattingElement != m_tree.currentElement())
+        if (formattingElement != &m_tree.currentElement())
             parseError(token);
         // 5.
-        auto* furthestBlock = m_tree.openElements()->furthestBlockForFormattingElement(formattingElement);
+        auto* furthestBlock = m_tree.openElements().furthestBlockForFormattingElement(formattingElement);
         // 6.
         if (!furthestBlock) {
-            m_tree.openElements()->popUntilPopped(formattingElement);
-            m_tree.activeFormattingElements()->remove(formattingElement);
+            m_tree.openElements().popUntilPopped(formattingElement);
+            m_tree.activeFormattingElements().remove(formattingElement);
             return;
         }
         // 7.
         ASSERT(furthestBlock->isAbove(formattingElementRecord));
-        RefPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
+        Ref<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
         // 8.
-        HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
+        HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements().bookmarkFor(formattingElement);
         // 9.
         auto* node = furthestBlock;
         auto* nextNode = node->next();
@@ -1520,8 +1519,8 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
             ASSERT(node);
             nextNode = node->next(); // Save node->next() for the next iteration in case node is deleted in 9.5.
             // 9.5
-            if (!m_tree.activeFormattingElements()->contains(node->element())) {
-                m_tree.openElements()->remove(node->element());
+            if (!m_tree.activeFormattingElements().contains(&node->element())) {
+                m_tree.openElements().remove(&node->element());
                 node = 0;
                 continue;
             }
@@ -1529,10 +1528,10 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
             if (node == formattingElementRecord)
                 break;
             // 9.7
-            RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
+            RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(&node->stackItem());
 
-            HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
-            nodeEntry->replaceElement(newItem);
+            HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements().find(&node->element());
+            nodeEntry->replaceElement(newItem.copyRef());
             node->replaceElement(newItem.release());
 
             // 9.8
@@ -1544,18 +1543,18 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
             lastNode = node;
         }
         // 10.
-        m_tree.insertAlreadyParsedChild(*commonAncestor, *lastNode);
+        m_tree.insertAlreadyParsedChild(commonAncestor.get(), *lastNode);
         // 11.
-        RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
+        RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(&formattingElementRecord->stackItem());
         // 12.
         m_tree.takeAllChildren(*newItem, *furthestBlock);
         // 13.
         m_tree.reparent(*furthestBlock, *newItem);
         // 14.
-        m_tree.activeFormattingElements()->swapTo(formattingElement, newItem, bookmark);
+        m_tree.activeFormattingElements().swapTo(formattingElement, newItem, bookmark);
         // 15.
-        m_tree.openElements()->remove(formattingElement);
-        m_tree.openElements()->insertAbove(newItem, furthestBlock);
+        m_tree.openElements().remove(formattingElement);
+        m_tree.openElements().insertAbove(newItem, furthestBlock);
     }
 }
 
@@ -1563,9 +1562,9 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
 {
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
     bool last = false;
-    for (auto* record = m_tree.openElements()->topRecord(); ; record = record->next()) {
-        HTMLStackItem* item = record->stackItem().get();
-        if (item->node() == m_tree.openElements()->rootNode()) {
+    for (auto* record = &m_tree.openElements().topRecord(); ; record = record->next()) {
+        HTMLStackItem* item = &record->stackItem();
+        if (&item->node() == &m_tree.openElements().rootNode()) {
             last = true;
 #if ENABLE(TEMPLATE_ELEMENT)
             bool shouldCreateItem = isParsingFragment();
@@ -1586,10 +1585,10 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
         if (item->hasTagName(selectTag)) {
 #if ENABLE(TEMPLATE_ELEMENT)
             if (!last) {
-                while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
+                while (&item->node() != &m_tree.openElements().rootNode() && !item->hasTagName(templateTag)) {
                     record = record->next();
-                    item = record->stackItem().get();
-                    if (is<HTMLTableElement>(*item->node())) {
+                    item = &record->stackItem();
+                    if (is<HTMLTableElement>(item->node())) {
                         m_insertionMode = InsertionMode::InSelectInTable;
                         return;
                     }
@@ -1619,13 +1618,13 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
             m_insertionMode = InsertionMode::InColumnGroup;
             return;
         }
-        if (is<HTMLTableElement>(*item->node())) {
+        if (is<HTMLTableElement>(item->node())) {
             m_insertionMode = InsertionMode::InTable;
             return;
         }
         if (item->hasTagName(headTag)) {
 #if ENABLE(TEMPLATE_ELEMENT)
-            if (!m_fragmentContext.fragment() || &m_fragmentContext.contextElement() != item->node()) {
+            if (!m_fragmentContext.fragment() || &m_fragmentContext.contextElement() != &item->node()) {
                 m_insertionMode = InsertionMode::InHead;
                 return;
             }
@@ -1662,25 +1661,25 @@ void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::EndTag);
     if (isTableBodyContextTag(token.name())) {
-        if (!m_tree.openElements()->inTableScope(token.name())) {
+        if (!m_tree.openElements().inTableScope(token.name())) {
             parseError(token);
             return;
         }
-        m_tree.openElements()->popUntilTableBodyScopeMarker();
-        m_tree.openElements()->pop();
+        m_tree.openElements().popUntilTableBodyScopeMarker();
+        m_tree.openElements().pop();
         m_insertionMode = InsertionMode::InTable;
         return;
     }
     if (token.name() == tableTag) {
         // FIXME: This is slow.
-        if (!m_tree.openElements()->inTableScope(tbodyTag) && !m_tree.openElements()->inTableScope(theadTag) && !m_tree.openElements()->inTableScope(tfootTag)) {
+        if (!m_tree.openElements().inTableScope(tbodyTag) && !m_tree.openElements().inTableScope(theadTag) && !m_tree.openElements().inTableScope(tfootTag)) {
             ASSERT(isParsingFragmentOrTemplateContents());
             parseError(token);
             return;
         }
-        m_tree.openElements()->popUntilTableBodyScopeMarker();
-        ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
-        processFakeEndTag(m_tree.currentStackItem()->localName());
+        m_tree.openElements().popUntilTableBodyScopeMarker();
+        ASSERT(isTableBodyContextTag(m_tree.currentStackItem().localName()));
+        processFakeEndTag(m_tree.currentStackItem().localName());
         processEndTag(token);
         return;
     }
@@ -1712,7 +1711,7 @@ void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
         return;
     }
     if (isTableBodyContextTag(token.name())) {
-        if (!m_tree.openElements()->inTableScope(token.name())) {
+        if (!m_tree.openElements().inTableScope(token.name())) {
             parseError(token);
             return;
         }
@@ -1735,15 +1734,15 @@ void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::EndTag);
     if (isTableCellContextTag(token.name())) {
-        if (!m_tree.openElements()->inTableScope(token.name())) {
+        if (!m_tree.openElements().inTableScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
-        m_tree.activeFormattingElements()->clearToLastMarker();
+        m_tree.openElements().popUntilPopped(token.name());
+        m_tree.activeFormattingElements().clearToLastMarker();
         m_insertionMode = InsertionMode::InRow;
         return;
     }
@@ -1756,9 +1755,9 @@ void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
     if (token.name() == tableTag
         || token.name() == trTag
         || isTableBodyContextTag(token.name())) {
-        if (!m_tree.openElements()->inTableScope(token.name())) {
+        if (!m_tree.openElements().inTableScope(token.name())) {
 #if ENABLE(TEMPLATE_ELEMENT)
-            ASSERT(isTableBodyContextTag(token.name()) || m_tree.openElements()->inTableScope(templateTag) || isParsingFragment());
+            ASSERT(isTableBodyContextTag(token.name()) || m_tree.openElements().inTableScope(templateTag) || isParsingFragment());
 #else
             ASSERT(isTableBodyContextTag(token.name()) || isParsingFragment());
 #endif
@@ -1810,83 +1809,83 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
         || token.name() == sectionTag
         || token.name() == summaryTag
         || token.name() == ulTag) {
-        if (!m_tree.openElements()->inScope(token.name())) {
+        if (!m_tree.openElements().inScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
+        m_tree.openElements().popUntilPopped(token.name());
         return;
     }
     if (token.name() == formTag) {
         if (!isParsingTemplateContents()) {
             RefPtr<Element> node = m_tree.takeForm();
-            if (!node || !m_tree.openElements()->inScope(node.get())) {
+            if (!node || !m_tree.openElements().inScope(node.get())) {
                 parseError(token);
                 return;
             }
             m_tree.generateImpliedEndTags();
-            if (m_tree.currentNode() != node.get())
+            if (&m_tree.currentNode() != node.get())
                 parseError(token);
-            m_tree.openElements()->remove(node.get());
+            m_tree.openElements().remove(node.get());
         } else {
-            if (!m_tree.openElements()->inScope(token.name())) {
+            if (!m_tree.openElements().inScope(token.name())) {
                 parseError(token);
                 return;
             }
             m_tree.generateImpliedEndTags();
-            if (!m_tree.currentNode()->hasTagName(formTag))
+            if (!m_tree.currentNode().hasTagName(formTag))
                 parseError(token);
-            m_tree.openElements()->popUntilPopped(token.name());
+            m_tree.openElements().popUntilPopped(token.name());
         }
     }
     if (token.name() == pTag) {
-        if (!m_tree.openElements()->inButtonScope(token.name())) {
+        if (!m_tree.openElements().inButtonScope(token.name())) {
             parseError(token);
             processFakeStartTag(pTag);
-            ASSERT(m_tree.openElements()->inScope(token.name()));
+            ASSERT(m_tree.openElements().inScope(token.name()));
             processEndTag(token);
             return;
         }
         m_tree.generateImpliedEndTagsWithExclusion(token.name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
+        m_tree.openElements().popUntilPopped(token.name());
         return;
     }
     if (token.name() == liTag) {
-        if (!m_tree.openElements()->inListItemScope(token.name())) {
+        if (!m_tree.openElements().inListItemScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTagsWithExclusion(token.name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
+        m_tree.openElements().popUntilPopped(token.name());
         return;
     }
     if (token.name() == ddTag || token.name() == dtTag) {
-        if (!m_tree.openElements()->inScope(token.name())) {
+        if (!m_tree.openElements().inScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTagsWithExclusion(token.name());
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
+        m_tree.openElements().popUntilPopped(token.name());
         return;
     }
     if (isNumberedHeaderTag(token.name())) {
-        if (!m_tree.openElements()->hasNumberedHeaderElementInScope()) {
+        if (!m_tree.openElements().hasNumberedHeaderElementInScope()) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilNumberedHeaderElementPopped();
+        m_tree.openElements().popUntilNumberedHeaderElementPopped();
         return;
     }
     if (isFormattingTag(token.name())) {
@@ -1894,15 +1893,15 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
         return;
     }
     if (token.name() == appletTag || token.name() == marqueeTag || token.name() == objectTag) {
-        if (!m_tree.openElements()->inScope(token.name())) {
+        if (!m_tree.openElements().inScope(token.name())) {
             parseError(token);
             return;
         }
         m_tree.generateImpliedEndTags();
-        if (!m_tree.currentStackItem()->matchesHTMLTag(token.name()))
+        if (!m_tree.currentStackItem().matchesHTMLTag(token.name()))
             parseError(token);
-        m_tree.openElements()->popUntilPopped(token.name());
-        m_tree.activeFormattingElements()->clearToLastMarker();
+        m_tree.openElements().popUntilPopped(token.name());
+        m_tree.activeFormattingElements().clearToLastMarker();
         return;
     }
     if (token.name() == brTag) {
@@ -1921,41 +1920,41 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
 
 bool HTMLTreeBuilder::processCaptionEndTagForInCaption()
 {
-    if (!m_tree.openElements()->inTableScope(captionTag.localName())) {
+    if (!m_tree.openElements().inTableScope(captionTag.localName())) {
         ASSERT(isParsingFragment());
         // FIXME: parse error
         return false;
     }
     m_tree.generateImpliedEndTags();
-    // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag))
-    m_tree.openElements()->popUntilPopped(captionTag.localName());
-    m_tree.activeFormattingElements()->clearToLastMarker();
+    // FIXME: parse error if (!m_tree.currentStackItem().hasTagName(captionTag))
+    m_tree.openElements().popUntilPopped(captionTag.localName());
+    m_tree.activeFormattingElements().clearToLastMarker();
     m_insertionMode = InsertionMode::InTable;
     return true;
 }
 
 bool HTMLTreeBuilder::processTrEndTagForInRow()
 {
-    if (!m_tree.openElements()->inTableScope(trTag)) {
+    if (!m_tree.openElements().inTableScope(trTag)) {
         ASSERT(isParsingFragmentOrTemplateContents());
         // FIXME: parse error
         return false;
     }
-    m_tree.openElements()->popUntilTableRowScopeMarker();
-    ASSERT(m_tree.currentStackItem()->hasTagName(trTag));
-    m_tree.openElements()->pop();
+    m_tree.openElements().popUntilTableRowScopeMarker();
+    ASSERT(m_tree.currentStackItem().hasTagName(trTag));
+    m_tree.openElements().pop();
     m_insertionMode = InsertionMode::InTableBody;
     return true;
 }
 
 bool HTMLTreeBuilder::processTableEndTagForInTable()
 {
-    if (!m_tree.openElements()->inTableScope(tableTag)) {
+    if (!m_tree.openElements().inTableScope(tableTag)) {
         ASSERT(isParsingFragmentOrTemplateContents());
         // FIXME: parse error.
         return false;
     }
-    m_tree.openElements()->popUntilPopped(tableTag.localName());
+    m_tree.openElements().popUntilPopped(tableTag.localName());
     resetInsertionModeAppropriately();
     return true;
 }
@@ -2017,7 +2016,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
         }
 #endif
         if (token.name() == headTag) {
-            m_tree.openElements()->popHTMLHeadElement();
+            m_tree.openElements().popHTMLHeadElement();
             m_insertionMode = InsertionMode::AfterHead;
             return;
         }
@@ -2116,9 +2115,9 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
         break;
     case InsertionMode::InHeadNoscript:
         if (token.name() == noscriptTag) {
-            ASSERT(m_tree.currentStackItem()->hasTagName(noscriptTag));
-            m_tree.openElements()->pop();
-            ASSERT(m_tree.currentStackItem()->hasTagName(headTag));
+            ASSERT(m_tree.currentStackItem().hasTagName(noscriptTag));
+            m_tree.openElements().pop();
+            ASSERT(m_tree.currentStackItem().hasTagName(headTag));
             m_insertionMode = InsertionMode::InHead;
             return;
         }
@@ -2132,10 +2131,10 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
     case InsertionMode::Text:
         if (token.name() == scriptTag) {
             // Pause ourselves so that parsing stops until the script can be processed by the caller.
-            ASSERT(m_tree.currentStackItem()->hasTagName(scriptTag));
+            ASSERT(m_tree.currentStackItem().hasTagName(scriptTag));
             if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
-                m_scriptToProcess = m_tree.currentElement();
-            m_tree.openElements()->pop();
+                m_scriptToProcess = &m_tree.currentElement();
+            m_tree.openElements().pop();
             m_insertionMode = m_originalInsertionMode;
 
             // This token will not have been created by the tokenizer if a
@@ -2146,22 +2145,22 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             m_parser.tokenizer().setState(HTMLTokenizer::DataState);
             return;
         }
-        m_tree.openElements()->pop();
+        m_tree.openElements().pop();
         m_insertionMode = m_originalInsertionMode;
         break;
     case InsertionMode::InFrameset:
         if (token.name() == framesetTag) {
             bool ignoreFramesetForFragmentParsing  = m_tree.currentIsRootNode();
 #if ENABLE(TEMPLATE_ELEMENT)
-            ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing || m_tree.openElements()->hasTemplateInHTMLScope();
+            ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing || m_tree.openElements().hasTemplateInHTMLScope();
 #endif
             if (ignoreFramesetForFragmentParsing) {
                 ASSERT(isParsingFragmentOrTemplateContents());
                 parseError(token);
                 return;
             }
-            m_tree.openElements()->pop();
-            if (!isParsingFragment() && !m_tree.currentStackItem()->hasTagName(framesetTag))
+            m_tree.openElements().pop();
+            if (!isParsingFragment() && !m_tree.currentStackItem().hasTagName(framesetTag))
                 m_insertionMode = InsertionMode::AfterFrameset;
             return;
         }
@@ -2189,7 +2188,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             || token.name() == trTag
             || isTableCellContextTag(token.name())) {
             parseError(token);
-            if (m_tree.openElements()->inTableScope(token.name())) {
+            if (m_tree.openElements().inTableScope(token.name())) {
                 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
                 processEndTag(endSelect);
                 processEndTag(token);
@@ -2200,30 +2199,30 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
     case InsertionMode::InSelect:
         ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable);
         if (token.name() == optgroupTag) {
-            if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node()) && m_tree.oneBelowTop() && is<HTMLOptGroupElement>(*m_tree.oneBelowTop()->node()))
+            if (is<HTMLOptionElement>(m_tree.currentStackItem().node()) && m_tree.oneBelowTop() && is<HTMLOptGroupElement>(m_tree.oneBelowTop()->node()))
                 processFakeEndTag(optionTag);
-            if (is<HTMLOptGroupElement>(*m_tree.currentStackItem()->node())) {
-                m_tree.openElements()->pop();
+            if (is<HTMLOptGroupElement>(m_tree.currentStackItem().node())) {
+                m_tree.openElements().pop();
                 return;
             }
             parseError(token);
             return;
         }
         if (token.name() == optionTag) {
-            if (is<HTMLOptionElement>(*m_tree.currentStackItem()->node())) {
-                m_tree.openElements()->pop();
+            if (is<HTMLOptionElement>(m_tree.currentStackItem().node())) {
+                m_tree.openElements().pop();
                 return;
             }
             parseError(token);
             return;
         }
         if (token.name() == selectTag) {
-            if (!m_tree.openElements()->inSelectScope(token.name())) {
+            if (!m_tree.openElements().inSelectScope(token.name())) {
                 ASSERT(isParsingFragment());
                 parseError(token);
                 return;
             }
-            m_tree.openElements()->popUntilPopped(selectTag.localName());
+            m_tree.openElements().popUntilPopped(selectTag.localName());
             resetInsertionModeAppropriately();
             return;
         }
@@ -2442,12 +2441,12 @@ ReprocessBuffer:
     case InsertionMode::InTableBody:
     case InsertionMode::InRow:
         ASSERT(m_pendingTableCharacters.isEmpty());
-        if (m_tree.currentStackItem()->isElementNode()
-            && (is<HTMLTableElement>(*m_tree.currentStackItem()->element())
-                || m_tree.currentStackItem()->hasTagName(HTMLNames::tbodyTag)
-                || m_tree.currentStackItem()->hasTagName(HTMLNames::tfootTag)
-                || m_tree.currentStackItem()->hasTagName(HTMLNames::theadTag)
-                || m_tree.currentStackItem()->hasTagName(HTMLNames::trTag))) {
+        if (is<HTMLTableElement>(m_tree.currentStackItem().node())
+            || m_tree.currentStackItem().hasTagName(HTMLNames::tbodyTag)
+            || m_tree.currentStackItem().hasTagName(HTMLNames::tfootTag)
+            || m_tree.currentStackItem().hasTagName(HTMLNames::theadTag)
+            || m_tree.currentStackItem().hasTagName(HTMLNames::trTag)) {
+
             m_originalInsertionMode = m_insertionMode;
             m_insertionMode = InsertionMode::InTableText;
             // Note that we fall through to the InsertionMode::InTableText case below.
@@ -2586,9 +2585,9 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
             return; // FIXME: Should we break here instead of returning?
         }
 #if ENABLE(TEMPLATE_ELEMENT)
-        ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || m_tree.currentNode()->hasTagName(templateTag));
+        ASSERT(m_tree.currentNode().hasTagName(colgroupTag) || m_tree.currentNode().hasTagName(templateTag));
 #else
-        ASSERT(m_tree.currentNode()->hasTagName(colgroupTag));
+        ASSERT(m_tree.currentNode().hasTagName(colgroupTag));
 #endif
         processColgroupEndTagForInColumnGroup();
         FALLTHROUGH;
@@ -2598,7 +2597,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
     case InsertionMode::InSelectInTable:
     case InsertionMode::InSelect:
         ASSERT(m_insertionMode == InsertionMode::InSelect || m_insertionMode == InsertionMode::InSelectInTable || m_insertionMode == InsertionMode::InTable || m_insertionMode == InsertionMode::InFrameset || m_insertionMode == InsertionMode::InTableBody || m_insertionMode == InsertionMode::InColumnGroup);
-        if (m_tree.currentNode() != m_tree.openElements()->rootNode())
+        if (&m_tree.currentNode() != &m_tree.openElements().rootNode())
             parseError(token);
 #if ENABLE(TEMPLATE_ELEMENT)
         if (!m_templateInsertionModes.isEmpty()) {
@@ -2613,9 +2612,9 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
         return;
     case InsertionMode::Text:
         parseError(token);
-        if (m_tree.currentStackItem()->hasTagName(scriptTag))
+        if (m_tree.currentStackItem().hasTagName(scriptTag))
             notImplemented(); // mark the script element as "already started".
-        m_tree.openElements()->pop();
+        m_tree.openElements().pop();
         ASSERT(m_originalInsertionMode != InsertionMode::Text);
         m_insertionMode = m_originalInsertionMode;
         processEndOfFile(token);
@@ -2627,8 +2626,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
         break;
 #endif
     }
-    ASSERT(m_tree.currentNode());
-    m_tree.openElements()->popAll();
+    m_tree.openElements().popAll();
 }
 
 void HTMLTreeBuilder::defaultForInitial()
@@ -2777,10 +2775,10 @@ void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
 HTMLStackItem& HTMLTreeBuilder::adjustedCurrentStackItem() const
 {
     ASSERT(!m_tree.isEmpty());
-    if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement())
+    if (isParsingFragment() && m_tree.openElements().hasOnlyOneElement())
         return m_fragmentContext.contextElementStackItem();
 
-    return *m_tree.currentStackItem();
+    return m_tree.currentStackItem();
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#tree-construction
@@ -2789,9 +2787,9 @@ bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken& token)
     if (m_tree.isEmpty())
         return false;
     HTMLStackItem& adjustedCurrentNode = adjustedCurrentStackItem();
-    if (adjustedCurrentNode.isInHTMLNamespace())
+    if (isInHTMLNamespace(adjustedCurrentNode))
         return false;
-    if (HTMLElementStack::isMathMLTextIntegrationPoint(&adjustedCurrentNode)) {
+    if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode)) {
         if (token.type() == HTMLToken::StartTag
             && token.name() != MathMLNames::mglyphTag
             && token.name() != MathMLNames::malignmarkTag)
@@ -2803,7 +2801,7 @@ bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken& token)
         && token.type() == HTMLToken::StartTag
         && token.name() == SVGNames::svgTag)
         return false;
-    if (HTMLElementStack::isHTMLIntegrationPoint(&adjustedCurrentNode)) {
+    if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)) {
         if (token.type() == HTMLToken::StartTag)
             return false;
         if (token.type() == HTMLToken::Character)
@@ -2867,7 +2865,7 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
             || token.name() == varTag
             || (token.name() == fontTag && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
             parseError(token);
-            m_tree.openElements()->popUntilForeignContentScopeMarker();
+            m_tree.openElements().popUntilForeignContentScopeMarker();
             processStartTag(token);
             return;
         }
@@ -2886,25 +2884,25 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken& token)
         if (adjustedCurrentNode.namespaceURI() == SVGNames::svgNamespaceURI)
             adjustSVGTagNameCase(token);
 
-        if (token.name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
+        if (token.name() == SVGNames::scriptTag && m_tree.currentStackItem().hasTagName(SVGNames::scriptTag)) {
             if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
-                m_scriptToProcess = m_tree.currentElement();
-            m_tree.openElements()->pop();
+                m_scriptToProcess = &m_tree.currentElement();
+            m_tree.openElements().pop();
             return;
         }
-        if (!m_tree.currentStackItem()->isInHTMLNamespace()) {
+        if (!isInHTMLNamespace(m_tree.currentStackItem())) {
             // FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
-            auto* nodeRecord = m_tree.openElements()->topRecord();
-            if (!nodeRecord->stackItem()->hasLocalName(token.name()))
+            auto* nodeRecord = &m_tree.openElements().topRecord();
+            if (nodeRecord->stackItem().localName() != token.name())
                 parseError(token);
             while (1) {
-                if (nodeRecord->stackItem()->hasLocalName(token.name())) {
-                    m_tree.openElements()->popUntilPopped(nodeRecord->element());
+                if (nodeRecord->stackItem().localName() == token.name()) {
+                    m_tree.openElements().popUntilPopped(&nodeRecord->element());
                     return;
                 }
                 nodeRecord = nodeRecord->next();
 
-                if (nodeRecord->stackItem()->isInHTMLNamespace())
+                if (isInHTMLNamespace(nodeRecord->stackItem()))
                     break;
             }
         }