Simplify DocumentType handling.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Sep 2013 17:05:18 +0000 (17:05 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Sep 2013 17:05:18 +0000 (17:05 +0000)
<https://webkit.org/b/120529>

Reviewed by Antti Koivisto.

Removed the insertedInto()/removedFrom() handlers from DocumentType.

Document no longer keeps a pointer to its doctype node, it was only used for the
document.doctype DOM API, which now just looks through the list of (<=2) children.

The ENABLE(LEGACY_VIEWPORT_ADAPTION) hunk from Document::setDocType() was moved
into Document::childrenChanged().

We no longer clear the style resolver on doctype insertion/removal since it
doesn't actually affect style anyway.

Also made doctype() return a PassRefPtr<DocumentType> instead of a raw pointer.

* dom/Document.cpp:
(WebCore::Document::dispose):
(WebCore::Document::doctype):
(WebCore::Document::childrenChanged):
* dom/Document.h:
* dom/DocumentType.cpp:
* dom/DocumentType.h:
* editing/markup.cpp:
(WebCore::documentTypeString):

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

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/DocumentType.cpp
Source/WebCore/dom/DocumentType.h
Source/WebCore/editing/markup.cpp

index 9b52392..75f8636 100644 (file)
@@ -1,3 +1,33 @@
+2013-09-02  Andreas Kling  <akling@apple.com>
+
+        Simplify DocumentType handling.
+        <https://webkit.org/b/120529>
+
+        Reviewed by Antti Koivisto.
+
+        Removed the insertedInto()/removedFrom() handlers from DocumentType.
+
+        Document no longer keeps a pointer to its doctype node, it was only used for the
+        document.doctype DOM API, which now just looks through the list of (<=2) children.
+
+        The ENABLE(LEGACY_VIEWPORT_ADAPTION) hunk from Document::setDocType() was moved
+        into Document::childrenChanged().
+
+        We no longer clear the style resolver on doctype insertion/removal since it
+        doesn't actually affect style anyway.
+
+        Also made doctype() return a PassRefPtr<DocumentType> instead of a raw pointer.
+
+        * dom/Document.cpp:
+        (WebCore::Document::dispose):
+        (WebCore::Document::doctype):
+        (WebCore::Document::childrenChanged):
+        * dom/Document.h:
+        * dom/DocumentType.cpp:
+        * dom/DocumentType.h:
+        * editing/markup.cpp:
+        (WebCore::documentTypeString):
+
 2013-09-02  Anton Obzhirov  <a.obzhirov@samsung.com>
 
         <https://webkit.org/b/98350> [GTK] accessibility/aria-invalid.html times out
index f0f671a..ed3869d 100644 (file)
@@ -623,7 +623,6 @@ void Document::dispose()
     ASSERT(!m_deletionHasBegun);
     // We must make sure not to be retaining any of our children through
     // these extra pointers or we will create a reference cycle.
-    m_docType = 0;
     m_focusedElement = 0;
     m_hoveredElement = 0;
     m_activeElement = 0;
@@ -744,22 +743,6 @@ void Document::resetActiveLinkColor()
     m_activeLinkColor.setNamedColor("red");
 }
 
-void Document::setDocType(PassRefPtr<DocumentType> docType)
-{
-    // This should never be called more than once.
-    ASSERT(!m_docType || !docType);
-    m_docType = docType;
-    if (m_docType) {
-        this->adoptIfNeeded(m_docType.get());
-#if ENABLE(LEGACY_VIEWPORT_ADAPTION)
-        if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
-            processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile);
-#endif
-    }
-    // Doctype affects the interpretation of the stylesheets.
-    clearStyleResolver();
-}
-
 DOMImplementation* Document::implementation()
 {
     if (!m_implementation)
@@ -772,10 +755,28 @@ bool Document::hasManifest() const
     return documentElement() && documentElement()->hasTagName(htmlTag) && documentElement()->hasAttribute(manifestAttr);
 }
 
+PassRefPtr<DocumentType> Document::doctype() const
+{
+    for (Node* node = firstChild(); node; node = node->nextSibling()) {
+        if (node->isDocumentTypeNode())
+            return static_cast<DocumentType*>(node);
+    }
+    return 0;
+}
+
 void Document::childrenChanged(const ChildChange& change)
 {
     ContainerNode::childrenChanged(change);
 
+    // NOTE: Per DOM, dynamically inserting/removing doctype nodes doesn't affect compatibility mode.
+
+#if ENABLE(LEGACY_VIEWPORT_ADAPTION)
+    if (RefPtr<DocumentType> documentType = doctype()) {
+        if (documentType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
+            processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile);
+    }
+#endif
+
     Element* newDocumentElement = 0;
     auto firstElementChild = elementChildren(this).begin();
     if (firstElementChild != elementChildren(this).end())
index 77bedbe..b9c9966 100644 (file)
@@ -327,7 +327,7 @@ public:
     void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
     ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
 
-    DocumentType* doctype() const { return m_docType.get(); }
+    PassRefPtr<DocumentType> doctype() const;
 
     DOMImplementation* implementation();
     
@@ -885,8 +885,6 @@ public:
     void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
     uint64_t domTreeVersion() const { return m_domTreeVersion; }
 
-    void setDocType(PassRefPtr<DocumentType>);
-
     // XPathEvaluator methods
     PassRefPtr<XPathExpression> createExpression(const String& expression,
                                                  XPathNSResolver* resolver,
@@ -1306,7 +1304,6 @@ private:
 
     String m_baseTarget;
 
-    RefPtr<DocumentType> m_docType;
     OwnPtr<DOMImplementation> m_implementation;
 
     RefPtr<CSSStyleSheet> m_elementSheet;
index 61e60bf..844bd80 100644 (file)
@@ -56,28 +56,4 @@ PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
     return create(&document(), m_name, m_publicId, m_systemId);
 }
 
-Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* insertionPoint)
-{
-    Node::insertedInto(insertionPoint);
-    if (!insertionPoint->inDocument())
-        return InsertionDone;
-
-    // Our document node can be null if we were created by a DOMImplementation.  We use the parent() instead.
-    ASSERT(parentNode() && parentNode()->isDocumentNode());
-    if (parentNode() && parentNode()->isDocumentNode()) {
-        Document* doc = toDocument(parentNode());
-        if (!doc->doctype())
-            doc->setDocType(this);
-    }
-
-    return InsertionDone;
-}
-
-void DocumentType::removedFrom(ContainerNode* insertionPoint)
-{
-    if (insertionPoint->inDocument()&& document().doctype() == this)
-        document().setDocType(0);
-    Node::removedFrom(insertionPoint);
-}
-
 }
index c57ac25..e1c111a 100644 (file)
@@ -54,9 +54,6 @@ private:
     virtual NodeType nodeType() const;
     virtual PassRefPtr<Node> cloneNode(bool deep);
 
-    virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
-    virtual void removedFrom(ContainerNode*) OVERRIDE;
-
     OwnPtr<NamedNodeMap> m_entities;
     OwnPtr<NamedNodeMap> m_notations;
 
index 80d81f7..ac6e0a9 100644 (file)
@@ -926,11 +926,11 @@ PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const V
 
 String documentTypeString(const Document& document)
 {
-    DocumentType* documentType = document.doctype();
+    RefPtr<DocumentType> documentType = document.doctype();
     if (!documentType)
         return String();
 
-    return createMarkup(documentType);
+    return createMarkup(documentType.get());
 }
 
 String createFullMarkup(const Node* node)