2010-06-30 Eric Seidel <eric@webkit.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jun 2010 19:50:36 +0000 (19:50 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jun 2010 19:50:36 +0000 (19:50 +0000)
        Reviewed by Adam Barth.

        Split HTMLElementStack out into its own file
        https://bugs.webkit.org/show_bug.cgi?id=41399

        No functional change, thus no tests.

        * Android.mk:
        * CMakeLists.txt:
        * GNUmakefile.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * html/HTMLElementStack.cpp: Added.
        (WebCore::HTMLElementStack::ElementRecord::ElementRecord):
        (WebCore::HTMLElementStack::ElementRecord::element):
        (WebCore::HTMLElementStack::ElementRecord::next):
        (WebCore::HTMLElementStack::ElementRecord::releaseNext):
        (WebCore::HTMLElementStack::ElementRecord::setNext):
        (WebCore::HTMLElementStack::HTMLElementStack):
        (WebCore::HTMLElementStack::~HTMLElementStack):
        (WebCore::HTMLElementStack::popHTMLHeadElement):
        (WebCore::HTMLElementStack::pop):
        (WebCore::HTMLElementStack::pushHTMLHtmlElement):
        (WebCore::HTMLElementStack::pushHTMLHeadElement):
        (WebCore::HTMLElementStack::pushHTMLBodyElement):
        (WebCore::HTMLElementStack::push):
        (WebCore::HTMLElementStack::top):
        (WebCore::HTMLElementStack::removeHTMLHeadElement):
        (WebCore::HTMLElementStack::remove):
        (WebCore::HTMLElementStack::contains):
        (WebCore::HTMLElementStack::inScope):
        (WebCore::HTMLElementStack::htmlElement):
        (WebCore::HTMLElementStack::headElement):
        (WebCore::HTMLElementStack::bodyElement):
        (WebCore::HTMLElementStack::pushCommon):
        (WebCore::HTMLElementStack::popCommon):
        (WebCore::HTMLElementStack::removeNonFirstCommon):
        * html/HTMLElementStack.h: Added.
        * html/HTMLTreeBuilder.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@62195 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/Android.mk
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/html/HTMLElementStack.cpp [new file with mode: 0644]
WebCore/html/HTMLElementStack.h [new file with mode: 0644]
WebCore/html/HTMLTreeBuilder.h

index ef7b7b5..775d512 100644 (file)
@@ -264,6 +264,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        html/HTMLDataListElement.cpp \
        html/HTMLDocument.cpp \
        html/HTMLElementsAllInOne.cpp \
+       html/HTMLElementStack.cpp \
        html/HTMLFormCollection.cpp \
        html/HTMLImageLoader.cpp \
        html/HTMLNameCollection.cpp \
index 68d366b..ad1ff3f 100644 (file)
@@ -941,6 +941,7 @@ SET(WebCore_SOURCES
     html/HTMLDivElement.cpp
     html/HTMLDocument.cpp
     html/HTMLElement.cpp
+    html/HTMLElementStack.cpp
     html/HTMLEmbedElement.cpp
     html/HTMLFieldSetElement.cpp
     html/HTMLFontElement.cpp
index 0cab209..55b6cb3 100644 (file)
@@ -1,3 +1,47 @@
+2010-06-30  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Adam Barth.
+
+        Split HTMLElementStack out into its own file
+        https://bugs.webkit.org/show_bug.cgi?id=41399
+
+        No functional change, thus no tests.
+
+        * Android.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/HTMLElementStack.cpp: Added.
+        (WebCore::HTMLElementStack::ElementRecord::ElementRecord):
+        (WebCore::HTMLElementStack::ElementRecord::element):
+        (WebCore::HTMLElementStack::ElementRecord::next):
+        (WebCore::HTMLElementStack::ElementRecord::releaseNext):
+        (WebCore::HTMLElementStack::ElementRecord::setNext):
+        (WebCore::HTMLElementStack::HTMLElementStack):
+        (WebCore::HTMLElementStack::~HTMLElementStack):
+        (WebCore::HTMLElementStack::popHTMLHeadElement):
+        (WebCore::HTMLElementStack::pop):
+        (WebCore::HTMLElementStack::pushHTMLHtmlElement):
+        (WebCore::HTMLElementStack::pushHTMLHeadElement):
+        (WebCore::HTMLElementStack::pushHTMLBodyElement):
+        (WebCore::HTMLElementStack::push):
+        (WebCore::HTMLElementStack::top):
+        (WebCore::HTMLElementStack::removeHTMLHeadElement):
+        (WebCore::HTMLElementStack::remove):
+        (WebCore::HTMLElementStack::contains):
+        (WebCore::HTMLElementStack::inScope):
+        (WebCore::HTMLElementStack::htmlElement):
+        (WebCore::HTMLElementStack::headElement):
+        (WebCore::HTMLElementStack::bodyElement):
+        (WebCore::HTMLElementStack::pushCommon):
+        (WebCore::HTMLElementStack::popCommon):
+        (WebCore::HTMLElementStack::removeNonFirstCommon):
+        * html/HTMLElementStack.h: Added.
+        * html/HTMLTreeBuilder.h:
+
 2010-06-30  Kenneth Russell  <kbr@google.com>
 
         Reviewed by Oliver Hunt.
index e04c1e0..a8e1dae 100644 (file)
@@ -1157,6 +1157,8 @@ webcore_sources += \
        WebCore/html/HTMLDocument.h \
        WebCore/html/HTMLElement.cpp \
        WebCore/html/HTMLElement.h \
+       WebCore/html/HTMLElementStack.cpp \
+       WebCore/html/HTMLElementStack.h \
        WebCore/html/HTMLEmbedElement.cpp \
        WebCore/html/HTMLEmbedElement.h \
        WebCore/html/HTMLFieldSetElement.cpp \
index 98f14ba..43a99d2 100644 (file)
             'html/HTMLDocument.h',
             'html/HTMLElement.cpp',
             'html/HTMLElement.h',
+            'html/HTMLElementStack.cpp',
+            'html/HTMLElementStack.h',
             'html/HTMLEmbedElement.cpp',
             'html/HTMLEmbedElement.h',
             'html/HTMLFieldSetElement.cpp',
index 66bc708..a6b2191 100644 (file)
@@ -654,6 +654,7 @@ SOURCES += \
     html/HTMLDListElement.cpp \
     html/HTMLDocument.cpp \
     html/HTMLElement.cpp \
+    html/HTMLElementStack.cpp \
     html/HTMLEmbedElement.cpp \
     html/HTMLFieldSetElement.cpp \
     html/HTMLFontElement.cpp \
index 87a6660..6b70dc6 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\html\HTMLElementStack.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\html\HTMLElementStack.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\html\HTMLElementsAllInOne.cpp"\r
                                >\r
                        </File>\r
index e6a43ce..fd99009 100644 (file)
                A89943290B42338800D7C802 /* BitmapImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A89943270B42338700D7C802 /* BitmapImage.cpp */; };
                A89CCC520F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A89CCC500F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.cpp */; };
                A89CCC530F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = A89CCC510F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.h */; };
