2010-12-24 Justin Schuh <jschuh@chromium.org>
authorjschuh@chromium.org <jschuh@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Dec 2010 17:31:15 +0000 (17:31 +0000)
committerjschuh@chromium.org <jschuh@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Dec 2010 17:31:15 +0000 (17:31 +0000)
        Reviewed by Nikolas Zimmermann.

        SVGElementInstance::m_useElement should be cleared when use element is removed from document
        https://bugs.webkit.org/show_bug.cgi?id=51486

        Test: svg/custom/use-instanceRoot-with-use-removed.svg

        * svg/SVGElementInstance.cpp:
        (WebCore::SVGElementInstance::invalidateAllInstancesOfElement):
        * svg/SVGElementInstance.h:
        (WebCore::SVGElementInstance::clearUseElement):
        * svg/SVGUseElement.cpp:
        (WebCore::SVGUseElement::removedFromDocument):
        (WebCore::ShadowTreeUpdateBlocker::if):
        (WebCore::SVGUseElement::detachInstance):
        (WebCore::SVGUseElement::detach):
        * svg/SVGUseElement.h:
2010-12-24  Justin Schuh  <jschuh@chromium.org>

        Reviewed by Nikolas Zimmermann.

        SVGElementInstance::m_useElement should be cleared when use element is removed from document
        https://bugs.webkit.org/show_bug.cgi?id=51486

        * svg/custom/use-instanceRoot-with-use-removed-expected.txt: Added.
        * svg/custom/use-instanceRoot-with-use-removed.svg: Added.

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

LayoutTests/ChangeLog
LayoutTests/svg/custom/use-instanceRoot-with-use-removed-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/use-instanceRoot-with-use-removed.svg [new file with mode: 0644]
WebCore/ChangeLog
WebCore/svg/SVGElementInstance.cpp
WebCore/svg/SVGElementInstance.h
WebCore/svg/SVGUseElement.cpp
WebCore/svg/SVGUseElement.h

index f721d20..bd9bc43 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-24  Justin Schuh  <jschuh@chromium.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGElementInstance::m_useElement should be cleared when use element is removed from document
+        https://bugs.webkit.org/show_bug.cgi?id=51486
+
+        * svg/custom/use-instanceRoot-with-use-removed-expected.txt: Added.
+        * svg/custom/use-instanceRoot-with-use-removed.svg: Added.
+
 2010-12-24  Alexander Pavlov  <apavlov@chromium.org>
 
         Reviewed by Yury Semikhatsky.
diff --git a/LayoutTests/svg/custom/use-instanceRoot-with-use-removed-expected.txt b/LayoutTests/svg/custom/use-instanceRoot-with-use-removed-expected.txt
new file mode 100644 (file)
index 0000000..c333423
--- /dev/null
@@ -0,0 +1 @@
+PASS: Successfully removed use element.
diff --git a/LayoutTests/svg/custom/use-instanceRoot-with-use-removed.svg b/LayoutTests/svg/custom/use-instanceRoot-with-use-removed.svg
new file mode 100644 (file)
index 0000000..195ea83
--- /dev/null
@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\r
+<script>\r
+<![CDATA[\r
+if (window.layoutTestController) {\r
+    layoutTestController.dumpAsText();\r
+    layoutTestController.waitUntilDone();\r
+    gc = function(){window.GCController.collect()};\r
+} else if (!window.gc)\r
+    gc = function(){};\r
+\r
+window.onload = function(){\r
+    if (location.hash != "#2") {\r
+        if (location.hash)\r
+            location.hash = "#" + (parseInt(location.hash.slice(1)) + 1).toString();\r
+        else\r
+            location.hash = "#1";\r
+        var ir = document.getElementById("use1").instanceRoot;\r
+        ir.correspondingUseElement.parentElement.removeChild(ir.correspondingUseElement);\r
+        gc();\r
+        ir.correspondingUseElement;\r
+        setTimeout(function(){location.reload()},0);\r
+    } else {\r
+        document.getElementById("t1").appendChild(document.createTextNode("PASS: Successfully removed use element."));\r
+        if (window.layoutTestController)\r
+            layoutTestController.notifyDone();\r
+    }\r
+}\r
+//]]>\r
+</script>\r
+<g id="g1" />\r
+<use xlink:href="#g1" id="use1" />\r
+<text x="20" y="20" fill="green" id="t1"></text>\r
+</svg>\r
index 8da3369..c317d2e 100644 (file)
@@ -1,3 +1,23 @@
+2010-12-24  Justin Schuh  <jschuh@chromium.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        SVGElementInstance::m_useElement should be cleared when use element is removed from document
+        https://bugs.webkit.org/show_bug.cgi?id=51486
+
+        Test: svg/custom/use-instanceRoot-with-use-removed.svg
+
+        * svg/SVGElementInstance.cpp:
+        (WebCore::SVGElementInstance::invalidateAllInstancesOfElement):
+        * svg/SVGElementInstance.h:
+        (WebCore::SVGElementInstance::clearUseElement):
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::removedFromDocument):
+        (WebCore::ShadowTreeUpdateBlocker::if):
+        (WebCore::SVGUseElement::detachInstance):
+        (WebCore::SVGUseElement::detach):
+        * svg/SVGUseElement.h:
+
 2010-12-23  Joseph Pecoraro  <joepeck@webkit.org>
 
         Reviewed by Yury Semikhatsky.
index f2812dd..a873f0b 100644 (file)
@@ -103,7 +103,8 @@ void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
     const HashSet<SVGElementInstance*>::const_iterator end = set.end();
     for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) {
         ASSERT((*it)->correspondingElement() == element);
-        (*it)->correspondingUseElement()->invalidateShadowTree();
+        if (SVGUseElement* element = (*it)->correspondingUseElement())
+            element->invalidateShadowTree();
     }
 
     // Be sure to rebuild use trees, if needed
