[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

zimmermann at webkit.org zimmermann at webkit.org
Wed Dec 22 11:33:39 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit b984a40e7ed4ae231ec436930a5a8283067681e3
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jul 29 13:50:51 2010 +0000

    2010-07-29  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            WebKit shouldn't ignore resource cycles, but break them as Opera does
            https://bugs.webkit.org/show_bug.cgi?id=43031
    
            mask images are not updated when render objects' bounds change
            https://bugs.webkit.org/show_bug.cgi?id=15124
    
            SVG Gradients do not resize correctly
            https://bugs.webkit.org/show_bug.cgi?id=41902
    
            svg/dynamic-updates: SVGMarkerElement markerHeight/Width tests are broken
            https://bugs.webkit.org/show_bug.cgi?id=42616
    
            svg/dynamic-updates: SVGMaskElement tests are all broken
            https://bugs.webkit.org/show_bug.cgi?id=42617
    
            Don't ignore resources containing cyclic references, but break them, as discussed on SVG WG mailing lists - to be compatible with Opera which already does that.
    
            We used to lookup RenderSVGResourceContainers objects, by extracting the URI reference from the SVGRenderStyle, then utilizing getElementById() to lookup the
            node, and access its renderer. Opera ignores such references, if they point to resources that contain cyclic references. Ignoring them would mean we have
            to mutate the render style to empty the resource strings. That obviously doesn't work, as it would break expectations (getComputedStyle, etc.).
    
            Introduce a SVGResources class that stores pointers to all resources, that can be applied to a RenderObject (clipper/filter/markers/masker).
            Add a SVGResourcesCache class, which is basically a HashMap<RenderObject*, SVGResources*>. Whenever a RenderObject receives style, we extract the URI references
            from the SVGRenderStyle, look up the RenderSVGResourceContainer* objects, and store them in a SVGResources* class. Then we execute a cycle detection logic,
            which detects cyclic references and breaks them. Breaking them means just nulling the pointer to the resource in the SVGResources object. Those SVGResources
            objects are cached, and used throughout the render tree to access resources. This way it's guaranteed that all cyclic references are resolved until layout/paint
            phase begins.
    
            Add destroy/styleDidChange/updateFromElement methods to all SVG renderers, in order to keep track of resource/client changes in the SVGResourcesCache.
            As side-effect the SVGResourcesCache now knows which RenderObject references which resource, and thus can handle client registration for a RenderSVGResourceContainer.
            The RenderSVGResourceContainer now holds a HashSet of RenderObjects, that's always up2date, and not related to the fact wheter a resources has already been used
            for painting. The old logic missed to register clients for a resource, when the resource was in an invalid state. Fixing that fixes the svg/dynamic-updates/SVGMaskElement* tests.
    
            Rewrite all svg/custom/recursive-(filter|gradient|mask|pattern).svg tests to contain a reference image how it should be renderered. All 1:1 compatible with Opera now.
    
            * rendering/RenderForeignObject.cpp:
            (WebCore::RenderForeignObject::layout): Grab selfNeedsLayout() before calling RenderBlock::layout(), otherwhise it's always false.
            * rendering/RenderPath.cpp: Don't look up resources manually, use SVGResourcesCache.
            (WebCore::RenderPath::fillContains): Remove constness, to avoid the need to pass around const RenderObjects* to the SVGResourcesCache.
            (WebCore::RenderPath::strokeContains): Ditto.
            (WebCore::RenderPath::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
            (WebCore::RenderPath::calculateMarkerBoundsIfNeeded): Remove special client handling for markers, it's all unified now.
            (WebCore::RenderPath::styleWillChange): Only call setNeedsBoundariesUpdate when handling StyleDifferenceRepaint/Layout.
            * rendering/RenderPath.h:
            * rendering/RenderSVGBlock.cpp:
            (WebCore::RenderSVGBlock::destroy): Forward to SVGResourcesCache::clientDestroyed.
            (WebCore::RenderSVGBlock::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
            (WebCore::RenderSVGBlock::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
            * rendering/RenderSVGBlock.h:
            * rendering/RenderSVGContainer.cpp:
            (WebCore::RenderSVGContainer::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
            (WebCore::RenderSVGContainer::selfWillPaint): Don't look up resources manually, use SVGResourcesCache.
            * rendering/RenderSVGContainer.h:
            * rendering/RenderSVGGradientStop.cpp:
            (WebCore::RenderSVGGradientStop::styleDidChange): Rewrite, as invalidateResourceClients() is gone.
            * rendering/RenderSVGHiddenContainer.h: Make layout() protected, as RenderSVGResourceContainer overrides it.
            * rendering/RenderSVGImage.cpp:
            (WebCore::RenderSVGImage::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
            (WebCore::RenderSVGImage::destroy): Forward to SVGResourcesCache::clientDestroyed.
            (WebCore::RenderSVGImage::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
            (WebCore::RenderSVGImage::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
            (WebCore::RenderSVGImage::imageChanged): Don't look up resources manually, use SVGResourcesCache.
            * rendering/RenderSVGImage.h:
            * rendering/RenderSVGInline.cpp:
            (WebCore::RenderSVGInline::destroy): Forward to SVGResourcesCache::clientDestroyed.
            (WebCore::RenderSVGInline::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
            (WebCore::RenderSVGInline::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
            * rendering/RenderSVGInline.h:
            * rendering/RenderSVGModelObject.cpp:
            (WebCore::RenderSVGModelObject::destroy): Forward to SVGResourcesCache::clientDestroyed.
            (WebCore::RenderSVGModelObject::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
            (WebCore::RenderSVGModelObject::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
            * rendering/RenderSVGModelObject.h:
            * rendering/RenderSVGResource.cpp:
            (WebCore::RenderSVGResource::fillPaintingResource): Remove const from RenderObject parameter.
            (WebCore::RenderSVGResource::strokePaintingResource): Ditto.
            (WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): Early exit if we found the first parent resource.
            * rendering/RenderSVGResource.h:
            * rendering/RenderSVGResourceClipper.cpp:
            (WebCore::RenderSVGResourceClipper::~RenderSVGResourceClipper): Early exit if m_clipper is empty.
            (WebCore::RenderSVGResourceClipper::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourceClipper::invalidateClient): Ditto.
            (WebCore::RenderSVGResourceClipper::applyResource): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
            (WebCore::RenderSVGResourceClipper::createClipData): Don't look up resources manually, use SVGResourcesCache.
            (WebCore::RenderSVGResourceClipper::hitTestClipContent): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
            * rendering/RenderSVGResourceClipper.h:
            * rendering/RenderSVGResourceContainer.cpp:
            (WebCore::svgExtensionsFromNode):
            (WebCore::RenderSVGResourceContainer::RenderSVGResourceContainer): Stop registering resource from the constructor, delegate to styleDidChange.
            (WebCore::RenderSVGResourceContainer::~RenderSVGResourceContainer): Only deregister resource if it was ever registered.
            (WebCore::RenderSVGResourceContainer::layout): invalidateClients() here, to avoid the need for invalidateResourceClients() in the SVG DOM. Just call setNeedsLayout() from the SVG DOM.
            (WebCore::RenderSVGResourceContainer::destroy): Forward to SVGResourcesCache::resourceDestroyed.
            (WebCore::RenderSVGResourceContainer::styleDidChange): Register resource not in the constructor but when it first receives style.
            (WebCore::RenderSVGResourceContainer::idChanged): Don't duplicate code, use existing methods from SVGResourcesCache.
            (WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation): Add new helper function, to share code between all resources.
            (WebCore::RenderSVGResourceContainer::markClientForInvalidation): Ditto.
            (WebCore::RenderSVGResourceContainer::addClient): SVGResourcesCache now manages the list of clients. It calls addClient() for each RenderObject that uses this resource.
            (WebCore::RenderSVGResourceContainer::removeClient): SVGResourcesCache now manages the list of clients.
            (WebCore::RenderSVGResourceContainer::registerResource): New helper function sharing code between idChanged / styleDidChange.
            (WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke): Add FIXME that the function is misplaced.
            * rendering/RenderSVGResourceContainer.h: Move most functions to the new RenderSVGResourceContainer.cpp file.
            * rendering/RenderSVGResourceFilter.cpp:
            (WebCore::RenderSVGResourceFilter::~RenderSVGResourceFilter): Early exit if m_filter is empty.
            (WebCore::RenderSVGResourceFilter::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourceFilter::invalidateClient): Ditto.
            * rendering/RenderSVGResourceGradient.cpp:
            (WebCore::RenderSVGResourceGradient::~RenderSVGResourceGradient): Early exit if m_gradient is empty.
            (WebCore::RenderSVGResourceGradient::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourceGradient::invalidateClient): Ditto.
            * rendering/RenderSVGResourceMarker.cpp:
            (WebCore::RenderSVGResourceMarker::~RenderSVGResourceMarker): Now a no-op, markers are unified within the new client handling concept, no more special code needed.
            (WebCore::RenderSVGResourceMarker::layout): As RenderSVGResourceMarker skips the RenderSVGResourceContainer::layout() method, we also need to call invalidateClients() here.
            (WebCore::RenderSVGResourceMarker::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourceMarker::invalidateClient): Ditto.
            (WebCore::RenderSVGResourceMarker::draw): Remove marker specific logic to catch circular references.
            * rendering/RenderSVGResourceMarker.h:
            * rendering/RenderSVGResourceMasker.cpp:
            (WebCore::RenderSVGResourceMasker::~RenderSVGResourceMasker): Early exit if m_masker is empty.
            (WebCore::RenderSVGResourceMasker::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourceMasker::invalidateClient): Ditto.
            (WebCore::RenderSVGResourceMasker::applyResource): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
            * rendering/RenderSVGResourceMasker.h:
            * rendering/RenderSVGResourcePattern.cpp:
            (WebCore::RenderSVGResourcePattern::~RenderSVGResourcePattern): Early exit if m_pattern is empty.
            (WebCore::RenderSVGResourcePattern::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
            (WebCore::RenderSVGResourcePattern::invalidateClient): Ditto.
            (WebCore::RenderSVGResourcePattern::createTileImage): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
            * rendering/RenderSVGResourcePattern.h:
            * rendering/RenderSVGRoot.cpp:
            (WebCore::RenderSVGRoot::selfWillPaint): Don't look up resources manually, use SVGResourcesCache.
            (WebCore::RenderSVGRoot::destroy): Forward to SVGResourcesCache::clientDestroyed.
            (WebCore::RenderSVGRoot::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
            (WebCore::RenderSVGRoot::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
            * rendering/RenderSVGRoot.h:
            * rendering/RenderSVGText.cpp:
            (WebCore::RenderSVGText::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
            * rendering/RenderSVGText.h:
            * rendering/SVGInlineTextBox.cpp:
            (WebCore::SVGInlineTextBox::acquirePaintingResource): Add RenderObject* parameter, don't assume the style comes from the InlineTextBox parent renderer.
            (WebCore::SVGInlineTextBox::prepareGraphicsContextForTextPainting): Pass the parent()->renderer() to acquirePaintingResource.
            (WebCore::SVGInlineTextBox::paintDecoration): Pass the decoration renderer to acquirePaintingResource.
            (WebCore::SVGInlineTextBox::paintDecorationWithStyle): Ditto.
            (WebCore::SVGInlineTextBox::paintText): When a selection pseudo style is used to paint the selection, swap styles in the SVGResourcesCache, to take the right resources when painting.
            * rendering/SVGInlineTextBox.h:
            * rendering/SVGRenderSupport.cpp:
            (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Don't look up resources manually, use SVGResourcesCache.
            (WebCore::SVGRenderSupport::finishRenderSVGContent): Ditto.
            (WebCore::SVGRenderSupport::intersectRepaintRectWithResources): Ditto.
            (WebCore::SVGRenderSupport::pointInClippingArea): Remove const from RenderObject parameter.
            * rendering/SVGRenderSupport.h:
            * rendering/SVGRenderTreeAsText.cpp:
            (WebCore::writeStyle): Add two const_cast now that fill/strokePaintingResource take RenderObject* parameters. This was the less intrusive approach, otherwhise more const_casts would be needed.
            (WebCore::writeResources): Add FIXME that we should dump the resources present in the SVGResourcesCache instead of manually looking them up from the SVGRenderStyle, to avoid dumping cycles.
            * rendering/SVGResourcesCache.cpp:
            (WebCore::SVGResourcesCache::clientStyleChanged): Use markForLayoutAndParentResourceInvalidation() instead of duplicating code.
            * rendering/SVGResourcesCycleSolver.cpp:
            (WebCore::setFollowLinkForChainableResource): Implemented stub method.
            * rendering/style/SVGRenderStyle.cpp:
            (WebCore::SVGRenderStyle::diff): Return StyleDifferenceLayout, not Repaint for stroke paint changes, otherwhise the cached boundaries are not correctly updated.
            * svg/SVGClipPathElement.cpp:
            (WebCore::SVGClipPathElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGClipPathElement::childrenChanged): Ditto.
            * svg/SVGClipPathElement.h:
            (WebCore::SVGClipPathElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            * svg/SVGElement.cpp:
            (WebCore::SVGElement::insertedIntoDocument): Only execute buildPendingResource() logic, if needsPendingResourceHandling() returns true. Cleaned up code a bit, to deploy early returns.
            * svg/SVGElement.h:
            (WebCore::SVGElement::needsPendingResourceHandling): Return true (default). Only needed by SVGTextPathElement/SVGUseElement, and should be removed in future.
            * svg/SVGFilterElement.cpp:
            (WebCore::SVGFilterElement::SVGFilterElement): Initialize m_followLink=true.
            (WebCore::SVGFilterElement::setFilterRes): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGFilterElement::svgAttributeChanged): Ditto.
            (WebCore::SVGFilterElement::childrenChanged): Ditto.
            * svg/SVGFilterElement.h:
            (WebCore::SVGFilterElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            (WebCore::SVGFilterElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
            * svg/SVGFilterPrimitiveStandardAttributes.cpp:
            (WebCore::SVGFilterPrimitiveStandardAttributes::childrenChanged): Don't use invalidateResourceClients(), it's a no-op as effects don't have a renderer -> use invalidateFilter().
            * svg/SVGFilterPrimitiveStandardAttributes.h:
            (WebCore::SVGFilterPrimitiveStandardAttributes::invalidateFilter): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            * svg/SVGGradientElement.cpp:
            (WebCore::SVGGradientElement::SVGGradientElement): Initialize m_followLink=true.
            (WebCore::SVGGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGGradientElement::childrenChanged): Ditto.
            * svg/SVGGradientElement.h:
            (WebCore::SVGGradientElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            (WebCore::SVGGradientElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
            * svg/SVGLinearGradientElement.cpp:
            (WebCore::SVGLinearGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGLinearGradientElement::collectGradientProperties): Only follow xlink:href links if m_followLinks == true.
            * svg/SVGMarkerElement.cpp:
            (WebCore::SVGMarkerElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGMarkerElement::childrenChanged): Ditto.
            (WebCore::SVGMarkerElement::setOrientToAuto): Ditto.
            (WebCore::SVGMarkerElement::setOrientToAngle): Ditto.
            * svg/SVGMarkerElement.h:
            (WebCore::SVGMarkerElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            * svg/SVGMaskElement.cpp:
            (WebCore::SVGMaskElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGMaskElement::childrenChanged): Ditto.
            * svg/SVGMaskElement.h:
            (WebCore::SVGMaskElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            * svg/SVGPatternElement.cpp:
            (WebCore::SVGPatternElement::SVGPatternElement): Initialize m_followLink=true.
            (WebCore::SVGPatternElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGPatternElement::childrenChanged): Ditto.
            (WebCore::SVGPatternElement::collectPatternProperties): Only follow xlink:href links if m_followLinks == true.
            * svg/SVGPatternElement.h:
            (WebCore::SVGPatternElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
            (WebCore::SVGPatternElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
            * svg/SVGRadialGradientElement.cpp:
            (WebCore::SVGRadialGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
            (WebCore::SVGRadialGradientElement::collectGradientProperties): Only follow xlink:href links if m_followLinks == true.
            * svg/SVGStyledElement.cpp:
            (WebCore::SVGStyledElement::attach): Call updateFromElement upon attach(), needed by all resource renderers. Defaults to a no-op in RenderObject.h
            * svg/SVGStyledElement.h: Remove invalidateResourceClients(), it's not needed anymore.
    2010-07-29  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            WebKit shouldn't ignore resource cycles, but break them as Opera does
            https://bugs.webkit.org/show_bug.cgi?id=43031
    
            Rebaseline results now that cycles are broken, instead of ignored.
    
            * platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt:
            * platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum:
            * platform/mac/svg/clip-path/clip-path-recursive-call-expected.png:
            * platform/mac/svg/custom/circular-marker-reference-4-expected.txt:
            * platform/mac/svg/custom/gradient-cycle-detection-expected.checksum:
            * platform/mac/svg/custom/gradient-cycle-detection-expected.png:
            * platform/mac/svg/custom/recursive-clippath-expected.checksum:
            * platform/mac/svg/custom/recursive-clippath-expected.png:
            * platform/mac/svg/custom/recursive-clippath-expected.txt:
            * platform/mac/svg/custom/recursive-filter-expected.checksum:
            * platform/mac/svg/custom/recursive-filter-expected.png:
            * platform/mac/svg/custom/recursive-filter-expected.txt:
            * platform/mac/svg/custom/recursive-gradient-expected.checksum:
            * platform/mac/svg/custom/recursive-gradient-expected.png:
            * platform/mac/svg/custom/recursive-gradient-expected.txt:
            * platform/mac/svg/custom/recursive-mask-expected.checksum:
            * platform/mac/svg/custom/recursive-mask-expected.png:
            * platform/mac/svg/custom/recursive-mask-expected.txt:
            * platform/mac/svg/custom/recursive-pattern-expected.checksum:
            * platform/mac/svg/custom/recursive-pattern-expected.png:
            * platform/mac/svg/custom/recursive-pattern-expected.txt:
            * platform/mac/svg/custom/use-events-crash-expected.txt:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum:
            * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png:
            * platform/mac/svg/hixie/error/017-expected.txt:
            * svg/clip-path/clip-path-recursive-call-by-child.svg: Rewrite test to match expectations, now that cycles are broken, not ignored. Looks like in Opera.
            * svg/custom/js-late-clipPath-and-object-creation.svg: Don't update from within the onload event, instead use zero-ms timeouts, to test updating reliable. It failed before this patch.
            * svg/custom/js-late-clipPath-creation.svg: Ditto.
            * svg/custom/js-late-gradient-and-object-creation.svg: Ditto.
            * svg/custom/js-late-gradient-creation.svg: Ditto.
            * svg/custom/js-late-marker-and-object-creation.svg: Ditto.
            * svg/custom/js-late-marker-creation.svg: Ditto.
            * svg/custom/js-late-mask-and-object-creation.svg: Ditto.
            * svg/custom/js-late-mask-creation.svg: Ditto.
            * svg/custom/js-late-pattern-and-object-creation.svg: Ditto.
            * svg/custom/js-late-pattern-creation.svg: Ditto.
            * svg/custom/recursive-clippath.svg: Add a reference rendering, side by side to the test, for the ease of comparision. Passes in WebKit + Opera.
            * svg/custom/recursive-filter.svg: Ditto.
            * svg/custom/recursive-gradient.svg: Ditto.
            * svg/custom/recursive-mask.svg: Ditto.
            * svg/custom/recursive-pattern.svg: Ditto.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64275 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2eee200..c57128f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,84 @@
+2010-07-29  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        WebKit shouldn't ignore resource cycles, but break them as Opera does
+        https://bugs.webkit.org/show_bug.cgi?id=43031
+
+        Rebaseline results now that cycles are broken, instead of ignored.
+
+        * platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt:
+        * platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum:
+        * platform/mac/svg/clip-path/clip-path-recursive-call-expected.png:
+        * platform/mac/svg/custom/circular-marker-reference-4-expected.txt:
+        * platform/mac/svg/custom/gradient-cycle-detection-expected.checksum:
+        * platform/mac/svg/custom/gradient-cycle-detection-expected.png:
+        * platform/mac/svg/custom/recursive-clippath-expected.checksum:
+        * platform/mac/svg/custom/recursive-clippath-expected.png:
+        * platform/mac/svg/custom/recursive-clippath-expected.txt:
+        * platform/mac/svg/custom/recursive-filter-expected.checksum:
+        * platform/mac/svg/custom/recursive-filter-expected.png:
+        * platform/mac/svg/custom/recursive-filter-expected.txt:
+        * platform/mac/svg/custom/recursive-gradient-expected.checksum:
+        * platform/mac/svg/custom/recursive-gradient-expected.png:
+        * platform/mac/svg/custom/recursive-gradient-expected.txt:
+        * platform/mac/svg/custom/recursive-mask-expected.checksum:
+        * platform/mac/svg/custom/recursive-mask-expected.png:
+        * platform/mac/svg/custom/recursive-mask-expected.txt:
+        * platform/mac/svg/custom/recursive-pattern-expected.checksum:
+        * platform/mac/svg/custom/recursive-pattern-expected.png:
+        * platform/mac/svg/custom/recursive-pattern-expected.txt:
+        * platform/mac/svg/custom/use-events-crash-expected.txt:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum:
+        * platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png:
+        * platform/mac/svg/hixie/error/017-expected.txt:
+        * svg/clip-path/clip-path-recursive-call-by-child.svg: Rewrite test to match expectations, now that cycles are broken, not ignored. Looks like in Opera.
+        * svg/custom/js-late-clipPath-and-object-creation.svg: Don't update from within the onload event, instead use zero-ms timeouts, to test updating reliable. It failed before this patch.
+        * svg/custom/js-late-clipPath-creation.svg: Ditto.
+        * svg/custom/js-late-gradient-and-object-creation.svg: Ditto.
+        * svg/custom/js-late-gradient-creation.svg: Ditto.
+        * svg/custom/js-late-marker-and-object-creation.svg: Ditto.
+        * svg/custom/js-late-marker-creation.svg: Ditto.
+        * svg/custom/js-late-mask-and-object-creation.svg: Ditto.
+        * svg/custom/js-late-mask-creation.svg: Ditto.
+        * svg/custom/js-late-pattern-and-object-creation.svg: Ditto.
+        * svg/custom/js-late-pattern-creation.svg: Ditto.
+        * svg/custom/recursive-clippath.svg: Add a reference rendering, side by side to the test, for the ease of comparision. Passes in WebKit + Opera.
+        * svg/custom/recursive-filter.svg: Ditto.
+        * svg/custom/recursive-gradient.svg: Ditto.
+        * svg/custom/recursive-mask.svg: Ditto.
+        * svg/custom/recursive-pattern.svg: Ditto.
+
 2010-07-21 Antonio Gomes  <tonikitoo at webkit.org> , Grace Kloba  <klobag at gmail.com>
 
         Reviewed by David Hyatt.
diff --git a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt
index dfccbfe..693d1c9 100644
--- a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt
+++ b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-by-child-expected.txt
@@ -4,8 +4,8 @@ layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 100x100
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
       RenderSVGResourceClipper {clipPath} [id="clip"] [clipPathUnits=userSpaceOnUse]
-        RenderPath {rect} at (0,0) size 100x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,50.00 L0.00,50.00 Z"]
-          [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x50
+        RenderPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+          [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x100
     RenderPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-    RenderPath {rect} at (0,0) size 100x50 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x50
+    RenderPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+      [clipPath="clip"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x100
diff --git a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum
index d69a371..7363841 100644
--- a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum
+++ b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.checksum
@@ -1 +1 @@
-853de00567d121bea0b7bece66a5d61c
\ No newline at end of file
+778803df0a824ed8f2c7dfa07c56832e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.png b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.png
index 12fde95..a56e38c 100644
Binary files a/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.png and b/LayoutTests/platform/mac/svg/clip-path/clip-path-recursive-call-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/circular-marker-reference-4-expected.txt b/LayoutTests/platform/mac/svg/custom/circular-marker-reference-4-expected.txt
index eb71836..92f8ddd 100644
--- a/LayoutTests/platform/mac/svg/custom/circular-marker-reference-4-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/circular-marker-reference-4-expected.txt
@@ -5,5 +5,5 @@ layer at (0,0) size 800x600
     RenderSVGResourceMarker {marker} [id="mark1"] [markerUnits=strokeWidth] [ref at (4,4)] [angle=0.00]
       RenderPath {path} at (310,240) size 180x60 [stroke={[type=SOLID] [color=#000000] [line cap=ROUND]}] [fill={[type=SOLID] [color=#000000]}] [start marker=mark2] [middle marker=mark2] [end marker=mark2] [data="M-5.00,-2.00 L0.00,-2.00 L5.00,-2.00"]
     RenderSVGResourceMarker {marker} [id="mark2"] [markerUnits=strokeWidth] [ref at (4,4)] [angle=0.00]
-      RenderPath {path} at (280,270) size 210x90 [stroke={[type=SOLID] [color=#000000] [line cap=ROUND]}] [fill={[type=SOLID] [color=#000000]}] [start marker=mark1] [middle marker=mark1] [end marker=mark1] [data="M-5.00,2.00 L0.00,2.00 L5.00,2.00"]
+      RenderPath {path} at (310,300) size 180x60 [stroke={[type=SOLID] [color=#000000] [line cap=ROUND]}] [fill={[type=SOLID] [color=#000000]}] [start marker=mark1] [middle marker=mark1] [end marker=mark1] [data="M-5.00,2.00 L0.00,2.00 L5.00,2.00"]
     RenderPath {path} at (130,270) size 450x120 [stroke={[type=SOLID] [color=#000000] [line cap=ROUND]}] [fill={[type=SOLID] [color=#000000]}] [start marker=mark1] [middle marker=mark1] [end marker=mark1] [data="M-5.00,2.00 L0.00,2.00 L5.00,2.00"]
diff --git a/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.checksum b/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.checksum
index 4485a4d..b51684e 100644
--- a/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.checksum
@@ -1 +1 @@
-c31435453e4b5fe90b3b618f35608ef3
\ No newline at end of file
+a7754e874db94ad931cb2db1054e361f
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.png b/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.png
index c3e12d2..0d572d8 100644
Binary files a/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.png and b/LayoutTests/platform/mac/svg/custom/gradient-cycle-detection-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.checksum b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.checksum
index 1204038..52ffc5d 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.checksum
@@ -1 +1 @@
-67516477d9f265bd907635bbade318cd
\ No newline at end of file
+72e669ce7be88c04c721d627b566c3cb
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.png b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.png
index ee3fbf8..8ecd6c7 100644
Binary files a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.png and b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.txt b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.txt
index 65f1133..bdf5998 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/recursive-clippath-expected.txt
@@ -1,21 +1,30 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  RenderSVGRoot {svg} at (0,0) size 200x300
+  RenderSVGRoot {svg} at (29,0) size 292x304
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
       RenderSVGResourceClipper {clipPath} [id="clipPath_0"] [clipPathUnits=userSpaceOnUse]
-        RenderPath {rect} at (0,0) size 100x100 [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-          [clipPath="clipPath_0"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x100
-      RenderPath {rect} at (0,100) size 100x100 [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
-        [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (0,100) size 100x100
+        RenderPath {rect} at (50,0) size 50x50 [data="M50.00,0.00 L100.00,0.00 L100.00,50.00 L50.00,50.00 Z"]
+          [clipPath="clipPath_0"] RenderSVGResourceClipper {clipPath} at (50,0) size 50x50
+      RenderPath {rect} at (50,150) size 50x50 [data="M50.00,150.00 L100.00,150.00 L100.00,200.00 L50.00,200.00 Z"]
+        [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (50,150) size 50x50
       RenderSVGResourceClipper {clipPath} [id="clipPath_1"] [clipPathUnits=userSpaceOnUse]
-        RenderSVGContainer {use} at (0,100) size 100x100
-          RenderSVGContainer {g} at (0,100) size 100x100
-            RenderPath {rect} at (0,100) size 100x100 [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
-              [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (0,100) size 100x100
-    RenderPath {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L200.00,0.00 L200.00,200.00 L0.00,200.00 Z"]
-    RenderPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00 L200.00,0.00 L200.00,200.00 L0.00,200.00 Z"]
-      [clipPath="clipPath_0"] RenderSVGResourceClipper {clipPath} at (0,0) size 100x100
-    RenderPath {rect} at (0,100) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,100.00 L200.00,100.00 L200.00,300.00 L0.00,300.00 Z"]
-    RenderPath {rect} at (0,100) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,100.00 L200.00,100.00 L200.00,300.00 L0.00,300.00 Z"]
-      [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (0,100) size 100x100
+        RenderSVGContainer {use} at (50,150) size 50x50
+          RenderSVGContainer {g} at (50,150) size 50x50
+            RenderPath {rect} at (50,150) size 50x50 [data="M50.00,150.00 L100.00,150.00 L100.00,200.00 L50.00,200.00 Z"]
+              [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (50,150) size 50x50
+    RenderPath {rect} at (50,0) size 100x100 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,0.00 L150.00,0.00 L150.00,100.00 L50.00,100.00 Z"]
+    RenderPath {rect} at (50,0) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,0.00 L150.00,0.00 L150.00,100.00 L50.00,100.00 Z"]
+      [clipPath="clipPath_0"] RenderSVGResourceClipper {clipPath} at (50,0) size 50x50
+    RenderPath {rect} at (50,150) size 100x100 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,150.00 L150.00,150.00 L150.00,250.00 L50.00,250.00 Z"]
+    RenderPath {rect} at (50,150) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,150.00 L150.00,150.00 L150.00,250.00 L50.00,250.00 Z"]
+      [clipPath="clipPath_1"] RenderSVGResourceClipper {clipPath} at (50,150) size 50x50
+    RenderPath {line} at (174,0) size 2x250 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M175.00,0.00 L175.00,250.00"]
+    RenderSVGText {text} at (29,286) size 292x18 contains 1 chunk(s)
+      RenderSVGInlineText {#text} at (0,0) size 292x18
+        chunk 1 (middle anchor) text run 1 at (29.00,300.00) startOffset 0 endOffset 48 width 292.00: "Both sides of the red line should look identical"
+    RenderSVGContainer {g} at (200,0) size 100x250 [transform={m=((1.00,0.00)(0.00,1.00)) t=(150.00,0.00)}]
+      RenderPath {rect} at (200,0) size 100x100 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,0.00 L150.00,0.00 L150.00,100.00 L50.00,100.00 Z"]
+      RenderPath {rect} at (200,0) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,0.00 L100.00,0.00 L100.00,50.00 L50.00,50.00 Z"]
+      RenderPath {rect} at (200,150) size 100x100 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,150.00 L150.00,150.00 L150.00,250.00 L50.00,250.00 Z"]
+      RenderPath {rect} at (200,150) size 50x50 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,150.00 L100.00,150.00 L100.00,200.00 L50.00,200.00 Z"]
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.checksum b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.checksum
index 8c9fcbd..b897005 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.checksum
@@ -1 +1 @@
-dda4f1b67cf9fb2058815ce9466326fc
\ No newline at end of file
+0e4859e3b02f2f48bba2c68cad4e0e7b
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.png b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.png
index 2634333..0d5315d 100644
Binary files a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.png and b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.txt b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.txt
index c3d7c3f..164a5de 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/recursive-filter-expected.txt
@@ -1,13 +1,23 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  RenderSVGRoot {svg} at (0,0) size 111x210
+  RenderSVGRoot {svg} at (29,0) size 292x304
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceFilter {filter} [id="filter0"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feGaussianBlur stdDeviation="4.00, 4.00"]
+          [SourceGraphic]
       RenderSVGResourceFilter {filter} [id="filter1"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
         [feGaussianBlur stdDeviation="4.00, 4.00"]
           [SourceGraphic]
       RenderSVGResourceFilter {filter} [id="filter2"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
-    RenderPath {rect} at (0,0) size 111x111 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      [filter="filter1"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
-    RenderPath {rect} at (0,90) size 111x120 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
-      [filter="filter2"] RenderSVGResourceFilter {filter} at (-10,90) size 120x120
+    RenderPath {rect} at (40,0) size 120x111 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,0.00 L150.00,0.00 L150.00,100.00 L50.00,100.00 Z"]
+      [filter="filter1"] RenderSVGResourceFilter {filter} at (40,-10) size 120x120
+    RenderPath {rect} at (40,140) size 120x120 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,150.00 L150.00,150.00 L150.00,250.00 L50.00,250.00 Z"]
+      [filter="filter2"] RenderSVGResourceFilter {filter} at (40,140) size 120x120
+    RenderPath {line} at (174,0) size 2x250 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M175.00,0.00 L175.00,250.00"]
+    RenderSVGText {text} at (29,286) size 292x18 contains 1 chunk(s)
+      RenderSVGInlineText {#text} at (0,0) size 292x18
+        chunk 1 (middle anchor) text run 1 at (29.00,300.00) startOffset 0 endOffset 48 width 292.00: "Both sides of the red line should look identical"
+    RenderSVGContainer {g} at (190,0) size 120x111 [transform={m=((1.00,0.00)(0.00,1.00)) t=(150.00,0.00)}]
+      RenderPath {rect} at (190,0) size 120x111 [fill={[type=SOLID] [color=#0000FF]}] [data="M50.00,0.00 L150.00,0.00 L150.00,100.00 L50.00,100.00 Z"]
+        [filter="filter0"] RenderSVGResourceFilter {filter} at (40,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.checksum b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.checksum
index b4831d5..3ed8142 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.checksum
@@ -1 +1 @@
-efd46e2c198be8ead9a8d0392dbc1e94
\ No newline at end of file
+2e73268fd422007888f75dd8c8ba6490
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.png b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.png
index dcc1f56..b861b31 100644
Binary files a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.png and b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.txt b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.txt
index 9e52ddf..fb8db9e 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/recursive-gradient-expected.txt
@@ -1,13 +1,25 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  RenderSVGRoot {svg} at (0,0) size 201x201
+  RenderSVGRoot {svg} at (0,0) size 451x254
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
-      RenderSVGResourceRadialGradient {radialGradient} [id="gradient1"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.15,0.15)] [radius=0.50]
+      RenderSVGResourceRadialGradient {radialGradient} [id="gradient0"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.50,0.50)] [radius=0.50]
         RenderSVGGradientStop {stop} [offset=0.00] [color=#0000FF]
         RenderSVGGradientStop {stop} [offset=1.00] [color=#FF0000]
-      RenderSVGResourceRadialGradient {radialGradient} [id="gradient2"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.15,0.15)] [radius=0.50]
-      RenderSVGResourceRadialGradient {radialGradient} [id="gradient3"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.15,0.15)] [radius=0.50]
+      RenderSVGResourceRadialGradient {radialGradient} [id="gradient1"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.50,0.50)] [radius=0.50]
+        RenderSVGGradientStop {stop} [offset=0.00] [color=#0000FF]
+        RenderSVGGradientStop {stop} [offset=1.00] [color=#FF0000]
+      RenderSVGResourceRadialGradient {radialGradient} [id="gradient2"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.50,0.50)] [radius=0.50]
+      RenderSVGResourceRadialGradient {radialGradient} [id="gradient4"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.50,0.50)] [radius=0.50]
+      RenderSVGResourceRadialGradient {radialGradient} [id="gradient3"] [gradientUnits=objectBoundingBox] [center=(0.50,0.50)] [focal=(0.50,0.50)] [radius=0.50]
     RenderPath {rect} at (0,0) size 101x101 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=RADIAL-GRADIENT] [id="gradient1"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
     RenderPath {rect} at (99,0) size 102x101 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=RADIAL-GRADIENT] [id="gradient2"]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
     RenderPath {rect} at (0,99) size 101x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=RADIAL-GRADIENT] [id="gradient3"]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
+    RenderPath {line} at (224,0) size 2x200 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M225.00,0.00 L225.00,200.00"]
+    RenderSVGText {text} at (79,236) size 292x18 contains 1 chunk(s)
+      RenderSVGInlineText {#text} at (0,0) size 292x18
+        chunk 1 (middle anchor) text run 1 at (79.00,250.00) startOffset 0 endOffset 48 width 292.00: "Both sides of the red line should look identical"
+    RenderSVGContainer {g} at (249,0) size 202x201 [transform={m=((1.00,0.00)(0.00,1.00)) t=(250.00,0.00)}]
+      RenderPath {rect} at (249,0) size 102x101 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=RADIAL-GRADIENT] [id="gradient0"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+      RenderPath {rect} at (349,0) size 102x101 [stroke={[type=SOLID] [color=#008000]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
+      RenderPath {rect} at (249,99) size 102x102 [stroke={[type=SOLID] [color=#008000]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.checksum b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.checksum
index 724c7ee..9d9ff7d 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.checksum
@@ -1 +1 @@
-7f078b4f3971b046bbab30231bfb350c
\ No newline at end of file
+a3e27e4285fbd10b7edbf738101b1339
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.png b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.png
index 12349fa..593339f 100644
Binary files a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.png and b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.txt b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.txt
index af3768a..e379081 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/recursive-mask-expected.txt
@@ -1,7 +1,7 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  RenderSVGRoot {svg} at (0,0) size 150x250
+  RenderSVGRoot {svg} at (0,0) size 350x204
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
       RenderSVGResourceMasker {mask} [id="mask1"] [maskUnits=objectBoundingBox] [maskContentUnits=userSpaceOnUse]
         RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
@@ -13,18 +13,26 @@ layer at (0,0) size 800x600
           [masker="mask1"] RenderSVGResourceMasker {mask} at (0,0) size 0x0
         RenderPath {rect} at (0,0) size 0x0 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M100.00,100.00 L150.00,100.00 L150.00,150.00 L100.00,150.00 Z"]
           [masker="mask2"] RenderSVGResourceMasker {mask} at (0,0) size 0x0
-      RenderPath {rect} at (0,200) size 50x50 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M0.00,200.00 L50.00,200.00 L50.00,250.00 L0.00,250.00 Z"]
-        [masker="mask4"] RenderSVGResourceMasker {mask} at (0,200) size 50x50
+      RenderPath {rect} at (0,100) size 50x50 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M0.00,100.00 L50.00,100.00 L50.00,150.00 L0.00,150.00 Z"]
+        [masker="mask4"] RenderSVGResourceMasker {mask} at (0,100) size 50x50
       RenderSVGResourceMasker {mask} [id="mask4"] [maskUnits=objectBoundingBox] [maskContentUnits=userSpaceOnUse]
-        RenderSVGContainer {use} at (0,200) size 50x50
-          RenderSVGContainer {g} at (0,200) size 50x50
-            RenderPath {rect} at (0,200) size 50x50 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M0.00,200.00 L50.00,200.00 L50.00,250.00 L0.00,250.00 Z"]
-              [masker="mask4"] RenderSVGResourceMasker {mask} at (0,200) size 50x50
-    RenderPath {rect} at (0,0) size 50x50 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+        RenderSVGContainer {use} at (0,100) size 50x50
+          RenderSVGContainer {g} at (0,100) size 50x50
+            RenderPath {rect} at (0,100) size 50x50 [fill={[type=SOLID] [color=#FFFFFF]}] [data="M0.00,100.00 L50.00,100.00 L50.00,150.00 L0.00,150.00 Z"]
+              [masker="mask4"] RenderSVGResourceMasker {mask} at (0,100) size 50x50
+    RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
       [masker="mask1"] RenderSVGResourceMasker {mask} at (0,0) size 50x50
-    RenderPath {rect} at (100,0) size 50x50 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
+    RenderPath {rect} at (100,0) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
       [masker="mask2"] RenderSVGResourceMasker {mask} at (100,0) size 50x50
-    RenderPath {rect} at (0,0) size 0x0 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M100.00,100.00 L200.00,100.00 L200.00,200.00 L100.00,200.00 Z"]
+    RenderPath {rect} at (0,0) size 0x0 [fill={[type=SOLID] [color=#0000FF]}] [data="M100.00,100.00 L200.00,100.00 L200.00,200.00 L100.00,200.00 Z"]
       [masker="mask3"] RenderSVGResourceMasker {mask} at (0,0) size 0x0
-    RenderPath {rect} at (0,200) size 50x50 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,200.00 L100.00,200.00 L100.00,300.00 L0.00,300.00 Z"]
-      [masker="mask4"] RenderSVGResourceMasker {mask} at (0,200) size 50x50
+    RenderPath {rect} at (0,100) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
+      [masker="mask4"] RenderSVGResourceMasker {mask} at (0,100) size 50x50
+    RenderPath {line} at (174,0) size 2x150 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M175.00,0.00 L175.00,150.00"]
+    RenderSVGText {text} at (29,186) size 292x18 contains 1 chunk(s)
+      RenderSVGInlineText {#text} at (0,0) size 292x18
+        chunk 1 (middle anchor) text run 1 at (29.00,200.00) startOffset 0 endOffset 48 width 292.00: "Both sides of the red line should look identical"
+    RenderSVGContainer {g} at (200,0) size 150x150 [transform={m=((1.00,0.00)(0.00,1.00)) t=(200.00,0.00)}]
+      RenderPath {rect} at (200,0) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderPath {rect} at (300,0) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M100.00,0.00 L150.00,0.00 L150.00,50.00 L100.00,50.00 Z"]
+      RenderPath {rect} at (200,100) size 50x50 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L50.00,100.00 L50.00,150.00 L0.00,150.00 Z"]
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.checksum b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.checksum
index 4f12c44..40b6a46 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.checksum
+++ b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.checksum
@@ -1 +1 @@
-c313c4ce6fc9ac267436fef6a4d7f5d6
\ No newline at end of file
+2886112189091c741b0f22d4331cd31c
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.png b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.png
index efd9852..636a8bc 100644
Binary files a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.png and b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.txt b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.txt
index 766c877..e007faa 100644
--- a/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/recursive-pattern-expected.txt
@@ -1,36 +1,71 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  RenderSVGRoot {svg} at (0,0) size 201x401
+  RenderSVGRoot {svg} at (0,0) size 650x354
     RenderSVGHiddenContainer {defs} at (0,0) size 0x0
-      RenderSVGResourcePattern {pattern} [id="pattern1"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-        RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern1"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderSVGResourcePattern {pattern} [id="pattern2"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-        RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern1"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderSVGResourcePattern {pattern} [id="pattern3"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-      RenderSVGResourcePattern {pattern} [id="pattern4"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-      RenderSVGResourcePattern {pattern} [id="pattern6"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-      RenderSVGResourcePattern {pattern} [id="pattern5"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-        RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern6"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern7"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderSVGResourcePattern {pattern} [id="pattern7"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-        RenderSVGContainer {use} at (0,0) size 100x100
-          RenderSVGContainer {g} at (0,0) size 100x100
-            RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern7"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderSVGContainer {use} at (0,0) size 100x100
-        RenderSVGContainer {g} at (0,0) size 100x100
-          RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-      RenderSVGResourcePattern {pattern} [id="pattern8"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
-        RenderSVGContainer {use} at (0,0) size 100x100
-          RenderSVGContainer {g} at (0,0) size 100x100
-            RenderSVGContainer {g} at (0,0) size 100x100
-              RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-    RenderPath {rect} at (0,0) size 101x101 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern1"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
-    RenderPath {rect} at (0,99) size 101x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern2"]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
-    RenderPath {rect} at (99,0) size 102x101 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern3"]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
-    RenderPath {rect} at (99,99) size 102x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern4"]}] [data="M100.00,100.00 L200.00,100.00 L200.00,200.00 L100.00,200.00 Z"]
-    RenderPath {rect} at (0,199) size 101x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern5"]}] [data="M0.00,200.00 L100.00,200.00 L100.00,300.00 L0.00,300.00 Z"]
-    RenderPath {rect} at (99,199) size 102x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern6"]}] [data="M100.00,200.00 L200.00,200.00 L200.00,300.00 L100.00,300.00 Z"]
-    RenderPath {rect} at (0,299) size 101x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern7"]}] [data="M0.00,300.00 L100.00,300.00 L100.00,400.00 L0.00,400.00 Z"]
-    RenderPath {rect} at (99,299) size 102x102 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=PATTERN] [id="pattern8"]}] [data="M100.00,300.00 L200.00,300.00 L200.00,400.00 L100.00,400.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern0"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+        RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern1"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+        RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern2"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+        RenderPath {rect} at (0,0) size 50x50 [fill={[type=PATTERN] [id="pattern1"]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern3"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+      RenderSVGResourcePattern {pattern} [id="pattern4"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+      RenderSVGResourcePattern {pattern} [id="pattern6"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+      RenderSVGResourcePattern {pattern} [id="pattern5"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+        RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+      RenderPath {rect} at (0,0) size 50x50 [fill={[type=PATTERN] [id="pattern7"]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern7"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderSVGContainer {use} at (0,0) size 50x50
+          RenderSVGContainer {g} at (0,0) size 50x50
+            RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+        RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+      RenderPath {rect} at (0,0) size 50x50 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderSVGContainer {use} at (0,0) size 50x50
+        RenderSVGContainer {g} at (0,0) size 50x50
+          RenderPath {rect} at (0,0) size 50x50 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern8"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderSVGContainer {g} at (0,0) size 150x150
+          RenderSVGContainer {use} at (50,50) size 100x100
+            RenderSVGContainer {g} at (50,50) size 100x100
+              RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+          RenderSVGContainer {use} at (0,0) size 50x50
+            RenderSVGContainer {g} at (0,0) size 50x50
+              RenderSVGContainer {g} at (0,0) size 50x50
+                RenderPath {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+      RenderSVGResourcePattern {pattern} [id="pattern9"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+        RenderSVGContainer {use} at (0,0) size 150x150
+          RenderSVGContainer {g} at (0,0) size 150x150
+            RenderSVGContainer {g} at (0,0) size 150x150
+              RenderSVGContainer {g} at (50,50) size 100x100
+                RenderPath {rect} at (50,50) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M50.00,50.00 L150.00,50.00 L150.00,150.00 L50.00,150.00 Z"]
+              RenderSVGContainer {g} at (0,0) size 50x50
+                RenderSVGContainer {g} at (0,0) size 50x50
+                  RenderPath {rect} at (0,0) size 50x50 [fill={[type=PATTERN] [id="pattern8"]}] [data="M0.00,0.00 L50.00,0.00 L50.00,50.00 L0.00,50.00 Z"]
+    RenderPath {rect} at (0,0) size 100x100 [fill={[type=PATTERN] [id="pattern1"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+    RenderPath {rect} at (100,0) size 100x100 [fill={[type=PATTERN] [id="pattern2"]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
+    RenderPath {rect} at (200,0) size 100x100 [fill={[type=PATTERN] [id="pattern3"]}] [data="M200.00,0.00 L300.00,0.00 L300.00,100.00 L200.00,100.00 Z"]
+    RenderPath {rect} at (0,100) size 100x100 [fill={[type=PATTERN] [id="pattern4"]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
+    RenderPath {rect} at (100,100) size 100x100 [fill={[type=PATTERN] [id="pattern5"]}] [data="M100.00,100.00 L200.00,100.00 L200.00,200.00 L100.00,200.00 Z"]
+    RenderPath {rect} at (200,100) size 100x100 [fill={[type=PATTERN] [id="pattern6"]}] [data="M200.00,100.00 L300.00,100.00 L300.00,200.00 L200.00,200.00 Z"]
+    RenderPath {rect} at (0,200) size 100x100 [fill={[type=PATTERN] [id="pattern7"]}] [data="M0.00,200.00 L100.00,200.00 L100.00,300.00 L0.00,300.00 Z"]
+    RenderPath {rect} at (100,200) size 100x100 [fill={[type=PATTERN] [id="pattern8"]}] [data="M100.00,200.00 L200.00,200.00 L200.00,300.00 L100.00,300.00 Z"]
+    RenderPath {rect} at (200,200) size 100x100 [fill={[type=PATTERN] [id="pattern9"]}] [data="M200.00,200.00 L300.00,200.00 L300.00,300.00 L200.00,300.00 Z"]
+    RenderPath {line} at (324,0) size 2x300 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M325.00,0.00 L325.00,300.00"]
+    RenderSVGText {text} at (179,336) size 292x18 contains 1 chunk(s)
+      RenderSVGInlineText {#text} at (0,0) size 292x18
+        chunk 1 (middle anchor) text run 1 at (179.00,350.00) startOffset 0 endOffset 48 width 292.00: "Both sides of the red line should look identical"
+    RenderSVGContainer {g} at (350,0) size 300x300 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,0.00)}]
+      RenderPath {rect} at (350,0) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M0.00,0.00 L100.00,0.00 L100.00,100.00 L0.00,100.00 Z"]
+      RenderPath {rect} at (450,0) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M100.00,0.00 L200.00,0.00 L200.00,100.00 L100.00,100.00 Z"]
+      RenderPath {rect} at (550,0) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M200.00,0.00 L300.00,0.00 L300.00,100.00 L200.00,100.00 Z"]
+      RenderPath {rect} at (350,100) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M0.00,100.00 L100.00,100.00 L100.00,200.00 L0.00,200.00 Z"]
+      RenderPath {rect} at (450,100) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M100.00,100.00 L200.00,100.00 L200.00,200.00 L100.00,200.00 Z"]
+      RenderPath {rect} at (550,100) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M200.00,100.00 L300.00,100.00 L300.00,200.00 L200.00,200.00 Z"]
+      RenderPath {rect} at (350,200) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M0.00,200.00 L100.00,200.00 L100.00,300.00 L0.00,300.00 Z"]
+      RenderPath {rect} at (450,200) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M100.00,200.00 L200.00,200.00 L200.00,300.00 L100.00,300.00 Z"]
+      RenderPath {rect} at (550,200) size 100x100 [fill={[type=PATTERN] [id="pattern0"]}] [data="M200.00,200.00 L300.00,200.00 L300.00,300.00 L200.00,300.00 Z"]
diff --git a/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt b/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
index c6bea1b..1df140f 100644
--- a/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
@@ -19,4 +19,3 @@ layer at (0,0) size 480x360
         RenderSVGContainer {use} at (350,25) size 40x40
           RenderSVGContainer {g} at (350,25) size 40x40
             RenderPath {rect} at (350,25) size 40x40 [fill={[type=SOLID] [color=#00FF00]}] [data="M0.00,0.00 L40.00,0.00 L40.00,40.00 L0.00,40.00 Z"]
-caret: position 0 of child 0 {#text} of child 1 {text} of child 1 {g} of child 3 {g} of child 3 {g} of child 1 {svg} of document
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum
index 605905c..2a9b10f 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.checksum
@@ -1 +1 @@
-224fae800d3d427aba91701730990d02
\ No newline at end of file
+7d9ed1ba3cca05516d0a91561ed24feb
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png
index edfe02d..b7418c0 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerHeight-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum
index b2b5405..3c96f43 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.checksum
@@ -1 +1 @@
-11c3c4e16ba9180cdaeb785027d292e2
\ No newline at end of file
+5bf96e5173d6653c73e6163b7e203c72
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png
index 967760a..4612161 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-dom-markerWidth-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum
index 4f78959..af45b91 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.checksum
@@ -1 +1 @@
-c2ba9334d9a0f68b163099615799ac39
\ No newline at end of file
+31c467d114864ed4ea30162d45c6c289
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png
index f4a8bd1..6e1da2c 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerHeight-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum
index d9000aa..154f8a2 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.checksum
@@ -1 +1 @@
-7ef89ade3d06a052d987f755b9dfcaf2
\ No newline at end of file
+4080ad4d8c7c50db21c1b2a2b98e0562
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png
index 8be103f..a183613 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMarkerElement-svgdom-markerWidth-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum
index a40a766..1e363ea 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.checksum
@@ -1 +1 @@
-d11382e9cbf749aadd4a0953a865956e
\ No newline at end of file
+6669ab446ddc0ff912c784ee18705928
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png
index ef08666..1af8420 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum
index c2cb196..eff0bf4 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.checksum
@@ -1 +1 @@
-173b41ad238e25454717720add78ea84
\ No newline at end of file
+cca7e1243ffc4052ae39c1729fe5676a
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png
index 67035db..502c26c 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum
index 88a5e3a..69a1d26 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.checksum
@@ -1 +1 @@
-382386d8794e17490484c55f5b025481
\ No newline at end of file
+4d9ca776de74d7e38d9e758a89b93d27
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png
index 1015a84..4f94d36 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum
index 43e5eb9..30381d7 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.checksum
@@ -1 +1 @@
-c17365eee489e97e9b1bb7f649414ee1
\ No newline at end of file
+ca73b7faa6d86098712f37b66bbc1c82
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png
index 23f6626..213ab16 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum
index 53b73d0..09953c7 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.checksum
@@ -1 +1 @@
-716714632a1b9c8b0c947a52a354e676
\ No newline at end of file
+3019c8444d91d7c726cd6a6d2540fb1e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png
index 949f0d1..ebd5806 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum
index 77f61d6..17243e7 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.checksum
@@ -1 +1 @@
-0c5df953535e3db2abb9d999b01032b7
\ No newline at end of file
+70ef44d927c6ad84a702c9771c169905
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png
index 0c4ea9a..4f9de10 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum
index 7ca5e06..08476fd 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.checksum
@@ -1 +1 @@
-d6ce0b1dc577c6fbff58f0f3f4f56d32
\ No newline at end of file
+414528c414a3ad821d167564502995bb
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png
index b70285b..875a1bc 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum
index 540f44d..0bf2dfc 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.checksum
@@ -1 +1 @@
-0e2770c1b7a4543ad89484ef9fa5a0b6
\ No newline at end of file
+51768de61cfef35e4c8f5d45029ffa8c
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png
index b018077..47dc0e6 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum
index e2498e3..9c58092 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.checksum
@@ -1 +1 @@
-4dcda8de30ac50477518851d437d282d
\ No newline at end of file
+21e1b5d7baf0d61fe046185ce31c8263
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png
index aef07ab..5a3308e 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum
index bef8967..947e381 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.checksum
@@ -1 +1 @@
-5d0b62709f3a4d7733ab98e58ccc7b1f
\ No newline at end of file
+d79313dfe1948cb30b740f17f7861030
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png
index 1e69ae0..c7fd4df 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum
index 95bbb6c..8e1dda9 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.checksum
@@ -1 +1 @@
-b0d903966f3ebfa1be3346b5bd0a8521
\ No newline at end of file
+bb05754e3fbf1cd483529bc6024a8e0e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png
index c7520ba..986a69d 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum
index 7619a87..52d2298 100644
--- a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum
+++ b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.checksum
@@ -1 +1 @@
-0ec6e3c4aef5a60c2b8f0efcc05b26cb
\ No newline at end of file
+a3b34c5887a55c800641ee576b137d06
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png
index 0f80807..aa8c59e 100644
Binary files a/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png and b/LayoutTests/platform/mac/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt b/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
index ab152a9..2f5d538 100644
--- a/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
+++ b/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
@@ -6,8 +6,6 @@ layer at (0,0) size 800x600
       RenderSVGContainer {g} at (0,0) size 0x0
         RenderSVGContainer {use} at (0,0) size 0x0
           RenderSVGContainer {g} at (0,0) size 0x0
-            RenderSVGContainer {g} at (0,0) size 0x0
-              RenderSVGContainer {g} at (0,0) size 0x0
       RenderSVGContainer {g} at (0,0) size 0x0
         RenderSVGContainer {use} at (0,0) size 0x0
           RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/svg/clip-path/clip-path-recursive-call-by-child.svg b/LayoutTests/svg/clip-path/clip-path-recursive-call-by-child.svg
index 2da9627..ae9927f 100644
--- a/LayoutTests/svg/clip-path/clip-path-recursive-call-by-child.svg
+++ b/LayoutTests/svg/clip-path/clip-path-recursive-call-by-child.svg
@@ -1,7 +1,7 @@
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
     <clipPath id="clip">
-        <rect x="0" y="0" width="100" height="50" clip-path="url(#clip)"/>
+        <rect x="0" y="0" width="100" height="100" clip-path="url(#clip)"/>
     </clipPath>
 </defs>
 <!--
diff --git a/LayoutTests/svg/custom/js-late-clipPath-and-object-creation.svg b/LayoutTests/svg/custom/js-late-clipPath-and-object-creation.svg
index 0246b07..22b6e20 100644
--- a/LayoutTests/svg/custom/js-late-clipPath-and-object-creation.svg
+++ b/LayoutTests/svg/custom/js-late-clipPath-and-object-creation.svg
@@ -1,10 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createClipPath()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content" transform="scale(1, 1.5)"/>
 <script>
     var content = document.getElementById("content");
- 
+
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createObject, 0);
+
     function createObject()
     {
         var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
@@ -16,12 +21,12 @@
 
         text.appendChild(document.createTextNode("Clipped. INVISIBLE."));        
         content.appendChild(text);
+
+        setTimeout(createClipPath, 0);
     }
 
     function createClipPath()
     {
-        createObject();
-
         var clipPath = document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
         clipPath.setAttribute("id", "dynClip");
         clipPath.setAttribute("clipPathUnits", "userSpaceOnUse");
@@ -31,6 +36,9 @@
 
         clipPath.appendChild(path);
         content.appendChild(clipPath);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-clipPath-creation.svg b/LayoutTests/svg/custom/js-late-clipPath-creation.svg
index 8c0be90..41015c3 100644
--- a/LayoutTests/svg/custom/js-late-clipPath-creation.svg
+++ b/LayoutTests/svg/custom/js-late-clipPath-creation.svg
@@ -1,12 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createClipPath()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content" transform="scale(1, 1.5)">
      <text font-size="60" fill="navy" clip-path="url(#dynClip)" x="10" y="70">Clipped. INVISIBLE.</text>
 </g>
 <script>
     var content = document.getElementById("content");
 
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createClipPath, 0);
+
     function createClipPath()
     {
         var clipPath = document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
@@ -18,6 +23,9 @@
 
         clipPath.appendChild(path);
         content.appendChild(clipPath);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-gradient-and-object-creation.svg b/LayoutTests/svg/custom/js-late-gradient-and-object-creation.svg
index 9e8de48..94b7741 100644
--- a/LayoutTests/svg/custom/js-late-gradient-and-object-creation.svg
+++ b/LayoutTests/svg/custom/js-late-gradient-and-object-creation.svg
@@ -1,86 +1,93 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createGradients()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content"/>
 
 <script>
-	var content = document.getElementById("content");
-
-	function createGradients()
-	{
-		// Setup "fillLinearGradient"
-		var gradient1 = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
-		gradient1.setAttribute("id", "fillLinearGradient");
-		gradient1.setAttribute("x1", "0");
-		gradient1.setAttribute("x2", "1");
-
-		var stop11 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop11.setAttribute("stop-color", "blue");
-		stop11.setAttribute("offset", "0");
-
-		var stop21 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop21.setAttribute("stop-color", "red");
-		stop21.setAttribute("offset", "1");
-
-		gradient1.appendChild(stop11);
-		gradient1.appendChild(stop21);
-
-		content.appendChild(gradient1);
-
-		// Setup "strokeLinearGradient"
-		var gradient2 = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
-		gradient2.setAttribute("id", "strokeLinearGradient");
-		gradient2.setAttribute("x1", "0");
-		gradient2.setAttribute("x2", "1");
-
-		var stop22 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop22.setAttribute("stop-color", "yellow");
-		stop22.setAttribute("offset", "0");
-
-		var stop22 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop22.setAttribute("stop-color", "green");
-		stop22.setAttribute("offset", "1");
-
-		gradient2.appendChild(stop22);
-		gradient2.appendChild(stop22);
-
-		content.appendChild(gradient2);
-
-		setupGradientUsers();
-	}
-
-	function setupGradientUsers()
-	{
-		var text1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text1.setAttribute("font-size", "68");
-		text1.setAttribute("x", "-150");
-		text1.setAttribute("y", "70")
-		text1.setAttribute("fill", "url(#fillLinearGradient)");
-		text1.setAttribute("stroke", "none");
-		text1.appendChild(document.createTextNode("Gradient on fill"));
-
-		content.appendChild(text1);
-
-		var text2 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text2.setAttribute("font-size", "68");
-		text2.setAttribute("x", "-150");
-		text2.setAttribute("y", "140")
-		text2.setAttribute("fill", "none");	
-		text2.setAttribute("stroke", "url(#strokeLinearGradient)");
-		text2.appendChild(document.createTextNode("Gradient on stroke"));
-
-		content.appendChild(text2);
-
-		var text3 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text3.setAttribute("font-size", "68");
-		text3.setAttribute("x", "-150");
-		text3.setAttribute("y", "210")
-		text3.setAttribute("fill", "url(#fillLinearGradient)");	
-		text3.setAttribute("stroke", "url(#strokeLinearGradient)");
-		text3.appendChild(document.createTextNode("Gradient on fill/stroke"));
-
-		content.appendChild(text3);
-	}
+    var content = document.getElementById("content");
+
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createGradients, 0);
+
+    function createGradients()
+    {
+        // Setup "fillLinearGradient"
+        var gradient1 = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
+        gradient1.setAttribute("id", "fillLinearGradient");
+        gradient1.setAttribute("x1", "0");
+        gradient1.setAttribute("x2", "1");
+
+        var stop11 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop11.setAttribute("stop-color", "blue");
+        stop11.setAttribute("offset", "0");
+
+        var stop21 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop21.setAttribute("stop-color", "red");
+        stop21.setAttribute("offset", "1");
+
+        gradient1.appendChild(stop11);
+        gradient1.appendChild(stop21);
+
+        content.appendChild(gradient1);
+
+        // Setup "strokeLinearGradient"
+        var gradient2 = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
+        gradient2.setAttribute("id", "strokeLinearGradient");
+        gradient2.setAttribute("x1", "0");
+        gradient2.setAttribute("x2", "1");
+
+        var stop22 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop22.setAttribute("stop-color", "yellow");
+        stop22.setAttribute("offset", "0");
+
+        var stop22 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop22.setAttribute("stop-color", "green");
+        stop22.setAttribute("offset", "1");
+
+        gradient2.appendChild(stop22);
+        gradient2.appendChild(stop22);
+
+        content.appendChild(gradient2);
+        setTimeout(setupGradientUsers, 0);
+    }
+
+    function setupGradientUsers()
+    {
+        var text1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text1.setAttribute("font-size", "68");
+        text1.setAttribute("x", "-150");
+        text1.setAttribute("y", "70")
+        text1.setAttribute("fill", "url(#fillLinearGradient)");
+        text1.setAttribute("stroke", "none");
+        text1.appendChild(document.createTextNode("Gradient on fill"));
+
+        content.appendChild(text1);
+
+        var text2 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text2.setAttribute("font-size", "68");
+        text2.setAttribute("x", "-150");
+        text2.setAttribute("y", "140")
+        text2.setAttribute("fill", "none");    
+        text2.setAttribute("stroke", "url(#strokeLinearGradient)");
+        text2.appendChild(document.createTextNode("Gradient on stroke"));
+
+        content.appendChild(text2);
+
+        var text3 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text3.setAttribute("font-size", "68");
+        text3.setAttribute("x", "-150");
+        text3.setAttribute("y", "210")
+        text3.setAttribute("fill", "url(#fillLinearGradient)");    
+        text3.setAttribute("stroke", "url(#strokeLinearGradient)");
+        text3.appendChild(document.createTextNode("Gradient on fill/stroke"));
+
+        content.appendChild(text3);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
 </script>
 
 </svg>
diff --git a/LayoutTests/svg/custom/js-late-gradient-creation.svg b/LayoutTests/svg/custom/js-late-gradient-creation.svg
index 703d4ae..62b66ce 100644
--- a/LayoutTests/svg/custom/js-late-gradient-creation.svg
+++ b/LayoutTests/svg/custom/js-late-gradient-creation.svg
@@ -1,32 +1,40 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createGradient()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content" transform="scale(1, 1.5)">
      <text font-size="68" fill="url(#dynGrad)"  x="20" y="70">Gradient on fill</text>
 </g>
 <script>
-	var content = document.getElementById("content");
+    var content = document.getElementById("content");
 
-	function createGradient()
-	{
-		var gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
-		gradient.setAttribute("id", "dynGrad");
-		gradient.setAttribute("x1", "0");
-		gradient.setAttribute("x2", "1");
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
 
-		var stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop1.setAttribute("stop-color", "blue");
-		stop1.setAttribute("offset", "0");
+    setTimeout(createGradient, 0);
 
-		var stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
-		stop2.setAttribute("stop-color", "red");
-		stop2.setAttribute("offset", "1");
+    function createGradient()
+    {
+        var gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
+        gradient.setAttribute("id", "dynGrad");
+        gradient.setAttribute("x1", "0");
+        gradient.setAttribute("x2", "1");
 
-		gradient.appendChild(stop1);
-		gradient.appendChild(stop2);
+        var stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop1.setAttribute("stop-color", "blue");
+        stop1.setAttribute("offset", "0");
 
-		content.appendChild(gradient);
-	}
+        var stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
+        stop2.setAttribute("stop-color", "red");
+        stop2.setAttribute("offset", "1");
+
+        gradient.appendChild(stop1);
+        gradient.appendChild(stop2);
+
+        content.appendChild(gradient);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
 </script>
 
 </svg>
diff --git a/LayoutTests/svg/custom/js-late-marker-and-object-creation.svg b/LayoutTests/svg/custom/js-late-marker-and-object-creation.svg
index c80f180..60f3855 100644
--- a/LayoutTests/svg/custom/js-late-marker-and-object-creation.svg
+++ b/LayoutTests/svg/custom/js-late-marker-and-object-creation.svg
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createMarker()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <defs id="defs">
     <marker id="markerStart" viewBox="0 0 10 10" markerWidth="2" markerHeight="2" refX="5" refY="5" markerUnits="strokeWidth">
         <rect width="10" height="10" fill="red" stroke="none"/>
@@ -16,6 +16,11 @@
     var defs = document.getElementById("defs");
     var content = document.getElementById("content");
 
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createObject, 0);
+
     function createObject()
     {
         var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
@@ -28,12 +33,11 @@
         path.setAttribute("d", "M 130 135 L 180 135 L 180 185");
 
         content.appendChild(path);
+        setTimeout(createMarker, 0);
     }
 
     function createMarker()
     {
-        createObject();
-
         var marker = document.createElementNS("http://www.w3.org/2000/svg", "marker");
         marker.setAttribute("id", "markerMiddle");
         marker.setAttribute("viewBox", "0 0 10 10");
@@ -52,6 +56,9 @@
 
         marker.appendChild(circle);
         defs.appendChild(marker);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-marker-creation.svg b/LayoutTests/svg/custom/js-late-marker-creation.svg
index a3730d9..0e823ee 100644
--- a/LayoutTests/svg/custom/js-late-marker-creation.svg
+++ b/LayoutTests/svg/custom/js-late-marker-creation.svg
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createMarker()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <defs id="defs">
     <marker id="markerStart" viewBox="0 0 10 10" markerWidth="2" markerHeight="2" refX="5" refY="5" markerUnits="strokeWidth">
         <rect width="10" height="10" fill="red" stroke="none"/>
@@ -16,6 +16,11 @@
 <script>
     var defs = document.getElementById("defs");
 
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createMarker, 0);
+
     function createMarker()
     {
         var marker = document.createElementNS("http://www.w3.org/2000/svg", "marker");
@@ -36,6 +41,9 @@
 
         marker.appendChild(circle);
         defs.appendChild(marker);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-mask-and-object-creation.svg b/LayoutTests/svg/custom/js-late-mask-and-object-creation.svg
index 2b0977b..4ca2b73 100644
--- a/LayoutTests/svg/custom/js-late-mask-and-object-creation.svg
+++ b/LayoutTests/svg/custom/js-late-mask-and-object-creation.svg
@@ -1,12 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 800 600" onload="createMask()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 800 600">
 
 <g id="content"/>
 
 <script>
     var content = document.getElementById("content");
 
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createObject, 0);
+
     function createObject()
     {
         var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
@@ -17,12 +22,11 @@
         rect.setAttribute("mask", "url(#dynMask)");
 
         content.appendChild(rect);
+        setTimeout(createMask, 0);
     }
 
     function createMask()
     {
-        createObject();
-
         var mask = document.createElementNS("http://www.w3.org/2000/svg", "mask");
         mask.setAttribute("id", "dynMask");
         mask.setAttribute("maskUnits", "userSpaceOnUse");
@@ -38,6 +42,9 @@
 
         mask.appendChild(rect);
         content.appendChild(mask);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-mask-creation.svg b/LayoutTests/svg/custom/js-late-mask-creation.svg
index 45d043f..bbe2c19 100644
--- a/LayoutTests/svg/custom/js-late-mask-creation.svg
+++ b/LayoutTests/svg/custom/js-late-mask-creation.svg
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 800 600" onload="createMask()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 800 600">
 
 <rect x="0" y="100" width="800" height="100" fill="blue" mask="url(#dynMask)"/>
 <g id="content"/>
@@ -8,6 +8,11 @@
 <script>
     var content = document.getElementById("content");
 
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createMask, 0);
+
     function createMask()
     {
         var mask = document.createElementNS("http://www.w3.org/2000/svg", "mask");
@@ -25,6 +30,9 @@
 
         mask.appendChild(rect);
         content.appendChild(mask);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
     }
 </script>
 
diff --git a/LayoutTests/svg/custom/js-late-pattern-and-object-creation.svg b/LayoutTests/svg/custom/js-late-pattern-and-object-creation.svg
index 111598d..c538da3 100644
--- a/LayoutTests/svg/custom/js-late-pattern-and-object-creation.svg
+++ b/LayoutTests/svg/custom/js-late-pattern-and-object-creation.svg
@@ -1,104 +1,112 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createPatterns()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content"/>
 
 <script>
-	var content = document.getElementById("content");
-
-	function createPatterns()
-	{
-		// Setup "fillPattern"	
-		var pattern1 = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
-		pattern1.setAttribute("id", "fillPattern");
-		pattern1.setAttribute("patternUnits", "userSpaceOnUse");
-		pattern1.setAttribute("x", "0");
-		pattern1.setAttribute("y", "0");
-		pattern1.setAttribute("width", "20");
-		pattern1.setAttribute("height", "20");
-
-		var rect11 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect11.setAttribute("x", "5");
-		rect11.setAttribute("y", "5");
-		rect11.setAttribute("width", "10");
-		rect11.setAttribute("height", "10");
-		rect11.setAttribute("fill", "red");
-
-		var rect21 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect21.setAttribute("x", "10");
-		rect21.setAttribute("y", "10");
-		rect21.setAttribute("width", "10");
-		rect21.setAttribute("height", "10");
-		rect21.setAttribute("fill", "green");
-
-		pattern1.appendChild(rect11);
-		pattern1.appendChild(rect21);
-
-		content.appendChild(pattern1);
-
-		// Setup "strokePattern"	
-		var pattern2 = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
-		pattern2.setAttribute("id", "strokePattern");
-		pattern2.setAttribute("patternUnits", "userSpaceOnUse");
-		pattern2.setAttribute("x", "0");
-		pattern2.setAttribute("y", "0");
-		pattern2.setAttribute("width", "20");
-		pattern2.setAttribute("height", "20");
-
-		var rect12 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect12.setAttribute("x", "5");
-		rect12.setAttribute("y", "5");
-		rect12.setAttribute("width", "10");
-		rect12.setAttribute("height", "10");
-		rect12.setAttribute("fill", "yellow");
-
-		var rect22 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect22.setAttribute("x", "10");
-		rect22.setAttribute("y", "10");
-		rect22.setAttribute("width", "10");
-		rect22.setAttribute("height", "10");
-		rect22.setAttribute("fill", "blue");
-
-		pattern2.appendChild(rect12);
-		pattern2.appendChild(rect22);
-
-		content.appendChild(pattern2);
-
-		setupPatternUsers();
-	}
-
-	function setupPatternUsers()
-	{
-		var text1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text1.setAttribute("font-size", "68");
-		text1.setAttribute("x", "-150");
-		text1.setAttribute("y", "70")
-		text1.setAttribute("fill", "url(#fillPattern)");
-		text1.setAttribute("stroke", "none");
-		text1.appendChild(document.createTextNode("Pattern on fill"));
-
-		content.appendChild(text1);
-
-		var text2 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text2.setAttribute("font-size", "68");
-		text2.setAttribute("x", "-150");
-		text2.setAttribute("y", "140")
-		text2.setAttribute("fill", "none");	
-		text2.setAttribute("stroke", "url(#strokePattern)");
-		text2.appendChild(document.createTextNode("Pattern on stroke"));
-
-		content.appendChild(text2);
-
-		var text3 = document.createElementNS("http://www.w3.org/2000/svg", "text");
-		text3.setAttribute("font-size", "68");
-		text3.setAttribute("x", "-150");
-		text3.setAttribute("y", "210")
-		text3.setAttribute("fill", "url(#fillPattern)");	
-		text3.setAttribute("stroke", "url(#strokePattern)");
-		text3.appendChild(document.createTextNode("Pattern on fill/stroke"));
-
-		content.appendChild(text3);
-	}
+    var content = document.getElementById("content");
+
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createPatterns, 0);
+
+    function createPatterns()
+    {
+        // Setup "fillPattern"    
+        var pattern1 = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
+        pattern1.setAttribute("id", "fillPattern");
+        pattern1.setAttribute("patternUnits", "userSpaceOnUse");
+        pattern1.setAttribute("x", "0");
+        pattern1.setAttribute("y", "0");
+        pattern1.setAttribute("width", "20");
+        pattern1.setAttribute("height", "20");
+
+        var rect11 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect11.setAttribute("x", "5");
+        rect11.setAttribute("y", "5");
+        rect11.setAttribute("width", "10");
+        rect11.setAttribute("height", "10");
+        rect11.setAttribute("fill", "red");
+
+        var rect21 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect21.setAttribute("x", "10");
+        rect21.setAttribute("y", "10");
+        rect21.setAttribute("width", "10");
+        rect21.setAttribute("height", "10");
+        rect21.setAttribute("fill", "green");
+
+        pattern1.appendChild(rect11);
+        pattern1.appendChild(rect21);
+
+        content.appendChild(pattern1);
+
+        // Setup "strokePattern"    
+        var pattern2 = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
+        pattern2.setAttribute("id", "strokePattern");
+        pattern2.setAttribute("patternUnits", "userSpaceOnUse");
+        pattern2.setAttribute("x", "0");
+        pattern2.setAttribute("y", "0");
+        pattern2.setAttribute("width", "20");
+        pattern2.setAttribute("height", "20");
+
+        var rect12 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect12.setAttribute("x", "5");
+        rect12.setAttribute("y", "5");
+        rect12.setAttribute("width", "10");
+        rect12.setAttribute("height", "10");
+        rect12.setAttribute("fill", "yellow");
+
+        var rect22 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect22.setAttribute("x", "10");
+        rect22.setAttribute("y", "10");
+        rect22.setAttribute("width", "10");
+        rect22.setAttribute("height", "10");
+        rect22.setAttribute("fill", "blue");
+
+        pattern2.appendChild(rect12);
+        pattern2.appendChild(rect22);
+
+        content.appendChild(pattern2);
+
+        setTimeout(setupPatternUsers, 0);
+    }
+
+    function setupPatternUsers()
+    {
+        var text1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text1.setAttribute("font-size", "68");
+        text1.setAttribute("x", "-150");
+        text1.setAttribute("y", "70")
+        text1.setAttribute("fill", "url(#fillPattern)");
+        text1.setAttribute("stroke", "none");
+        text1.appendChild(document.createTextNode("Pattern on fill"));
+
+        content.appendChild(text1);
+
+        var text2 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text2.setAttribute("font-size", "68");
+        text2.setAttribute("x", "-150");
+        text2.setAttribute("y", "140")
+        text2.setAttribute("fill", "none");    
+        text2.setAttribute("stroke", "url(#strokePattern)");
+        text2.appendChild(document.createTextNode("Pattern on stroke"));
+
+        content.appendChild(text2);
+
+        var text3 = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        text3.setAttribute("font-size", "68");
+        text3.setAttribute("x", "-150");
+        text3.setAttribute("y", "210")
+        text3.setAttribute("fill", "url(#fillPattern)");    
+        text3.setAttribute("stroke", "url(#strokePattern)");
+        text3.appendChild(document.createTextNode("Pattern on fill/stroke"));
+
+        content.appendChild(text3);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
 </script>
 
 </svg>
diff --git a/LayoutTests/svg/custom/js-late-pattern-creation.svg b/LayoutTests/svg/custom/js-late-pattern-creation.svg
index ffcc15e..2b2326d 100644
--- a/LayoutTests/svg/custom/js-late-pattern-creation.svg
+++ b/LayoutTests/svg/custom/js-late-pattern-creation.svg
@@ -1,41 +1,49 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">  
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360" onload="createPattern()">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  id="svg-root" width="100%" height="100%" viewBox="0 0 480 360">
 <g id="content" transform="scale(1, 1.5)">
      <text font-size="68" fill="url(#dynPattern)"  x="20" y="70">Pattern on fill</text>
 </g>
 <script>
-	var content = document.getElementById("content");
-
-	function createPattern()
-	{
-		var pattern = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
-		pattern.setAttribute("id", "dynPattern");
-		pattern.setAttribute("patternUnits", "userSpaceOnUse");
-		pattern.setAttribute("x", "0");
-		pattern.setAttribute("y", "0");
-		pattern.setAttribute("width", "20");
-		pattern.setAttribute("height", "20");
-
-		var rect1 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect1.setAttribute("x", "5");
-		rect1.setAttribute("y", "5");
-		rect1.setAttribute("width", "10");
-		rect1.setAttribute("height", "10");
-		rect1.setAttribute("fill", "red");
-
-		var rect2 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-		rect2.setAttribute("x", "10");
-		rect2.setAttribute("y", "10");
-		rect2.setAttribute("width", "10");
-		rect2.setAttribute("height", "10");
-		rect2.setAttribute("fill", "green");
-
-		pattern.appendChild(rect1);
-		pattern.appendChild(rect2);
-
-		content.appendChild(pattern);
-	}
+    var content = document.getElementById("content");
+
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+
+    setTimeout(createPattern, 0);
+
+    function createPattern()
+    {
+        var pattern = document.createElementNS("http://www.w3.org/2000/svg", "pattern");
+        pattern.setAttribute("id", "dynPattern");
+        pattern.setAttribute("patternUnits", "userSpaceOnUse");
+        pattern.setAttribute("x", "0");
+        pattern.setAttribute("y", "0");
+        pattern.setAttribute("width", "20");
+        pattern.setAttribute("height", "20");
+
+        var rect1 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect1.setAttribute("x", "5");
+        rect1.setAttribute("y", "5");
+        rect1.setAttribute("width", "10");
+        rect1.setAttribute("height", "10");
+        rect1.setAttribute("fill", "red");
+
+        var rect2 = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rect2.setAttribute("x", "10");
+        rect2.setAttribute("y", "10");
+        rect2.setAttribute("width", "10");
+        rect2.setAttribute("height", "10");
+        rect2.setAttribute("fill", "green");
+
+        pattern.appendChild(rect1);
+        pattern.appendChild(rect2);
+
+        content.appendChild(pattern);
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
 </script>
 
 </svg>
diff --git a/LayoutTests/svg/custom/recursive-clippath.svg b/LayoutTests/svg/custom/recursive-clippath.svg
index b568921..9a6642d 100644
--- a/LayoutTests/svg/custom/recursive-clippath.svg
+++ b/LayoutTests/svg/custom/recursive-clippath.svg
@@ -1,10 +1,10 @@
 <svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
 <defs>
     <clipPath id='clipPath_0'>
-        <rect x='0' y='0' width='100' height='100' fill='none' clip-path='url(#clipPath_0)'/>
+        <rect x='50' y='0' width='50' height='50' fill='none' clip-path='url(#clipPath_0)'/>
     </clipPath>
 
-    <rect x='0' y='100' width='100' height='100' id="rect" fill='none' clip-path='url(#clipPath_1)'/>
+    <rect x='50' y='150' width='50' height='50' id="rect" fill='none' clip-path='url(#clipPath_1)'/>
     <clipPath id='clipPath_1'>
         <use xlink:href="#rect"/>
     </clipPath>
@@ -13,14 +13,22 @@
 <!--
 Spec: clip-path: If the IRI reference is not valid (e.g it points to an object that doesn't exist or the object
                  is not a ‘clipPath’ element) the ‘clip-path’ property must be treated as if it hadn't been specified.
-
-      Our view is that an clipPath containing a cycle is not valid, and thus should be ignored.
-      But the object that references the clipPath should still be drawn.
 -->
 
-<rect x='0' y='0' width='200' height='200' fill='red'/>
-<rect x='0' y='0' width='200' height='200' fill='green' clip-path='url(#clipPath_0)'/>
+<rect x='50' y='0' width='100' height='100' fill='blue'/>
+<rect x='50' y='0' width='100' height='100' fill='green' clip-path='url(#clipPath_0)'/>
+
+<rect x='50' y='150' width='100' height='100' fill='blue'/>
+<rect x='50' y='150' width='100' height='100' fill='green' clip-path='url(#clipPath_1)'/>
+
+<line x1="175" x2="175" y1="0" y2="250" stroke="red"/>
+<text text-anchor="middle" x="175" y="300">Both sides of the red line should look identical</text>
 
-<rect x='0' y='100' width='200' height='200' fill='red'/>
-<rect x='0' y='100' width='200' height='200' fill='green' clip-path='url(#clipPath_1)'/>
+<!-- This is the reference rendering -->
+<g transform="translate(150,0)">
+    <rect x="50" y="0" width="100" height="100" fill="blue"/>
+    <rect x="50" y="0" width="50" height="50" fill="green"/>
+    <rect x="50" y="150" width="100" height="100" fill="blue"/>
+    <rect x="50" y="150" width="50" height="50" fill="green"/>
+</g>
 </svg>
diff --git a/LayoutTests/svg/custom/recursive-filter.svg b/LayoutTests/svg/custom/recursive-filter.svg
index 7b4e617..7cfa6c9 100644
--- a/LayoutTests/svg/custom/recursive-filter.svg
+++ b/LayoutTests/svg/custom/recursive-filter.svg
@@ -1,15 +1,28 @@
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
+    <filter id="filter0">
+        <feGaussianBlur stdDeviation="4"/>
+    </filter>
+
     <filter id="filter1" filter="url(#filter1)">
         <feGaussianBlur stdDeviation="4"/>
     </filter>
 
+    <!-- WebKit currently does not implement filter chaining -->
     <filter id="filter2" xlink:href="#filter2"/>
 </defs>
 
 <!-- This should be blurred -->
-<rect x="0" y="0" width="100" height="100" filter="url(#filter1)" fill="blue" stroke="green"/>
+<rect x="50" y="0" width="100" height="100" filter="url(#filter1)" fill="blue"/>
+
+<!-- This should not render anything -->
+<rect x="50" y="150" width="100" height="100" filter="url(#filter2)" fill="blue"/>
+
+<line x1="175" x2="175" y1="0" y2="250" stroke="red"/>
+<text text-anchor="middle" x="175" y="300">Both sides of the red line should look identical</text>
 
-<!-- This should not crash and not render anything -->
-<rect x="0" y="100" width="100" height="100" filter="url(#filter2)" fill="blue" stroke="green"/>
+<!-- This is the reference rendering -->
+<g transform="translate(150,0)">
+    <rect x="50" y="0" width="100" height="100" filter="url(#filter0)" fill="blue"/>
+</g>
 </svg>
diff --git a/LayoutTests/svg/custom/recursive-gradient.svg b/LayoutTests/svg/custom/recursive-gradient.svg
index c8b482a..c6f97a7 100644
--- a/LayoutTests/svg/custom/recursive-gradient.svg
+++ b/LayoutTests/svg/custom/recursive-gradient.svg
@@ -1,15 +1,36 @@
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
+    <radialGradient id="gradient0" gradientUnits="objectBoundingBox" cx=".5" cy=".5" fx=".5" fy=".5" r=".5">
+        <stop stop-color="blue" offset="0"/>
+        <stop stop-color="red" offset="1"/>
+    </radialGradient>
+
     <radialGradient xlink:href="#gradient1" id="gradient1" gradientUnits="objectBoundingBox" cx=".5" cy=".5" fx=".5" fy=".5" r=".5">
         <stop stop-color="blue" offset="0"/>
         <stop stop-color="red" offset="1"/>
     </radialGradient>
-    <radialGradient id="gradient2" xlink:href="#gradient3"/>
+
+    <radialGradient id="gradient2" xlink:href="#gradient4"/>
+    <radialGradient id="gradient4" xlink:href="#gradient2"/>
     <radialGradient id="gradient3" xlink:href="#gradient2"/>
 </defs>
 
-<!-- This should not crash -->
+<!-- This should render with a gradient -->
 <rect x="0" y="0" width="100" height="100" fill="url(#gradient1)" stroke="green"/>
+
+<!-- This should not render anything -->
 <rect x="100" y="0" width="100" height="100" fill="url(#gradient2)" stroke="green"/>
+
+<!-- This should not render anything -->
 <rect x="0" y="100" width="100" height="100" fill="url(#gradient3)" stroke="green"/>
+
+<line x1="225" x2="225" y1="0" y2="200" stroke="red"/>
+<text text-anchor="middle" x="225" y="250">Both sides of the red line should look identical</text>
+
+<!-- This is the reference rendering -->
+<g transform="translate(250,0)">
+    <rect x="0" y="0" width="100" height="100" fill="url(#gradient0)" stroke="green"/>
+    <rect x="100" y="0" width="100" height="100" fill="none" stroke="green"/>
+    <rect x="0" y="100" width="100" height="100" fill="none" stroke="green"/>
+</g>
 </svg>
diff --git a/LayoutTests/svg/custom/recursive-mask.svg b/LayoutTests/svg/custom/recursive-mask.svg
index f3035b1..53ac3ee 100644
--- a/LayoutTests/svg/custom/recursive-mask.svg
+++ b/LayoutTests/svg/custom/recursive-mask.svg
@@ -13,21 +13,31 @@
         <rect x="100" y="100" width="50" height="50" fill="white" mask="url(#mask2)"/>
     </mask>
 
-    <rect id="rect" x="0" y="200" width="50" height="50" fill="white" mask="url(#mask4)"/>
+    <rect id="rect" x="0" y="100" width="50" height="50" fill="white" mask="url(#mask4)"/>
     <mask id="mask4">
         <use xlink:href="#rect"/>
     </mask>
 </defs>
 
-<!-- This should be masked, resulting in a 50x50 rect -->
-<rect x="0" y="0" width="100" height="100" fill="blue" mask="url(#mask1)" stroke="green"/>
+<!-- This should result in a 50x50 rect -->
+<rect x="0" y="0" width="100" height="100" fill="blue" mask="url(#mask1)"/>
 
-<!-- This should not render anything -->
-<rect x="100" y="0" width="100" height="100" fill="blue" mask="url(#mask2)" stroke="green"/>
+<!-- This should result in a 50x50 rect -->
+<rect x="100" y="0" width="100" height="100" fill="blue" mask="url(#mask2)"/>
 
-<!-- This should not render anything -->
-<rect x="100" y="100" width="100" height="100" fill="blue" mask="url(#mask3)" stroke="green"/>
+<!-- This should not render -->
+<rect x="100" y="100" width="100" height="100" fill="blue" mask="url(#mask3)"/>
 
-<!-- This should not render anything -->
-<rect x="0" y="200" width="100" height="100" fill="blue" mask="url(#mask4)" stroke="green"/>
+<!-- This should result in a 50x50 rect -->
+<rect x="0" y="100" width="100" height="100" fill="blue" mask="url(#mask4)"/>
+
+<line x1="175" x2="175" y1="0" y2="150" stroke="red"/>
+<text text-anchor="middle" x="175" y="200">Both sides of the red line should look identical</text>
+
+<!-- This is the reference rendering -->
+<g transform="translate(200,0)">
+    <rect x="0" y="0" width="50" height="50" fill="blue"/>
+    <rect x="100" y="0" width="50" height="50" fill="blue"/>
+    <rect x="0" y="100" width="50" height="50" fill="blue"/>
+</g>
 </svg>
diff --git a/LayoutTests/svg/custom/recursive-pattern.svg b/LayoutTests/svg/custom/recursive-pattern.svg
index 7ebd4e9..0830f8b 100644
--- a/LayoutTests/svg/custom/recursive-pattern.svg
+++ b/LayoutTests/svg/custom/recursive-pattern.svg
@@ -1,40 +1,72 @@
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
-    <pattern id="pattern1" x="0" y="0" width="100" height="100">
-        <rect x="0" y="0" width="100" height="100" fill="url(#pattern1)"/>
+    <pattern patternUnits="userSpaceOnUse" id="pattern0" x="0" y="0" width="100" height="100">
+        <rect x="0" y="0" width="50" height="50" fill="black"/>
+        <rect x="50" y="50" width="100" height="100" fill="green"/>
     </pattern>
 
-    <pattern id="pattern2" x="0" y="0" width="100" height="100">
-        <rect x="0" y="0" width="100" height="100" fill="url(#pattern1)"/>
+    <pattern patternUnits="userSpaceOnUse" id="pattern1" x="0" y="0" width="100" height="100">
+        <rect x="0" y="0" width="50" height="50" fill="url(#pattern1)"/>
+        <rect x="50" y="50" width="100" height="100" fill="green"/>
+    </pattern>
+
+    <pattern patternUnits="userSpaceOnUse" id="pattern2" x="0" y="0" width="100" height="100">
+        <rect x="50" y="50" width="100" height="100" fill="green"/>
+        <rect x="0" y="0" width="50" height="50" fill="url(#pattern1)"/>
     </pattern>
 
     <pattern id="pattern3" x="0" y="0" width="100" height="100" xlink:href="#pattern1"/>
     <pattern id="pattern4" x="0" y="0" width="100" height="100" xlink:href="#pattern2"/>
 
     <pattern id="pattern6" xlink:href="#pattern5"/>
-    <pattern id="pattern5" x="0" y="0" width="100" height="100">
-        <rect x="0" y="0" width="100" height="100" fill="url(#pattern6)"/>
+    <pattern patternUnits="userSpaceOnUse"  id="pattern5" x="0" y="0" width="100" height="100">
+        <rect x="0" y="0" width="50" height="50" fill="url(#pattern6)"/>
+        <rect x="50" y="50" width="100" height="100" fill="green"/>
     </pattern>
 
-    <rect id="rect" x="0" y="0" width="100" height="100" fill="url(#pattern7)"/>
-    <pattern id="pattern7" x="0" y="0" width="100" height="100">
+    <rect id="rect" x="0" y="0" width="50" height="50" fill="url(#pattern7)"/>
+    <pattern patternUnits="userSpaceOnUse" id="pattern7" x="0" y="0" width="100" height="100">
         <use xlink:href="#rect"/>
+        <rect id="reuse" x="50" y="50" width="100" height="100" fill="green"/>
     </pattern>
     
-	<rect id="rect2" x="0" y="0" width="100" height="100" fill="url(#pattern8)"/>
-	<use id="use" xlink:href="#rect2"/>
-    <pattern id="pattern8" x="0" y="0" width="100" height="100">
-        <use xlink:href="#use"/>
+    <rect id="rect2" x="0" y="0" width="50" height="50" fill="url(#pattern8)"/>
+    <use id="use" xlink:href="#rect2"/>
+    <pattern patternUnits="userSpaceOnUse" id="pattern8" x="0" y="0" width="100" height="100">
+        <g id="reuse2">
+            <use xlink:href="#reuse"/>
+            <use xlink:href="#use"/>
+        </g>
+    </pattern>
+
+    <pattern patternUnits="userSpaceOnUse" id="pattern9" x="0" y="0" width="100" height="100">
+        <use xlink:href="#reuse2"/>
     </pattern>
 </defs>
 
-<!-- This should not crash -->
-<rect x="0" y="0" width="100" height="100" fill="url(#pattern1)" stroke="green"/>
-<rect x="0" y="100" width="100" height="100" fill="url(#pattern2)" stroke="green"/>
-<rect x="100" y="0" width="100" height="100" fill="url(#pattern3)" stroke="green"/>
-<rect x="100" y="100" width="100" height="100" fill="url(#pattern4)" stroke="green"/>
-<rect x="0" y="200" width="100" height="100" fill="url(#pattern5)" stroke="green"/>
-<rect x="100" y="200" width="100" height="100" fill="url(#pattern6)" stroke="green"/>
-<rect x="0" y="300" width="100" height="100" fill="url(#pattern7)" stroke="green"/>
-<rect x="100" y="300" width="100" height="100" fill="url(#pattern8)" stroke="green"/>
+<rect x="0" y="0" width="100" height="100" fill="url(#pattern1)"/>
+<rect x="100" y="0" width="100" height="100" fill="url(#pattern2)"/>
+<rect x="200" y="0" width="100" height="100" fill="url(#pattern3)"/>
+<rect x="0" y="100" width="100" height="100" fill="url(#pattern4)"/>
+<rect x="100" y="100" width="100" height="100" fill="url(#pattern5)"/>
+<rect x="200" y="100" width="100" height="100" fill="url(#pattern6)"/>
+<rect x="0" y="200" width="100" height="100" fill="url(#pattern7)"/>
+<rect x="100" y="200" width="100" height="100" fill="url(#pattern8)"/>
+<rect x="200" y="200" width="100" height="100" fill="url(#pattern9)"/>
+
+<line x1="325" x2="325" y1="0" y2="300" stroke="red"/>
+<text text-anchor="middle" x="325" y="350">Both sides of the red line should look identical</text>
+
+<!-- This is the reference rendering -->
+<g transform="translate(350,0)">
+    <rect x="0" y="0" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="100" y="0" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="200" y="0" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="0" y="100" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="100" y="100" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="200" y="100" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="0" y="200" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="100" y="200" width="100" height="100" fill="url(#pattern0)"/>
+    <rect x="200" y="200" width="100" height="100" fill="url(#pattern0)"/>
+</g>
 </svg>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e6c7ba1..6ed2ae4 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,224 @@
+2010-07-29  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        WebKit shouldn't ignore resource cycles, but break them as Opera does
+        https://bugs.webkit.org/show_bug.cgi?id=43031
+
+        mask images are not updated when render objects' bounds change
+        https://bugs.webkit.org/show_bug.cgi?id=15124
+
+        SVG Gradients do not resize correctly
+        https://bugs.webkit.org/show_bug.cgi?id=41902
+
+        svg/dynamic-updates: SVGMarkerElement markerHeight/Width tests are broken
+        https://bugs.webkit.org/show_bug.cgi?id=42616
+
+        svg/dynamic-updates: SVGMaskElement tests are all broken
+        https://bugs.webkit.org/show_bug.cgi?id=42617
+
+        Don't ignore resources containing cyclic references, but break them, as discussed on SVG WG mailing lists - to be compatible with Opera which already does that.
+
+        We used to lookup RenderSVGResourceContainers objects, by extracting the URI reference from the SVGRenderStyle, then utilizing getElementById() to lookup the
+        node, and access its renderer. Opera ignores such references, if they point to resources that contain cyclic references. Ignoring them would mean we have
+        to mutate the render style to empty the resource strings. That obviously doesn't work, as it would break expectations (getComputedStyle, etc.).
+
+        Introduce a SVGResources class that stores pointers to all resources, that can be applied to a RenderObject (clipper/filter/markers/masker).
+        Add a SVGResourcesCache class, which is basically a HashMap<RenderObject*, SVGResources*>. Whenever a RenderObject receives style, we extract the URI references
+        from the SVGRenderStyle, look up the RenderSVGResourceContainer* objects, and store them in a SVGResources* class. Then we execute a cycle detection logic,
+        which detects cyclic references and breaks them. Breaking them means just nulling the pointer to the resource in the SVGResources object. Those SVGResources
+        objects are cached, and used throughout the render tree to access resources. This way it's guaranteed that all cyclic references are resolved until layout/paint
+        phase begins.
+
+        Add destroy/styleDidChange/updateFromElement methods to all SVG renderers, in order to keep track of resource/client changes in the SVGResourcesCache.
+        As side-effect the SVGResourcesCache now knows which RenderObject references which resource, and thus can handle client registration for a RenderSVGResourceContainer.
+        The RenderSVGResourceContainer now holds a HashSet of RenderObjects, that's always up2date, and not related to the fact wheter a resources has already been used
+        for painting. The old logic missed to register clients for a resource, when the resource was in an invalid state. Fixing that fixes the svg/dynamic-updates/SVGMaskElement* tests.
+
+        Rewrite all svg/custom/recursive-(filter|gradient|mask|pattern).svg tests to contain a reference image how it should be renderered. All 1:1 compatible with Opera now.
+
+        * rendering/RenderForeignObject.cpp:
+        (WebCore::RenderForeignObject::layout): Grab selfNeedsLayout() before calling RenderBlock::layout(), otherwhise it's always false.
+        * rendering/RenderPath.cpp: Don't look up resources manually, use SVGResourcesCache.
+        (WebCore::RenderPath::fillContains): Remove constness, to avoid the need to pass around const RenderObjects* to the SVGResourcesCache.
+        (WebCore::RenderPath::strokeContains): Ditto.
+        (WebCore::RenderPath::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
+        (WebCore::RenderPath::calculateMarkerBoundsIfNeeded): Remove special client handling for markers, it's all unified now.
+        (WebCore::RenderPath::styleWillChange): Only call setNeedsBoundariesUpdate when handling StyleDifferenceRepaint/Layout.
+        * rendering/RenderPath.h:
+        * rendering/RenderSVGBlock.cpp:
+        (WebCore::RenderSVGBlock::destroy): Forward to SVGResourcesCache::clientDestroyed.
+        (WebCore::RenderSVGBlock::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
+        (WebCore::RenderSVGBlock::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
+        * rendering/RenderSVGBlock.h:
+        * rendering/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
+        (WebCore::RenderSVGContainer::selfWillPaint): Don't look up resources manually, use SVGResourcesCache.
+        * rendering/RenderSVGContainer.h:
+        * rendering/RenderSVGGradientStop.cpp:
+        (WebCore::RenderSVGGradientStop::styleDidChange): Rewrite, as invalidateResourceClients() is gone.
+        * rendering/RenderSVGHiddenContainer.h: Make layout() protected, as RenderSVGResourceContainer overrides it.
+        * rendering/RenderSVGImage.cpp:
+        (WebCore::RenderSVGImage::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
+        (WebCore::RenderSVGImage::destroy): Forward to SVGResourcesCache::clientDestroyed.
+        (WebCore::RenderSVGImage::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
+        (WebCore::RenderSVGImage::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
+        (WebCore::RenderSVGImage::imageChanged): Don't look up resources manually, use SVGResourcesCache.
+        * rendering/RenderSVGImage.h:
+        * rendering/RenderSVGInline.cpp:
+        (WebCore::RenderSVGInline::destroy): Forward to SVGResourcesCache::clientDestroyed.
+        (WebCore::RenderSVGInline::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
+        (WebCore::RenderSVGInline::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
+        * rendering/RenderSVGInline.h:
+        * rendering/RenderSVGModelObject.cpp:
+        (WebCore::RenderSVGModelObject::destroy): Forward to SVGResourcesCache::clientDestroyed.
+        (WebCore::RenderSVGModelObject::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
+        (WebCore::RenderSVGModelObject::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
+        * rendering/RenderSVGModelObject.h:
+        * rendering/RenderSVGResource.cpp:
+        (WebCore::RenderSVGResource::fillPaintingResource): Remove const from RenderObject parameter.
+        (WebCore::RenderSVGResource::strokePaintingResource): Ditto.
+        (WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): Early exit if we found the first parent resource.
+        * rendering/RenderSVGResource.h:
+        * rendering/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::~RenderSVGResourceClipper): Early exit if m_clipper is empty.
+        (WebCore::RenderSVGResourceClipper::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourceClipper::invalidateClient): Ditto.
+        (WebCore::RenderSVGResourceClipper::applyResource): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
+        (WebCore::RenderSVGResourceClipper::createClipData): Don't look up resources manually, use SVGResourcesCache.
+        (WebCore::RenderSVGResourceClipper::hitTestClipContent): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
+        * rendering/RenderSVGResourceClipper.h:
+        * rendering/RenderSVGResourceContainer.cpp:
+        (WebCore::svgExtensionsFromNode):
+        (WebCore::RenderSVGResourceContainer::RenderSVGResourceContainer): Stop registering resource from the constructor, delegate to styleDidChange.
+        (WebCore::RenderSVGResourceContainer::~RenderSVGResourceContainer): Only deregister resource if it was ever registered.
+        (WebCore::RenderSVGResourceContainer::layout): invalidateClients() here, to avoid the need for invalidateResourceClients() in the SVG DOM. Just call setNeedsLayout() from the SVG DOM.
+        (WebCore::RenderSVGResourceContainer::destroy): Forward to SVGResourcesCache::resourceDestroyed.
+        (WebCore::RenderSVGResourceContainer::styleDidChange): Register resource not in the constructor but when it first receives style.
+        (WebCore::RenderSVGResourceContainer::idChanged): Don't duplicate code, use existing methods from SVGResourcesCache.
+        (WebCore::RenderSVGResourceContainer::markAllClientsForInvalidation): Add new helper function, to share code between all resources.
+        (WebCore::RenderSVGResourceContainer::markClientForInvalidation): Ditto.
+        (WebCore::RenderSVGResourceContainer::addClient): SVGResourcesCache now manages the list of clients. It calls addClient() for each RenderObject that uses this resource.
+        (WebCore::RenderSVGResourceContainer::removeClient): SVGResourcesCache now manages the list of clients.
+        (WebCore::RenderSVGResourceContainer::registerResource): New helper function sharing code between idChanged / styleDidChange.
+        (WebCore::RenderSVGResourceContainer::transformOnNonScalingStroke): Add FIXME that the function is misplaced.
+        * rendering/RenderSVGResourceContainer.h: Move most functions to the new RenderSVGResourceContainer.cpp file.
+        * rendering/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::~RenderSVGResourceFilter): Early exit if m_filter is empty.
+        (WebCore::RenderSVGResourceFilter::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourceFilter::invalidateClient): Ditto.
+        * rendering/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::~RenderSVGResourceGradient): Early exit if m_gradient is empty.
+        (WebCore::RenderSVGResourceGradient::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourceGradient::invalidateClient): Ditto.
+        * rendering/RenderSVGResourceMarker.cpp:
+        (WebCore::RenderSVGResourceMarker::~RenderSVGResourceMarker): Now a no-op, markers are unified within the new client handling concept, no more special code needed.
+        (WebCore::RenderSVGResourceMarker::layout): As RenderSVGResourceMarker skips the RenderSVGResourceContainer::layout() method, we also need to call invalidateClients() here.
+        (WebCore::RenderSVGResourceMarker::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourceMarker::invalidateClient): Ditto.
+        (WebCore::RenderSVGResourceMarker::draw): Remove marker specific logic to catch circular references.
+        * rendering/RenderSVGResourceMarker.h:
+        * rendering/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::~RenderSVGResourceMasker): Early exit if m_masker is empty.
+        (WebCore::RenderSVGResourceMasker::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourceMasker::invalidateClient): Ditto.
+        (WebCore::RenderSVGResourceMasker::applyResource): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
+        * rendering/RenderSVGResourceMasker.h:
+        * rendering/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::~RenderSVGResourcePattern): Early exit if m_pattern is empty.
+        (WebCore::RenderSVGResourcePattern::invalidateClients): Use new helper functions to invalidate clients, shared between all resources in RenderSVGResourceContainer.
+        (WebCore::RenderSVGResourcePattern::invalidateClient): Ditto.
+        (WebCore::RenderSVGResourcePattern::createTileImage): Remove containsCyclicReference() check, SVGResourcesCycleSolver breaks cyclic references, resources do not need to take care anymore.
+        * rendering/RenderSVGResourcePattern.h:
+        * rendering/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::selfWillPaint): Don't look up resources manually, use SVGResourcesCache.
+        (WebCore::RenderSVGRoot::destroy): Forward to SVGResourcesCache::clientDestroyed.
+        (WebCore::RenderSVGRoot::styleDidChange): Forward to SVGResourcesCache::clientStyleChanged.
+        (WebCore::RenderSVGRoot::updateFromElement): Forward to SVGResourcesCache::clientUpdatedFromElement.
+        * rendering/RenderSVGRoot.h:
+        * rendering/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::layout): s/RenderSVGResource::invalidateAllResourcesOfRenderer/SVGResourcesCache::clientLayoutChanged/.
+        * rendering/RenderSVGText.h:
+        * rendering/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::acquirePaintingResource): Add RenderObject* parameter, don't assume the style comes from the InlineTextBox parent renderer.
+        (WebCore::SVGInlineTextBox::prepareGraphicsContextForTextPainting): Pass the parent()->renderer() to acquirePaintingResource.
+        (WebCore::SVGInlineTextBox::paintDecoration): Pass the decoration renderer to acquirePaintingResource.
+        (WebCore::SVGInlineTextBox::paintDecorationWithStyle): Ditto.
+        (WebCore::SVGInlineTextBox::paintText): When a selection pseudo style is used to paint the selection, swap styles in the SVGResourcesCache, to take the right resources when painting.
+        * rendering/SVGInlineTextBox.h:
+        * rendering/SVGRenderSupport.cpp:
+        (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Don't look up resources manually, use SVGResourcesCache.
+        (WebCore::SVGRenderSupport::finishRenderSVGContent): Ditto.
+        (WebCore::SVGRenderSupport::intersectRepaintRectWithResources): Ditto.
+        (WebCore::SVGRenderSupport::pointInClippingArea): Remove const from RenderObject parameter. 
+        * rendering/SVGRenderSupport.h:
+        * rendering/SVGRenderTreeAsText.cpp:
+        (WebCore::writeStyle): Add two const_cast now that fill/strokePaintingResource take RenderObject* parameters. This was the less intrusive approach, otherwhise more const_casts would be needed.
+        (WebCore::writeResources): Add FIXME that we should dump the resources present in the SVGResourcesCache instead of manually looking them up from the SVGRenderStyle, to avoid dumping cycles.
+        * rendering/SVGResourcesCache.cpp:
+        (WebCore::SVGResourcesCache::clientStyleChanged): Use markForLayoutAndParentResourceInvalidation() instead of duplicating code.
+        * rendering/SVGResourcesCycleSolver.cpp:
+        (WebCore::setFollowLinkForChainableResource): Implemented stub method.
+        * rendering/style/SVGRenderStyle.cpp:
+        (WebCore::SVGRenderStyle::diff): Return StyleDifferenceLayout, not Repaint for stroke paint changes, otherwhise the cached boundaries are not correctly updated.
+        * svg/SVGClipPathElement.cpp:
+        (WebCore::SVGClipPathElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGClipPathElement::childrenChanged): Ditto.
+        * svg/SVGClipPathElement.h:
+        (WebCore::SVGClipPathElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::insertedIntoDocument): Only execute buildPendingResource() logic, if needsPendingResourceHandling() returns true. Cleaned up code a bit, to deploy early returns.
+        * svg/SVGElement.h:
+        (WebCore::SVGElement::needsPendingResourceHandling): Return true (default). Only needed by SVGTextPathElement/SVGUseElement, and should be removed in future.
+        * svg/SVGFilterElement.cpp:
+        (WebCore::SVGFilterElement::SVGFilterElement): Initialize m_followLink=true.
+        (WebCore::SVGFilterElement::setFilterRes): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGFilterElement::svgAttributeChanged): Ditto.
+        (WebCore::SVGFilterElement::childrenChanged): Ditto.
+        * svg/SVGFilterElement.h:
+        (WebCore::SVGFilterElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        (WebCore::SVGFilterElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
+        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::childrenChanged): Don't use invalidateResourceClients(), it's a no-op as effects don't have a renderer -> use invalidateFilter().
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::invalidateFilter): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        * svg/SVGGradientElement.cpp:
+        (WebCore::SVGGradientElement::SVGGradientElement): Initialize m_followLink=true.
+        (WebCore::SVGGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGGradientElement::childrenChanged): Ditto.
+        * svg/SVGGradientElement.h:
+        (WebCore::SVGGradientElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        (WebCore::SVGGradientElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGLinearGradientElement::collectGradientProperties): Only follow xlink:href links if m_followLinks == true.
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGMarkerElement::childrenChanged): Ditto.
+        (WebCore::SVGMarkerElement::setOrientToAuto): Ditto.
+        (WebCore::SVGMarkerElement::setOrientToAngle): Ditto.
+        * svg/SVGMarkerElement.h:
+        (WebCore::SVGMarkerElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGMaskElement::childrenChanged): Ditto.
+        * svg/SVGMaskElement.h:
+        (WebCore::SVGMaskElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        * svg/SVGPatternElement.cpp:
+        (WebCore::SVGPatternElement::SVGPatternElement): Initialize m_followLink=true.
+        (WebCore::SVGPatternElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGPatternElement::childrenChanged): Ditto.
+        (WebCore::SVGPatternElement::collectPatternProperties): Only follow xlink:href links if m_followLinks == true.
+        * svg/SVGPatternElement.h:
+        (WebCore::SVGPatternElement::needsPendingResourceHandling): Return false, buildPendingResource() logic not needed anymore for resources, handled by RenderSVGResourceContainer.
+        (WebCore::SVGPatternElement::setFollowLink): Used by SVGResourcesCycleSolver, to stop following xlink:href links, if that leads to cyclic references.
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::svgAttributeChanged): Don't use invalidateResourceClients(), it's not needed anymore, only call setNeedsLayout() on the renderer.
+        (WebCore::SVGRadialGradientElement::collectGradientProperties): Only follow xlink:href links if m_followLinks == true.
+        * svg/SVGStyledElement.cpp:
+        (WebCore::SVGStyledElement::attach): Call updateFromElement upon attach(), needed by all resource renderers. Defaults to a no-op in RenderObject.h
+        * svg/SVGStyledElement.h: Remove invalidateResourceClients(), it's not needed anymore.
+
 2010-07-29  Gyuyoung Kim  <gyuyoung.kim at samsung.com>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 8b84f97..50c1a42 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -117,14 +117,16 @@ void RenderForeignObject::layout()
 
     // FIXME: Investigate in location rounding issues - only affects RenderForeignObject & RenderSVGText
     setLocation(roundedIntPoint(viewportLocation));
+
+    bool layoutChanged = m_everHadLayout && selfNeedsLayout();
     RenderBlock::layout();
+    ASSERT(!needsLayout());
 
-    // Invalidate all resources of this client, if we changed something.
-    if (m_everHadLayout && selfNeedsLayout())
-        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+    // Invalidate all resources of this client if our layout changed.
+    if (layoutChanged)
+        SVGResourcesCache::clientLayoutChanged(this);
 
     repainter.repaintAfterLayout();
-    setNeedsLayout(false);
 }
 
 bool RenderForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index dd79397..915be5d 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -35,11 +35,12 @@
 #include "PointerEventsHitRules.h"
 #include "RenderSVGContainer.h"
 #include "RenderSVGResourceMarker.h"
-#include "StrokeStyleApplier.h"
 #include "SVGRenderSupport.h"
+#include "SVGResources.h"
 #include "SVGStyledTransformableElement.h"
 #include "SVGTransformList.h"
 #include "SVGURIReference.h"
+#include "StrokeStyleApplier.h"
 #include <wtf/MathExtras.h>
 
 namespace WebCore {
@@ -72,7 +73,7 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
 {
 }
 
-bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule) const
+bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule)
 {
     if (!m_fillBoundingBox.contains(point))
         return false;
@@ -83,7 +84,7 @@ bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRu
     return m_path.contains(point, fillRule);
 }
 
-bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
+bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke)
 {
     if (!m_strokeAndMarkerBoundingBox.contains(point))
         return false;
@@ -111,9 +112,9 @@ void RenderPath::layout()
         m_needsTransformUpdate = false;
     }
 
-    // Invalidate all resources of this client, if we changed something.
+    // Invalidate all resources of this client if our layout changed.
     if (m_everHadLayout && selfNeedsLayout())
-        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+        SVGResourcesCache::clientLayoutChanged(this);
 
     // At this point LayoutRepainter already grabbed the old bounds,
     // recalculate them now so repaintAfterLayout() uses the new bounds
@@ -234,8 +235,6 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult&
 
 FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
 {
-    Document* doc = document();
-
     SVGElement* svgElement = static_cast<SVGElement*>(node());
     ASSERT(svgElement && svgElement->document());
     if (!svgElement->isStyled())
@@ -248,39 +247,24 @@ FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
     const SVGRenderStyle* svgStyle = style()->svgStyle();
     ASSERT(svgStyle->hasMarkers());
 
-    AtomicString startMarkerId(svgStyle->markerStartResource());
-    AtomicString midMarkerId(svgStyle->markerMidResource());
-    AtomicString endMarkerId(svgStyle->markerEndResource());
-
-    RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, startMarkerId);
-    RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, midMarkerId);
-    RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, endMarkerId);
-
-    if (!startMarker && !startMarkerId.isEmpty())
-        svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement);
-    else if (startMarker)
-        startMarker->addClient(this);
-
-    if (!midMarker && !midMarkerId.isEmpty())
-        svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement);
-    else if (midMarker)
-        midMarker->addClient(this);
-
-    if (!endMarker && !endMarkerId.isEmpty())
-        svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement);
-    else if (endMarker)
-        endMarker->addClient(this);
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+    if (!resources)
+        return FloatRect();
 
-    if (!startMarker && !midMarker && !endMarker)
+    RenderSVGResourceMarker* markerStart = resources->markerStart();
+    RenderSVGResourceMarker* markerMid = resources->markerMid();
+    RenderSVGResourceMarker* markerEnd = resources->markerEnd();
+    if (!markerStart && !markerMid && !markerEnd)
         return FloatRect();
 
     float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f);
-    return m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
+    return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, strokeWidth, m_path);
 }
 
 void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
 {
-    setNeedsBoundariesUpdate();
+    if (diff == StyleDifferenceLayout)
+        setNeedsBoundariesUpdate();
     RenderSVGModelObject::styleWillChange(diff, newStyle);
 }
 
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 3748f39..57900ad 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -47,8 +47,8 @@ public:
 
 private:
     // Hit-detection seperated for the fill and the stroke
-    bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO) const;
-    bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
+    bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO);
+    bool strokeContains(const FloatPoint&, bool requiresStroke = true);
 
     virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; }
     virtual FloatRect strokeBoundingBox() const { return m_strokeAndMarkerBoundingBox; }
diff --git a/WebCore/rendering/RenderSVGBlock.cpp b/WebCore/rendering/RenderSVGBlock.cpp
index 2bae158..d6022b5 100644
--- a/WebCore/rendering/RenderSVGBlock.cpp
+++ b/WebCore/rendering/RenderSVGBlock.cpp
@@ -25,6 +25,7 @@
 #if ENABLE(SVG)
 #include "RenderSVGBlock.h"
 
+#include "RenderSVGResource.h"
 #include "SVGElement.h"
 
 namespace WebCore {
@@ -73,6 +74,25 @@ void RenderSVGBlock::absoluteRects(Vector<IntRect>&, int, int)
     // This code path should never be taken for SVG, as we're assuming useTransforms=true everywhere, absoluteQuads should be used.
     ASSERT_NOT_REACHED();
 }
+
+void RenderSVGBlock::destroy()
+{
+    SVGResourcesCache::clientDestroyed(this);
+    RenderBlock::destroy();
+}
+
+void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderBlock::styleDidChange(diff, oldStyle);
+    SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGBlock::updateFromElement()
+{
+    RenderBlock::updateFromElement();
+    SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
 }
 
 #endif
diff --git a/WebCore/rendering/RenderSVGBlock.h b/WebCore/rendering/RenderSVGBlock.h
index 8dd140b..c4337cc 100644
--- a/WebCore/rendering/RenderSVGBlock.h
+++ b/WebCore/rendering/RenderSVGBlock.h
@@ -38,6 +38,10 @@ private:
     virtual void updateBoxModelInfoFromStyle();
 
     virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
+
+    virtual void destroy();
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+    virtual void updateFromElement();
 };
 
 }
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index ad63771..5c737ef 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -31,6 +31,7 @@
 #include "RenderSVGResourceFilter.h"
 #include "RenderView.h"
 #include "SVGRenderSupport.h"
+#include "SVGResources.h"
 #include "SVGStyledElement.h"
 
 namespace WebCore {
@@ -58,21 +59,19 @@ void RenderSVGContainer::layout()
 
     SVGRenderSupport::layoutChildren(this, selfNeedsLayout());
 
-    // Invalidate all resources of this client, if we changed something.
+    // Invalidate all resources of this client if our layout changed.
     if (m_everHadLayout && selfNeedsLayout())
-        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+        SVGResourcesCache::clientLayoutChanged(this);
 
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
 }
 
-bool RenderSVGContainer::selfWillPaint() const
+bool RenderSVGContainer::selfWillPaint()
 {
 #if ENABLE(FILTERS)
-    const SVGRenderStyle* svgStyle = style()->svgStyle();
-    RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
-    if (filter)
-        return true;
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+    return resources && resources->filter();
 #endif
     return false;
 }
diff --git a/WebCore/rendering/RenderSVGContainer.h b/WebCore/rendering/RenderSVGContainer.h
index 53f1a97..0a122cd 100644
--- a/WebCore/rendering/RenderSVGContainer.h
+++ b/WebCore/rendering/RenderSVGContainer.h
@@ -69,7 +69,7 @@ protected:
     virtual void applyViewportClip(PaintInfo&) { }
     virtual bool pointIsInsideViewportClip(const FloatPoint& /*pointInParent*/) { return true; }
 
-    bool selfWillPaint() const;
+    bool selfWillPaint();
 
 private:
     RenderObjectChildList m_children;
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index 754f31f..3494aa7 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -25,8 +25,10 @@
 #if ENABLE(SVG)
 #include "RenderSVGGradientStop.h"
 
+#include "RenderSVGResourceContainer.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
+#include "SVGResourcesCache.h"
 #include "SVGStopElement.h"
 
 namespace WebCore {
@@ -48,8 +50,17 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
 
     // <stop> elements should only be allowed to make renderers under gradient elements
     // but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
-    if (SVGGradientElement* gradient = gradientElement())
-        gradient->invalidateResourceClients();
+    SVGGradientElement* gradient = gradientElement();
+    if (!gradient)
+        return;
+
+    RenderObject* renderer = gradient->renderer();
+    if (!renderer)
+        return;
+
+    ASSERT(renderer->isSVGResourceContainer());
+    RenderSVGResourceContainer* container = renderer->toRenderSVGResourceContainer();
+    container->invalidateClients();
 }
 
 void RenderSVGGradientStop::layout()
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.h b/WebCore/rendering/RenderSVGHiddenContainer.h
index 297a738..e0daac1 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -24,7 +24,6 @@
 #define RenderSVGHiddenContainer_h
 
 #if ENABLE(SVG)
-
 #include "RenderSVGContainer.h"
 
 namespace WebCore {
@@ -39,11 +38,13 @@ namespace WebCore {
 
         virtual const char* renderName() const { return "RenderSVGHiddenContainer"; }
 
+    protected:
+        virtual void layout();
+
     private:
         virtual bool isSVGHiddenContainer() const { return true; }
         virtual bool requiresLayer() const { return false; }
 
-        virtual void layout();
         virtual void paint(PaintInfo&, int parentX, int parentY);
         
         virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 44b68b1..5a92e33 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -39,6 +39,7 @@
 #include "SVGLength.h"
 #include "SVGPreserveAspectRatio.h"
 #include "SVGRenderSupport.h"
+#include "SVGResources.h"
 
 namespace WebCore {
 
@@ -70,9 +71,9 @@ void RenderSVGImage::layout()
     m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image));
     m_cachedLocalRepaintRect = FloatRect();
 
-    // Invalidate all resources of this client, if we changed something.
+    // Invalidate all resources of this client if our layout changed.
     if (m_everHadLayout && selfNeedsLayout())
-        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+        SVGResourcesCache::clientLayoutChanged(this);
 
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
@@ -110,10 +111,22 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
 
 void RenderSVGImage::destroy()
 {
-    RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+    SVGResourcesCache::clientDestroyed(this);
     RenderImage::destroy();
 }
 
+void RenderSVGImage::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderImage::styleDidChange(diff, oldStyle);
+    SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGImage::updateFromElement()
+{
+    RenderImage::updateFromElement();
+    SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
 bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
 {
     // We only draw in the forground phase, so we only hit-test then.
@@ -160,12 +173,12 @@ FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
 void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
 {
     RenderImage::imageChanged(image, rect);
-#if ENABLE(FILTERS)
+
     // The image resource defaults to nullImage until the resource arrives.
-    // This empty image may be cached by SVG filter effects which must be invalidated.
-    if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), style()->svgStyle()->filterResource()))
-        filter->invalidateClient(this);
-#endif
+    // This empty image may be cached by SVG resources which must be invalidated.
+    if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this))
+        resources->invalidateClient(this);
+
     repaint();
 }
 
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 3baac23..6ee0179 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -65,6 +65,8 @@ private:
     virtual void paint(PaintInfo&, int parentX, int parentY);
 
     virtual void destroy();
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+    virtual void updateFromElement();
 
     virtual bool requiresLayer() const { return false; }
 
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index ffc6b62..93e6a06 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -26,6 +26,7 @@
 #if ENABLE(SVG)
 #include "RenderSVGInline.h"
 
+#include "RenderSVGResource.h"
 #include "SVGInlineFlowBox.h"
 
 namespace WebCore {
@@ -92,6 +93,24 @@ void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
         quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->width(), box->height())));
 }
 
+void RenderSVGInline::destroy()
+{
+    SVGResourcesCache::clientDestroyed(this);
+    RenderInline::destroy();
+}
+
+void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderInline::styleDidChange(diff, oldStyle);
+    SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGInline::updateFromElement()
+{
+    RenderInline::updateFromElement();
+    SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
 
 }
 
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index 6f44162..56d911f 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -54,6 +54,10 @@ public:
 
 private:
     virtual InlineFlowBox* createInlineFlowBox();
+
+    virtual void destroy();
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+    virtual void updateFromElement();
 };
 
 }
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index 49404cb..5a19749 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -83,16 +83,20 @@ void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads)
 
 void RenderSVGModelObject::destroy()
 {
-    RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+    SVGResourcesCache::clientDestroyed(this);
     RenderObject::destroy();
 }
 
 void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
     RenderObject::styleDidChange(diff, oldStyle);
+    SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
 
-    if (style() && (diff == StyleDifferenceLayout || diff == StyleDifferenceRepaint))
-        RenderSVGResource::markForLayoutAndParentResourceInvalidation(this, false);
+void RenderSVGModelObject::updateFromElement()
+{
+    RenderObject::updateFromElement();
+    SVGResourcesCache::clientUpdatedFromElement(this, style());
 }
 
 bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index 741cd61..35c4dc3 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -62,6 +62,7 @@ public:
 
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+    virtual void updateFromElement();
 
 private:
     // This method should never be called, SVG uses a different nodeAtPoint method
diff --git a/WebCore/rendering/RenderSVGResource.cpp b/WebCore/rendering/RenderSVGResource.cpp
index b4f499e..9c89d3c 100644
--- a/WebCore/rendering/RenderSVGResource.cpp
+++ b/WebCore/rendering/RenderSVGResource.cpp
@@ -26,28 +26,13 @@
 #if ENABLE(SVG)
 #include "RenderSVGResource.h"
 
-#include "RenderSVGResourceClipper.h"
 #include "RenderSVGResourceContainer.h"
-#include "RenderSVGResourceFilter.h"
-#include "RenderSVGResourceMarker.h"
-#include "RenderSVGResourceMasker.h"
 #include "RenderSVGResourceSolidColor.h"
+#include "SVGResources.h"
 #include "SVGURIReference.h"
 
 namespace WebCore {
 
-static inline void registerPendingResource(const AtomicString& id, const SVGPaint::SVGPaintType& paintType, const RenderObject* object)
-{
-    if (paintType != SVGPaint::SVG_PAINTTYPE_URI)
-        return;
-
-    SVGElement* svgElement = static_cast<SVGElement*>(object->node());
-    ASSERT(svgElement);
-    ASSERT(svgElement->isStyled());
-
-    object->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
-}
-
 inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
 {
     if (style->insideLink() != InsideVisitedLink)
@@ -69,7 +54,7 @@ inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* styl
 }
 
 // FIXME: This method and strokePaintingResource() should be refactored, to share even more code
-RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* object, const RenderStyle* style)
+RenderSVGResource* RenderSVGResource::fillPaintingResource(RenderObject* object, const RenderStyle* style)
 {
     ASSERT(object);
     ASSERT(style);
@@ -84,13 +69,9 @@ RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* o
     RenderSVGResource* fillPaintingResource = 0;
 
     SVGPaint::SVGPaintType paintType = fillPaint->paintType();
-    if (paintType == SVGPaint::SVG_PAINTTYPE_URI
-        || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
-        AtomicString id(SVGURIReference::getTarget(fillPaint->uri()));
-        fillPaintingResource = getRenderSVGResourceContainerById(object->document(), id);
-
-        if (!fillPaintingResource)
-            registerPendingResource(id, paintType, object);
+    if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
+        if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object))
+            fillPaintingResource = resources->fill();
     }
 
     if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !fillPaintingResource) {
@@ -122,7 +103,7 @@ RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* o
     return fillPaintingResource;
 }
 
-RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject* object, const RenderStyle* style)
+RenderSVGResource* RenderSVGResource::strokePaintingResource(RenderObject* object, const RenderStyle* style)
 {
     ASSERT(object);
     ASSERT(style);
@@ -138,13 +119,9 @@ RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject*
     FloatRect objectBoundingBox = object->objectBoundingBox();
 
     SVGPaint::SVGPaintType paintType = strokePaint->paintType();
-    if (!objectBoundingBox.isEmpty()
-        && (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
-        AtomicString id(SVGURIReference::getTarget(strokePaint->uri()));
-        strokePaintingResource = getRenderSVGResourceContainerById(object->document(), id);
-
-        if (!strokePaintingResource)
-            registerPendingResource(id, paintType, object);
+    if (!objectBoundingBox.isEmpty() && (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
+        if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object))
+            strokePaintingResource = resources->stroke();
     }
 
     if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !strokePaintingResource) {
@@ -184,72 +161,6 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
     return s_sharedSolidPaintingResource;
 }
 
-void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object, bool needsBoundariesUpdate)
-{
-    ASSERT(object);
-    ASSERT(object->node());
-    ASSERT(object->node()->isSVGElement());
-
-    // Eventually mark the renderer needing a boundaries update
-    if (needsBoundariesUpdate)
-        object->setNeedsBoundariesUpdate();
-
-    markForLayoutAndParentResourceInvalidation(object);
-}
-
-static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* object)
-{
-    ASSERT(paint);
-
-    SVGPaint::SVGPaintType paintType = paint->paintType();
-    if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
-        return;
-
-    AtomicString id(SVGURIReference::getTarget(paint->uri()));
-    if (RenderSVGResourceContainer* paintingResource = getRenderSVGResourceContainerById(object->document(), id))
-        paintingResource->invalidateClient(object);
-}
-
-void RenderSVGResource::invalidateAllResourcesOfRenderer(RenderObject* object)
-{
-    ASSERT(object);
-    ASSERT(object->style());
-
-    Document* document = object->document();
-    ASSERT(document);
-
-    const SVGRenderStyle* svgStyle = object->style()->svgStyle();
-    ASSERT(svgStyle);
-
-    // Masker
-    if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, svgStyle->maskerResource()))
-        masker->invalidateClient(object);
-
-    // Clipper
-    if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
-        clipper->invalidateClient(object);
-
-    // Filter
-#if ENABLE(FILTERS)
-    if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, svgStyle->filterResource()))
-        filter->invalidateClient(object);
-#endif
-
-    // Markers
-    if (RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerStartResource()))
-        startMarker->invalidateClient(object);
-    if (RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerMidResource()))
-        midMarker->invalidateClient(object);
-    if (RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerEndResource()))
-        endMarker->invalidateClient(object);
-
-    // Gradients/Patterns
-    if (svgStyle->hasFill())
-        invalidatePaintingResource(svgStyle->fillPaint(), object);
-    if (svgStyle->hasStroke())
-        invalidatePaintingResource(svgStyle->strokePaint(), object);
-}
-
 void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
 {
     ASSERT(object);
@@ -259,8 +170,10 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject*
     // Invalidate resources in ancestor chain, if needed.
     RenderObject* current = object->parent();
     while (current) {
-        if (current->isSVGResourceContainer()) 
+        if (current->isSVGResourceContainer()) {
             current->toRenderSVGResourceContainer()->invalidateClients();
+            break;
+        }
 
         current = current->parent();
     }
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index b3ea6fb..e2d8216 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -22,6 +22,7 @@
 #define RenderSVGResource_h
 
 #if ENABLE(SVG)
+#include "RenderStyleConstants.h"
 #include "SVGDocumentExtensions.h"
 
 namespace WebCore {
@@ -75,18 +76,14 @@ public:
     }
 
     // Helper utilities used in the render tree to access resources used for painting shapes/text (gradients & patterns only)
-    static RenderSVGResource* fillPaintingResource(const RenderObject*, const RenderStyle*);
-    static RenderSVGResource* strokePaintingResource(const RenderObject*, const RenderStyle*);
+    static RenderSVGResource* fillPaintingResource(RenderObject*, const RenderStyle*);
+    static RenderSVGResource* strokePaintingResource(RenderObject*, const RenderStyle*);
     static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
 
-    static void invalidateAllResourcesOfRenderer(RenderObject*);
     static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
 
 private:
     static void adjustColorForPseudoRules(const RenderStyle*, bool useFillPaint, Color&);
-    
-protected:
-    void markForLayoutAndResourceInvalidation(RenderObject*, bool needsBoundariesUpdate = true);
 };
 
 }
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index e923f7e..a201d1f 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "config.h"
+
 #if ENABLE(SVG)
 #include "RenderSVGResourceClipper.h"
 
@@ -32,11 +33,12 @@
 #include "ImageBuffer.h"
 #include "IntRect.h"
 #include "RenderObject.h"
-#include "RenderStyle.h"
 #include "RenderSVGResource.h"
+#include "RenderStyle.h"
 #include "SVGClipPathElement.h"
 #include "SVGElement.h"
 #include "SVGRenderSupport.h"
+#include "SVGResources.h"
 #include "SVGStyledElement.h"
 #include "SVGStyledTransformableElement.h"
 #include "SVGUnitTypes.h"
@@ -55,6 +57,9 @@ RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement* node)
 
 RenderSVGResourceClipper::~RenderSVGResourceClipper()
 {
+    if (m_clipper.isEmpty())
+        return;
+
     deleteAllValues(m_clipper);
     m_clipper.clear();
 }
@@ -64,26 +69,26 @@ void RenderSVGResourceClipper::invalidateClients()
     if (m_invalidationBlocked)
         return;
 
-    HashMap<RenderObject*, ClipperData*>::const_iterator end = m_clipper.end();
-    for (HashMap<RenderObject*, ClipperData*>::const_iterator it = m_clipper.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first);
-
-    deleteAllValues(m_clipper);
-    m_clipper.clear();
     m_clipBoundaries = FloatRect();
+    if (!m_clipper.isEmpty()) {
+        deleteAllValues(m_clipper);
+        m_clipper.clear();
+    }
+
+    markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
 }
 
-void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
+void RenderSVGResourceClipper::invalidateClient(RenderObject* client)
 {
+    ASSERT(client);
     if (m_invalidationBlocked)
         return;
 
-    ASSERT(object);
-    if (!m_clipper.contains(object))
-        return;
+    ASSERT(client->selfNeedsLayout());
+    if (m_clipper.contains(client))
+        delete m_clipper.take(client);
 
-    delete m_clipper.take(object);
-    markForLayoutAndResourceInvalidation(object);
+    markClientForInvalidation(client, BoundariesInvalidation);
 }
 
 bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -96,10 +101,6 @@ bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*,
     UNUSED_PARAM(resourceMode);
 #endif
 
-    // Early exit, if this resource contains a child which references ourselves.
-    if (containsCyclicReference(node()))
-        return false;
-
     applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
     return true;
 }
@@ -191,11 +192,13 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl
     maskContext->translate(-repaintRect.x(), -repaintRect.y());
 
     // clipPath can also be clipped by another clipPath.
-    if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(this->document(), style()->svgStyle()->clipperResource())) {
-        if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
-            maskContext->restore();
-            return false;
-        }            
+    if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
+        if (RenderSVGResourceClipper* clipper = resources->clipper()) {
+            if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
+                maskContext->restore();
+                return false;
+            }
+        }
     }
 
     SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node());
@@ -280,12 +283,6 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
 
 bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
 {
-    // FIXME: We should be able to check whether m_clipper.contains(object) - this doesn't work at the moment
-    // as resourceBoundingBox() has already created ClipperData, even if applyResource() returned false.
-    // Early exit, if this resource contains a child which references ourselves.
-    if (containsCyclicReference(node()))
-        return false;
-
     FloatPoint point = nodeAtPoint;
     if (!SVGRenderSupport::pointInClippingArea(this, point))
         return false;
@@ -312,14 +309,6 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
     return false;
 }
 
-bool RenderSVGResourceClipper::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
-{
-    if (!style->hasClipper())
-        return false;
-
-    return style->clipperResource() == referenceId;
-}
-
 FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
 {
     // Resource was not layouted yet. Give back the boundingBox of the object.
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index 7128aa1..3c76bc8 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -68,8 +68,6 @@ private:
     bool createClipData(ClipperData*, const FloatRect&, const FloatRect&);
     void calculateClipContentRepaintRect();
 
-    virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
     bool m_invalidationBlocked;
     FloatRect m_clipBoundaries;
     HashMap<RenderObject*, ClipperData*> m_clipper;
diff --git a/WebCore/rendering/RenderSVGResourceContainer.cpp b/WebCore/rendering/RenderSVGResourceContainer.cpp
index 3707797..90d81db 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.cpp
+++ b/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -28,102 +28,141 @@
 
 namespace WebCore {
 
+static inline SVGDocumentExtensions* svgExtensionsFromNode(Node* node)
+{
+    ASSERT(node);
+    ASSERT(node->document());
+    return node->document()->accessSVGExtensions();
+}
+
 RenderSVGResourceContainer::RenderSVGResourceContainer(SVGStyledElement* node)
     : RenderSVGHiddenContainer(node)
-    , RenderSVGResource()
     , m_id(node->hasID() ? node->getIdAttribute() : nullAtom)
+    , m_registered(false)
 {
-    ASSERT(node->document());
-    node->document()->accessSVGExtensions()->addResource(m_id, this);
 }
 
 RenderSVGResourceContainer::~RenderSVGResourceContainer()
 {
-    ASSERT(node());
-    ASSERT(node()->document());
-    node()->document()->accessSVGExtensions()->removeResource(m_id);
+    if (m_registered)
+        svgExtensionsFromNode(node())->removeResource(m_id);
 }
 
-void RenderSVGResourceContainer::idChanged()
+void RenderSVGResourceContainer::layout()
 {
-    ASSERT(node());
-    ASSERT(node()->document());
-    SVGDocumentExtensions* extensions = node()->document()->accessSVGExtensions();
+    // Invalidate all resources if our layout changed.
+    if (m_everHadLayout && selfNeedsLayout())
+        invalidateClients();
 
-    // Remove old id, that is guaranteed to be present in cache
-    extensions->removeResource(m_id);
-    m_id = static_cast<Element*>(node())->getIdAttribute();
+    RenderSVGHiddenContainer::layout();
+}
 
-    // It's possible that an element is referencing us with the new id, and has to be notified that we're existing now
-    if (extensions->isPendingResource(m_id)) {
-        OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
-        if (clients->isEmpty())
-            return;
+void RenderSVGResourceContainer::destroy()
+{
+    SVGResourcesCache::resourceDestroyed(this);
+    RenderSVGHiddenContainer::destroy();
+}
 
-        HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
-        const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
 
-        for (; it != end; ++it) {
-            if (RenderObject* renderer = (*it)->renderer())
-                renderer->setNeedsLayout(true);
-        }
+    if (!m_registered) {
+        m_registered = true;
+        registerResource();
     }
-
-    // Recache us with the new id
-    extensions->addResource(m_id, this);
 }
 
-AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
+void RenderSVGResourceContainer::idChanged()
 {
-    if (!object->isRenderPath())
-        return resourceTransform;
+    // Invalidate all our current clients.
+    invalidateClients();
 
-    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
-    AffineTransform transform = resourceTransform;
-    transform.multiply(element->getScreenCTM());
-    return transform;
+    // Remove old id, that is guaranteed to be present in cache.
+    SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
+    extensions->removeResource(m_id);
+    m_id = static_cast<Element*>(node())->getIdAttribute();
+
+    registerResource();
 }
 
-bool RenderSVGResourceContainer::containsCyclicReference(const Node* startNode) const
+void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode)
 {
-    ASSERT(startNode->document());
+    if (m_clients.isEmpty())
+        return;
 
-    for (Node* node = startNode->firstChild(); node; node = node->nextSibling()) {
-        if (!node->isSVGElement())
-            continue;
+    bool needsLayout = mode == LayoutAndBoundariesInvalidation;
 
-        RenderObject* renderer = node->renderer();
-        if (!renderer)
-            continue;
+    HashSet<RenderObject*>::iterator end = m_clients.end();
+    for (HashSet<RenderObject*>::iterator it = m_clients.begin(); it != end; ++it) {
+        markClientForInvalidation(*it, mode);
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(*it, needsLayout);
+    }
+}
 
-        RenderStyle* style = renderer->style();
-        if (!style)
-            continue;
+void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client, InvalidationMode mode)
+{
+    ASSERT(client);
+    ASSERT(!m_clients.isEmpty());
+
+    switch (mode) {
+    case LayoutAndBoundariesInvalidation:
+    case BoundariesInvalidation:
+        client->setNeedsBoundariesUpdate();
+        break;
+    case RepaintInvalidation:
+        if (client->view())
+            client->repaint();
+        break;
+    }
+}
 
-        const SVGRenderStyle* svgStyle = style->svgStyle();
-        ASSERT(svgStyle);
+void RenderSVGResourceContainer::addClient(RenderObject* client)
+{
+    ASSERT(client);
+    m_clients.add(client);
+}
 
-        // Let the class inheriting from us decide whether the child element references ourselves.
-        if (childElementReferencesResource(svgStyle, m_id))
-            return true;
+void RenderSVGResourceContainer::removeClient(RenderObject* client)
+{
+    ASSERT(client);
+    m_clients.remove(client);
+}
 
-        // Dive into shadow tree to check for cycles there.
-        if (node->hasTagName(SVGNames::useTag)) {
-            ASSERT(renderer->isSVGShadowTreeRootContainer());
-            if (Node* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer)->rootElement()) {
-                if (containsCyclicReference(shadowRoot))
-                    return true;
-            }
+void RenderSVGResourceContainer::registerResource()
+{
+    SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
+    if (!extensions->isPendingResource(m_id)) {
+        extensions->addResource(m_id, this);
+        return;
+    }
 
-        }
+    OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
 
-        if (node->hasChildNodes()) {
-            if (containsCyclicReference(node))
-                return true;
-        }
+    // Cache us with the new id.
+    extensions->addResource(m_id, this);
+
+    // Update cached resources of pending clients.
+    const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+    for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it) {
+        RenderObject* renderer = (*it)->renderer();
+        if (!renderer)
+            continue;
+        SVGResourcesCache::clientUpdatedFromElement(renderer, renderer->style());
+        renderer->setNeedsLayout(true);
     }
+}
 
-    return false;
+// FIXME: This does not belong here.
+AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
+{
+    if (!object->isRenderPath())
+        return resourceTransform;
+
+    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+    AffineTransform transform = resourceTransform;
+    transform.multiply(element->getScreenCTM());
+    return transform;
 }
 
 }
diff --git a/WebCore/rendering/RenderSVGResourceContainer.h b/WebCore/rendering/RenderSVGResourceContainer.h
index d57b1db..4271a5f 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.h
+++ b/WebCore/rendering/RenderSVGResourceContainer.h
@@ -23,10 +23,7 @@
 
 #if ENABLE(SVG)
 #include "RenderSVGHiddenContainer.h"
-
-#include "SVGStyledTransformableElement.h"
 #include "RenderSVGResource.h"
-#include "RenderSVGShadowTreeRootContainer.h"
 
 namespace WebCore {
 
@@ -36,27 +33,40 @@ public:
     RenderSVGResourceContainer(SVGStyledElement*);
     virtual ~RenderSVGResourceContainer();
 
-    void idChanged();
+    virtual void layout();
+    virtual void destroy();
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
     virtual bool isSVGResourceContainer() const { return true; }
     virtual bool drawsContents() { return false; }
-
     virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
-    virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const { return false; }
 
     static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
 
-    bool containsCyclicReference(const Node* startNode) const;
+    void idChanged();
+
+protected:
+    enum InvalidationMode {
+        LayoutAndBoundariesInvalidation,
+        BoundariesInvalidation,
+        RepaintInvalidation
+    };
+
+    // Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
+    void markAllClientsForInvalidation(InvalidationMode);
+    void markClientForInvalidation(RenderObject*, InvalidationMode);
 
 private:
     friend class SVGResourcesCache;
-
-    // FIXME: No-ops for now, until follow-up patch on bug 43031 lands.
-    void addClient(RenderObject*) { }
-    void removeClient(RenderObject*) { }
+    void addClient(RenderObject*);
+    void removeClient(RenderObject*);
 
 private:
+    void registerResource();
+
     AtomicString m_id;
+    bool m_registered;
+    HashSet<RenderObject*> m_clients;
 };
 
 inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document* document, const AtomicString& id)
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index a6358f0..bc5feaf 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -60,28 +60,32 @@ RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
 
 RenderSVGResourceFilter::~RenderSVGResourceFilter()
 {
+    if (m_filter.isEmpty())
+        return;
+
     deleteAllValues(m_filter);
     m_filter.clear();
 }
 
 void RenderSVGResourceFilter::invalidateClients()
 {
-    HashMap<RenderObject*, FilterData*>::const_iterator end = m_filter.end();
-    for (HashMap<RenderObject*, FilterData*>::const_iterator it = m_filter.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first);
+    if (!m_filter.isEmpty()) {
+        deleteAllValues(m_filter);
+        m_filter.clear();
+    }
 
-    deleteAllValues(m_filter);
-    m_filter.clear();
+    markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
 }
 
-void RenderSVGResourceFilter::invalidateClient(RenderObject* object)
+void RenderSVGResourceFilter::invalidateClient(RenderObject* client)
 {
-    ASSERT(object);
-    if (!m_filter.contains(object))
-        return;
+    ASSERT(client);
+    ASSERT(client->selfNeedsLayout());
+
+    if (m_filter.contains(client))
+        delete m_filter.take(client);
 
-    delete m_filter.take(object);
-    markForLayoutAndResourceInvalidation(object);
+    markClientForInvalidation(client, BoundariesInvalidation);
 }
 
 PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index ce51369..73b2ab6 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -43,28 +43,32 @@ RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement* node)
 
 RenderSVGResourceGradient::~RenderSVGResourceGradient()
 {
+    if (m_gradient.isEmpty())
+        return;
+
     deleteAllValues(m_gradient);
     m_gradient.clear();
 }
 
 void RenderSVGResourceGradient::invalidateClients()
 {
-    const HashMap<RenderObject*, GradientData*>::const_iterator end = m_gradient.end();
-    for (HashMap<RenderObject*, GradientData*>::const_iterator it = m_gradient.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first, false);
+    if (!m_gradient.isEmpty()) {
+        deleteAllValues(m_gradient);
+        m_gradient.clear();
+    }
 
-    deleteAllValues(m_gradient);
-    m_gradient.clear();
+    markAllClientsForInvalidation(RepaintInvalidation);
 }
 
-void RenderSVGResourceGradient::invalidateClient(RenderObject* object)
+void RenderSVGResourceGradient::invalidateClient(RenderObject* client)
 {
-    ASSERT(object);
-    if (!m_gradient.contains(object))
-        return;
+    ASSERT(client);
+    ASSERT(client->selfNeedsLayout());
+
+    if (m_gradient.contains(client))
+        delete m_gradient.take(client);
 
-    delete m_gradient.take(object);
-    markForLayoutAndResourceInvalidation(object, false);
+    markClientForInvalidation(client, RepaintInvalidation);
 }
 
 #if PLATFORM(CG)
diff --git a/WebCore/rendering/RenderSVGResourceMarker.cpp b/WebCore/rendering/RenderSVGResourceMarker.cpp
index 4f0cace..fa00fa3 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMarker.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "config.h"
+
 #if ENABLE(SVG)
 #include "RenderSVGResourceMarker.h"
 
@@ -43,39 +44,30 @@ RenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement* node)
 
 RenderSVGResourceMarker::~RenderSVGResourceMarker()
 {
-    m_marker.clear();
 }
 
 void RenderSVGResourceMarker::layout()
 {
+    // Invalidate all resources if our layout changed.
+    if (m_everHadLayout && selfNeedsLayout())
+        invalidateClients();
+
     // RenderSVGHiddenContainer overwrites layout(). We need the
     // layouting of RenderSVGContainer for calculating  local
     // transformations and repaint.
     RenderSVGContainer::layout();
 }
 
-void RenderSVGResourceMarker::addClient(const RenderObject* object)
-{
-    m_marker.add(object);
-}
-
 void RenderSVGResourceMarker::invalidateClients()
 {
-    const HashSet<const RenderObject*>::const_iterator end = m_marker.end();
-    for (HashSet<const RenderObject*>::const_iterator it = m_marker.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(const_cast<RenderObject*>(*it));
-
-    m_marker.clear();
+    markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
 }
 
-void RenderSVGResourceMarker::invalidateClient(RenderObject* object)
+void RenderSVGResourceMarker::invalidateClient(RenderObject* client)
 {
-    ASSERT(object);
-    if (!m_marker.contains(object))
-        return;
-
-    m_marker.remove(object);
-    markForLayoutAndResourceInvalidation(object);
+    ASSERT(client);
+    ASSERT(client->selfNeedsLayout());
+    markClientForInvalidation(client, BoundariesInvalidation);
 }
 
 void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
@@ -140,20 +132,11 @@ AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint&
 
 void RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform& transform)
 {
-    DEFINE_STATIC_LOCAL(HashSet<RenderSVGResourceMarker*>, currentlyDrawingMarkers, ());
-
-    // avoid drawing circular marker references
-    if (currentlyDrawingMarkers.contains(this))
-        return;
-
-    currentlyDrawingMarkers.add(this);
     PaintInfo info(paintInfo);
     info.context->save();
     info.applyTransform(transform);
     RenderSVGContainer::paint(info, 0, 0);
     info.context->restore();
-
-    currentlyDrawingMarkers.remove(this);
 }
 
 AffineTransform RenderSVGResourceMarker::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
index 75c442e..8509aca 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.h
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -41,7 +41,6 @@ public:
 
     virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
 
-    void addClient(const RenderObject*);
     virtual void invalidateClients();
     virtual void invalidateClient(RenderObject*);
 
@@ -74,9 +73,6 @@ private:
 
     AffineTransform viewportTransform() const;
 
-    // Save objects using this marker for invalidation.
-    HashSet<const RenderObject*> m_marker;
-
     mutable AffineTransform m_localToParentTransform;
     FloatRect m_viewport;
 };
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 83a64b5..2c36c96 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -19,6 +19,7 @@
  */
 
 #include "config.h"
+
 #if ENABLE(SVG)
 #include "RenderSVGResourceMasker.h"
 
@@ -51,37 +52,33 @@ RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement* node)
 
 RenderSVGResourceMasker::~RenderSVGResourceMasker()
 {
+    if (m_masker.isEmpty())
+        return;
+
     deleteAllValues(m_masker);
     m_masker.clear();
 }
 
 void RenderSVGResourceMasker::invalidateClients()
 {
-    HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
-    for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first);
-
-    deleteAllValues(m_masker);
-    m_masker.clear();
     m_maskBoundaries = FloatRect();
-}
-
-void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
-{
-    ASSERT(object);
-    if (!m_masker.contains(object))
-        return;
+    if (!m_masker.isEmpty()) {
+        deleteAllValues(m_masker);
+        m_masker.clear();
+    }
 
-    delete m_masker.take(object);
-    markForLayoutAndResourceInvalidation(object);
+    markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
 }
 
-bool RenderSVGResourceMasker::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
+void RenderSVGResourceMasker::invalidateClient(RenderObject* client)
 {
-    if (!style->hasMasker())
-        return false;
+    ASSERT(client);
+    ASSERT(client->selfNeedsLayout());
 
-    return style->maskerResource() == referenceId;
+    if (m_masker.contains(client))
+        delete m_masker.take(client);
+
+    markClientForInvalidation(client, BoundariesInvalidation);
 }
 
 bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -102,11 +99,6 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
         SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
         if (!maskElement)
             return false;
-
-        // Early exit, if this resource contains a child which references ourselves.
-        if (containsCyclicReference(node()))
-            return false;
-
         createMaskImage(maskerData, maskElement, object);
     }
 
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index 56f657b..f6301cb 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -69,8 +69,6 @@ private:
     void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
     void calculateMaskContentRepaintRect();
 
-    virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
     FloatRect m_maskBoundaries;
     HashMap<RenderObject*, MaskerData*> m_masker;
 };
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index a2234c8..902ff02 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -40,43 +40,32 @@ RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement* node)
 
 RenderSVGResourcePattern::~RenderSVGResourcePattern()
 {
-    deleteAllValues(m_pattern);
-    m_pattern.clear();
-}
-
-void RenderSVGResourcePattern::invalidateClients()
-{
-    const HashMap<RenderObject*, PatternData*>::const_iterator end = m_pattern.end();
-    for (HashMap<RenderObject*, PatternData*>::const_iterator it = m_pattern.begin(); it != end; ++it)
-        markForLayoutAndResourceInvalidation(it->first, false);
+    if (m_pattern.isEmpty())
+        return;
 
     deleteAllValues(m_pattern);
     m_pattern.clear();
 }
 
-void RenderSVGResourcePattern::invalidateClient(RenderObject* object)
+void RenderSVGResourcePattern::invalidateClients()
 {
-    ASSERT(object);
-    if (!m_pattern.contains(object))
-        return;
+    if (!m_pattern.isEmpty()) {
+        deleteAllValues(m_pattern);
+        m_pattern.clear();
+    }
 
-    delete m_pattern.take(object);
-    markForLayoutAndResourceInvalidation(object, false);
+    markAllClientsForInvalidation(RepaintInvalidation);
 }
 
-bool RenderSVGResourcePattern::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
+void RenderSVGResourcePattern::invalidateClient(RenderObject* client)
 {
-    if (style->hasFill()) {
-        if (style->fillPaint()->matchesTargetURI(referenceId))
-            return true;
-    }
+    ASSERT(client);
+    ASSERT(client->selfNeedsLayout());
 
-    if (style->hasStroke()) {
-        if (style->strokePaint()->matchesTargetURI(referenceId))
-            return true;
-    }
+    if (m_pattern.contains(client))
+        delete m_pattern.take(client);
 
-    return false;
+    markClientForInvalidation(client, RepaintInvalidation);
 }
 
 bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
@@ -244,10 +233,6 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* p
     if (!attributes.patternContentElement())
         return 0;
 
-    // Early exit, if this resource contains a child which references ourselves.
-    if (containsCyclicReference(attributes.patternContentElement()))
-        return 0;
-
     FloatRect objectBoundingBox = object->objectBoundingBox();    
     FloatRect patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement); 
     AffineTransform patternTransform = attributes.patternTransform();
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index ec89777..690b0de 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -67,8 +67,6 @@ private:
     FloatRect calculatePatternBoundariesIncludingOverflow(PatternAttributes&, const FloatRect& objectBoundingBox,
                                                           const AffineTransform& viewBoxCTM, const FloatRect& patternBoundaries) const;
 
-    virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
     HashMap<RenderObject*, PatternData*> m_pattern;
 };
 
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index e2dee5f..012a164 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -32,6 +32,7 @@
 #include "RenderView.h"
 #include "SVGLength.h"
 #include "SVGRenderSupport.h"
+#include "SVGResources.h"
 #include "SVGSVGElement.h"
 #include "SVGStyledElement.h"
 #include "TransformState.h"
@@ -129,13 +130,11 @@ void RenderSVGRoot::layout()
     setNeedsLayout(false);
 }
 
-bool RenderSVGRoot::selfWillPaint() const
+bool RenderSVGRoot::selfWillPaint()
 {
 #if ENABLE(FILTERS)
-    const SVGRenderStyle* svgStyle = style()->svgStyle();
-    RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
-    if (filter)
-        return true;
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+    return resources && resources->filter();
 #endif
     return false;
 }
@@ -192,10 +191,22 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
 
 void RenderSVGRoot::destroy()
 {
-    RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+    SVGResourcesCache::clientDestroyed(this);
     RenderBox::destroy();
 }
 
+void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderBox::styleDidChange(diff, oldStyle);
+    SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGRoot::updateFromElement()
+{
+    RenderBox::updateFromElement();
+    SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
 void RenderSVGRoot::calcViewport()
 {
     SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index 0a08ab5..b90113c 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -58,6 +58,8 @@ private:
     virtual void paint(PaintInfo&, int parentX, int parentY);
 
     virtual void destroy();
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+    virtual void updateFromElement();
 
     virtual const AffineTransform& localToParentTransform() const;
 
@@ -77,7 +79,7 @@ private:
 
     void calcViewport();
 
-    bool selfWillPaint() const;
+    bool selfWillPaint();
 
     IntSize parentOriginToBorderBox() const;
     IntSize borderOriginToContentBox() const;
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index 58348db..c4fc353 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -98,9 +98,9 @@ void RenderSVGText::layout()
     ASSERT(childrenInline());
     forceLayoutInlineChildren();
 
-    // Invalidate all resources of this client, if we changed something.
+    // Invalidate all resources of this client if our layout changed.
     if (m_everHadLayout && selfNeedsLayout())
-        RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+        SVGResourcesCache::clientLayoutChanged(this);
 
     repainter.repaintAfterLayout();
     setNeedsLayout(false);
@@ -132,12 +132,6 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul
     return false;
 }
 
-void RenderSVGText::destroy()
-{
-    RenderSVGResource::invalidateAllResourcesOfRenderer(this);
-    RenderSVGBlock::destroy();
-}
-
 bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
 {
     ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index 6e7d03a..be19419 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -51,8 +51,6 @@ private:
     virtual bool requiresLayer() const { return false; }
     virtual void layout();
 
-    virtual void destroy();
-
     virtual void absoluteQuads(Vector<FloatQuad>&);
 
     virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index 8e498ad..a293124 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -295,17 +295,16 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
     ASSERT(!m_paintingResource);
 }
 
-bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderStyle* style)
+bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderObject* renderer, RenderStyle* style)
 {
+    ASSERT(renderer);
+    ASSERT(style);
     ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
 
-    RenderObject* parentRenderer = parent()->renderer();
-    ASSERT(parentRenderer);
-
     if (m_paintingResourceMode & ApplyToFillMode)
-        m_paintingResource = RenderSVGResource::fillPaintingResource(parentRenderer, style);
+        m_paintingResource = RenderSVGResource::fillPaintingResource(renderer, style);
     else if (m_paintingResourceMode & ApplyToStrokeMode)
-        m_paintingResource = RenderSVGResource::strokePaintingResource(parentRenderer, style);
+        m_paintingResource = RenderSVGResource::strokePaintingResource(renderer, style);
     else {
         // We're either called for stroking or filling.
         ASSERT_NOT_REACHED();
@@ -314,7 +313,7 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, Render
     if (!m_paintingResource)
         return false;
 
-    m_paintingResource->applyResource(parentRenderer, style, context, m_paintingResourceMode);
+    m_paintingResource->applyResource(renderer, style, context, m_paintingResourceMode);
     return true;
 }
 
@@ -331,7 +330,7 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context)
 
 bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, TextRun& textRun, RenderStyle* style)
 {
-    bool acquiredResource = acquirePaintingResource(context, style);
+    bool acquiredResource = acquirePaintingResource(context, parent()->renderer(), style);
 
 #if ENABLE(SVG_FONTS)
     // SVG Fonts need access to the painting resource used to draw the current text chunk.
@@ -508,21 +507,24 @@ void SVGInlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoin
 
     if (hasDecorationFill) {
         m_paintingResourceMode = ApplyToFillMode;
-        paintDecorationWithStyle(context, textOrigin, decorationStyle, decoration);
+        paintDecorationWithStyle(context, textOrigin, decorationRenderer, decoration);
     }
 
     if (hasDecorationStroke) {
         m_paintingResourceMode = ApplyToStrokeMode;
-        paintDecorationWithStyle(context, textOrigin, decorationStyle, decoration);
+        paintDecorationWithStyle(context, textOrigin, decorationRenderer, decoration);
     }
 }
 
-void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const FloatPoint& textOrigin, RenderStyle* decorationStyle, ETextDecoration decoration)
+void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const FloatPoint& textOrigin, RenderObject* decorationRenderer, ETextDecoration decoration)
 {
     ASSERT(!m_paintingResource);
     ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
     ASSERT(m_currentChunkPart.isValid());
 
+    RenderStyle* decorationStyle = decorationRenderer->style();
+    ASSERT(decorationStyle);
+
     const Font& font = decorationStyle->font();
 
     // The initial y value refers to overline position.
@@ -534,7 +536,7 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const
     context->beginPath();
     context->addPath(Path::createRectangle(FloatRect(x, y, m_currentChunkPart.width, thickness)));
 
-    if (acquirePaintingResource(context, decorationStyle))
+    if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
         releasePaintingResource(context);
 
     context->restore();
@@ -614,9 +616,15 @@ void SVGInlineTextBox::paintText(GraphicsContext* context, const FloatPoint& tex
         paintTextWithShadows(context, textOrigin, style, textRun, 0, startPos);
 
     // Draw text using selection style from the start to the end position of the selection
+    if (style != selectionStyle)
+        SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
+
     TextRun selectionTextRun(constructTextRun(selectionStyle));
     paintTextWithShadows(context, textOrigin, selectionStyle, textRun, startPos, endPos);
 
+    if (style != selectionStyle)
+        SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, style);
+
     // Eventually draw text using regular style from the end position of the selection to the end of the current chunk part
     if (endPos < m_currentChunkPart.length && !paintSelectedTextOnly)
         paintTextWithShadows(context, textOrigin, style, textRun, endPos, m_currentChunkPart.length);
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index 602fff1..7711db4 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -75,7 +75,7 @@ private:
     TextRun constructTextRun(RenderStyle*) const;
     AffineTransform buildChunkTransformation(SVGChar& firstCharacter) const;
 
-    bool acquirePaintingResource(GraphicsContext*&, RenderStyle*);
+    bool acquirePaintingResource(GraphicsContext*&, RenderObject*, RenderStyle*);
     void releasePaintingResource(GraphicsContext*&);
 
     bool prepareGraphicsContextForTextPainting(GraphicsContext*&, TextRun&, RenderStyle*);
@@ -83,7 +83,7 @@ private:
 
     void computeTextMatchMarkerRect(RenderStyle*);
     void paintDecoration(GraphicsContext*, const FloatPoint& textOrigin, ETextDecoration, bool hasSelection);
-    void paintDecorationWithStyle(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, ETextDecoration);
+    void paintDecorationWithStyle(GraphicsContext*, const FloatPoint& textOrigin, RenderObject*, ETextDecoration);
     void paintSelection(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*);
     void paintText(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, RenderStyle* selectionStyle, bool hasSelection, bool paintSelectedTextOnly);
     void paintTextWithShadows(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, TextRun&, int startPos, int endPos);
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 0d4a42b..df4a936 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -40,6 +40,7 @@
 #include "RenderSVGResourceMarker.h"
 #include "RenderSVGResourceMasker.h"
 #include "RenderSVGRoot.h"
+#include "SVGResources.h"
 #include "SVGStyledElement.h"
 #include "TransformState.h"
 #include <wtf/UnusedParam.h>
@@ -82,7 +83,6 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
     SVGElement* svgElement = static_cast<SVGElement*>(object->node());
     ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
 
-    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
     RenderStyle* style = object->style();
     ASSERT(style);
 
@@ -109,33 +109,22 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
         paintInfo.context->beginTransparencyLayer(1);
     }
 
-    Document* document = object->document();
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+    if (!resources)
+        return true;
 
-    if (svgStyle->hasMasker()) {
-        AtomicString maskerId(svgStyle->maskerResource());
-        if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
-            if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
-                return false;
-        } else
-            document->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+    if (RenderSVGResourceMasker* masker = resources->masker()) {
+        if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+            return false;
     }
 
-    if (svgStyle->hasClipper()) {
-        AtomicString clipperId(svgStyle->clipperResource());
-        if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
-            clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
-        else
-            document->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
-    }
+    if (RenderSVGResourceClipper* clipper = resources->clipper())
+        clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
 
 #if ENABLE(FILTERS)
-    if (svgStyle->hasFilter()) {
-        AtomicString filterId(svgStyle->filterResource());
-        if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, filterId)) { 
-            if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
-                return false;
-        } else
-            document->accessSVGExtensions()->addPendingResource(filterId, styledElement);
+    if (RenderSVGResourceFilter* filter = resources->filter()) {
+        if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+            return false;
     }
 #endif
 
@@ -157,9 +146,9 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
     ASSERT(svgStyle);
 
 #if ENABLE(FILTERS)
-    if (svgStyle->hasFilter()) {
-        AtomicString filterId(svgStyle->filterResource());
-        if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), filterId)) { 
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+    if (resources) {
+        if (RenderSVGResourceFilter* filter = resources->filter()) {
             filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode);
             paintInfo.context = savedContext;
         }
@@ -289,49 +278,52 @@ bool SVGRenderSupport::isOverflowHidden(const RenderObject* object)
 void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* object, FloatRect& repaintRect)
 {
     ASSERT(object);
-    ASSERT(object->style());
-    const SVGRenderStyle* svgStyle = object->style()->svgStyle();
-    if (!svgStyle)
-        return;
-        
+
+    RenderStyle* style = object->style();
+    ASSERT(style);
+
+    const SVGRenderStyle* svgStyle = style->svgStyle();
+    ASSERT(svgStyle);
+
     RenderObject* renderer = const_cast<RenderObject*>(object);
-#if ENABLE(FILTERS)
-    if (svgStyle->hasFilter()) {
-        if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), svgStyle->filterResource()))
-            repaintRect = filter->resourceBoundingBox(renderer);
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
+    if (!resources) {
+        svgStyle->inflateForShadow(repaintRect);
+        return;
     }
+
+#if ENABLE(FILTERS)
+    if (RenderSVGResourceFilter* filter = resources->filter())
+        repaintRect = filter->resourceBoundingBox(renderer);
 #endif
 
-    if (svgStyle->hasClipper()) {
-        if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), svgStyle->clipperResource()))
-            repaintRect.intersect(clipper->resourceBoundingBox(renderer));
-    }
-    
-    if (svgStyle->hasMasker()) {
-        if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), svgStyle->maskerResource()))
-            repaintRect.intersect(masker->resourceBoundingBox(renderer));
-    }
-    
+    if (RenderSVGResourceClipper* clipper = resources->clipper())
+        repaintRect.intersect(clipper->resourceBoundingBox(renderer));
+
+    if (RenderSVGResourceMasker* masker = resources->masker())
+        repaintRect.intersect(masker->resourceBoundingBox(renderer));
+
     svgStyle->inflateForShadow(repaintRect);
 }
 
-bool SVGRenderSupport::pointInClippingArea(const RenderObject* object, const FloatPoint& point)
+bool SVGRenderSupport::pointInClippingArea(RenderObject* object, const FloatPoint& point)
 {
     ASSERT(object);
-    ASSERT(object->style());
 
-    Document* document = object->document();
-    ASSERT(document);
+    RenderStyle* style = object->style();
+    ASSERT(style);
 
-    const SVGRenderStyle* svgStyle = object->style()->svgStyle();
+    const SVGRenderStyle* svgStyle = style->svgStyle();
     ASSERT(svgStyle);
 
     // We just take clippers into account to determine if a point is on the node. The Specification may
     // change later and we also need to check maskers.
-    if (svgStyle->hasClipper()) {
-        if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
-            return clipper->hitTestClipContent(object->objectBoundingBox(), point);
-    }
+    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+    if (!resources)
+        return true;
+
+    if (RenderSVGResourceClipper* clipper = resources->clipper())
+        return clipper->hitTestClipContent(object->objectBoundingBox(), point);
 
     return true;
 }
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 8eb486e..371ac75 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -56,7 +56,7 @@ public:
     static void intersectRepaintRectWithResources(const RenderObject*, FloatRect&);
 
     // Determines whether the passed point lies in a clipping area
-    static bool pointInClippingArea(const RenderObject*, const FloatPoint&);
+    static bool pointInClippingArea(RenderObject*, const FloatPoint&);
 
     enum ContainerBoundingBoxMode {
         ObjectBoundingBox,
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index bec78e7..d298544 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -366,7 +366,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
     if (object.isRenderPath()) {
         const RenderPath& path = static_cast<const RenderPath&>(object);
 
-        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(&path, path.style())) {
+        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderPath*>(&path), path.style())) {
             TextStreamSeparator s(" ");
             ts << " [stroke={" << s;
             writeSVGPaintingResource(ts, strokePaintingResource);
@@ -387,7 +387,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
             ts << "}]";
         }
 
-        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(&path, path.style())) {
+        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderPath*>(&path), path.style())) {
             TextStreamSeparator s(" ");
             ts << " [fill={" << s;
             writeSVGPaintingResource(ts, fillPaintingResource);
@@ -734,6 +734,8 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
     const RenderStyle* style = object.style();
     const SVGRenderStyle* svgStyle = style->svgStyle();
 
+    // FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache.
+    // For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output.
     RenderObject& renderer = const_cast<RenderObject&>(object);
     if (!svgStyle->maskerResource().isEmpty()) {
         if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) {
diff --git a/WebCore/rendering/SVGResourcesCache.cpp b/WebCore/rendering/SVGResourcesCache.cpp
index 46586cc..b922b44 100644
--- a/WebCore/rendering/SVGResourcesCache.cpp
+++ b/WebCore/rendering/SVGResourcesCache.cpp
@@ -131,17 +131,7 @@ void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifferen
         return;
 
     clientUpdatedFromElement(renderer, newStyle);
-
-    // Invalidate resources in ancestor chain, if needed.
-    RenderObject* parent = renderer->parent();
-    while (parent) {
-        if (parent->isSVGResourceContainer()) {
-            parent->toRenderSVGResourceContainer()->invalidateClients();
-            break;
-        }
-
-        parent = parent->parent();
-    }
+    RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
 }
  
 void SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle)
diff --git a/WebCore/rendering/SVGResourcesCycleSolver.cpp b/WebCore/rendering/SVGResourcesCycleSolver.cpp
index 838758b..2d38a8c 100644
--- a/WebCore/rendering/SVGResourcesCycleSolver.cpp
+++ b/WebCore/rendering/SVGResourcesCycleSolver.cpp
@@ -111,9 +111,14 @@ static inline String targetReferenceFromResource(SVGElement* element, bool& isVa
     return SVGURIReference::getTarget(target);
 }
 
-static inline void setFollowLinkForChainableResource(SVGElement*, bool)
+static inline void setFollowLinkForChainableResource(SVGElement* element, bool followLink)
 {
-    // FIXME: Enable once the follow-up patch for bug 43031 lands
+    if (element->hasTagName(SVGNames::patternTag))
+        static_cast<SVGPatternElement*>(element)->setFollowLink(followLink);
+    else if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
+        static_cast<SVGGradientElement*>(element)->setFollowLink(followLink);
+    else if (element->hasTagName(SVGNames::filterTag))
+        static_cast<SVGFilterElement*>(element)->setFollowLink(followLink);
 }
 
 bool SVGResourcesCycleSolver::chainableResourceContainsCycles(RenderSVGResourceContainer* container) const
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 93e50cc..2a9003c 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -165,13 +165,14 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
     if (stroke != other->stroke) {
         if (stroke->width != other->stroke->width
+            || stroke->paint != other->stroke->paint
             || stroke->miterLimit != other->stroke->miterLimit
             || stroke->dashArray != other->stroke->dashArray
             || stroke->dashOffset != other->stroke->dashOffset)
             return StyleDifferenceLayout;
 
-        // Only these two cases remain, where we only need a repaint.
-        ASSERT(stroke->paint != other->stroke->paint || stroke->opacity != other->stroke->opacity);
+        // Only the stroke-opacity case remains, where we only need a repaint.
+        ASSERT(stroke->opacity != other->stroke->opacity);
         return StyleDifferenceRepaint;
     }
 
diff --git a/WebCore/svg/SVGClipPathElement.cpp b/WebCore/svg/SVGClipPathElement.cpp
index c3a514e..5c23031 100644
--- a/WebCore/svg/SVGClipPathElement.cpp
+++ b/WebCore/svg/SVGClipPathElement.cpp
@@ -69,12 +69,16 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGStyledTransformableElement::svgAttributeChanged(attrName);
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (attrName == SVGNames::clipPathUnitsAttr ||
         SVGTests::isKnownAttribute(attrName) || 
         SVGLangSpace::isKnownAttribute(attrName) ||
         SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
         SVGStyledTransformableElement::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGClipPathElement::synchronizeProperty(const QualifiedName& attrName)
@@ -97,8 +101,11 @@ void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChang
 {
     SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 RenderObject* SVGClipPathElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/svg/SVGClipPathElement.h b/WebCore/svg/SVGClipPathElement.h
index eb74f72..11b07fb 100644
--- a/WebCore/svg/SVGClipPathElement.h
+++ b/WebCore/svg/SVGClipPathElement.h
@@ -39,6 +39,7 @@ public:
     virtual ~SVGClipPathElement();
 
     virtual bool isValid() const { return SVGTests::isValid(); }
+    virtual bool needsPendingResourceHandling() const { return false; }
 
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index b262e45..0497edf 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -278,20 +278,22 @@ bool SVGElement::childShouldCreateRenderer(Node* child) const
 void SVGElement::insertedIntoDocument()
 {
     StyledElement::insertedIntoDocument();
-    SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
 
-    String resourceId = getIdAttribute();
-    if (extensions->isPendingResource(resourceId)) {
-        OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId));
-        if (clients->isEmpty())
-            return;
+    if (!needsPendingResourceHandling())
+        return;
 
-        HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
-        const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+    SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
+    String resourceId = getIdAttribute();
+    if (!extensions->isPendingResource(resourceId))
+        return;
+    
+    OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId));
+    if (clients->isEmpty())
+        return;
 
-        for (; it != end; ++it)
-            (*it)->buildPendingResource();
-    }
+    const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+    for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it)
+        (*it)->buildPendingResource();
 }
 
 void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls)
diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h
index 64afe8e..eccf03e 100644
--- a/WebCore/svg/SVGElement.h
+++ b/WebCore/svg/SVGElement.h
@@ -97,6 +97,8 @@ namespace WebCore {
         virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
 
         virtual ContainerNode* eventParentNode();
+
+        virtual bool needsPendingResourceHandling() const { return true; }
         virtual void buildPendingResource() { }
 
         void mapInstanceToElement(SVGElementInstance*);
diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp
index 4387e71..73a935b 100644
--- a/WebCore/svg/SVGFilterElement.cpp
+++ b/WebCore/svg/SVGFilterElement.cpp
@@ -47,6 +47,7 @@ SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document* doc)
     , SVGURIReference()
     , SVGLangSpace()
     , SVGExternalResourcesRequired()
+    , m_followLink(true)
     , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
     , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
     , m_x(LengthModeWidth, "-10%")
@@ -66,7 +67,9 @@ void SVGFilterElement::setFilterRes(unsigned long filterResX, unsigned long filt
 {
     setFilterResXBaseValue(filterResX);
     setFilterResYBaseValue(filterResY);
-    invalidateResourceClients();
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 void SVGFilterElement::parseMappedAttribute(Attribute* attr)
@@ -121,6 +124,10 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
         updateRelativeLengthsInformation();
     }
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (invalidateClients
         || attrName == SVGNames::filterUnitsAttr
         || attrName == SVGNames::primitiveUnitsAttr
@@ -129,7 +136,7 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGURIReference::isKnownAttribute(attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName)
@@ -175,8 +182,11 @@ void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange,
 {
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 FloatRect SVGFilterElement::filterBoundingBox(const FloatRect& objectBoundingBox) const
diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h
index 7b0192c..d37fff4 100644
--- a/WebCore/svg/SVGFilterElement.h
+++ b/WebCore/svg/SVGFilterElement.h
@@ -43,6 +43,8 @@ public:
     SVGFilterElement(const QualifiedName&, Document*);
     virtual ~SVGFilterElement();
 
+    virtual bool needsPendingResourceHandling() const { return false; }
+
     void setFilterRes(unsigned long filterResX, unsigned long filterResY);
     FloatRect filterBoundingBox(const FloatRect&) const;
 
@@ -53,9 +55,14 @@ public:
 
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
+    // FIXME: Add xlink:href support for filters, and use this property
+    void setFollowLink(bool followLink) { m_followLink = followLink; }
+
 private:
     virtual bool selfHasRelativeLengths() const;
 
+    bool m_followLink;
+
     DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::filterUnitsAttr, int, FilterUnits, filterUnits)
     DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::primitiveUnitsAttr, int, PrimitiveUnits, primitiveUnits)
     DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::xAttr, SVGLength, X, x)
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
index 8e284e6..042d93b 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -107,7 +107,7 @@ void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser,
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
     if (!changedByParser)
-        invalidateResourceClients();
+        invalidateFilter();
 }
 
 void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveBoundingBoxMode, FilterEffect* filterEffect) const
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
index 14784a5..19f6f3a 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -55,7 +55,8 @@ protected:
     {
         if (!inDocument() || !parentNode()->hasTagName(SVGNames::filterTag))
             return;
-        static_cast<SVGFilterElement*>(parentNode())->invalidateResourceClients();
+        if (RenderObject* object = parentNode()->renderer())
+            object->setNeedsLayout(true);
     }
 
 private:
diff --git a/WebCore/svg/SVGGradientElement.cpp b/WebCore/svg/SVGGradientElement.cpp
index b314674..43e5b34 100644
--- a/WebCore/svg/SVGGradientElement.cpp
+++ b/WebCore/svg/SVGGradientElement.cpp
@@ -42,6 +42,7 @@ SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* d
     : SVGStyledElement(tagName, doc)
     , SVGURIReference()
     , SVGExternalResourcesRequired()
+    , m_followLink(true)
     , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
     , m_gradientTransform(SVGTransformList::create(SVGNames::gradientTransformAttr))
 {
@@ -85,13 +86,17 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGStyledElement::svgAttributeChanged(attrName);
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (attrName == SVGNames::gradientUnitsAttr
         || attrName == SVGNames::gradientTransformAttr
         || attrName == SVGNames::spreadMethodAttr
         || SVGURIReference::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
         || SVGStyledElement::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGGradientElement::synchronizeProperty(const QualifiedName& attrName)
@@ -123,8 +128,11 @@ void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChang
 {
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 Vector<Gradient::ColorStop> SVGGradientElement::buildStops()
diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h
index 2736ab3..3602cff 100644
--- a/WebCore/svg/SVGGradientElement.h
+++ b/WebCore/svg/SVGGradientElement.h
@@ -37,6 +37,8 @@ namespace WebCore {
         SVGGradientElement(const QualifiedName&, Document*);
         virtual ~SVGGradientElement();
 
+        virtual bool needsPendingResourceHandling() const { return false; }
+
         virtual void parseMappedAttribute(Attribute*);
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
@@ -45,7 +47,11 @@ namespace WebCore {
 
         Vector<Gradient::ColorStop> buildStops();
  
+        void setFollowLink(bool followLink) { m_followLink = followLink; }
+
     protected:
+        bool m_followLink;
+
         DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::spreadMethodAttr, int, SpreadMethod, spreadMethod)
         DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientUnitsAttr, int, GradientUnits, gradientUnits)
         DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientTransformAttr, SVGTransformList*, GradientTransform, gradientTransform)
diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp
index d95c084..94e4ef7 100644
--- a/WebCore/svg/SVGLinearGradientElement.cpp
+++ b/WebCore/svg/SVGLinearGradientElement.cpp
@@ -76,7 +76,12 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName
         || attrName == SVGNames::x2Attr
         || attrName == SVGNames::y2Attr) {
         updateRelativeLengthsInformation();
-        invalidateResourceClients();
+
+        RenderObject* object = renderer();
+        if (!object)
+            return;
+
+        object->setNeedsLayout(true);
     }
 }
 
@@ -150,13 +155,15 @@ LinearGradientAttributes SVGLinearGradientElement::collectGradientProperties()
         processedGradients.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = ownerDocument()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = m_followLink ? ownerDocument()->getElementById(SVGURIReference::getTarget(current->href())) : 0;
         if (refNode && (refNode->hasTagName(SVGNames::linearGradientTag) || refNode->hasTagName(SVGNames::radialGradientTag))) {
             current = static_cast<SVGGradientElement*>(refNode);
 
             // Cycle detection
-            if (processedGradients.contains(current))
-                return LinearGradientAttributes();
+            if (processedGradients.contains(current)) {
+                current = 0;
+                break;
+            }
 
             isLinear = current->hasTagName(SVGNames::linearGradientTag);
         } else
diff --git a/WebCore/svg/SVGMarkerElement.cpp b/WebCore/svg/SVGMarkerElement.cpp
index 01faf21..195e91d 100644
--- a/WebCore/svg/SVGMarkerElement.cpp
+++ b/WebCore/svg/SVGMarkerElement.cpp
@@ -113,6 +113,10 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
         updateRelativeLengthsInformation();
     }
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (invalidateClients
         || attrName == SVGNames::markerUnitsAttr
         || attrName == SVGNames::orientAttr
@@ -120,7 +124,7 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
         || SVGFitToViewBox::isKnownAttribute(attrName)
         || SVGStyledElement::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGMarkerElement::synchronizeProperty(const QualifiedName& attrName)
@@ -166,8 +170,11 @@ void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange,
 {
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 void SVGMarkerElement::setOrientToAuto()
@@ -175,7 +182,8 @@ void SVGMarkerElement::setOrientToAuto()
     setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO);
     setOrientAngleBaseValue(SVGAngle());
 
-    invalidateResourceClients();
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
@@ -183,7 +191,8 @@ void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
     setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE);
     setOrientAngleBaseValue(angle);
 
-    invalidateResourceClients();
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 RenderObject* SVGMarkerElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/svg/SVGMarkerElement.h b/WebCore/svg/SVGMarkerElement.h
index 689a7e5..7b13d34 100644
--- a/WebCore/svg/SVGMarkerElement.h
+++ b/WebCore/svg/SVGMarkerElement.h
@@ -56,6 +56,8 @@ public:
     SVGMarkerElement(const QualifiedName&, Document*);
     virtual ~SVGMarkerElement();
 
+    virtual bool needsPendingResourceHandling() const { return false; }
+
     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
 
     void setOrientToAuto();
diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp
index 5013e5c..a87c28e 100644
--- a/WebCore/svg/SVGMaskElement.cpp
+++ b/WebCore/svg/SVGMaskElement.cpp
@@ -102,6 +102,10 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
         updateRelativeLengthsInformation();
     }
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (invalidateClients
         || attrName == SVGNames::maskUnitsAttr
         || attrName == SVGNames::maskContentUnitsAttr
@@ -109,7 +113,7 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
         || SVGStyledElement::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGMaskElement::synchronizeProperty(const QualifiedName& attrName)
@@ -141,8 +145,11 @@ void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, N
 {
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 FloatRect SVGMaskElement::maskBoundingBox(const FloatRect& objectBoundingBox) const
diff --git a/WebCore/svg/SVGMaskElement.h b/WebCore/svg/SVGMaskElement.h
index e941667..2df8f31 100644
--- a/WebCore/svg/SVGMaskElement.h
+++ b/WebCore/svg/SVGMaskElement.h
@@ -40,6 +40,7 @@ namespace WebCore {
         virtual ~SVGMaskElement();
 
         virtual bool isValid() const { return SVGTests::isValid(); }
+        virtual bool needsPendingResourceHandling() const { return false; }
 
         FloatRect maskBoundingBox(const FloatRect&) const;
         virtual void parseMappedAttribute(Attribute*);
diff --git a/WebCore/svg/SVGPatternElement.cpp b/WebCore/svg/SVGPatternElement.cpp
index e258946..6196ff5 100644
--- a/WebCore/svg/SVGPatternElement.cpp
+++ b/WebCore/svg/SVGPatternElement.cpp
@@ -56,6 +56,7 @@ SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Document* doc
     , SVGLangSpace()
     , SVGExternalResourcesRequired()
     , SVGFitToViewBox()
+    , m_followLink(true)
     , m_x(LengthModeWidth)
     , m_y(LengthModeHeight)
     , m_width(LengthModeWidth)
@@ -129,6 +130,10 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
         updateRelativeLengthsInformation();
     }
 
+    RenderObject* object = renderer();
+    if (!object)
+        return;
+
     if (invalidateClients
         || attrName == SVGNames::patternUnitsAttr
         || attrName == SVGNames::patternContentUnitsAttr
@@ -139,7 +144,7 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
         || SVGFitToViewBox::isKnownAttribute(attrName)
         || SVGStyledElement::isKnownAttribute(attrName))
-        invalidateResourceClients();
+        object->setNeedsLayout(true);
 }
 
 void SVGPatternElement::synchronizeProperty(const QualifiedName& attrName)
@@ -188,8 +193,11 @@ void SVGPatternElement::childrenChanged(bool changedByParser, Node* beforeChange
 {
     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!changedByParser)
-        invalidateResourceClients();
+    if (changedByParser)
+        return;
+
+    if (RenderObject* object = renderer())
+        object->setNeedsLayout(true);
 }
 
 RenderObject* SVGPatternElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -231,13 +239,15 @@ PatternAttributes SVGPatternElement::collectPatternProperties() const
         processedPatterns.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = ownerDocument()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = m_followLink ? ownerDocument()->getElementById(SVGURIReference::getTarget(current->href())) : 0;
         if (refNode && refNode->hasTagName(SVGNames::patternTag)) {
             current = static_cast<const SVGPatternElement*>(const_cast<const Node*>(refNode));
 
             // Cycle detection
-            if (processedPatterns.contains(current))
-                return PatternAttributes();
+            if (processedPatterns.contains(current)) {
+                current = 0;
+                break;
+            }
         } else
             current = 0;
     }
diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h
index 105b8e2..f1bd3f4 100644
--- a/WebCore/svg/SVGPatternElement.h
+++ b/WebCore/svg/SVGPatternElement.h
@@ -47,6 +47,7 @@ namespace WebCore {
         virtual ~SVGPatternElement();
         
         virtual bool isValid() const { return SVGTests::isValid(); }
+        virtual bool needsPendingResourceHandling() const { return false; }
 
         virtual void parseMappedAttribute(Attribute*);
         virtual void svgAttributeChanged(const QualifiedName&);
@@ -56,10 +57,13 @@ namespace WebCore {
         virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 
         PatternAttributes collectPatternProperties() const;
+        void setFollowLink(bool followLink) { m_followLink = followLink; }
 
     private:
         virtual bool selfHasRelativeLengths() const;
 
+        bool m_followLink;
+
         DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::xAttr, SVGLength, X, x)
         DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::yAttr, SVGLength, Y, y)
         DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::widthAttr, SVGLength, Width, width)
diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp
index 2a97b9d..dc1c8d5 100644
--- a/WebCore/svg/SVGRadialGradientElement.cpp
+++ b/WebCore/svg/SVGRadialGradientElement.cpp
@@ -83,7 +83,12 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName
         || attrName == SVGNames::fyAttr
         || attrName == SVGNames::rAttr) {
         updateRelativeLengthsInformation();
-        invalidateResourceClients();
+        
+        RenderObject* object = renderer();
+        if (!object)
+            return;
+
+        object->setNeedsLayout(true);
     }
 }
 
@@ -163,13 +168,15 @@ RadialGradientAttributes SVGRadialGradientElement::collectGradientProperties()
         processedGradients.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = ownerDocument()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = m_followLink ? ownerDocument()->getElementById(SVGURIReference::getTarget(current->href())) : 0;
         if (refNode && (refNode->hasTagName(SVGNames::radialGradientTag) || refNode->hasTagName(SVGNames::linearGradientTag))) {
             current = static_cast<SVGGradientElement*>(refNode);
 
             // Cycle detection
-            if (processedGradients.contains(current))
-                return RadialGradientAttributes();
+            if (processedGradients.contains(current)) {
+                current = 0;
+                break;
+            }
 
             isRadial = current->hasTagName(SVGNames::radialGradientTag);
         } else
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 6c2993c..09447c5 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -258,17 +258,12 @@ void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeClassName();
 }
 
-void SVGStyledElement::invalidateResourceClients()
+void SVGStyledElement::attach()
 {
-    if (document()->parsing())
-        return;
-
-    RenderObject* object = renderer();
-    if (!object)
-        return;
+    SVGElement::attach();
 
-    if (object->isSVGResourceContainer())
-        object->toRenderSVGResourceContainer()->invalidateClients();
+    if (RenderObject* object = renderer())
+        object->updateFromElement();
 }
 
 void SVGStyledElement::insertedIntoDocument()
diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h
index 4982908..79ee0d5 100644
--- a/WebCore/svg/SVGStyledElement.h
+++ b/WebCore/svg/SVGStyledElement.h
@@ -57,6 +57,7 @@ namespace WebCore {
         virtual void svgAttributeChanged(const QualifiedName&);
         virtual void synchronizeProperty(const QualifiedName&);
 
+        virtual void attach();
         virtual void insertedIntoDocument();
         virtual void removedFromDocument();
         virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
@@ -64,8 +65,6 @@ namespace WebCore {
         // Centralized place to force a manual style resolution. Hacky but needed for now.
         PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle);
 
-        void invalidateResourceClients();
-
         bool instanceUpdatesBlocked() const;
         void setInstanceUpdatesBlocked(bool);
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list