+               A8A563B411DB3D10003AC2F0 /* HTMLElementStack.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A563B211DB3D10003AC2F0 /* HTMLElementStack.h */; };
+               A8A563B511DB3D10003AC2F0 /* HTMLElementStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A563B311DB3D10003AC2F0 /* HTMLElementStack.cpp */; };
                A8A909AC0CBCD6B50029B807 /* RenderSVGTransformableContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A909AA0CBCD6B50029B807 /* RenderSVGTransformableContainer.h */; };
                A8A909AD0CBCD6B50029B807 /* RenderSVGTransformableContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A909AB0CBCD6B50029B807 /* RenderSVGTransformableContainer.cpp */; };
                A8C2280E11D4A59700D5A7D3 /* DocumentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8C2280D11D4A59700D5A7D3 /* DocumentParser.cpp */; };
                A89943270B42338700D7C802 /* BitmapImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapImage.cpp; sourceTree = "<group>"; };
                A89CCC500F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplaceNodeWithSpanCommand.cpp; sourceTree = "<group>"; };
                A89CCC510F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplaceNodeWithSpanCommand.h; sourceTree = "<group>"; };
+               A8A563B211DB3D10003AC2F0 /* HTMLElementStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElementStack.h; sourceTree = "<group>"; };
+               A8A563B311DB3D10003AC2F0 /* HTMLElementStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLElementStack.cpp; sourceTree = "<group>"; };
                A8A909AA0CBCD6B50029B807 /* RenderSVGTransformableContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGTransformableContainer.h; sourceTree = "<group>"; };
                A8A909AB0CBCD6B50029B807 /* RenderSVGTransformableContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGTransformableContainer.cpp; sourceTree = "<group>"; };
                A8C2280D11D4A59700D5A7D3 /* DocumentParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentParser.cpp; sourceTree = "<group>"; };
                                15C77089100D3C6A005BA267 /* ValidityState.idl */,
                                E44613B40CD6344E00FADA75 /* VoidCallback.h */,
                                E44613A00CD6331000FADA75 /* VoidCallback.idl */,
