15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google, Inc. All Rights Reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Apple Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef HTMLConstructionSite_h
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define HTMLConstructionSite_h
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/dom/Document.h"
31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/ParserContentPolicy.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLElementStack.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLFormattingElementList.h"
34591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Noncopyable.h"
35591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/PassRefPtr.h"
36591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/RefPtr.h"
37591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/Vector.h"
381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/text/StringBuilder.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct HTMLConstructionSiteTask {
43d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ALLOW_ONLY_INLINE_ALLOCATION();
44d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)public:
4581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    enum Operation {
4681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        Insert,
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        InsertText, // Handles possible merging of text nodes.
481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        InsertAlreadyParsedChild, // Insert w/o calling begin/end parsing.
4981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        Reparent,
5081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        TakeAllChildren,
5181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    };
5281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
5381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    explicit HTMLConstructionSiteTask(Operation op)
5481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        : operation(op)
5581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        , selfClosing(false)
5681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    {
5781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    }
5881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
59d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void trace(Visitor* visitor)
60d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
61d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        visitor->trace(parent);
62d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        visitor->trace(nextChild);
63d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        visitor->trace(child);
64d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
65d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
6681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    ContainerNode* oldParent()
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        // It's sort of ugly, but we store the |oldParent| in the |child| field
6981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        // of the task so that we don't bloat the HTMLConstructionSiteTask
7081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        // object in the common case of the Insert operation.
7181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return toContainerNode(child.get());
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    Operation operation;
75d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<ContainerNode> parent;
76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<Node> nextChild;
77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<Node> child;
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool selfClosing;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8310f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochWTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::HTMLConstructionSiteTask);
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// Note: These are intentionally ordered so that when we concatonate
881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// strings and whitespaces the resulting whitespace is ws = min(ws1, ws2).
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum WhitespaceMode {
901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    WhitespaceUnknown,
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NotAllWhitespace,
921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    AllWhitespace,
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AtomicHTMLToken;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Document;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Element;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class HTMLFormElement;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
100f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)class HTMLConstructionSite FINAL {
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DISALLOW_ALLOCATION();
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HTMLConstructionSite(Document*, ParserContentPolicy);
10553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HTMLConstructionSite(DocumentFragment*, ParserContentPolicy);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ~HTMLConstructionSite();
107d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void trace(Visitor*);
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void detach();
11051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // executeQueuedTasks empties the queue but does not flush pending text.
11251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // NOTE: Possible reentrancy via JavaScript execution.
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void executeQueuedTasks();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // flushPendingText turns pending text into queued Text insertions, but does not execute them.
11651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void flushPendingText();
11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Called before every token in HTMLTreeBuilder::processToken, thus inlined:
11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void flush()
12051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!hasPendingTasks())
12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return;
12351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        flushPendingText();
12451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        executeQueuedTasks(); // NOTE: Possible reentrancy via JavaScript execution.
12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(!hasPendingTasks());
12651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
12751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool hasPendingTasks()
12951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
13051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return !m_pendingText.isEmpty() || !m_taskQueue.isEmpty();
13151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setDefaultCompatibilityMode();
1341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void processEndOfFile();
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void finishedParsing();
136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertDoctype(AtomicHTMLToken*);
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertComment(AtomicHTMLToken*);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertCommentOnDocument(AtomicHTMLToken*);
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertCommentOnHTMLHtmlElement(AtomicHTMLToken*);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLElement(AtomicHTMLToken*);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertSelfClosingHTMLElement(AtomicHTMLToken*);
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertFormattingElement(AtomicHTMLToken*);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHeadElement(AtomicHTMLToken*);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLBodyElement(AtomicHTMLToken*);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLFormElement(AtomicHTMLToken*, bool isDemoted = false);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertScriptElement(AtomicHTMLToken*);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertTextNode(const String&, WhitespaceMode = WhitespaceUnknown);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertForeignElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken*);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHtmlStartTagInBody(AtomicHTMLToken*);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLBodyStartTagInBody(AtomicHTMLToken*);
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void reparent(HTMLElementStack::ElementRecord* newParent, HTMLElementStack::ElementRecord* child);
15681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void reparent(HTMLElementStack::ElementRecord* newParent, HTMLStackItem* child);
15781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // insertAlreadyParsedChild assumes that |child| has already been parsed (i.e., we're just
15881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // moving it around in the tree rather than parsing it for the first time). That means
15981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // this function doesn't call beginParsingChildren / finishParsingChildren.
16081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void insertAlreadyParsedChild(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* child);
16181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void takeAllChildren(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* oldParent);
16281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
163d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool shouldFosterParent() const;
166d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void fosterParent(PassRefPtrWillBeRawPtr<Node>);
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reconstructTheActiveFormattingElements();
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void generateImpliedEndTags();
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool inQuirksMode();
175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isEmpty() const { return !m_openElements.stackDepth(); }
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* currentElement() const { return m_openElements.top(); }
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* currentNode() const { return m_openElements.topNode(); }
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* currentStackItem() const { return m_openElements.topStackItem(); }
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* oneBelowTop() const { return m_openElements.oneBelowTop(); }
1828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& ownerDocumentForCurrentNode();
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElementStack* openElements() const { return &m_openElements; }
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool currentIsRootNode() { return m_openElements.topNode() == m_openElements.rootNode(); }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* head() const { return m_head->element(); }
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* headStackItem() const { return m_head.get(); }
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setForm(HTMLFormElement*);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFormElement* form() const { return m_form.get(); }
192d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLFormElement> takeForm();
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    class RedirectToFosterParentGuard {
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RedirectToFosterParentGuard(HTMLConstructionSite& tree)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            : m_tree(tree)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_tree.m_redirectAttachToFosterParent = true;
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ~RedirectToFosterParentGuard()
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLConstructionSite& m_tree;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool m_wasRedirectingBefore;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In the common case, this queue will have only one task because most
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // tokens produce only one DOM mutation.
219d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    typedef WillBeHeapVector<HTMLConstructionSiteTask, 1> TaskQueue;
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setCompatibilityMode(Document::CompatibilityMode);
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId);
223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
224d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> child, bool selfClosing = false);
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void findFosterSite(HTMLConstructionSiteTask&);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
228f523d2789ac2f83c4eca0ee4d5161bfdb5f2d052Torne (Richard Coles)    PassRefPtrWillBeRawPtr<Element> createHTMLElement(AtomicHTMLToken*);
229d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void dispatchDocumentElementAvailableIfNeeded();
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void executeTask(HTMLConstructionSiteTask&);
2351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void queueTask(const HTMLConstructionSiteTask&);
2361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
237d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RawPtrWillBeMember<Document> m_document;
23802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is the root ContainerNode to which the parser attaches all newly
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // constructed nodes. It points to a DocumentFragment when parsing fragments
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and a Document in all other cases.
242d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RawPtrWillBeMember<ContainerNode> m_attachmentRoot;
24302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
244d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<HTMLStackItem> m_head;
245d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<HTMLFormElement> m_form;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mutable HTMLElementStack m_openElements;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mutable HTMLFormattingElementList m_activeFormattingElements;
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
24981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    TaskQueue m_taskQueue;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
251f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    class PendingText FINAL {
252f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        DISALLOW_ALLOCATION();
253f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    public:
25451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        PendingText()
25551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            : whitespaceMode(WhitespaceUnknown)
25651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
25751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
25851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
259f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        void append(PassRefPtrWillBeRawPtr<ContainerNode> newParent, PassRefPtrWillBeRawPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
26051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
26151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!parent || parent == newParent);
26251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parent = newParent;
26351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!nextChild || nextChild == newNextChild);
26451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            nextChild = newNextChild;
26551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            stringBuilder.append(newString);
26651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            whitespaceMode = std::min(whitespaceMode, newWhitespaceMode);
26751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
26951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        void swap(PendingText& other)
27051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
27151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            std::swap(whitespaceMode, other.whitespaceMode);
27251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parent.swap(other.parent);
27351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            nextChild.swap(other.nextChild);
27451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            stringBuilder.swap(other.stringBuilder);
27551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
27651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
27751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        void discard()
27851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
27951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            PendingText discardedText;
28051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            swap(discardedText);
28151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
28251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
28351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        bool isEmpty()
28451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
28551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // When the stringbuilder is empty, the parent and whitespace should also be "empty".
28651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(stringBuilder.isEmpty() == !parent);
28751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!stringBuilder.isEmpty() || !nextChild);
28851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnknown));
28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return stringBuilder.isEmpty();
29051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
29151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
292f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        void trace(Visitor*);
293f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
294f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeMember<ContainerNode> parent;
295f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeMember<Node> nextChild;
29651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        StringBuilder stringBuilder;
29751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        WhitespaceMode whitespaceMode;
29851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    };
29951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
30051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    PendingText m_pendingText;
30151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
302926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ParserContentPolicy m_parserContentPolicy;
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_isParsingFragment;
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In the "in table" insertion mode, we sometimes get into a state where
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // "whenever a node would be inserted into the current node, it must instead
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be foster parented."  This flag tracks whether we're in that state.
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_redirectAttachToFosterParent;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool m_inQuirksMode;
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
317