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)
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
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)
81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::HTMLConstructionSiteTask);
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
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)
957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccienum FlushMode {
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Flush pending text. Flush queued tasks.
977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FlushAlways,
987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Flush pending text if node has length limit. Flush queued tasks.
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    FlushIfAtTextLimit,
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class AtomicHTMLToken;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Document;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Element;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class HTMLFormElement;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
108f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)class HTMLConstructionSite FINAL {
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
110d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    DISALLOW_ALLOCATION();
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HTMLConstructionSite(Document*, ParserContentPolicy);
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HTMLConstructionSite(DocumentFragment*, ParserContentPolicy);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ~HTMLConstructionSite();
115d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void trace(Visitor*);
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void detach();
11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // executeQueuedTasks empties the queue but does not flush pending text.
12051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // NOTE: Possible reentrancy via JavaScript execution.
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void executeQueuedTasks();
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // flushPendingText turns pending text into queued Text insertions, but does not execute them.
1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void flushPendingText(FlushMode);
12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Called before every token in HTMLTreeBuilder::processToken, thus inlined:
1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void flush(FlushMode mode)
12851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
12951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!hasPendingTasks())
13051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return;
1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        flushPendingText(mode);
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        executeQueuedTasks(); // NOTE: Possible reentrancy via JavaScript execution.
1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(mode == FlushIfAtTextLimit || !hasPendingTasks());
13451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
13551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool hasPendingTasks()
13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
13851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return !m_pendingText.isEmpty() || !m_taskQueue.isEmpty();
13951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
14051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setDefaultCompatibilityMode();
1421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void processEndOfFile();
143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void finishedParsing();
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertDoctype(AtomicHTMLToken*);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertComment(AtomicHTMLToken*);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertCommentOnDocument(AtomicHTMLToken*);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertCommentOnHTMLHtmlElement(AtomicHTMLToken*);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLElement(AtomicHTMLToken*);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertSelfClosingHTMLElement(AtomicHTMLToken*);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertFormattingElement(AtomicHTMLToken*);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHeadElement(AtomicHTMLToken*);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLBodyElement(AtomicHTMLToken*);
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLFormElement(AtomicHTMLToken*, bool isDemoted = false);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertScriptElement(AtomicHTMLToken*);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertTextNode(const String&, WhitespaceMode = WhitespaceUnknown);
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertForeignElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken*);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLHtmlStartTagInBody(AtomicHTMLToken*);
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void insertHTMLBodyStartTagInBody(AtomicHTMLToken*);
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void reparent(HTMLElementStack::ElementRecord* newParent, HTMLElementStack::ElementRecord* child);
16481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void reparent(HTMLElementStack::ElementRecord* newParent, HTMLStackItem* child);
16581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // insertAlreadyParsedChild assumes that |child| has already been parsed (i.e., we're just
16681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // moving it around in the tree rather than parsing it for the first time). That means
16781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // this function doesn't call beginParsingChildren / finishParsingChildren.
16881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void insertAlreadyParsedChild(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* child);
16981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    void takeAllChildren(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* oldParent);
17081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
171d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool shouldFosterParent() const;
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void fosterParent(PassRefPtrWillBeRawPtr<Node>);
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reconstructTheActiveFormattingElements();
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void generateImpliedEndTags();
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool inQuirksMode();
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isEmpty() const { return !m_openElements.stackDepth(); }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* currentElement() const { return m_openElements.top(); }
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* currentNode() const { return m_openElements.topNode(); }
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* currentStackItem() const { return m_openElements.topStackItem(); }
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* oneBelowTop() const { return m_openElements.oneBelowTop(); }
1908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& ownerDocumentForCurrentNode();
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElementStack* openElements() const { return &m_openElements; }
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool currentIsRootNode() { return m_openElements.topNode() == m_openElements.rootNode(); }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* head() const { return m_head->element(); }
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLStackItem* headStackItem() const { return m_head.get(); }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setForm(HTMLFormElement*);
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLFormElement* form() const { return m_form.get(); }
200d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLFormElement> takeForm();
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    class RedirectToFosterParentGuard {
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RedirectToFosterParentGuard(HTMLConstructionSite& tree)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            : m_tree(tree)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_tree.m_redirectAttachToFosterParent = true;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ~RedirectToFosterParentGuard()
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        HTMLConstructionSite& m_tree;
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool m_wasRedirectingBefore;
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In the common case, this queue will have only one task because most
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // tokens produce only one DOM mutation.
227d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    typedef WillBeHeapVector<HTMLConstructionSiteTask, 1> TaskQueue;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setCompatibilityMode(Document::CompatibilityMode);
230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId);
231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
232d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> child, bool selfClosing = false);
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void findFosterSite(HTMLConstructionSiteTask&);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
236c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(AtomicHTMLToken*);
237d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void dispatchDocumentElementAvailableIfNeeded();
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void executeTask(HTMLConstructionSiteTask&);
2431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void queueTask(const HTMLConstructionSiteTask&);
2441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
245d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RawPtrWillBeMember<Document> m_document;
24602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is the root ContainerNode to which the parser attaches all newly
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // constructed nodes. It points to a DocumentFragment when parsing fragments
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and a Document in all other cases.
250d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RawPtrWillBeMember<ContainerNode> m_attachmentRoot;
25102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
252d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<HTMLStackItem> m_head;
253d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeMember<HTMLFormElement> m_form;
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mutable HTMLElementStack m_openElements;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    mutable HTMLFormattingElementList m_activeFormattingElements;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    TaskQueue m_taskQueue;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
259f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    class PendingText FINAL {
260f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        DISALLOW_ALLOCATION();
261f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    public:
26251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        PendingText()
26351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            : whitespaceMode(WhitespaceUnknown)
26451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
26551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
26651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
267f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        void append(PassRefPtrWillBeRawPtr<ContainerNode> newParent, PassRefPtrWillBeRawPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
26951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!parent || parent == newParent);
27051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parent = newParent;
27151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!nextChild || nextChild == newNextChild);
27251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            nextChild = newNextChild;
27351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            stringBuilder.append(newString);
27451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            whitespaceMode = std::min(whitespaceMode, newWhitespaceMode);
27551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
27651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
27751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        void swap(PendingText& other)
27851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
27951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            std::swap(whitespaceMode, other.whitespaceMode);
28051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parent.swap(other.parent);
28151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            nextChild.swap(other.nextChild);
28251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            stringBuilder.swap(other.stringBuilder);
28351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
28451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
28551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        void discard()
28651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
28751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            PendingText discardedText;
28851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            swap(discardedText);
28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
29051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
29151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        bool isEmpty()
29251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
29351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // When the stringbuilder is empty, the parent and whitespace should also be "empty".
29451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(stringBuilder.isEmpty() == !parent);
29551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!stringBuilder.isEmpty() || !nextChild);
29651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnknown));
29751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return stringBuilder.isEmpty();
29851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
29951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
300f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        void trace(Visitor*);
301f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
302f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeMember<ContainerNode> parent;
303f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeMember<Node> nextChild;
30451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        StringBuilder stringBuilder;
30551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        WhitespaceMode whitespaceMode;
30651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    };
30751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
30851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    PendingText m_pendingText;
30951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
310926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ParserContentPolicy m_parserContentPolicy;
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_isParsingFragment;
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // In the "in table" insertion mode, we sometimes get into a state where
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // "whenever a node would be inserted into the current node, it must instead
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be foster parented."  This flag tracks whether we're in that state.
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_redirectAttachToFosterParent;
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool m_inQuirksMode;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
322c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
325