+                               A8A563B211DB3D10003AC2F0 /* HTMLElementStack.h */,
+                               A8A563B311DB3D10003AC2F0 /* HTMLElementStack.cpp */,
                        );
                        path = html;
                        sourceTree = "<group>";
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
                                97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
                                CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
+                               A8A563B411DB3D10003AC2F0 /* HTMLElementStack.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
+                               A8A563B511DB3D10003AC2F0 /* HTMLElementStack.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/WebCore/html/HTMLElementStack.cpp b/WebCore/html/HTMLElementStack.cpp
new file mode 100644 (file)
index 0000000..0b4b1a3
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "HTMLElementStack.h"
+
+#include "Element.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class HTMLElementStack::ElementRecord : public Noncopyable {
+public:
+    ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next)
+        : m_element(element)
+        , m_next(next)
+    {
+    }
+
+    Element* element() const { return m_element.get(); }
+    ElementRecord* next() const { return m_next.get(); }
+    PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
+    void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
+
+private:
+    RefPtr<Element> m_element;
+    OwnPtr<ElementRecord> m_next;
+};
+
+HTMLElementStack::HTMLElementStack()
+    : m_htmlElement(0)
+    , m_headElement(0)
+    , m_bodyElement(0)
+{
+}
+
+HTMLElementStack::~HTMLElementStack()
+{
+}
+
+void HTMLElementStack::popHTMLHeadElement()
+{
+    ASSERT(top() == m_headElement);
+    m_headElement = 0;
+    popCommon();
+}
+
+void HTMLElementStack::pop()
+{
+    ASSERT(!top()->hasTagName(HTMLNames::headTag));
+    popCommon();
+}
+
+void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<Element> element)
+{
+    ASSERT(element->hasTagName(HTMLNames::htmlTag));
+    ASSERT(!m_htmlElement);
+    m_htmlElement = element.get();
+    pushCommon(element);
+}
+
+void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<Element> element)
+{
+    ASSERT(element->hasTagName(HTMLNames::headTag));
+    ASSERT(!m_headElement);
+    m_headElement = element.get();
+    pushCommon(element);
+}
+
+void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<Element> element)
+{
+    ASSERT(element->hasTagName(HTMLNames::bodyTag));
+    ASSERT(!m_bodyElement);
+    m_bodyElement = element.get();
+    pushCommon(element);
+}
+
+void HTMLElementStack::push(PassRefPtr<Element> element)
+{
+    ASSERT(!element->hasTagName(HTMLNames::htmlTag));
+    ASSERT(!element->hasTagName(HTMLNames::headTag));
+    ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+    ASSERT(m_htmlElement);
+    pushCommon(element);
+}
+
+Element* HTMLElementStack::top() const
+{
+    return m_top->element();
+}
+
+void HTMLElementStack::removeHTMLHeadElement(Element* element)
+{
+    ASSERT(m_headElement == element);
+    if (m_top->element() == element) {
+        popHTMLHeadElement();
+        return;
+    }
+    m_headElement = 0;
+    removeNonFirstCommon(element);
+}
+
+void HTMLElementStack::remove(Element* element)
+{
+    ASSERT(!element->hasTagName(HTMLNames::headTag));
+    if (m_top->element() == element) {
+        pop();
+        return;
+    }
+    removeNonFirstCommon(element);
+}
+
+bool HTMLElementStack::contains(Element* element) const
+{
+    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+        if (pos->element() == element)
+            return true;
+    }
+    return false;
+}
+
+bool HTMLElementStack::inScope(const AtomicString& name) const
+{
+    // FIXME: This algorithm is wrong.
+    for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
+        if (pos->element()->tagQName() == name)
+            return true;
+    }
+    return false;
+}
+
+bool HTMLElementStack::inScope(Element* element) const
+{
+    // FIXME: This algorithm is wrong.
+    return contains(element);
+}
+
+Element* HTMLElementStack::htmlElement()
+{
+    ASSERT(m_htmlElement);
+    return m_htmlElement;
+}
+
+Element* HTMLElementStack::headElement()
+{
+    ASSERT(m_headElement);
+    return m_headElement;
+}
+
+Element* HTMLElementStack::bodyElement()
+{
+    ASSERT(m_bodyElement);
+    return m_bodyElement;
+}
+
+void HTMLElementStack::pushCommon(PassRefPtr<Element> element)
+{
+    m_top.set(new ElementRecord(element, m_top.release()));
+    top()->beginParsingChildren();
+}
+
+void HTMLElementStack::popCommon()
+{
+    ASSERT(!top()->hasTagName(HTMLNames::htmlTag));
+    ASSERT(!top()->hasTagName(HTMLNames::bodyTag));
+    top()->finishParsingChildren();
+    m_top = m_top->releaseNext();
+}
+
+void HTMLElementStack::removeNonFirstCommon(Element* element)
+{
+    ASSERT(!element->hasTagName(HTMLNames::htmlTag));
+    ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+    ElementRecord* pos = m_top.get();
+    ASSERT(pos->element() != element);
+    while (pos->next()) {
+        if (pos->next()->element() == element) {
+            // FIXME: Is it OK to call finishParsingChildren()
+            // when the children aren't actually finished?
+            element->finishParsingChildren();
+            pos->setNext(pos->next()->releaseNext());
+            return;
+        }
+    }
+    ASSERT_NOT_REACHED();
+}
+
+}
diff --git a/WebCore/html/HTMLElementStack.h b/WebCore/html/HTMLElementStack.h
new file mode 100644 (file)
index 0000000..801ab6a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef HTMLElementStack_h
+#define HTMLElementStack_h
+
+#include "HTMLNames.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class Element;
+
+class HTMLElementStack : public Noncopyable {
+public:
+    HTMLElementStack();
+    ~HTMLElementStack();
+
+    Element* top() const;
+
+    void push(PassRefPtr<Element>);
+    void pushHTMLHtmlElement(PassRefPtr<Element>);
+    void pushHTMLHeadElement(PassRefPtr<Element>);
+    void pushHTMLBodyElement(PassRefPtr<Element>);
+
+    void pop();
+    void popHTMLHeadElement();
+
+    void remove(Element*);
+    void removeHTMLHeadElement(Element*);
+
+    bool contains(Element*) const;
+
+    bool inScope(const AtomicString& name) const;
+    bool inScope(Element*) const;
+
+    Element* htmlElement();
+    Element* headElement();
+    Element* bodyElement();
+
+private:
+    void pushCommon(PassRefPtr<Element>);
+    void popCommon();
+    void removeNonFirstCommon(Element*);
+
+    class ElementRecord;
+    OwnPtr<ElementRecord> m_top;
+
+    // We remember <html>, <head> and <body> as they are pushed.  Their
+    // ElementRecords keep them alive.  <html> and <body> are never popped.
+    // FIXME: We don't currently require type-specific information about
+    // these elements so we haven't yet bothered to plumb the types all the
+    // way down through createElement, etc.
+    Element* m_htmlElement;
+    Element* m_headElement;
+    Element* m_bodyElement;
+};
+
+} // namespace WebCore
+
+#endif // HTMLElementStack_h
index 9f48ef4..7e40df3 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "Element.h"
 #include "FragmentScriptingPermission.h"
-#include "HTMLNames.h"
+#include "HTMLElementStack.h"
 #include "HTMLTokenizer.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
@@ -101,193 +101,6 @@ private:
         AfterAfterFramesetMode,
     };
 
-    class ElementRecord : public Noncopyable {
-    public:
-        ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next)
-            : m_element(element)
-            , m_next(next)
-        {
-        }
-
-        Element* element() const { return m_element.get(); }
-        ElementRecord* next() const { return m_next.get(); }
-        PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
-        void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
-
-    private:
-        RefPtr<Element> m_element;
-        OwnPtr<ElementRecord> m_next;
-    };
-
-    class ElementStack : public Noncopyable {
-    public:
-        ElementStack()
-            : m_htmlElement(0)
-            , m_headElement(0)
-            , m_bodyElement(0)
-        {
-        }
-
-        void popHTMLHeadElement()
-        {
-            ASSERT(top() == m_headElement);
-            m_headElement = 0;
-            popCommon();
-        }
-
-        void pop()
-        {
-            ASSERT(!top()->hasTagName(HTMLNames::headTag));
-            popCommon();
-        }
-
-        void pushHTMLHtmlElement(PassRefPtr<Element> element)
-        {
-            ASSERT(element->hasTagName(HTMLNames::htmlTag));
-            ASSERT(!m_htmlElement);
-            m_htmlElement = element.get();
-            pushCommon(element);
-        }
-
-        void pushHTMLHeadElement(PassRefPtr<Element> element)
-        {
-            ASSERT(element->hasTagName(HTMLNames::headTag));
-            ASSERT(!m_headElement);
-            m_headElement = element.get();
-            pushCommon(element);
-        }
-
-        void pushHTMLBodyElement(PassRefPtr<Element> element)
-        {
-            ASSERT(element->hasTagName(HTMLNames::bodyTag));
-            ASSERT(!m_bodyElement);
-            m_bodyElement = element.get();
-            pushCommon(element);
-        }
-
-        void push(PassRefPtr<Element> element)
-        {
-            ASSERT(!element->hasTagName(HTMLNames::htmlTag));
-            ASSERT(!element->hasTagName(HTMLNames::headTag));
-            ASSERT(!element->hasTagName(HTMLNames::bodyTag));
-            ASSERT(m_htmlElement);
-            pushCommon(element);
-        }
-
-        Element* top() const
-        {
-            return m_top->element();
-        }
-
-        void removeHTMLHeadElement(Element* element)
-        {
-            ASSERT(m_headElement == element);
-            if (m_top->element() == element) {
-                popHTMLHeadElement();
-                return;
-            }
-            m_headElement = 0;
-            removeNonFirstCommon(element);
-        }
-
-        void remove(Element* element)
-        {
-            ASSERT(!element->hasTagName(HTMLNames::headTag));
-            if (m_top->element() == element) {
-                pop();
-                return;
-            }
-            removeNonFirstCommon(element);
-        }
-
-        bool contains(Element* element) const
-        {
-            for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-                if (pos->element() == element)
-                    return true;
-            }
-            return false;
-        }
-
-        bool inScope(const AtomicString& name) const
-        {
-            // FIXME: This algorithm is wrong.
-            for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
-                if (pos->element()->tagQName() == name)
-                    return true;
-            }
-            return false;
-        }
-
-        bool inScope(Element* element) const
-        {
-            // FIXME: This algorithm is wrong.
-            return contains(element);
-        }
-
-        Element* htmlElement()
-        {
-            ASSERT(m_htmlElement);
-            return m_htmlElement;
-        }
-
-        Element* headElement()
-        {
-            ASSERT(m_headElement);
-            return m_headElement;
-        }
-
-        Element* bodyElement()
-        {
-            ASSERT(m_bodyElement);
-            return m_bodyElement;
-        }
-
-    private:
-        void pushCommon(PassRefPtr<Element> element)
-        {
-            m_top.set(new ElementRecord(element, m_top.release()));
-            top()->beginParsingChildren();
-        }
-
-        void popCommon()
-        {
-            ASSERT(!top()->hasTagName(HTMLNames::htmlTag));
-            ASSERT(!top()->hasTagName(HTMLNames::bodyTag));
-            top()->finishParsingChildren();
-            m_top = m_top->releaseNext();
-        }
-
-        void removeNonFirstCommon(Element* element)
-        {
-            ASSERT(!element->hasTagName(HTMLNames::htmlTag));
-            ASSERT(!element->hasTagName(HTMLNames::bodyTag));
-            ElementRecord* pos = m_top.get();
-            ASSERT(pos->element() != element);
-            while (pos->next()) {
-                if (pos->next()->element() == element) {
-                    // FIXME: Is it OK to call finishParsingChildren()
-                    // when the children aren't actually finished?
-                    element->finishParsingChildren();
-                    pos->setNext(pos->next()->releaseNext());
-                    return;
-                }
-            }
-            ASSERT_NOT_REACHED();
-        }
-
-        OwnPtr<ElementRecord> m_top;
-
-        // We remember <html>, <head> and <body> as they are pushed.  Their
-        // ElementRecords keep them alive.  <html> and <body> are never popped.
-        // FIXME: We don't currently require type-specific information about
-        // these elements so we haven't yet bothered to plumb the types all the
-        // way down through createElement, etc.
-        Element* m_htmlElement;
-        Element* m_headElement;
-        Element* m_bodyElement;
-    };
-
     void passTokenToLegacyParser(HTMLToken&);
 
     // Specialized functions for processing the different types of tokens.
@@ -355,7 +168,7 @@ private:
 
     RefPtr<Element> m_headElement;
     RefPtr<Element> m_formElement;
-    ElementStack m_openElements;
+    HTMLElementStack m_openElements;
 
     class FormattingElementEntry {
     public: