+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.
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
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();
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)
&& !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>();
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(element, token));
+ 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();
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()
void HTMLConstructionSite::insertComment(AtomicHTMLToken* token)
{
ASSERT(token->type() == HTMLToken::Comment);
- attachLater(currentNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
+ attachLater(¤tNode(), Comment::create(ownerDocumentForCurrentNode(), token->comment()));
}
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(¤tNode(), &m_head->element());
m_openElements.pushHTMLHeadElement(m_head);
}
{
ASSERT(!shouldFosterParent());
RefPtr<Element> body = createHTMLElement(token);
- attachLater(currentNode(), body);
- m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
+ attachLater(¤tNode(), body.get());
+ m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.releaseNonNull(), *token));
}
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
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(¤tNode(), 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(¤tNode(), element);
+ m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
}
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(¤tNode(), 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
}
// 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(¤tStackItem());
}
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(¤tNode(), element);
+ m_openElements.push(HTMLStackItem::create(element.releaseNonNull(), *token));
}
void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
RefPtr<Element> element = createElement(token, namespaceURI);
if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptElementIfPossible(element.get()))
- attachLater(currentNode(), element, token->selfClosing());
+ attachLater(¤tNode(), 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 = ¤tNode();
if (shouldFosterParent())
findFosterSite(task);
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);
}
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)
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
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();
}
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(¤tNode(), &reconstructed->node());
m_openElements.push(reconstructed);
unopenedEntry.replaceElement(reconstructed.release());
}
void HTMLConstructionSite::generateImpliedEndTagsWithExclusion(const AtomicString& tagName)
{
- while (hasImpliedEndTag(currentStackItem()) && !currentStackItem()->matchesHTMLTag(tagName))
+ while (hasImpliedEndTag(currentStackItem()) && !currentStackItem().matchesHTMLTag(tagName))
m_openElements.pop();
}
// 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;
}
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)
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*);
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());
}
}
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;
}
bool HTMLElementStack::hasOnlyOneElement() const
{
- return !topRecord()->next();
+ return !topRecord().next();
}
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();
}
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();
}
void HTMLElementStack::popUntilNumberedHeaderElementPopped()
{
- while (!topStackItem()->isNumberedHeaderElement())
+ while (!isNumberedHeaderElement(topStackItem()))
pop();
pop();
}
void HTMLElementStack::popUntil(Element* element)
{
- while (top() != element)
+ while (&top() != element)
pop();
}
}
// 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")
}
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()
void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
{
- ASSERT(rootItem->isDocumentFragmentNode());
+ ASSERT(rootItem->isDocumentFragment());
pushRootNodeCommon(rootItem);
}
{
ASSERT(!m_top);
ASSERT(!m_rootNode);
- m_rootNode = rootItem->node();
+ m_rootNode = &rootItem->node();
pushCommon(rootItem);
}
{
ASSERT(item->hasTagName(HTMLNames::headTag));
ASSERT(!m_headElement);
- m_headElement = item->element();
+ m_headElement = &item->element();
pushCommon(item);
}
{
ASSERT(item->hasTagName(HTMLNames::bodyTag));
ASSERT(!m_bodyElement);
- m_bodyElement = item->element();
+ m_bodyElement = &item->element();
pushCommon(item);
}
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
// 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;
}
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
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;
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;
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;
}
#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)
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--;
{
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;
}
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
void HTMLElementStack::show()
{
for (ElementRecord* record = m_top.get(); record; record = record->next())
- record->element()->showNode();
+ record->element().showNode();
}
#endif
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;
// 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;
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*);
#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();
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)
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;
}
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)
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);
}
// 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
if (entry.isMarker())
fprintf(stderr, "marker\n");
else
- entry.element()->showNode();
+ entry.element().showNode();
}
}
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().
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;
/*
* 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
|| 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
|| 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
inline bool HTMLTreeBuilder::isParsingTemplateContents() const
{
#if ENABLE(TEMPLATE_ELEMENT)
- return m_tree.openElements()->hasTemplateInHTMLScope();
+ return m_tree.openElements().hasTemplateInHTMLScope();
#else
return false;
#endif
// 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))
: 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
processToken(token);
bool inForeignContent = !m_tree.isEmpty()
- && !adjustedCurrentStackItem().isInHTMLNamespace()
+ && !isInHTMLNamespace(adjustedCurrentStackItem())
&& !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
&& !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
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);
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();
}
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());
}
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;
}
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;
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?
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);
}
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();
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;
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);
}
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);
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;
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;
{
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) {
// FIXME: parse error
return false;
}
- m_tree.openElements()->pop();
+ m_tree.openElements().pop();
m_insertionMode = InsertionMode::InTable;
return true;
}
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);
}
{
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;
return;
}
if (isTableBodyContextTag(token.name())) {
- m_tree.openElements()->popUntilTableScopeMarker();
+ m_tree.openElements().popUntilTableScopeMarker();
m_tree.insertHTMLElement(&token);
m_insertionMode = InsertionMode::InTableBody;
return;
if (m_tree.form() && !isParsingTemplateContents())
return;
m_tree.insertHTMLFormElement(&token, true);
- m_tree.openElements()->pop();
+ m_tree.openElements().pop();
return;
}
#if ENABLE(TEMPLATE_ELEMENT)
#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) {
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;
}
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;
}
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
|| 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;
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);
}
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);
}
}
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;
}
{
parseError(token);
#if ENABLE(TEMPLATE_ELEMENT)
- if (m_tree.openElements()->hasTemplateInHTMLScope()) {
+ if (m_tree.openElements().hasTemplateInHTMLScope()) {
ASSERT(isParsingTemplateContents());
return;
}
{
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;
}
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;
}
// 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();
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;
}
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
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);
}
}
{
// 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();
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;
}
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;
}
{
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;
}
return;
}
if (isTableBodyContextTag(token.name())) {
- if (!m_tree.openElements()->inTableScope(token.name())) {
+ if (!m_tree.openElements().inTableScope(token.name())) {
parseError(token);
return;
}
{
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;
}
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
|| 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())) {
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) {
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;
}
}
#endif
if (token.name() == headTag) {
- m_tree.openElements()->popHTMLHeadElement();
+ m_tree.openElements().popHTMLHeadElement();
m_insertionMode = InsertionMode::AfterHead;
return;
}
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;
}
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
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;
}
|| 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);
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;
}
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.
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;
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()) {
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);
break;
#endif
}
- ASSERT(m_tree.currentNode());
- m_tree.openElements()->popAll();
+ m_tree.openElements().popAll();
}
void HTMLTreeBuilder::defaultForInitial()
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
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)
&& 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)
|| 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;
}
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;
}
}