Home | History | Annotate | Download | only in parser
      1 /*
      2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
      3  * Copyright (C) 2011 Apple Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef HTMLConstructionSite_h
     28 #define HTMLConstructionSite_h
     29 
     30 #include "FragmentScriptingPermission.h"
     31 #include "HTMLElementStack.h"
     32 #include "HTMLFormattingElementList.h"
     33 #include "NotImplemented.h"
     34 #include <wtf/Noncopyable.h>
     35 #include <wtf/PassRefPtr.h>
     36 #include <wtf/RefPtr.h>
     37 
     38 namespace WebCore {
     39 
     40 class AtomicHTMLToken;
     41 class Document;
     42 class Element;
     43 
     44 class HTMLConstructionSite {
     45     WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
     46 public:
     47     HTMLConstructionSite(Document*);
     48     HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission);
     49     ~HTMLConstructionSite();
     50 
     51     void detach();
     52 
     53     void insertDoctype(AtomicHTMLToken&);
     54     void insertComment(AtomicHTMLToken&);
     55     void insertCommentOnDocument(AtomicHTMLToken&);
     56     void insertCommentOnHTMLHtmlElement(AtomicHTMLToken&);
     57     void insertHTMLElement(AtomicHTMLToken&);
     58     void insertSelfClosingHTMLElement(AtomicHTMLToken&);
     59     void insertFormattingElement(AtomicHTMLToken&);
     60     void insertHTMLHeadElement(AtomicHTMLToken&);
     61     void insertHTMLBodyElement(AtomicHTMLToken&);
     62     void insertHTMLFormElement(AtomicHTMLToken&, bool isDemoted = false);
     63     void insertScriptElement(AtomicHTMLToken&);
     64     void insertTextNode(const String&);
     65     void insertForeignElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
     66 
     67     void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken&);
     68     void insertHTMLHtmlStartTagInBody(AtomicHTMLToken&);
     69     void insertHTMLBodyStartTagInBody(AtomicHTMLToken&);
     70 
     71     PassRefPtr<Element> createHTMLElement(AtomicHTMLToken&);
     72     PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
     73 
     74     bool shouldFosterParent() const;
     75     void fosterParent(Node*);
     76 
     77     bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
     78     void reconstructTheActiveFormattingElements();
     79 
     80     void generateImpliedEndTags();
     81     void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
     82 
     83     Element* currentElement() const { return m_openElements.top(); }
     84     ContainerNode* currentNode() const { return m_openElements.topNode(); }
     85     Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
     86 
     87     HTMLElementStack* openElements() const { return &m_openElements; }
     88     HTMLFormattingElementList* activeFormattingElements() const { return &m_activeFormattingElements; }
     89 
     90     Element* head() const { return m_head.get(); }
     91 
     92     void setForm(HTMLFormElement*);
     93     HTMLFormElement* form() const { return m_form.get(); }
     94     PassRefPtr<HTMLFormElement> takeForm();
     95 
     96     class RedirectToFosterParentGuard {
     97         WTF_MAKE_NONCOPYABLE(RedirectToFosterParentGuard);
     98     public:
     99         RedirectToFosterParentGuard(HTMLConstructionSite& tree)
    100             : m_tree(tree)
    101             , m_wasRedirectingBefore(tree.m_redirectAttachToFosterParent)
    102         {
    103             m_tree.m_redirectAttachToFosterParent = true;
    104         }
    105 
    106         ~RedirectToFosterParentGuard()
    107         {
    108             m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore;
    109         }
    110 
    111     private:
    112         HTMLConstructionSite& m_tree;
    113         bool m_wasRedirectingBefore;
    114     };
    115 
    116 private:
    117     struct AttachmentSite {
    118         ContainerNode* parent;
    119         Node* nextChild;
    120     };
    121 
    122     template<typename ChildType>
    123     PassRefPtr<ChildType> attach(ContainerNode* parent, PassRefPtr<ChildType> child);
    124     PassRefPtr<Element> attachToCurrent(PassRefPtr<Element>);
    125 
    126     void attachAtSite(const AttachmentSite&, PassRefPtr<Node> child);
    127     void findFosterSite(AttachmentSite&);
    128 
    129     PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
    130     PassRefPtr<Element> createElement(AtomicHTMLToken&, const AtomicString& namespaceURI);
    131 
    132     void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*);
    133     void dispatchDocumentElementAvailableIfNeeded();
    134 
    135     Document* m_document;
    136 
    137     // This is the root ContainerNode to which the parser attaches all newly
    138     // constructed nodes. It points to a DocumentFragment when parsing fragments
    139     // and a Document in all other cases.
    140     ContainerNode* m_attachmentRoot;
    141 
    142     RefPtr<Element> m_head;
    143     RefPtr<HTMLFormElement> m_form;
    144     mutable HTMLElementStack m_openElements;
    145     mutable HTMLFormattingElementList m_activeFormattingElements;
    146 
    147     FragmentScriptingPermission m_fragmentScriptingPermission;
    148     bool m_isParsingFragment;
    149 
    150     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-intable
    151     // In the "in table" insertion mode, we sometimes get into a state where
    152     // "whenever a node would be inserted into the current node, it must instead
    153     // be foster parented."  This flag tracks whether we're in that state.
    154     bool m_redirectAttachToFosterParent;
    155 };
    156 
    157 }
    158 
    159 #endif
    160