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
+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.
// 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
--- /dev/null
+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
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+<?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>
+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.
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)
return;
}
- if (SVGURIReference::parseMappedAttribute(attr)) {
- requestImageResource();
+ if (SVGURIReference::parseMappedAttribute(attr))
return;
- }
-
if (SVGLangSpace::parseMappedAttribute(attr))
return;
if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
}
if (SVGURIReference::isKnownAttribute(attrName)) {
- invalidateImageResource();
- invalidate();
+ buildPendingResource();
return;
}
ASSERT_NOT_REACHED();
}
+void SVGFEImageElement::insertedIntoDocument()
+{
+ SVGFilterPrimitiveStandardAttributes::insertedIntoDocument();
+ buildPendingResource();
+}
+
+void SVGFEImageElement::removedFromDocument()
+{
+ SVGFilterPrimitiveStandardAttributes::removedFromDocument();
+ clearResourceReferences();
+}
+
void SVGFEImageElement::notifyFinished(CachedResource*)
{
if (!inDocument())
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
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)
END_DECLARE_ANIMATED_PROPERTIES
CachedResourceHandle<CachedImage> m_cachedImage;
- OwnPtr<ImageBuffer> m_targetImage;
};
} // namespace WebCore