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