index 3e05ee9..6dbcff4 100644 (file)
@@ -57,6 +57,7 @@ public:
     SVGElement* correspondingElement() const { return m_element.get(); }
     SVGUseElement* correspondingUseElement() const { return m_useElement; }
     SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
+    void clearUseElement() { m_useElement = 0; }
 
     SVGElementInstance* parentNode() const { return parent(); }
     PassRefPtr<SVGElementInstanceList> childNodes();
index f259b85..4f23f46 100644 (file)
@@ -137,7 +137,7 @@ void SVGUseElement::insertedIntoDocument()
 void SVGUseElement::removedFromDocument()
 {
     SVGStyledTransformableElement::removedFromDocument();
-    m_targetElementInstance = 0;
+    detachInstance();
 }
 
 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -503,8 +503,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     if (targetElement && targetElement->isSVGElement())
         target = static_cast<SVGElement*>(targetElement);
 
-    if (m_targetElementInstance)
-        m_targetElementInstance = 0;
+    detachInstance();
 
     // Do not allow self-referencing.
     // 'target' may be null, if it's a non SVG namespaced element.
@@ -530,7 +529,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it!
     // Non-appearing <use> content is easier to debug, then half-appearing content.
     if (foundProblem) {
-        m_targetElementInstance = 0;
+        detachInstance();
         return;
     }
 
@@ -563,7 +562,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     // Do NOT leave an inconsistent instance tree around, instead destruct it.
     if (!m_targetElementInstance->shadowTreeElement()) {
         shadowRoot->removeAllChildren();
-        m_targetElementInstance = 0;
+        detachInstance();
         return;
     }
 
@@ -602,6 +601,14 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     updateRelativeLengthsInformation();
 }
 
+void SVGUseElement::detachInstance()
+{
+    if (!m_targetElementInstance)
+        return;
+    m_targetElementInstance->clearUseElement();
+    m_targetElementInstance = 0;
+}
+
 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*)
 {
     return new (arena) RenderSVGShadowTreeRootContainer(this);
@@ -624,7 +631,7 @@ void SVGUseElement::attach()
 void SVGUseElement::detach()
 {
     SVGStyledTransformableElement::detach();
-    m_targetElementInstance = 0;
+    detachInstance();
 }
 
 static bool isDirectReference(Node* node)
index a8f2b82..9b7a0bc 100644 (file)
@@ -77,6 +77,7 @@ private:
     friend class RenderSVGShadowTreeRootContainer;
     bool isPendingResource() const { return m_isPendingResource; }
     void buildShadowAndInstanceTree(SVGShadowTreeRootElement*);
+    void detachInstance();
 
     virtual bool selfHasRelativeLengths() const;