<feImage> DOM mutation problems
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 12:56:21 +0000 (12:56 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 12:56:21 +0000 (12:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=77198

Reviewed by Antti Koivisto.

Source/WebCore:

Consider <feImage xlink:href="#rect"/>, where <rect> gets dynamically added to the tree.
Currently <feImage> doesn't notice this, as it doesn't register itself pending on "#rect".

Integrate <feImage> properly within the pending resources concept, fixing the bug.

Tests: svg/filters/feImage-target-add-to-document.svg
       svg/filters/feImage-target-changes-id.svg
       svg/filters/feImage-target-id-change.svg
       svg/filters/feImage-target-reappend-to-document.svg
       svg/filters/feImage-target-remove-from-document.svg

* svg/SVGFEImageElement.cpp: Rename invalidateImageResource to clearResourceReferences.
(WebCore::SVGFEImageElement::~SVGFEImageElement): Call clearResourceReferences.
(WebCore::SVGFEImageElement::clearResourceReferences): Remove any occurence of m_targetImage, it's no longer used.
(WebCore::SVGFEImageElement::requestImageResource): requestImageResource is now called by buildPendingResource.
(WebCore::SVGFEImageElement::buildPendingResource): Called whenever any element that we depend on gets resolved - now invalidates the <filter>.
(WebCore::SVGFEImageElement::parseMappedAttribute): Don't start loading from parseMappedAttribute.
(WebCore::SVGFEImageElement::svgAttributeChanged): Start loading from here, for consistency with SVGImageElement.
(WebCore::SVGFEImageElement::insertedIntoDocument): Invoke buildPendingResource(), if we enter the tree.
(WebCore::SVGFEImageElement::removedFromDocument): Clear m_cachedImage as soon as we get removed from the tree.
(WebCore::SVGFEImageElement::build): Clean up this function, m_targetImage is no longer exist.
* svg/SVGFEImageElement.h: Remove OwnPtr<ImageBuffer> m_targetImage, which is no longer used.

LayoutTests:

Add new test cases covering <feImage> + DOM mutations.

* platform/chromium/test_expectations.txt: Updated expectations.
* svg/filters/feImage-target-add-to-document-expected.png: Added.
* svg/filters/feImage-target-add-to-document-expected.txt: Added.
* svg/filters/feImage-target-add-to-document.svg: Added.
* svg/filters/feImage-target-changes-id-expected.png: Added.
* svg/filters/feImage-target-changes-id-expected.txt: Added.
* svg/filters/feImage-target-changes-id.svg: Added.
* svg/filters/feImage-target-id-change-expected.png: Added.
* svg/filters/feImage-target-id-change-expected.txt: Added.
* svg/filters/feImage-target-id-change.svg: Added.
* svg/filters/feImage-target-reappend-to-document-expected.png: Added.
* svg/filters/feImage-target-reappend-to-document-expected.txt: Added.
* svg/filters/feImage-target-reappend-to-document.svg: Added.
* svg/filters/feImage-target-remove-from-document-expected.png: Added.
* svg/filters/feImage-target-remove-from-document-expected.txt: Added.
* svg/filters/feImage-target-remove-from-document.svg: Added.

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/svg/filters/feImage-target-add-to-document-expected.png [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-add-to-document.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-changes-id-expected.png [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-changes-id-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-changes-id.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-id-change-expected.png [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-id-change-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-id-change.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-reappend-to-document.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-remove-from-document.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGFEImageElement.cpp
Source/WebCore/svg/SVGFEImageElement.h

index ec68dad..e588092 100644 (file)
@@ -1,3 +1,29 @@
+2012-01-27  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        <feImage> DOM mutation problems
+        https://bugs.webkit.org/show_bug.cgi?id=77198
+
+        Reviewed by Antti Koivisto.
+
+        Add new test cases covering <feImage> + DOM mutations.
+
+        * platform/chromium/test_expectations.txt: Updated expectations.
+        * svg/filters/feImage-target-add-to-document-expected.png: Added.
+        * svg/filters/feImage-target-add-to-document-expected.txt: Added.
+        * svg/filters/feImage-target-add-to-document.svg: Added.
+        * svg/filters/feImage-target-changes-id-expected.png: Added.
+        * svg/filters/feImage-target-changes-id-expected.txt: Added.
+        * svg/filters/feImage-target-changes-id.svg: Added.
+        * svg/filters/feImage-target-id-change-expected.png: Added.
+        * svg/filters/feImage-target-id-change-expected.txt: Added.
+        * svg/filters/feImage-target-id-change.svg: Added.
+        * svg/filters/feImage-target-reappend-to-document-expected.png: Added.
+        * svg/filters/feImage-target-reappend-to-document-expected.txt: Added.
+        * svg/filters/feImage-target-reappend-to-document.svg: Added.
+        * svg/filters/feImage-target-remove-from-document-expected.png: Added.
+        * svg/filters/feImage-target-remove-from-document-expected.txt: Added.
+        * svg/filters/feImage-target-remove-from-document.svg: Added.
+
 2012-01-26  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         [Qt] WKTR: Use a software rendering pipiline when running tests.
index f215478..41e6567 100644 (file)
@@ -3960,6 +3960,11 @@ BUGWK76800 : svg/filters/feImage-reference-svg-primitive.svg = IMAGE
 // Just needs a rebaseline.
 BUGWK69714 : svg/clip-path/clip-path-tspan-and-stroke.svg = IMAGE+TEXT
 BUGWK77103 : svg/repaint/image-href-change.svg = IMAGE
+BUGWK77198 : svg/filters/feImage-target-remove-from-document.svg = IMAGE
+BUGWK77198 : svg/filters/feImage-target-add-to-document.svg = IMAGE
+BUGWK77198 : svg/filters/feImage-target-reappend-to-document.svg = IMAGE
+BUGWK77198 : svg/filters/feImage-target-changes-id.svg = IMAGE
+BUGWK77198 : svg/filters/feImage-target-id-change.svg = IMAGE
 
 // Change error (misspelling) underlines from Windows look to Mac look.
 BUG_CARYCLARK MAC : editing/deleting/delete-3928305-fix.html = IMAGE
diff --git a/LayoutTests/svg/filters/feImage-target-add-to-document-expected.png b/LayoutTests/svg/filters/feImage-target-add-to-document-expected.png
new file mode 100644 (file)
index 0000000..c319b37
Binary files /dev/null and b/LayoutTests/svg/filters/feImage-target-add-to-document-expected.png differ
diff --git a/LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt b/LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt
new file mode 100644 (file)
index 0000000..c3c346a
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-target-add-to-document.svg b/LayoutTests/svg/filters/feImage-target-add-to-document.svg
new file mode 100644 (file)
index 0000000..b3c9bf5
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="red-rect" width="100" height="100" fill="red"/>
+        <rect id="green-rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage-red" xlink:href="#red-rect"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function runTest()
+        {
+            setTimeout(function() {
+                var newFEImage = document.createElementNS("http://www.w3.org/2000/svg", "feImage");
+                newFEImage.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#green-rect");
+                document.getElementById("filter").appendChild(newFEImage);
+
+                if (window.layoutTestController)
+                    layoutTestController.notifyDone();
+            }, 0);
+        }
+
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        setTimeout(runTest, 0);
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-changes-id-expected.png b/LayoutTests/svg/filters/feImage-target-changes-id-expected.png
new file mode 100644 (file)
index 0000000..c319b37
Binary files /dev/null and b/LayoutTests/svg/filters/feImage-target-changes-id-expected.png differ
diff --git a/LayoutTests/svg/filters/feImage-target-changes-id-expected.txt b/LayoutTests/svg/filters/feImage-target-changes-id-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-target-changes-id.svg b/LayoutTests/svg/filters/feImage-target-changes-id.svg
new file mode 100644 (file)
index 0000000..d0871b7
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="notexistant" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function runTest()
+        {
+            setTimeout(function() {
+                document.getElementById("notexistant").setAttribute("id", "rect");
+
+                if (window.layoutTestController)
+                    layoutTestController.notifyDone();
+            }, 0);
+        }
+
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        setTimeout(runTest, 0);
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-id-change-expected.png b/LayoutTests/svg/filters/feImage-target-id-change-expected.png
new file mode 100644 (file)
index 0000000..c319b37
Binary files /dev/null and b/LayoutTests/svg/filters/feImage-target-id-change-expected.png differ
diff --git a/LayoutTests/svg/filters/feImage-target-id-change-expected.txt b/LayoutTests/svg/filters/feImage-target-id-change-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-target-id-change.svg b/LayoutTests/svg/filters/feImage-target-id-change.svg
new file mode 100644 (file)
index 0000000..c52b1ea
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#notexistant" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function runTest()
+        {
+            setTimeout(function() {
+                document.getElementById("feimage").setAttributeNS("http://www.w3.org/1999/xlink", "href", "#rect");
+
+                if (window.layoutTestController)
+                    layoutTestController.notifyDone();
+            }, 0);
+        }
+
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        setTimeout(runTest, 0);
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png b/LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png
new file mode 100644 (file)
index 0000000..c319b37
Binary files /dev/null and b/LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png differ
diff --git a/LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt b/LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt
new file mode 100644 (file)
index 0000000..c3c346a
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-target-reappend-to-document.svg b/LayoutTests/svg/filters/feImage-target-reappend-to-document.svg
new file mode 100644 (file)
index 0000000..29e4a5d
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="red-rect" width="100" height="100" fill="red"/>
+        <rect id="green-rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage-green" xlink:href="#green-rect"/>
+            <feImage id="feimage-red" xlink:href="#red-rect"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function runTest()
+        {
+            setTimeout(function() {
+                // Move feimage-green after feimage-red
+                var greenImage = document.getElementById("feimage-green");
+                document.getElementById("filter").removeChild(greenImage);
+
+                setTimeout(function() {
+                    document.getElementById("filter").appendChild(greenImage);
+                    if (window.layoutTestController)
+                        layoutTestController.notifyDone();
+                }, 0);
+            }, 0);
+        }
+
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        setTimeout(runTest, 0);
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png b/LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png
new file mode 100644 (file)
index 0000000..c319b37
Binary files /dev/null and b/LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png differ
diff --git a/LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt b/LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt
new file mode 100644 (file)
index 0000000..c3c346a
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-target-remove-from-document.svg b/LayoutTests/svg/filters/feImage-target-remove-from-document.svg
new file mode 100644 (file)
index 0000000..22e74e2
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="red-rect" width="100" height="100" fill="red"/>
+        <rect id="green-rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage-green" xlink:href="#green-rect"/>
+            <feImage id="feimage-red" xlink:href="#red-rect"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function runTest()
+        {
+            setTimeout(function() {
+                document.getElementById("filter").removeChild(document.getElementById("feimage-red"));
+
+                if (window.layoutTestController)
+                    layoutTestController.notifyDone();
+            }, 0);
+        }
+
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        setTimeout(runTest, 0);
+    ]]>
+    </script>
+</svg>
index 17524f9..49f0459 100644 (file)
@@ -1,3 +1,33 @@
+2012-01-27  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        <feImage> DOM mutation problems
+        https://bugs.webkit.org/show_bug.cgi?id=77198
+
+        Reviewed by Antti Koivisto.
+
+        Consider <feImage xlink:href="#rect"/>, where <rect> gets dynamically added to the tree.
+        Currently <feImage> doesn't notice this, as it doesn't register itself pending on "#rect".
+
+        Integrate <feImage> properly within the pending resources concept, fixing the bug.
+
+        Tests: svg/filters/feImage-target-add-to-document.svg
+               svg/filters/feImage-target-changes-id.svg
+               svg/filters/feImage-target-id-change.svg
+               svg/filters/feImage-target-reappend-to-document.svg
+               svg/filters/feImage-target-remove-from-document.svg
+
+        * svg/SVGFEImageElement.cpp: Rename invalidateImageResource to clearResourceReferences.
+        (WebCore::SVGFEImageElement::~SVGFEImageElement): Call clearResourceReferences.
+        (WebCore::SVGFEImageElement::clearResourceReferences): Remove any occurence of m_targetImage, it's no longer used.
+        (WebCore::SVGFEImageElement::requestImageResource): requestImageResource is now called by buildPendingResource.
+        (WebCore::SVGFEImageElement::buildPendingResource): Called whenever any element that we depend on gets resolved - now invalidates the <filter>.
+        (WebCore::SVGFEImageElement::parseMappedAttribute): Don't start loading from parseMappedAttribute.
+        (WebCore::SVGFEImageElement::svgAttributeChanged): Start loading from here, for consistency with SVGImageElement.
+        (WebCore::SVGFEImageElement::insertedIntoDocument): Invoke buildPendingResource(), if we enter the tree.
+        (WebCore::SVGFEImageElement::removedFromDocument): Clear m_cachedImage as soon as we get removed from the tree.
+        (WebCore::SVGFEImageElement::build): Clean up this function, m_targetImage is no longer exist.
+        * svg/SVGFEImageElement.h: Remove OwnPtr<ImageBuffer> m_targetImage, which is no longer used.
+
 2012-01-26  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         [Qt] WKTR: Use a software rendering pipiline when running tests.
index d64c232..7050c25 100644 (file)
@@ -64,39 +64,47 @@ PassRefPtr<SVGFEImageElement> SVGFEImageElement::create(const QualifiedName& tag
 
 SVGFEImageElement::~SVGFEImageElement()
 {
-    if (m_cachedImage)
-        m_cachedImage->removeClient(this);
+    clearResourceReferences();
 }
 
-void SVGFEImageElement::invalidateImageResource()
+void SVGFEImageElement::clearResourceReferences()
 {
     if (m_cachedImage) {
         m_cachedImage->removeClient(this);
         m_cachedImage = 0;
     }
-
-    m_targetImage.clear();
 }
 
 void SVGFEImageElement::requestImageResource()
 {
-    invalidateImageResource();
-
-    String fragmentIdentifier;
-    Element* hrefElement = SVGURIReference::targetElementFromIRIString(href(), document(), &fragmentIdentifier);
+    ResourceRequest request(ownerDocument()->completeURL(href()));
+    m_cachedImage = document()->cachedResourceLoader()->requestImage(request);
 
-    if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
-        return;
+    if (m_cachedImage)
+        m_cachedImage->addClient(this);
+}
 
-    // We have what appears to be a local fragment identifier, but it didn't resolve yet.
-    if (!fragmentIdentifier.isEmpty())
+void SVGFEImageElement::buildPendingResource()
+{
+    clearResourceReferences();
+    if (!inDocument())
         return;
 
-    ResourceRequest request(ownerDocument()->completeURL(href()));
-    m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(request);
+    String id;
+    Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
+    if (!target) {
+        if (hasPendingResources())
+            return;
+
+        if (id.isEmpty())
+            requestImageResource();
+        else {
+            document()->accessSVGExtensions()->addPendingResource(id, this);
+            ASSERT(hasPendingResources());
+        }
+    }
 
-    if (m_cachedImage)
-        m_cachedImage->addClient(this);
+    invalidate();
 }
 
 bool SVGFEImageElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -124,11 +132,8 @@ void SVGFEImageElement::parseMappedAttribute(Attribute* attr)
         return;
     }
 
-    if (SVGURIReference::parseMappedAttribute(attr)) {
-        requestImageResource();
+    if (SVGURIReference::parseMappedAttribute(attr))
         return;
-    }
-
     if (SVGLangSpace::parseMappedAttribute(attr))
         return;
     if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
@@ -152,8 +157,7 @@ void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
     }
 
     if (SVGURIReference::isKnownAttribute(attrName)) {
-        invalidateImageResource();
-        invalidate();
+        buildPendingResource();
         return;
     }
 
@@ -163,6 +167,18 @@ void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
     ASSERT_NOT_REACHED();
 }
 
+void SVGFEImageElement::insertedIntoDocument()
+{
+    SVGFilterPrimitiveStandardAttributes::insertedIntoDocument();
+    buildPendingResource();
+}
+
+void SVGFEImageElement::removedFromDocument()
+{
+    SVGFilterPrimitiveStandardAttributes::removedFromDocument();
+    clearResourceReferences();
+}
+
 void SVGFEImageElement::notifyFinished(CachedResource*)
 {
     if (!inDocument())
@@ -179,12 +195,9 @@ void SVGFEImageElement::notifyFinished(CachedResource*)
 
 PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter* filter)
 {
-    if (!m_cachedImage && !m_targetImage)
-        requestImageResource();
-
-    if (!m_cachedImage && !m_targetImage)
-        return FEImage::createWithIRIReference(filter, document(), href(), preserveAspectRatio());
-    return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());
+    if (m_cachedImage)
+        return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());
+    return FEImage::createWithIRIReference(filter, document(), href(), preserveAspectRatio());
 }
 
 void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
index 2d64713..112ef25 100644 (file)
@@ -56,9 +56,13 @@ private:
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
     virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
 
-    void invalidateImageResource();
+    void clearResourceReferences();
     void requestImageResource();
 
+    virtual void buildPendingResource();
+    virtual void insertedIntoDocument();
+    virtual void removedFromDocument();
+
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEImageElement)
         DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
         DECLARE_ANIMATED_STRING(Href, href)
@@ -66,7 +70,6 @@ private:
     END_DECLARE_ANIMATED_PROPERTIES
 
     CachedResourceHandle<CachedImage> m_cachedImage;
-    OwnPtr<ImageBuffer> m_targetImage;
 };
 
 } // namespace WebCore