[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

zimmermann at webkit.org zimmermann at webkit.org
Thu Apr 8 01:14:01 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit b74fff16baf1c00780376ae054b65b9108dde74d
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 19 02:17:28 2010 +0000

    2010-01-18  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Rewrite SVG <use> support in a modern-fashion
            https://bugs.webkit.org/show_bug.cgi?id=33776
    
            Tests: svg/custom/relative-sized-deep-shadow-tree-content.xhtml
                   svg/custom/relative-sized-shadow-tree-content.xhtml
    
            Fixes: svg/W3C-SVG-1.1/animate-elem-30-t.svg (animated circle sometimes takes wrong path)
    
            Rewrite <use> support in less intrusive way. Try hard to avoid recloning where possible, and do it lazily.
            Introduce RenderSVGShadowTreeRootContainer as special renderer for SVGUseElement, that now manages the
            render tree, instead of SVGUseElement manually hacking around it's own renderer from the DOM side.
    
            Instead of recloning the whole shadow tree for every attribute change (DOM setAttribute / SVG DOM changes / CSS changes / childrenChanged()...)
            just notify the RenderSVGShadowTreeRootContainer that it's supposed to reclone the tree upon the next updateFromElement() call.
    
            updateFromElement() is fired from SVGUseElement::attach() / recalcStyle(), as it's done for HTMLFormControlElement/HTMLMediaElement, thus
            lazily recloning the shadow tree if necessary.
    
            Animations for <use> elements was a real performance bottlenck as the tree got recloned on every attribute change. Reclones are _completly_
            avoided for animations now - the SVGAnim*Element classes already updated the instances of an element manually, though that resulted in a reclone
            nontheless, and thus killing performance. <use> elements can only be recloned through mutations of the elements that they reference to.
            For example referencing a <rect> element from a <use> element and scripting the <rect> element (setAttribute, or child tree mutations etc.).
            We reclone instead of trying to synchronize trees - as it's currenty implemented - because it's very hard to do it right.
    
            Any DOM / SVG DOM / CSS change on the <use> element don't reclone the tree anymore, this is a huge speed benefit.
            x/y attribute changes are correctly handled in the render tree now (by an additional local transformation), now percentual values work
            as expected, and resize on window changes - affecting lots of testcases.
    
            The <use> implementation is much safer now, not doing any mutations synchronously from svgAttributeChanged etc.
            Remove hack to force garbage collection on SVGElementInstance destruction - can't reproduce it anymore.
    
            * Android.mk: Add new files to build.
            * GNUmakefile.am: Ditto.
            * WebCore.gypi: Ditto.
            * WebCore.pro: Ditto.
            * WebCore.vcproj/WebCore.vcproj: Ditto.
            * WebCore.xcodeproj/project.pbxproj: Ditto.
            * rendering/RenderSVGShadowTreeRootContainer.cpp: Added. This is the rendered now created by SVGUseElement.
            (WebCore::RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer):
            (WebCore::RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer):
            (WebCore::RenderSVGShadowTreeRootContainer::updateStyle): Used form SVGUseElement to request style recalculations for the shadow tree renderers
            (WebCore::RenderSVGShadowTreeRootContainer::updateFromElement): Used from SVGUseElement attach/recalcStyle to eventually request shadow tree updates.
            (WebCore::RenderSVGShadowTreeRootContainer::styleDidChange): Used to propage style updates across shadow tree boundaries.
            * rendering/RenderSVGShadowTreeRootContainer.h: Added.
            (WebCore::RenderSVGShadowTreeRootContainer::markShadowTreeForRecreation): Marks the shadow tree for a reclone, next time updateFromElement is used.
            * rendering/RenderSVGTransformableContainer.cpp:
            (WebCore::RenderSVGTransformableContainer::calculateLocalTransform): Take containerTranslation() into account, supplied by RenderSVGSDhadowTreeContainer.
            * rendering/SVGShadowTreeElements.cpp: Added. This is the root element of the SVG shadow tree residing as (hidden) child of SVGUseElement (DOM wise).
            (WebCore::SVGShadowTreeContainerElement::SVGShadowTreeContainerElement):
            (WebCore::SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement):
            (WebCore::SVGShadowTreeContainerElement::containerTranslation): Used from calculateLocalTransform() to take x/y translation into account for shadow tree container elements.
            (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement):
            (WebCore::SVGShadowTreeRootElement::~SVGShadowTreeRootElement):
            (WebCore::SVGShadowTreeRootElement::attachElement): Used by RenderSVGShadowTreeRootContainer, instead of attach(), as we're a shadow tree root node.
            * rendering/SVGShadowTreeElements.h: Added. This is the root element of each SVG shadow sub-tree (whenever a <use> element is expanded in the shadow tree).
            (WebCore::SVGShadowTreeContainerElement::isShadowTreeContainerElement): Return true here.
            (WebCore::SVGShadowTreeContainerElement::setContainerOffset): Used from SVGUseElement to propagate x/y translation values set on <use> elements in the shadow tree.
            (WebCore::SVGShadowTreeRootElement::isShadowNode): Identify us as shadow node.
            (WebCore::SVGShadowTreeRootElement::shadowParentNode): Ditto. Return actual shadow parent node (== corresponding use element).
            * svg/SVGElement.cpp: Shrink size of all SVG*Elements, by removing the m_shadowParent parent. SVGShadowTreeRootElement is the new base class for shadow tree.
            (WebCore::SVGElement::SVGElement):
            (WebCore::SVGElement::eventParentNode): Call virtual shadowParentNode() method, instead of accessing m_shadowParent.
            * svg/SVGElement.h: Remove isShadowNode() / shadowParentNode() / setShadowParentNode().
            * svg/SVGElementInstance.cpp: Remove the hack, calling garbage collection before destruction. Can't reproduce this anymore, let's see what the bots say.
            (WebCore::SVGElementInstance::SVGElementInstance): Remove now unnecessary m_needsUpdate flag.
            (WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Don't invalidate if instance updates are blocked (see SVGStyledElement changes)
            * svg/SVGElementInstance.h: Remove m_needsUpdate, and forgetWrapper() method.
            * svg/SVGGElement.h:
            (WebCore::SVGGElement::isShadowTreeContainerElement): Add new virtual method here returning false by default, SVGShadowTreeContainerElement will override it.
            * svg/SVGStyledElement.cpp: Remove gElementsWithInstanceUpdatesBlocked HashSet tracking the state of instancesUpdatesBlocked() per SVGStyledElement - make it a member variable.
            * svg/SVGStyledElement.h: Add inline getter/setters around m_instanceUpdatesBlocked.
            (WebCore::SVGStyledElement::instanceUpdatesBlocked):
            (WebCore::SVGStyledElement::setInstanceUpdatesBlocked):
            * svg/SVGUseElement.cpp: Full rewrite of <use> support, a detailed discussion would blow the ChangeLog - see short version above.
            (WebCore::SVGUseElement::SVGUseElement):
            (WebCore::SVGUseElement::instanceRoot):
            (WebCore::SVGUseElement::insertedIntoDocument):
            (WebCore::SVGUseElement::removedFromDocument):
            (WebCore::SVGUseElement::svgAttributeChanged):
            (WebCore::updateContainerOffset):
            (WebCore::SVGUseElement::updateContainerOffsets):
            (WebCore::SVGUseElement::recalcStyle):
            (WebCore::dumpInstanceTree):
            (WebCore::SVGUseElement::buildPendingResource):
            (WebCore::SVGUseElement::buildShadowAndInstanceTree):
            (WebCore::SVGUseElement::createRenderer):
            (WebCore::updateFromElementCallback):
            (WebCore::SVGUseElement::attach):
            (WebCore::SVGUseElement::detach):
            (WebCore::SVGUseElement::toClipPath):
            (WebCore::SVGUseElement::buildInstanceTree):
            (WebCore::SVGUseElement::handleDeepUseReferencing):
            (WebCore::SVGUseElement::buildShadowTree):
            (WebCore::SVGUseElement::expandUseElementsInShadowTree):
            (WebCore::SVGUseElement::expandSymbolElementsInShadowTree):
            (WebCore::SVGUseElement::instanceForShadowTreeElement):
            (WebCore::SVGUseElement::invalidateShadowTree):
            (WebCore::SVGUseElement::transferUseAttributesToReplacedElement):
            * svg/SVGUseElement.h:
            (WebCore::SVGUseElement::isPendingResource):
    2010-01-18  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Rewrite SVG <use> support in a modern-fashion
            https://bugs.webkit.org/show_bug.cgi?id=33776
    
            Update some test results, after rewriting <use> support.
    
            * platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt:
            * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum: Added.
            * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png: Added.
            * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt: Added.
            * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum: Added.
            * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png: Added.
            * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt: Added.
            * platform/mac/svg/custom/use-events-crash-expected.txt:
            * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt:
            * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt:
            * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt:
            * platform/mac/svg/custom/use-recursion-1-expected.txt:
            * platform/mac/svg/custom/use-recursion-2-expected.txt:
            * platform/mac/svg/custom/use-recursion-3-expected.txt:
            * platform/mac/svg/custom/use-recursion-4-expected.txt:
            * platform/mac/svg/hixie/error/017-expected.txt:
            * platform/mac/svg/text/text-text-05-t-expected.checksum:
            * platform/mac/svg/text/text-text-05-t-expected.png:
            * svg/custom/relative-sized-deep-shadow-tree-content.xhtml: Added.
            * svg/custom/relative-sized-shadow-tree-content.xhtml: Added.
            * svg/text/text-text-05-t.svg: Remove possible race-condition, between selecting & dumping.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53446 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 0b1eefd..ea45242 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,34 @@
+2010-01-18  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Rewrite SVG <use> support in a modern-fashion
+        https://bugs.webkit.org/show_bug.cgi?id=33776
+
+        Update some test results, after rewriting <use> support.
+
+        * platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt:
+        * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum: Added.
+        * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png: Added.
+        * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt: Added.
+        * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum: Added.
+        * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png: Added.
+        * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt: Added.
+        * platform/mac/svg/custom/use-events-crash-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt:
+        * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt:
+        * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt:
+        * platform/mac/svg/custom/use-recursion-1-expected.txt:
+        * platform/mac/svg/custom/use-recursion-2-expected.txt:
+        * platform/mac/svg/custom/use-recursion-3-expected.txt:
+        * platform/mac/svg/custom/use-recursion-4-expected.txt:
+        * platform/mac/svg/hixie/error/017-expected.txt:
+        * platform/mac/svg/text/text-text-05-t-expected.checksum:
+        * platform/mac/svg/text/text-text-05-t-expected.png:
+        * svg/custom/relative-sized-deep-shadow-tree-content.xhtml: Added.
+        * svg/custom/relative-sized-shadow-tree-content.xhtml: Added.
+        * svg/text/text-text-05-t.svg: Remove possible race-condition, between selecting & dumping.
+
 2010-01-18  Kent Tamura  <tkent at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt
index ab9cdb9..8711387 100644
--- a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt
+++ b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt
@@ -12,7 +12,7 @@ layer at (0,0) size 480x360
           RenderSVGContainer {g} at (-18.50,-18.50) size 37x37
             RenderSVGContainer {use} at (-18.50,-18.50) size 7x7
               RenderSVGContainer {g} at (-18.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-15.00,-15.00)}]
-                RenderPath {rect} at (-18.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#E6E6E6]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
+                RenderPath {rect} at (-18.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#FFB400]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
             RenderSVGContainer {use} at (11.50,-18.50) size 7x7
               RenderSVGContainer {g} at (11.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(15.00,-15.00)}]
                 RenderPath {rect} at (11.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#E6E6E6]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
@@ -112,7 +112,7 @@ layer at (0,0) size 480x360
           RenderSVGContainer {g} at (-18.50,-18.50) size 37x37
             RenderSVGContainer {use} at (-18.50,-18.50) size 7x7
               RenderSVGContainer {g} at (-18.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-15.00,-15.00)}]
-                RenderPath {rect} at (-18.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#E6E6E6]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
+                RenderPath {rect} at (-18.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#FFB400]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
             RenderSVGContainer {use} at (11.50,-18.50) size 7x7
               RenderSVGContainer {g} at (11.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(15.00,-15.00)}]
                 RenderPath {rect} at (11.50,-18.50) size 7x7 [stroke={[type=SOLID] [color=#FFB400]}] [fill={[type=SOLID] [color=#E6E6E6]}] [data="M-3.00,-3.00 L3.00,-3.00 L3.00,3.00 L-3.00,3.00 Z"]
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum
new file mode 100644
index 0000000..59ecf10
--- /dev/null
+++ b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum
@@ -0,0 +1 @@
+40ae5846564985679efb127bc7cff6d2
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png
new file mode 100644
index 0000000..cde408b
Binary files /dev/null and b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt
new file mode 100644
index 0000000..9653ea7
--- /dev/null
+++ b/LayoutTests/platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt
@@ -0,0 +1,21 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x478
+  RenderBlock {html} at (0,0) size 800x478
+    RenderBody {body} at (8,16) size 784x454
+      RenderBlock {p} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 750x36
+          text run at (0,0) width 750: "The svg area contained in the div element (red box), should contain one blue rectangle from (50%,50%)-(100%,100%),"
+          text run at (0,18) width 360: "especially after resizing the content box to a different size"
+      RenderBlock {div} at (0,52) size 402x402 [border: (1px solid #FF0000)]
+        RenderSVGRoot {svg} at (209,269) size 200x200
+          RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+            RenderPath {rect} at (0,100) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L200.00,100.00 L200.00,300.00 L0.00,300.00 Z"]
+            RenderSVGContainer {use} at (100,100) size 200x200
+              RenderSVGContainer {g} at (100,100) size 200x200 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,0.00)}]
+                RenderPath {rect} at (100,100) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L200.00,100.00 L200.00,300.00 L0.00,300.00 Z"]
+          RenderSVGContainer {use} at (209,269) size 200x200
+            RenderSVGContainer {g} at (209,269) size 200x200 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,100.00)}]
+              RenderSVGContainer {g} at (209,269) size 200x200 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,0.00)}]
+                RenderPath {rect} at (209,269) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,100.00 L200.00,100.00 L200.00,300.00 L0.00,300.00 Z"]
+        RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum
new file mode 100644
index 0000000..6c1ffcb
--- /dev/null
+++ b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum
@@ -0,0 +1 @@
+0b5b1a4e1be0071849ce76576bbe56df
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png
new file mode 100644
index 0000000..b72cc05
Binary files /dev/null and b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt
new file mode 100644
index 0000000..2a7ff5b
--- /dev/null
+++ b/LayoutTests/platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt
@@ -0,0 +1,25 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x478
+  RenderBlock {html} at (0,0) size 800x478
+    RenderBody {body} at (8,16) size 784x454
+      RenderBlock {p} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 721x36
+          text run at (0,0) width 721: "The svg area contained in the div element (red box), should fill out the whole area (two blue rectangles, first: (0,0)-"
+          text run at (0,18) width 670: "(50%,50%), second: (50%,50%)-(100%,100%)), especially after resizing the content box to a different size"
+      RenderBlock {div} at (0,52) size 402x402 [border: (1px solid #FF0000)]
+        RenderSVGRoot {svg} at (9,69) size 400x400
+          RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+            RenderPath {rect} at (0,200) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,200.00 L200.00,200.00 L200.00,400.00 L0.00,400.00 Z"]
+            RenderPath {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L200.00,0.00 L200.00,200.00 L0.00,200.00 Z"]
+            RenderSVGContainer {use} at (0,0) size 200x200
+              RenderSVGContainer {g} at (0,0) size 200x200
+                RenderPath {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L200.00,0.00 L200.00,200.00 L0.00,200.00 Z"]
+          RenderSVGContainer {use} at (209,269) size 200x200
+            RenderSVGContainer {g} at (209,269) size 200x200 [transform={m=((1.00,0.00)(0.00,1.00)) t=(200.00,0.00)}]
+              RenderPath {rect} at (209,269) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,200.00 L200.00,200.00 L200.00,400.00 L0.00,400.00 Z"]
+          RenderSVGContainer {use} at (9,69) size 200x200
+            RenderSVGContainer {g} at (9,69) size 200x200
+              RenderSVGContainer {g} at (9,69) size 200x200
+                RenderPath {rect} at (9,69) size 200x200 [fill={[type=SOLID] [color=#0000FF]}] [data="M0.00,0.00 L200.00,0.00 L200.00,200.00 L0.00,200.00 Z"]
+        RenderText {#text} at (0,0) size 0x0
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 3a429f4..77440f9 100644
--- a/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
@@ -19,3 +19,4 @@ 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/custom/use-on-disallowed-foreign-object-1-expected.txt b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt
index 6497587..5738aba 100644
--- a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt
@@ -7,4 +7,4 @@ layer at (0,0) size 800x600
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
     RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}]
-      RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]
+      RenderSVGContainer {g} at (250,-50) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt
index b7ddab2..21eae1b 100644
--- a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt
@@ -7,7 +7,7 @@ layer at (0,0) size 800x600
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
     RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}]
-      RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]
+      RenderSVGContainer {g} at (250,-50) size 0x0
     RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}]
       RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]
-        RenderSVGContainer {g} at (452.13,115.56) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-35.86)}]
+        RenderSVGContainer {g} at (462.13,119.71) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(260.00,-40.00)}]
diff --git a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt
index 919de41..4885764 100644
--- a/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt
@@ -14,6 +14,6 @@ layer at (0,0) size 800x600
           RenderSVGContainer {g} at (250,-35.86) size 0x0
     RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}]
       RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]
-        RenderSVGContainer {g} at (452.13,115.56) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-35.86)}]
-          RenderSVGContainer {g} at (452.13,115.56) size 0x0
-            RenderSVGContainer {g} at (452.13,115.56) size 0x0
+        RenderSVGContainer {g} at (462.13,119.71) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(260.00,-40.00)}]
+          RenderSVGContainer {g} at (462.13,119.71) size 0x0
+            RenderSVGContainer {g} at (462.13,119.71) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt b/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt
index 5919608..5738aba 100644
--- a/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt
@@ -7,3 +7,4 @@ layer at (0,0) size 800x600
         RenderText {#text} at (0,0) size 244x18
           text run at (0,0) width 244: "You should only see this string ONCE"
     RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}]
+      RenderSVGContainer {g} at (250,-50) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt b/LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt
index 3dc10de..020e94a 100644
--- a/LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt
@@ -6,7 +6,9 @@ layer at (0,0) size 800x600
       RenderSVGContainer {g} at (-2.50,-2.50) size 65x15
         RenderPath {rect} at (-2.50,-2.50) size 65x15 [stroke={[type=SOLID] [color=#000080] [stroke width=5.00]}] [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L60.00,0.00 L60.00,10.00 L0.00,10.00 Z"]
         RenderSVGContainer {use} at (0,0) size 0x0
+          RenderSVGContainer {g} at (0,0) size 0x0
     RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,-14) size 139x18
         chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash."
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt b/LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt
index e724e44..b5d2bfa 100644
--- a/LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt
@@ -6,3 +6,4 @@ layer at (0,0) size 800x600
       RenderSVGInlineText {#text} at (0,-14) size 139x18
         chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash."
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt b/LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt
index 3dc10de..020e94a 100644
--- a/LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt
@@ -6,7 +6,9 @@ layer at (0,0) size 800x600
       RenderSVGContainer {g} at (-2.50,-2.50) size 65x15
         RenderPath {rect} at (-2.50,-2.50) size 65x15 [stroke={[type=SOLID] [color=#000080] [stroke width=5.00]}] [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L60.00,0.00 L60.00,10.00 L0.00,10.00 Z"]
         RenderSVGContainer {use} at (0,0) size 0x0
+          RenderSVGContainer {g} at (0,0) size 0x0
     RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,-14) size 139x18
         chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash."
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt b/LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt
index f432a22..a0afd78 100644
--- a/LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt
+++ b/LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt
@@ -10,7 +10,9 @@ layer at (0,0) size 800x600
       RenderSVGContainer {g} at (-2.50,-2.50) size 65x15
         RenderPath {rect} at (-2.50,-2.50) size 65x15 [stroke={[type=SOLID] [color=#000080] [stroke width=5.00]}] [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,0.00 L60.00,0.00 L60.00,10.00 L0.00,10.00 Z"]
         RenderSVGContainer {use} at (0,0) size 0x0
+          RenderSVGContainer {g} at (0,0) size 0x0
     RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,-14) size 139x18
         chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash."
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt b/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
index 26dd192..81d0a05 100644
--- a/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
+++ b/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
@@ -17,6 +17,7 @@ layer at (0,0) size 800x600
             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
     RenderSVGText {text} at (20,220) size 444x230 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,-180) size 444x230
         chunk 1 text run 1 at (20.00,220.00) startOffset 0 endOffset 4 width 444.00: "FAIL"
diff --git a/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.checksum b/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.checksum
index 4bd0641..d5df45e 100644
--- a/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.checksum
+++ b/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.checksum
@@ -1 +1 @@
-0571a94f26afb9720655647261fc786c
\ No newline at end of file
+db9ca27ce7850c95e06bb13bbcf32246
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.png b/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.png
index c487f76..9c1212c 100644
Binary files a/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.png and b/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.png differ
diff --git a/LayoutTests/svg/custom/relative-sized-deep-shadow-tree-content.xhtml b/LayoutTests/svg/custom/relative-sized-deep-shadow-tree-content.xhtml
new file mode 100644
index 0000000..7eeb80c
--- /dev/null
+++ b/LayoutTests/svg/custom/relative-sized-deep-shadow-tree-content.xhtml
@@ -0,0 +1,24 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body onload="window.setTimeout(resizeBox,0)">
+    <p>The svg area contained in the div element (red box), should contain one blue rectangle from (50%,50%)-(100%,100%), especially after resizing the content box to a different size</p>
+    <div id="contentBox" style="width: 100px; height: 400px; border: 1px solid red;">
+        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+            <defs>
+                <rect id="targetRect" y="25%" width="50%" height="50%" fill="blue"/>
+                <use id="targetUse" x="25%" xlink:href="#targetRect"/>
+            </defs>
+            <use x="25%" y="25%" xlink:href="#targetUse"/>
+        </svg>
+    </div>
+    <script>
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        function resizeBox() {
+            document.getElementById("contentBox").style.setProperty("width", "400px");
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }
+    </script>
+</body>
+</html>
diff --git a/LayoutTests/svg/custom/relative-sized-shadow-tree-content.xhtml b/LayoutTests/svg/custom/relative-sized-shadow-tree-content.xhtml
new file mode 100644
index 0000000..1e98288
--- /dev/null
+++ b/LayoutTests/svg/custom/relative-sized-shadow-tree-content.xhtml
@@ -0,0 +1,26 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body onload="window.setTimeout(resizeBox,0)">
+    <p>The svg area contained in the div element (red box), should fill out the whole area (two blue rectangles, first: (0,0)-(50%,50%), second: (50%,50%)-(100%,100%)), especially after resizing the content box to a different size</p>
+    <div id="contentBox" style="width: 100px; height: 400px; border: 1px solid red;">
+        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+            <defs>
+                <rect id="targetRect" y="50%" width="50%" height="50%" fill="blue"/>
+                <rect id="targetRect1" y="0%" width="50%" height="50%" fill="blue"/>
+                <use id="targetUse" xlink:href="#targetRect1"/>
+            </defs>
+            <use x="50%" xlink:href="#targetRect"/>
+            <use xlink:href="#targetUse"/>
+        </svg>
+    </div>
+    <script>
+        if (window.layoutTestController)
+            layoutTestController.waitUntilDone();
+
+        function resizeBox() {
+            document.getElementById("contentBox").style.setProperty("width", "400px");
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }
+    </script>
+</body>
+</html>
diff --git a/LayoutTests/svg/text/text-text-05-t.svg b/LayoutTests/svg/text/text-text-05-t.svg
index b6e5697..daa17b3 100644
--- a/LayoutTests/svg/text/text-text-05-t.svg
+++ b/LayoutTests/svg/text/text-text-05-t.svg
@@ -159,8 +159,15 @@
     <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
     
 <script>
-if (window.layoutTestController)
-    window.layoutTestController.dumpSelectionRect();
-document.execCommand("SelectAll");
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+    layoutTestController.dumpSelectionRect();
+}
+
+setTimeout(function() { 
+    document.execCommand("SelectAll");
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}, 0);
 </script>
 </svg>
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index bb87603..823dd35 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -596,6 +596,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
 	rendering/RenderSVGInlineText.cpp \
 	rendering/RenderSVGModelObject.cpp \
 	rendering/RenderSVGRoot.cpp \
+	rendering/RenderSVGShadowTreeRootContainer.cpp \
 	rendering/RenderSVGTSpan.cpp \
 	rendering/RenderSVGText.cpp \
 	rendering/RenderSVGTextPath.cpp \
@@ -634,7 +635,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
 	rendering/SVGMarkerLayoutInfo.cpp \
 	rendering/SVGRenderSupport.cpp \
 	rendering/SVGRenderTreeAsText.cpp \
-	rendering/SVGRootInlineBox.cpp
+	rendering/SVGRootInlineBox.cpp \
+	rendering/SVGShadowTreeElements.cpp
 endif
 
 LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d4d3a15..d260e17 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,108 @@
+2010-01-18  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Rewrite SVG <use> support in a modern-fashion
+        https://bugs.webkit.org/show_bug.cgi?id=33776
+
+        Tests: svg/custom/relative-sized-deep-shadow-tree-content.xhtml
+               svg/custom/relative-sized-shadow-tree-content.xhtml
+
+        Fixes: svg/W3C-SVG-1.1/animate-elem-30-t.svg (animated circle sometimes takes wrong path)
+
+        Rewrite <use> support in less intrusive way. Try hard to avoid recloning where possible, and do it lazily.
+        Introduce RenderSVGShadowTreeRootContainer as special renderer for SVGUseElement, that now manages the
+        render tree, instead of SVGUseElement manually hacking around it's own renderer from the DOM side.
+
+        Instead of recloning the whole shadow tree for every attribute change (DOM setAttribute / SVG DOM changes / CSS changes / childrenChanged()...)
+        just notify the RenderSVGShadowTreeRootContainer that it's supposed to reclone the tree upon the next updateFromElement() call.
+
+        updateFromElement() is fired from SVGUseElement::attach() / recalcStyle(), as it's done for HTMLFormControlElement/HTMLMediaElement, thus
+        lazily recloning the shadow tree if necessary.
+
+        Animations for <use> elements was a real performance bottlenck as the tree got recloned on every attribute change. Reclones are _completly_
+        avoided for animations now - the SVGAnim*Element classes already updated the instances of an element manually, though that resulted in a reclone
+        nontheless, and thus killing performance. <use> elements can only be recloned through mutations of the elements that they reference to.
+        For example referencing a <rect> element from a <use> element and scripting the <rect> element (setAttribute, or child tree mutations etc.).
+        We reclone instead of trying to synchronize trees - as it's currenty implemented - because it's very hard to do it right.
+
+        Any DOM / SVG DOM / CSS change on the <use> element don't reclone the tree anymore, this is a huge speed benefit.
+        x/y attribute changes are correctly handled in the render tree now (by an additional local transformation), now percentual values work
+        as expected, and resize on window changes - affecting lots of testcases.
+
+        The <use> implementation is much safer now, not doing any mutations synchronously from svgAttributeChanged etc.
+        Remove hack to force garbage collection on SVGElementInstance destruction - can't reproduce it anymore.
+
+        * Android.mk: Add new files to build.
+        * GNUmakefile.am: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.pro: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * rendering/RenderSVGShadowTreeRootContainer.cpp: Added. This is the rendered now created by SVGUseElement.
+        (WebCore::RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer):
+        (WebCore::RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer):
+        (WebCore::RenderSVGShadowTreeRootContainer::updateStyle): Used form SVGUseElement to request style recalculations for the shadow tree renderers
+        (WebCore::RenderSVGShadowTreeRootContainer::updateFromElement): Used from SVGUseElement attach/recalcStyle to eventually request shadow tree updates.
+        (WebCore::RenderSVGShadowTreeRootContainer::styleDidChange): Used to propage style updates across shadow tree boundaries.
+        * rendering/RenderSVGShadowTreeRootContainer.h: Added.
+        (WebCore::RenderSVGShadowTreeRootContainer::markShadowTreeForRecreation): Marks the shadow tree for a reclone, next time updateFromElement is used.
+        * rendering/RenderSVGTransformableContainer.cpp:
+        (WebCore::RenderSVGTransformableContainer::calculateLocalTransform): Take containerTranslation() into account, supplied by RenderSVGSDhadowTreeContainer.
+        * rendering/SVGShadowTreeElements.cpp: Added. This is the root element of the SVG shadow tree residing as (hidden) child of SVGUseElement (DOM wise).
+        (WebCore::SVGShadowTreeContainerElement::SVGShadowTreeContainerElement):
+        (WebCore::SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement):
+        (WebCore::SVGShadowTreeContainerElement::containerTranslation): Used from calculateLocalTransform() to take x/y translation into account for shadow tree container elements.
+        (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement):
+        (WebCore::SVGShadowTreeRootElement::~SVGShadowTreeRootElement):
+        (WebCore::SVGShadowTreeRootElement::attachElement): Used by RenderSVGShadowTreeRootContainer, instead of attach(), as we're a shadow tree root node.
+        * rendering/SVGShadowTreeElements.h: Added. This is the root element of each SVG shadow sub-tree (whenever a <use> element is expanded in the shadow tree).
+        (WebCore::SVGShadowTreeContainerElement::isShadowTreeContainerElement): Return true here.
+        (WebCore::SVGShadowTreeContainerElement::setContainerOffset): Used from SVGUseElement to propagate x/y translation values set on <use> elements in the shadow tree.
+        (WebCore::SVGShadowTreeRootElement::isShadowNode): Identify us as shadow node.
+        (WebCore::SVGShadowTreeRootElement::shadowParentNode): Ditto. Return actual shadow parent node (== corresponding use element).
+        * svg/SVGElement.cpp: Shrink size of all SVG*Elements, by removing the m_shadowParent parent. SVGShadowTreeRootElement is the new base class for shadow tree.
+        (WebCore::SVGElement::SVGElement):
+        (WebCore::SVGElement::eventParentNode): Call virtual shadowParentNode() method, instead of accessing m_shadowParent.
+        * svg/SVGElement.h: Remove isShadowNode() / shadowParentNode() / setShadowParentNode().
+        * svg/SVGElementInstance.cpp: Remove the hack, calling garbage collection before destruction. Can't reproduce this anymore, let's see what the bots say.
+        (WebCore::SVGElementInstance::SVGElementInstance): Remove now unnecessary m_needsUpdate flag.
+        (WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Don't invalidate if instance updates are blocked (see SVGStyledElement changes)
+        * svg/SVGElementInstance.h: Remove m_needsUpdate, and forgetWrapper() method.
+        * svg/SVGGElement.h:
+        (WebCore::SVGGElement::isShadowTreeContainerElement): Add new virtual method here returning false by default, SVGShadowTreeContainerElement will override it.
+        * svg/SVGStyledElement.cpp: Remove gElementsWithInstanceUpdatesBlocked HashSet tracking the state of instancesUpdatesBlocked() per SVGStyledElement - make it a member variable.
+        * svg/SVGStyledElement.h: Add inline getter/setters around m_instanceUpdatesBlocked.
+        (WebCore::SVGStyledElement::instanceUpdatesBlocked):
+        (WebCore::SVGStyledElement::setInstanceUpdatesBlocked):
+        * svg/SVGUseElement.cpp: Full rewrite of <use> support, a detailed discussion would blow the ChangeLog - see short version above.
+        (WebCore::SVGUseElement::SVGUseElement):
+        (WebCore::SVGUseElement::instanceRoot):
+        (WebCore::SVGUseElement::insertedIntoDocument):
+        (WebCore::SVGUseElement::removedFromDocument):
+        (WebCore::SVGUseElement::svgAttributeChanged):
+        (WebCore::updateContainerOffset):
+        (WebCore::SVGUseElement::updateContainerOffsets):
+        (WebCore::SVGUseElement::recalcStyle):
+        (WebCore::dumpInstanceTree):
+        (WebCore::SVGUseElement::buildPendingResource):
+        (WebCore::SVGUseElement::buildShadowAndInstanceTree):
+        (WebCore::SVGUseElement::createRenderer):
+        (WebCore::updateFromElementCallback):
+        (WebCore::SVGUseElement::attach):
+        (WebCore::SVGUseElement::detach):
+        (WebCore::SVGUseElement::toClipPath):
+        (WebCore::SVGUseElement::buildInstanceTree):
+        (WebCore::SVGUseElement::handleDeepUseReferencing):
+        (WebCore::SVGUseElement::buildShadowTree):
+        (WebCore::SVGUseElement::expandUseElementsInShadowTree):
+        (WebCore::SVGUseElement::expandSymbolElementsInShadowTree):
+        (WebCore::SVGUseElement::instanceForShadowTreeElement):
+        (WebCore::SVGUseElement::invalidateShadowTree):
+        (WebCore::SVGUseElement::transferUseAttributesToReplacedElement):
+        * svg/SVGUseElement.h:
+        (WebCore::SVGUseElement::isPendingResource):
+
 2010-01-18  Kent Tamura  <tkent at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 52dee53..dbb9f5f 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -2947,6 +2947,8 @@ webcore_sources += \
 	WebCore/rendering/RenderSVGModelObject.h \
 	WebCore/rendering/RenderSVGRoot.cpp \
 	WebCore/rendering/RenderSVGRoot.h \
+	WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp \
+	WebCore/rendering/RenderSVGShadowTreeRootContainer.h \
 	WebCore/rendering/RenderSVGTSpan.cpp \
 	WebCore/rendering/RenderSVGTSpan.h \
 	WebCore/rendering/RenderSVGText.cpp \
@@ -2972,6 +2974,8 @@ webcore_sources += \
 	WebCore/rendering/SVGRenderTreeAsText.h \
 	WebCore/rendering/SVGRootInlineBox.cpp \
 	WebCore/rendering/SVGRootInlineBox.h \
+	WebCore/rendering/SVGShadowTreeElements.cpp \
+	WebCore/rendering/SVGShadowTreeElements.h \
 	WebCore/rendering/style/SVGRenderStyle.cpp \
 	WebCore/rendering/style/SVGRenderStyle.h \
 	WebCore/rendering/style/SVGRenderStyleDefs.cpp \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index d7af39f..aa5f59b 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -3056,6 +3056,8 @@
             'rendering/RenderSVGModelObject.h',
             'rendering/RenderSVGRoot.cpp',
             'rendering/RenderSVGRoot.h',
+            'rendering/RenderSVGShadowTreeRootContainer.cpp',
+            'rendering/RenderSVGShadowTreeRootContainer.h',
             'rendering/RenderSVGTSpan.cpp',
             'rendering/RenderSVGTSpan.h',
             'rendering/RenderSVGText.cpp',
@@ -3140,6 +3142,8 @@
             'rendering/SVGRenderTreeAsText.h',
             'rendering/SVGRootInlineBox.cpp',
             'rendering/SVGRootInlineBox.h',
+            'rendering/SVGShadowTreeElements.cpp',
+            'rendering/SVGShadowTreeElements.h',
             'rendering/TableLayout.h',
             'rendering/TextControlInnerElements.cpp',
             'rendering/TextControlInnerElements.h',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index fce4312..51e26a1 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1634,6 +1634,7 @@ HEADERS += \
     rendering/RenderSVGInlineText.h \
     rendering/RenderSVGModelObject.h \
     rendering/RenderSVGRoot.h \
+    rendering/RenderSVGShadowTreeRootContainer.h \
     rendering/RenderSVGText.h \
     rendering/RenderSVGTextPath.h \
     rendering/RenderSVGTransformableContainer.h \
@@ -1691,6 +1692,7 @@ HEADERS += \
     rendering/SVGRenderSupport.h \
     rendering/SVGRenderTreeAsText.h \
     rendering/SVGRootInlineBox.h \
+    rendering/SVGShadowTreeElements.h \
     rendering/TextControlInnerElements.h \
     rendering/TransformState.h \
     svg/animation/SMILTimeContainer.h \
@@ -2578,6 +2580,7 @@ contains(DEFINES, ENABLE_SVG=1) {
         rendering/RenderSVGInlineText.cpp \
         rendering/RenderSVGModelObject.cpp \
         rendering/RenderSVGRoot.cpp \
+        rendering/RenderSVGShadowTreeRootContainer.cpp \
         rendering/RenderSVGText.cpp \
         rendering/RenderSVGTextPath.cpp \
         rendering/RenderSVGTransformableContainer.cpp \
@@ -2588,7 +2591,8 @@ contains(DEFINES, ENABLE_SVG=1) {
         rendering/SVGInlineTextBox.cpp \
         rendering/SVGMarkerLayoutInfo.cpp \
         rendering/SVGRenderSupport.cpp \
-        rendering/SVGRootInlineBox.cpp
+        rendering/SVGRootInlineBox.cpp \
+        rendering/SVGShadowTreeElements.cpp
 }
 
 contains(DEFINES, ENABLE_JAVASCRIPT_DEBUGGER=1) {
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 41d77a7..5d2ad8c 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -27465,6 +27465,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\rendering\RenderSVGShadowTreeRootContainer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\rendering\RenderSVGShadowTreeRootContainer.h"
+				>
+			</File>
+			<File
 				RelativePath="..\rendering\RenderSVGText.cpp"
 				>
 			</File>
@@ -27795,6 +27803,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\rendering\SVGShadowTreeElements.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\rendering\SVGShadowTreeElements.h"
+				>
+			</File>
+			<File
 				RelativePath="..\rendering\TableLayout.h"
 				>
 			</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index dad0a91..39a91e6 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -144,6 +144,10 @@
 		08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C925180FCC7C4A00480DEC /* FilterEffect.h */; };
 		08CD61BC0ED3929C002DDF51 /* WMLTaskElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08CD61B80ED3929C002DDF51 /* WMLTaskElement.cpp */; };
 		08CD61BD0ED3929C002DDF51 /* WMLTaskElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08CD61B90ED3929C002DDF51 /* WMLTaskElement.h */; };
+		08DAB9BA1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */; };
+		08DAB9BB1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */; };
+		08DAB9C21103D9C1003E7ABA /* SVGShadowTreeElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */; };
+		08DAB9C31103D9C1003E7ABA /* SVGShadowTreeElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */; };
 		08E192530EDE0C3A0087B780 /* WMLErrorHandling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08E192510EDE0C390087B780 /* WMLErrorHandling.cpp */; };
 		08E192540EDE0C3A0087B780 /* WMLErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E192520EDE0C3A0087B780 /* WMLErrorHandling.h */; };
 		08E4FE460E2BD41400F4CAE0 /* JSSVGLengthCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08E4FE450E2BD41400F4CAE0 /* JSSVGLengthCustom.cpp */; };
@@ -5368,6 +5372,10 @@
 		08C925180FCC7C4A00480DEC /* FilterEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FilterEffect.h; path = filters/FilterEffect.h; sourceTree = "<group>"; };
 		08CD61B80ED3929C002DDF51 /* WMLTaskElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLTaskElement.cpp; sourceTree = "<group>"; };
 		08CD61B90ED3929C002DDF51 /* WMLTaskElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLTaskElement.h; sourceTree = "<group>"; };
+		08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGShadowTreeRootContainer.cpp; sourceTree = "<group>"; };
+		08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGShadowTreeRootContainer.h; sourceTree = "<group>"; };
+		08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGShadowTreeElements.cpp; sourceTree = "<group>"; };
+		08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGShadowTreeElements.h; sourceTree = "<group>"; };
 		08E192510EDE0C390087B780 /* WMLErrorHandling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLErrorHandling.cpp; sourceTree = "<group>"; };
 		08E192520EDE0C3A0087B780 /* WMLErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLErrorHandling.h; sourceTree = "<group>"; };
 		08E4FE450E2BD41400F4CAE0 /* JSSVGLengthCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGLengthCustom.cpp; sourceTree = "<group>"; };
@@ -15581,6 +15589,8 @@
 				A8F5C0B60F9285AC0098E06B /* RenderSVGModelObject.h */,
 				AA31B5B20C1DFD1000AE7083 /* RenderSVGRoot.cpp */,
 				AA31B5B30C1DFD1000AE7083 /* RenderSVGRoot.h */,
+				08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */,
+				08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */,
 				853CA9D20AEEC5E9002372DC /* RenderSVGText.cpp */,
 				853CA9D30AEEC5E9002372DC /* RenderSVGText.h */,
 				B26554E80B80D74900A50EC3 /* RenderSVGTextPath.cpp */,
@@ -15644,6 +15654,8 @@
 				B2EBDC9B0AF77E3400AE4A68 /* SVGRenderTreeAsText.h */,
 				853CA9E40AEEC608002372DC /* SVGRootInlineBox.cpp */,
 				853CA9E50AEEC608002372DC /* SVGRootInlineBox.h */,
+				08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */,
+				08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */,
 				A8CFF04C0A154F09000A4234 /* TableLayout.h */,
 				AB014DE10E689A4300E10445 /* TextControlInnerElements.cpp */,
 				AB014DE20E689A4300E10445 /* TextControlInnerElements.h */,
@@ -18355,6 +18367,8 @@
 				6E4E91AD10F7FB3100A2779C /* CanvasContextAttributes.h in Headers */,
 				6E4E91AF10F7FB3100A2779C /* WebGLContextAttributes.h in Headers */,
 				6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */,
+				08DAB9BB1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h in Headers */,
+				08DAB9C31103D9C1003E7ABA /* SVGShadowTreeElements.h in Headers */,
 				E15A36D71104572000B7B639 /* XMLNSNames.h in Headers */,
 				59A9E7B21104759400DFB4C1 /* JavaInstanceJSC.h in Headers */,
 				59E560A71105336600AA1258 /* JavaClassJSC.h in Headers */,
@@ -20520,6 +20534,8 @@
 				6E4E91AC10F7FB3100A2779C /* CanvasContextAttributes.cpp in Sources */,
 				6E4E91AE10F7FB3100A2779C /* WebGLContextAttributes.cpp in Sources */,
 				6EE8A77210F803F3005A4A24 /* JSWebGLContextAttributes.cpp in Sources */,
+				08DAB9BA1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp in Sources */,
+				08DAB9C21103D9C1003E7ABA /* SVGShadowTreeElements.cpp in Sources */,
 				E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */,
 				59A9E7B01104758800DFB4C1 /* JavaInstanceJSC.cpp in Sources */,
 				59E560A91105336F00AA1258 /* JavaClassJSC.cpp in Sources */,
diff --git a/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
new file mode 100644
index 0000000..9d3d26f
--- /dev/null
+++ b/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
@@ -0,0 +1,101 @@
+/*
+    Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    aint with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGShadowTreeRootContainer.h"
+
+#include "MouseEvent.h"
+#include "SVGShadowTreeElements.h"
+#include "SVGUseElement.h"
+
+namespace WebCore {
+
+RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement* node)
+    : RenderSVGTransformableContainer(node)
+    , m_recreateTree(false)
+{
+}
+
+RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer()
+{
+    if (m_shadowRoot && m_shadowRoot->attached())
+        m_shadowRoot->detach();
+}
+
+void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change)
+{
+    if (m_shadowRoot && m_shadowRoot->attached())
+        m_shadowRoot->recalcStyle(change);
+}
+
+void RenderSVGShadowTreeRootContainer::updateFromElement()
+{
+    bool hadExistingTree = m_shadowRoot;
+
+    SVGUseElement* useElement = static_cast<SVGUseElement*>(node());
+    if (!m_shadowRoot) {
+        ASSERT(!m_recreateTree);
+        m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement);
+        useElement->buildPendingResource();
+    }
+
+    ASSERT(m_shadowRoot->shadowParentNode() == useElement);
+
+    bool shouldRecreateTree = m_recreateTree;
+    if (m_recreateTree) {
+        ASSERT(hadExistingTree);
+
+        if (m_shadowRoot->attached())
+            m_shadowRoot->detach();
+
+        m_shadowRoot->removeAllChildren();
+        m_recreateTree = false;
+    }
+
+    // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so
+    // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use
+    // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true.
+    if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) {
+        useElement->buildShadowAndInstanceTree(m_shadowRoot.get());
+
+        // Attach shadow root element
+        m_shadowRoot->attachElement(style(), renderArena());
+
+        // Attach subtree, as if it was a regular non-shadow tree
+        for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling())
+            child->attach();
+    }
+
+    ASSERT(!m_recreateTree);
+    RenderSVGTransformableContainer::updateFromElement();
+}
+
+void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+    RenderSVGTransformableContainer::styleDidChange(diff, oldStyle);
+
+    if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0)
+        shadowRootRenderer->setStyle(style());
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/RenderSVGShadowTreeRootContainer.h b/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
new file mode 100644
index 0000000..01cd427
--- /dev/null
+++ b/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
@@ -0,0 +1,50 @@
+/*
+    Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    aint with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RenderSVGShadowTreeRootContainer_h
+#define RenderSVGShadowTreeRootContainer_h
+
+#if ENABLE(SVG)
+#include "RenderSVGTransformableContainer.h"
+
+namespace WebCore {
+    
+class SVGUseElement;
+class SVGShadowTreeRootElement;
+
+class RenderSVGShadowTreeRootContainer : public RenderSVGTransformableContainer {
+public:
+    RenderSVGShadowTreeRootContainer(SVGUseElement*);
+    virtual ~RenderSVGShadowTreeRootContainer();
+
+    void markShadowTreeForRecreation() { m_recreateTree = true; }
+    void updateStyle(Node::StyleChange);
+    virtual void updateFromElement();
+
+private:
+    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+
+    bool m_recreateTree;
+    RefPtr<SVGShadowTreeRootElement> m_shadowRoot;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.cpp b/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 6520c6e..050e1bd 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox at kde.org>
+    Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann at kde.org>
                   2004, 2005, 2006 Rob Buis <buis at kde.org>
                   2009 Google, Inc.
 
@@ -20,12 +20,12 @@
  */
 
 #include "config.h"
-#if ENABLE(SVG)
 
+#if ENABLE(SVG)
 #include "RenderSVGTransformableContainer.h"
 
+#include "SVGShadowTreeElements.h"
 #include "SVGStyledTransformableElement.h"
-#include "SVGTransformList.h"
 
 namespace WebCore {
     
@@ -47,6 +47,14 @@ TransformationMatrix RenderSVGTransformableContainer::localTransform() const
 void RenderSVGTransformableContainer::calculateLocalTransform()
 {
     m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
+    if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement())
+        return;
+
+    FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(node())->containerTranslation();
+    if (translation.width() == 0 && translation.height() == 0)
+        return;
+
+    m_localTransform.translateRight(translation.width(), translation.height());
 }
 
 }
diff --git a/WebCore/rendering/SVGShadowTreeElements.cpp b/WebCore/rendering/SVGShadowTreeElements.cpp
new file mode 100644
index 0000000..d9ce640
--- /dev/null
+++ b/WebCore/rendering/SVGShadowTreeElements.cpp
@@ -0,0 +1,80 @@
+/*
+    Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    aint with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "SVGShadowTreeElements.h"
+
+#include "Document.h"
+#include "FloatSize.h"
+#include "RenderObject.h"
+#include "SVGNames.h"
+
+namespace WebCore {
+
+// SVGShadowTreeContainerElement
+SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document)
+    : SVGGElement(SVGNames::gTag, document)
+{
+}
+    
+SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement()
+{
+}
+
+FloatSize SVGShadowTreeContainerElement::containerTranslation() const
+{
+    return FloatSize(m_xOffset.value(this), m_yOffset.value(this));
+}
+
+// SVGShadowTreeRootElement
+SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* shadowParent)
+    : SVGShadowTreeContainerElement(document)
+    , m_shadowParent(shadowParent)
+{
+    setInDocument(true);
+}
+
+SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
+{
+}
+
+void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, RenderArena* arena)
+{
+    ASSERT(m_shadowParent);
+
+    // Create the renderer with the specified style
+    RenderObject* renderer = createRenderer(arena, style.get());
+    if (renderer) {
+        setRenderer(renderer);
+        renderer->setStyle(style);
+    }
+
+    // Set these explicitly since this normally happens during an attach()
+    setAttached();
+
+    // Add the renderer to the render tree
+    if (renderer)
+        m_shadowParent->renderer()->addChild(renderer);
+}
+
+}
+
+#endif
diff --git a/WebCore/rendering/SVGShadowTreeElements.h b/WebCore/rendering/SVGShadowTreeElements.h
new file mode 100644
index 0000000..ed42e89
--- /dev/null
+++ b/WebCore/rendering/SVGShadowTreeElements.h
@@ -0,0 +1,67 @@
+/*
+    Copyright (C) Research In Motion Limited 2010. All rights reserved.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    aint with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SVGShadowTreeElements_h
+#define SVGShadowTreeElements_h
+
+#if ENABLE(SVG)
+#include "SVGGElement.h"
+#include "SVGLength.h"
+
+namespace WebCore {
+
+class FloatSize;
+
+class SVGShadowTreeContainerElement : public SVGGElement {
+public:
+    SVGShadowTreeContainerElement(Document*);
+    virtual ~SVGShadowTreeContainerElement();
+
+    virtual bool isShadowTreeContainerElement() const { return true; }
+
+    FloatSize containerTranslation() const;
+    void setContainerOffset(const SVGLength& x, const SVGLength& y)
+    {
+        m_xOffset = x;
+        m_yOffset = y;
+    }
+
+private:
+    SVGLength m_xOffset;
+    SVGLength m_yOffset;
+};
+
+class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement {
+public:
+    SVGShadowTreeRootElement(Document*, Node* shadowParent);
+    virtual ~SVGShadowTreeRootElement();
+
+    virtual bool isShadowNode() const { return m_shadowParent; }
+    virtual Node* shadowParentNode() { return m_shadowParent; }
+
+    void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
+
+private:
+    Node* m_shadowParent;
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index a0d2d00..d039a4f 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -54,7 +54,6 @@ using namespace HTMLNames;
 
 SVGElement::SVGElement(const QualifiedName& tagName, Document* document)
     : StyledElement(tagName, document, CreateElementZeroRefCount)
-    , m_shadowParent(0)
     , m_cursorElement(0)
     , m_cursorImageValue(0)
 {
@@ -285,7 +284,11 @@ void SVGElement::setSynchronizedSVGAttributes(bool value) const
 
 ContainerNode* SVGElement::eventParentNode()
 {
-    return m_shadowParent ? m_shadowParent : StyledElement::eventParentNode();
+    if (Node* shadowParent = shadowParentNode()) {
+        ASSERT(shadowParent->isContainerNode());
+        return static_cast<ContainerNode*>(shadowParent);
+    }
+    return StyledElement::eventParentNode();
 }
 
 }
diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h
index b247a74..4e7f498 100644
--- a/WebCore/svg/SVGElement.h
+++ b/WebCore/svg/SVGElement.h
@@ -60,8 +60,6 @@ namespace WebCore {
         virtual bool isGradientStop() const { return false; }
         virtual bool isTextContent() const { return false; }
 
-        void setShadowParentNode(ContainerNode* node) { m_shadowParent = node; }
-
         // For SVGTests
         virtual bool isValid() const { return true; }
 
@@ -95,13 +93,9 @@ namespace WebCore {
         friend class SVGElementInstance;
 
         virtual bool isSVGElement() const { return true; }
-
         virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
-        
-        virtual bool isShadowNode() const { return m_shadowParent; }
-        virtual Node* shadowParentNode() { return m_shadowParent; }
-        virtual ContainerNode* eventParentNode();
 
+        virtual ContainerNode* eventParentNode();
         virtual void buildPendingResource() { }
 
         void mapInstanceToElement(SVGElementInstance*);
@@ -109,7 +103,6 @@ namespace WebCore {
 
         virtual bool haveLoadedRequiredResources();
 
-        ContainerNode* m_shadowParent;
         mutable SynchronizablePropertyController m_propertyController;
 
         SVGCursorElement* m_cursorElement;
diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp
index 46e8221..54ee1c4 100644
--- a/WebCore/svg/SVGElementInstance.cpp
+++ b/WebCore/svg/SVGElementInstance.cpp
@@ -33,10 +33,6 @@
 
 #include <wtf/RefCountedLeakCounter.h>
 
-#if USE(JSC)
-#include "GCController.h"
-#endif
-
 namespace WebCore {
 
 #ifndef NDEBUG
@@ -51,8 +47,7 @@ static EventTargetData& dummyEventTargetData()
 }
 
 SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement)
-    : m_needsUpdate(false)
-    , m_useElement(useElement)
+    : m_useElement(useElement)
     , m_element(originalElement)
     , m_previousSibling(0)
     , m_nextSibling(0)
@@ -93,20 +88,6 @@ void SVGElementInstance::setShadowTreeElement(SVGElement* element)
     m_shadowTreeElement = element;
 }
 
-void SVGElementInstance::forgetWrapper()
-{
-#if USE(JSC)
-    // FIXME: This is fragile, as discussed with Sam. Need to find a better solution.
-    // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;".
-    // We still have to recreate this wrapper somehow. The gc collection below, won't catch it.
-
-    // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects
-    // are still holding RefPtrs of SVGElementInstance objects, which prevent us to
-    // be deleted (and the shadow tree is not destructed as well). Force JS GC.
-    gcController().garbageCollectNow();
-#endif
-}
-
 void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
 {
     appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this);
@@ -114,27 +95,24 @@ void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
 
 void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
 {
-    if (!element)
+    if (!element || !element->isStyled())
+        return;
+
+    if (static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked())
         return;
 
     HashSet<SVGElementInstance*> set = element->instancesForElement();
     if (set.isEmpty())
         return;
 
-    // Find all use elements referencing the instances - ask them _once_ to rebuild.
+    // Mark all use elements referencing 'element' for rebuilding
     HashSet<SVGElementInstance*>::const_iterator it = set.begin();
     const HashSet<SVGElementInstance*>::const_iterator end = set.end();
 
-    for (; it != end; ++it)
-        (*it)->setNeedsUpdate(true);
-}
-
-void SVGElementInstance::setNeedsUpdate(bool value)
-{
-    m_needsUpdate = value;
-
-    if (m_needsUpdate)
-        correspondingUseElement()->setNeedsStyleRecalc();
+    for (; it != end; ++it) {
+        ASSERT((*it)->correspondingElement() == element);
+        (*it)->correspondingUseElement()->invalidateShadowTree();
+    }
 }
 
 ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const
diff --git a/WebCore/svg/SVGElementInstance.h b/WebCore/svg/SVGElementInstance.h
index 3cdc761..58152be 100644
--- a/WebCore/svg/SVGElementInstance.h
+++ b/WebCore/svg/SVGElementInstance.h
@@ -46,9 +46,6 @@ namespace WebCore {
 
         virtual ~SVGElementInstance();
 
-        bool needsUpdate() const { return m_needsUpdate; }
-        void setNeedsUpdate(bool);
-
         virtual ScriptExecutionContext* scriptExecutionContext() const;
 
         virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
@@ -129,7 +126,6 @@ namespace WebCore {
 
         void appendChild(PassRefPtr<SVGElementInstance> child);
         void setShadowTreeElement(SVGElement*);
-        void forgetWrapper();
 
         template<class GenericNode, class GenericNodeContainer>
         friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
@@ -153,8 +149,6 @@ namespace WebCore {
         virtual EventTargetData* eventTargetData();
         virtual EventTargetData* ensureEventTargetData();
 
-        bool m_needsUpdate : 1;
-
         SVGUseElement* m_useElement;
         RefPtr<SVGElement> m_element;
         RefPtr<SVGElement> m_shadowTreeElement;
diff --git a/WebCore/svg/SVGGElement.h b/WebCore/svg/SVGGElement.h
index 677f0df..4827a84 100644
--- a/WebCore/svg/SVGGElement.h
+++ b/WebCore/svg/SVGGElement.h
@@ -37,6 +37,7 @@ namespace WebCore {
         SVGGElement(const QualifiedName&, Document*);
         virtual ~SVGGElement();
 
+        virtual bool isShadowTreeContainerElement() const { return false; }
         virtual bool isValid() const { return SVGTests::isValid(); }
 
         virtual void parseMappedAttribute(MappedAttribute*);
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index aee0e35..a4a84ef 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -47,7 +47,6 @@ namespace WebCore {
 using namespace SVGNames;
 
 char SVGStyledElementIdentifier[] = "SVGStyledElement";
-static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0;
 
 void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName)
 {
@@ -59,6 +58,7 @@ void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToId
 SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc)
     : SVGElement(tagName, doc)
     , m_className(this, HTMLNames::classAttr)
+    , m_instanceUpdatesBlocked(false)
 {
 }
 
@@ -221,7 +221,7 @@ void SVGStyledElement::invalidateResources()
     Document* document = this->document();
 
     if (document->parsing())
-        return; 
+        return;
 
 #if ENABLE(FILTERS)
     SVGResourceFilter* filter = getFilterById(document, svgStyle->filter(), object);
@@ -302,19 +302,6 @@ void SVGStyledElement::detach()
     SVGResource::removeClient(this);
     SVGElement::detach();
 }
-
-void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates)
-{
-    if (blockUpdates) {
-        if (!gElementsWithInstanceUpdatesBlocked)
-            gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>;
-        gElementsWithInstanceUpdatesBlocked->add(this);
-    } else {
-        ASSERT(gElementsWithInstanceUpdatesBlocked);
-        ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this));
-        gElementsWithInstanceUpdatesBlocked->remove(this);
-    }
-}
     
 }
 
diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h
index f8055f6..0f2248f 100644
--- a/WebCore/svg/SVGStyledElement.h
+++ b/WebCore/svg/SVGStyledElement.h
@@ -50,10 +50,9 @@ namespace WebCore {
 
         virtual bool rendererIsNeeded(RenderStyle*);
         virtual SVGResource* canvasResource(const RenderObject*) { return 0; }
-        
+
         virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
         virtual void parseMappedAttribute(MappedAttribute*);
-
         virtual void svgAttributeChanged(const QualifiedName&);
 
         virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
@@ -65,14 +64,16 @@ namespace WebCore {
         void invalidateResources();
 
         virtual void detach();
-                                 
-        void setInstanceUpdatesBlocked(bool);
+
+        bool instanceUpdatesBlocked() const { return m_instanceUpdatesBlocked; }
+        void setInstanceUpdatesBlocked(bool value) { m_instanceUpdatesBlocked = value; }
 
     protected: 
         static int cssPropertyIdForSVGAttributeName(const QualifiedName&);
 
     private:
         ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className)
+        bool m_instanceUpdatesBlocked;
     };
 
 } // namespace WebCore
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 9abddc1..1011b88 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -1,7 +1,7 @@
 /*
     Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann at kde.org>
                   2004, 2005, 2006, 2007 Rob Buis <buis at kde.org>
-    Copyright (C) Research In Motion Limited 2009. All rights reserved.
+    Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -33,12 +33,13 @@
 #include "MappedAttribute.h"
 #include "NodeRenderStyle.h"
 #include "RegisteredEventListener.h"
-#include "RenderSVGTransformableContainer.h"
+#include "RenderSVGShadowTreeRootContainer.h"
 #include "SVGElementInstance.h"
 #include "SVGElementInstanceList.h"
 #include "SVGGElement.h"
 #include "SVGLength.h"
 #include "SVGPreserveAspectRatio.h"
+#include "SVGShadowTreeElements.h"
 #include "SVGSMILElement.h"
 #include "SVGSVGElement.h"
 #include "SVGSymbolElement.h"
@@ -65,6 +66,8 @@ SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document* doc)
     , m_height(this, SVGNames::heightAttr, LengthModeHeight)
     , m_href(this, XLinkNames::hrefAttr)
     , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false)
+    , m_isPendingResource(false)
+    , m_needsShadowTreeRecreation(false)
 {
 }
 
@@ -74,6 +77,16 @@ SVGUseElement::~SVGUseElement()
 
 SVGElementInstance* SVGUseElement::instanceRoot() const
 {
+    // If there is no element instance tree, force immediate SVGElementInstance tree
+    // creation, as we can't wait for the lazy creation to happen if ie. JS wants to
+    // access the instanceRoot object right after creating the element on-the-fly
+    if (!m_targetElementInstance) {
+        if (RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer())) {
+            shadowRoot->markShadowTreeForRecreation();
+            shadowRoot->updateFromElement();
+        }
+    }
+
     return m_targetElementInstance.get();
 }
 
@@ -112,14 +125,15 @@ void SVGUseElement::parseMappedAttribute(MappedAttribute* attr)
 
 void SVGUseElement::insertedIntoDocument()
 {
+    // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied.
     SVGElement::insertedIntoDocument();
-    buildPendingResource();
+    ASSERT(!m_targetElementInstance);
+    ASSERT(!m_isPendingResource);
 }
 
 void SVGUseElement::removedFromDocument()
 {
     m_targetElementInstance = 0;
-    m_shadowTreeRootElement = 0;
     SVGElement::removedFromDocument();
 }
 
@@ -127,87 +141,120 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     SVGStyledTransformableElement::svgAttributeChanged(attrName);
 
-    if (!attached())
+    if (!renderer())
+        return;
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
+        if (m_isPendingResource) {
+            document()->accessSVGExtensions()->removePendingResource(m_resourceId);
+            m_resourceId = String();
+            m_isPendingResource = false;
+        }
+
+        invalidateShadowTree();
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) {
+        updateContainerOffsets();
+        return;
+    }
+
+    // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree!
+    if (SVGStyledElement::isKnownAttribute(attrName)) {
+        setNeedsStyleRecalc();
         return;
+    }
 
-    if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
-        attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
-        SVGTests::isKnownAttribute(attrName) ||
-        SVGLangSpace::isKnownAttribute(attrName) ||
-        SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
-        SVGURIReference::isKnownAttribute(attrName) ||
-        SVGStyledTransformableElement::isKnownAttribute(attrName)) {
-        buildPendingResource();
-
-        if (m_shadowTreeRootElement)
-            m_shadowTreeRootElement->setNeedsStyleRecalc();
+    // TODO: We should be able to remove the need for width/height to require a reclone, similar to the x/y logic.
+    if (attrName == SVGNames::widthAttr
+        || attrName == SVGNames::heightAttr
+        || SVGTests::isKnownAttribute(attrName)
+        || SVGLangSpace::isKnownAttribute(attrName)
+        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
+        || SVGStyledTransformableElement::isKnownAttribute(attrName)) {
+        invalidateShadowTree();
     }
 }
 
-void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+static void updateContainerOffset(SVGElementInstance* targetInstance)
 {
-    SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+    // Depth-first used to write the method in early exit style, no particular other reason.
+    for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling())
+        updateContainerOffset(instance);
+
+    SVGElement* correspondingElement = targetInstance->correspondingElement();
+    ASSERT(correspondingElement);
 
-    if (!attached())
+    if (!correspondingElement->hasTagName(SVGNames::useTag))
         return;
 
-    buildPendingResource();
+    SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
+    ASSERT(shadowTreeElement);
+    ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag));
 
-    if (m_shadowTreeRootElement)
-        m_shadowTreeRootElement->setNeedsStyleRecalc();
+    if (!static_cast<SVGGElement*>(shadowTreeElement)->isShadowTreeContainerElement())
+        return;
+
+    // Spec: An additional transformation translate(x,y) is appended to the end
+    // (i.e., right-side) of the transform attribute on the generated 'g', where x
+    // and y represent the values of the x and y attributes on the 'use' element. 
+    SVGUseElement* useElement = static_cast<SVGUseElement*>(correspondingElement);
+    SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(shadowTreeElement);
+    containerElement->setContainerOffset(useElement->x(), useElement->y());
 }
- 
-static bool shadowTreeContainsChangedNodes(SVGElementInstance* target)
+
+void SVGUseElement::updateContainerOffsets()
 {
-    if (!target)      // when use is referencing an non-existing element, there will be no Instance tree built
-        return false;
+    if (!m_targetElementInstance)
+        return;
 
-    if (target->needsUpdate())
-        return true;
+    // Update root container offset (not reachable through instance tree)
+    SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement();
+    ASSERT(shadowRoot);
 
-    for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling())
-        if (shadowTreeContainsChangedNodes(instance))
-            return true;
+    Node* parentNode = shadowRoot->parentNode();
+    ASSERT(parentNode);
+    ASSERT(parentNode->isSVGElement());
+    ASSERT(parentNode->hasTagName(SVGNames::gTag));
+    ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement());
 
-    return false;
+    SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode);
+    containerElement->setContainerOffset(x(), y());
+
+    // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree
+    updateContainerOffset(m_targetElementInstance.get());
+
+    if (renderer())
+        renderer()->setNeedsLayout(true);
 }
 
 void SVGUseElement::recalcStyle(StyleChange change)
 {
-    if (attached() && needsStyleRecalc() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) {
-        buildPendingResource();
-
-        if (m_shadowTreeRootElement)
-            m_shadowTreeRootElement->setNeedsStyleRecalc();
+    // Eventually mark shadow root element needing style recalc
+    if (needsStyleRecalc() && m_targetElementInstance) {
+        if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement())
+            shadowRoot->setNeedsStyleRecalc();
     }
 
-    SVGStyledElement::recalcStyle(change);
+    SVGStyledTransformableElement::recalcStyle(change);
+
+    bool needsStyleUpdate = !m_needsShadowTreeRecreation;
+    if (m_needsShadowTreeRecreation) {
+        static_cast<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation();
+        m_needsShadowTreeRecreation = false;
+    }
 
-    // The shadow tree root element is NOT a direct child element of us.
-    // So we have to take care it receives style updates, manually.
-    if (!m_shadowTreeRootElement || !m_shadowTreeRootElement->attached())
+    RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer());
+    if (!shadowRoot)
         return;
 
-    // Mimic Element::recalcStyle(). The main difference is that we don't call attach() on the
-    // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash
-    // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky.
-    if (change >= Inherit || m_shadowTreeRootElement->needsStyleRecalc()) {
-        RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get());
-        StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get());
-        if (ch == Detach) {
-            ASSERT(m_shadowTreeRootElement->attached());
-            m_shadowTreeRootElement->detach();
-            attachShadowTree();
-
-            // attach recalulates the style for all children. No need to do it twice.
-            m_shadowTreeRootElement->setNeedsStyleRecalc(NoStyleChange);
-            m_shadowTreeRootElement->setChildNeedsStyleRecalc(false);
-            return;
-        }
-    }
+    shadowRoot->updateFromElement();
 
-    // Only change==Detach needs special treatment, for anything else recalcStyle() works.
-    m_shadowTreeRootElement->recalcStyle(change);
+    if (!needsStyleUpdate)
+        return;
+
+    shadowRoot->updateStyle(change);
 }
 
 #ifdef DUMP_INSTANCE_TREE
@@ -216,17 +263,21 @@ void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* tar
     SVGElement* element = targetInstance->correspondingElement();
     ASSERT(element);
 
+    SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
+    ASSERT(shadowTreeElement);
+
     String elementId = element->getIDAttribute();
     String elementNodeName = element->nodeName();
+    String shadowTreeElementNodeName = shadowTreeElement->nodeName();
     String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null";
     String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null";
 
     for (unsigned int i = 0; i < depth; ++i)
         text += "  ";
 
-    text += String::format("SVGElementInstance this=%p, (parentNode=%s, firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n",
-                           targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(),
-                           element, targetInstance->shadowTreeElement(), elementId.latin1().data());
+    text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n",
+                           targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(),
+                           elementNodeName.latin1().data(), element, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data());
 
     for (unsigned int i = 0; i < depth; ++i)
         text += "  ";
@@ -282,16 +333,36 @@ static bool subtreeContainsDisallowedElement(Node* start)
 
 void SVGUseElement::buildPendingResource()
 {
+    // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer)
+    // we either determine that our target is available or not - then we add ourselves to the pending resource list
+    // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time.
     String id = SVGURIReference::getTarget(href());
     Element* targetElement = document()->getElementById(id);
+    ASSERT(!m_targetElementInstance);
 
     if (!targetElement) {
-        // TODO: We want to deregister as pending resource, if our href() changed!
-        // TODO: Move to svgAttributeChanged, once we're fixing use & the new dynamic update concept.
+        if (m_isPendingResource)
+            return;
+
+        m_isPendingResource = true;
+        m_resourceId = id;
         document()->accessSVGExtensions()->addPendingResource(id, this);
         return;
     }
 
+    if (m_isPendingResource) {
+        ASSERT(!m_targetElementInstance);
+        m_isPendingResource = false;    
+        invalidateShadowTree();
+    }
+}
+
+void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowRoot)
+{
+    String id = SVGURIReference::getTarget(href());
+    Element* targetElement = document()->getElementById(id);
+    ASSERT(targetElement);
+
     // Do not build the shadow/instance tree for <use> elements living in a shadow tree.
     // The will be expanded soon anyway - see expandUseElementsInShadowTree().
     Node* parent = parentNode();
@@ -306,17 +377,13 @@ void SVGUseElement::buildPendingResource()
     if (targetElement && targetElement->isSVGElement())
         target = static_cast<SVGElement*>(targetElement);
 
-    if (m_targetElementInstance) {
-        m_targetElementInstance->forgetWrapper();
+    if (m_targetElementInstance)
         m_targetElementInstance = 0;
-    }
 
     // Do not allow self-referencing.
     // 'target' may be null, if it's a non SVG namespaced element.
-    if (!target || target == this) {
-        m_shadowTreeRootElement = 0;
+    if (!target || target == this)
         return;
-    }
 
     // Why a seperated instance/shadow tree? SVG demands it:
     // The instance tree is accesable from JavaScript, and has to
@@ -338,51 +405,44 @@ void SVGUseElement::buildPendingResource()
     // Non-appearing <use> content is easier to debug, then half-appearing content.
     if (foundProblem) {
         m_targetElementInstance = 0;
-        m_shadowTreeRootElement = 0;
         return;
     }
 
     // Assure instance tree building was successfull
     ASSERT(m_targetElementInstance);
+    ASSERT(!m_targetElementInstance->shadowTreeElement());
     ASSERT(m_targetElementInstance->correspondingUseElement() == this);
-
-    // Safe destruction, of the old shadow tree root element
-    if (m_shadowTreeRootElement) {
-        m_shadowTreeRootElement->detach();
-        m_shadowTreeRootElement = 0;
-    }
-
-    // Setup shadow tree root node
-    m_shadowTreeRootElement = new SVGGElement(SVGNames::gTag, document());
-    m_shadowTreeRootElement->setInDocument();
-    m_shadowTreeRootElement->setShadowParentNode(this);
-
-    // Spec: An additional transformation translate(x,y) is appended to the end
-    // (i.e., right-side) of the transform attribute on the generated 'g', where x
-    // and y represent the values of the x and y attributes on the 'use' element. 
-    if (x().value(this) != 0.0 || y().value(this) != 0.0) {
-        String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this));
-        m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString);
-    }
+    ASSERT(m_targetElementInstance->correspondingElement() == target);
 
     // Build shadow tree from instance tree
     // This also handles the special cases: <use> on <symbol>, <use> on <svg>.
-    buildShadowTree(target, m_targetElementInstance.get());
+    buildShadowTree(shadowRoot, target, m_targetElementInstance.get());
 
 #if ENABLE(SVG) && ENABLE(SVG_USE)
     // Expand all <use> elements in the shadow tree.
     // Expand means: replace the actual <use> element by what it references.
-    expandUseElementsInShadowTree(m_shadowTreeRootElement.get());
+    expandUseElementsInShadowTree(shadowRoot, shadowRoot);
 
     // Expand all <symbol> elements in the shadow tree.
     // Expand means: replace the actual <symbol> element by the <svg> element.
-    expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get());
-
+    expandSymbolElementsInShadowTree(shadowRoot, shadowRoot);
 #endif
 
     // Now that the shadow tree is completly expanded, we can associate
     // shadow tree elements <-> instances in the instance tree.
-    associateInstancesWithShadowTreeElements(m_shadowTreeRootElement->firstChild(), m_targetElementInstance.get());
+    associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetElementInstance.get());
+
+    // If no shadow tree element is present, this means that the reference root
+    // element was removed, as it is disallowed (ie. <use> on <foreignObject>)
+    // Do NOT leave an inconsistent instance tree around, instead destruct it.
+    if (!m_targetElementInstance->shadowTreeElement()) {
+        shadowRoot->removeAllChildren();
+        m_targetElementInstance = 0;
+        return;
+    }
+
+    // Consistency checks - this is assumed in updateContainerOffset().
+    ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowRoot);
 
     // Eventually dump instance tree
 #ifdef DUMP_INSTANCE_TREE
@@ -399,8 +459,8 @@ void SVGUseElement::buildPendingResource()
 
     PassRefPtr<XMLSerializer> serializer = XMLSerializer::create();
 
-    String markup = serializer->serializeToString(m_shadowTreeRootElement.get(), ec);
-    ASSERT(ec == 0);
+    String markup = serializer->serializeToString(shadowRoot, ec);
+    ASSERT(!ec);
 
     fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data());
 #endif
@@ -408,30 +468,33 @@ void SVGUseElement::buildPendingResource()
     // Transfer event listeners assigned to the referenced element to our shadow tree elements.
     transferEventListenersToShadowTree(m_targetElementInstance.get());
 
-    // The DOM side is setup properly. Now we have to attach the root shadow
-    // tree element manually - using attach() won't work for "shadow nodes".
-    attachShadowTree();
+    // Update container translation offsets
+    updateContainerOffsets();
 }
 
 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*)
 {
-    return new (arena) RenderSVGTransformableContainer(this);
+    return new (arena) RenderSVGShadowTreeRootContainer(this);
+}
+
+static void updateFromElementCallback(Node* node)
+{
+    if (RenderObject* renderer = node->renderer())
+        renderer->updateFromElement();
 }
 
 void SVGUseElement::attach()
 {
     SVGStyledTransformableElement::attach();
 
-    // If we're a pending resource, this doesn't have any effect.
-    attachShadowTree();
+    if (renderer())
+        queuePostAttachCallback(updateFromElementCallback, this);
 }
 
 void SVGUseElement::detach()
 {
     SVGStyledTransformableElement::detach();
-
-    if (m_shadowTreeRootElement)
-        m_shadowTreeRootElement->detach();
+    m_targetElementInstance = 0;
 }
 
 static bool isDirectReference(Node* n)
@@ -447,13 +510,10 @@ static bool isDirectReference(Node* n)
 
 Path SVGUseElement::toClipPath() const
 {
-    if (!m_shadowTreeRootElement)
-        const_cast<SVGUseElement*>(this)->buildPendingResource();
-
-    if (!m_shadowTreeRootElement)
+    Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
+    if (!n)
         return Path();
 
-    Node* n = m_shadowTreeRootElement->firstChild();
     if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) {
         if (!isDirectReference(n))
             // Spec: Indirect references are an error (14.3.5)
@@ -487,11 +547,12 @@ void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* ta
             continue;
 
         // Create SVGElementInstance object, for both container/non-container nodes.
-        RefPtr<SVGElementInstance> instancePtr = SVGElementInstance::create(this, element);
-        targetInstance->appendChild(instancePtr.get());
+        RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, element);
+        SVGElementInstance* instancePtr = instance.get();
+        targetInstance->appendChild(instance.release());
 
         // Enter recursion, appending new instance tree nodes to the "instance" object.
-        buildInstanceTree(element, instancePtr.get(), foundProblem);
+        buildInstanceTree(element, instancePtr, foundProblem);
     }
 
     // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
@@ -532,10 +593,11 @@ void SVGUseElement::handleDeepUseReferencing(SVGUseElement* use, SVGElementInsta
 
     // Create an instance object, even if we're dealing with a cycle
     RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, target);
-    targetInstance->appendChild(newInstance);
+    SVGElementInstance* newInstancePtr = newInstance.get();
+    targetInstance->appendChild(newInstance.release());
 
     // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children
-    buildInstanceTree(target, newInstance.get(), foundProblem);
+    buildInstanceTree(target, newInstancePtr, foundProblem);
 }
 
 void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target)
@@ -566,7 +628,7 @@ void SVGUseElement::removeDisallowedElementsFromSubtree(Node* subtree)
     }
 }
 
-void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance)
+void SVGUseElement::buildShadowTree(SVGShadowTreeRootElement* shadowRoot, SVGElement* target, SVGElementInstance* targetInstance)
 {
     // For instance <use> on <foreignObject> (direct case).
     if (isDisallowedElement(target))
@@ -588,8 +650,8 @@ void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targ
     ASSERT(newChildPtr);
 
     ExceptionCode ec = 0;
-    m_shadowTreeRootElement->appendChild(newChild.release(), ec);
-    ASSERT(ec == 0);
+    shadowRoot->appendChild(newChild.release(), ec);
+    ASSERT(!ec);
 
     // Handle use referencing <svg> special case
     if (target->hasTagName(SVGNames::svgTag))
@@ -597,7 +659,7 @@ void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targ
 }
 
 #if ENABLE(SVG) && ENABLE(SVG_USE)
-void SVGUseElement::expandUseElementsInShadowTree(Node* element)
+void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element)
 {
     // Why expand the <use> elements in the shadow tree here, and not just
     // do this directly in buildShadowTree, if we encounter a <use> element?
@@ -618,28 +680,14 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
         // Don't ASSERT(target) here, it may be "pending", too.
         if (target) {
             // Setup sub-shadow tree root node
-            RefPtr<SVGElement> cloneParent = new SVGGElement(SVGNames::gTag, document());
+            RefPtr<SVGShadowTreeContainerElement> cloneParent = new SVGShadowTreeContainerElement(document());
 
             // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the
             // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element.
             transferUseAttributesToReplacedElement(use, cloneParent.get());
 
-            // Spec: An additional transformation translate(x,y) is appended to the end
-            // (i.e., right-side) of the transform attribute on the generated 'g', where x
-            // and y represent the values of the x and y attributes on the 'use' element.
-            if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) {
-                if (!cloneParent->hasAttribute(SVGNames::transformAttr)) {
-                    String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this));
-                    cloneParent->setAttribute(SVGNames::transformAttr, transformString);
-                } else {
-                    String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this));
-                    const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr);
-                    cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString); 
-                }
-            }
-
             ExceptionCode ec = 0;
- 
+
             // For instance <use> on <foreignObject> (direct case).
             if (isDisallowedElement(target)) {
                 // We still have to setup the <use> replacment (<g>). Otherwhise
@@ -647,7 +695,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
                 // Replace <use> with referenced content.
                 ASSERT(use->parentNode()); 
                 use->parentNode()->replaceChild(cloneParent.release(), use, ec);
-                ASSERT(ec == 0);
+                ASSERT(!ec);
                 return;
             }
 
@@ -667,28 +715,28 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
             ASSERT(newChildPtr);
 
             cloneParent->appendChild(newChild.release(), ec);
-            ASSERT(ec == 0);
+            ASSERT(!ec);
 
             // Replace <use> with referenced content.
             ASSERT(use->parentNode()); 
             use->parentNode()->replaceChild(cloneParent.release(), use, ec);
-            ASSERT(ec == 0);
+            ASSERT(!ec);
 
             // Handle use referencing <svg> special case
             if (target->hasTagName(SVGNames::svgTag))
                 alterShadowTreeForSVGTag(newChildPtr);
 
             // Immediately stop here, and restart expanding.
-            expandUseElementsInShadowTree(m_shadowTreeRootElement.get());
+            expandUseElementsInShadowTree(shadowRoot, shadowRoot);
             return;
         }
     }
 
     for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
-        expandUseElementsInShadowTree(child.get());
+        expandUseElementsInShadowTree(shadowRoot, child.get());
 }
 
-void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
+void SVGUseElement::expandSymbolElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element)
 {
     if (element->hasTagName(SVGNames::symbolTag)) {
         // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree,
@@ -715,7 +763,7 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
         for (Node* child = element->firstChild(); child; child = child->nextSibling()) {
             RefPtr<Node> newChild = child->cloneNode(true);
             svgElement->appendChild(newChild.release(), ec);
-            ASSERT(ec == 0);
+            ASSERT(!ec);
         }
     
         // We don't walk the target tree element-by-element, and clone each element,
@@ -729,43 +777,19 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
         // Replace <symbol> with <svg>.
         ASSERT(element->parentNode()); 
         element->parentNode()->replaceChild(svgElement.release(), element, ec);
-        ASSERT(ec == 0);
+        ASSERT(!ec);
 
         // Immediately stop here, and restart expanding.
-        expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get());
+        expandSymbolElementsInShadowTree(shadowRoot, shadowRoot);
         return;
     }
 
     for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
-        expandSymbolElementsInShadowTree(child.get());
+        expandSymbolElementsInShadowTree(shadowRoot, child.get());
 }
 
 #endif
-    
-void SVGUseElement::attachShadowTree()
-{
-    if (!m_shadowTreeRootElement || m_shadowTreeRootElement->attached() || !document()->shouldCreateRenderers() || !attached() || !renderer())
-        return;
-
-    // Inspired by RenderTextControl::createSubtreeIfNeeded(). 
-    if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) {
-        RefPtr<RenderStyle> style = m_shadowTreeRootElement->styleForRenderer();
-
-        if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) {
-            m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get()));
-            if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) {
-                shadowRenderer->setStyle(style.release());
-                renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer());
-                m_shadowTreeRootElement->setAttached();
-            }
-        }
 
-        // This will take care of attaching all shadow tree child nodes.
-        for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling())
-            child->attach();
-    }
-}
- 
 void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target)
 {
     if (!target)
@@ -853,14 +877,19 @@ SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, S
         return instance;
 
     for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) {
-        SVGElementInstance* search = instanceForShadowTreeElement(element, current);
-        if (search)
+        if (SVGElementInstance* search = instanceForShadowTreeElement(element, current))
             return search;
     }
 
     return 0;
 }
 
+void SVGUseElement::invalidateShadowTree()
+{
+    m_needsShadowTreeRecreation = true;
+    setNeedsStyleRecalc();
+}
+
 void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const
 {
     ASSERT(from);
@@ -871,19 +900,19 @@ void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVG
     ExceptionCode ec = 0;
 
     to->removeAttribute(SVGNames::xAttr, ec);
-    ASSERT(ec == 0);
+    ASSERT(!ec);
 
     to->removeAttribute(SVGNames::yAttr, ec);
-    ASSERT(ec == 0);
+    ASSERT(!ec);
 
     to->removeAttribute(SVGNames::widthAttr, ec);
-    ASSERT(ec == 0);
+    ASSERT(!ec);
 
     to->removeAttribute(SVGNames::heightAttr, ec);
-    ASSERT(ec == 0);
+    ASSERT(!ec);
 
     to->removeAttribute(XLinkNames::hrefAttr, ec);
-    ASSERT(ec == 0);
+    ASSERT(!ec);
 }
 
 bool SVGUseElement::hasRelativeValues() const
diff --git a/WebCore/svg/SVGUseElement.h b/WebCore/svg/SVGUseElement.h
index 5a17105..a24bcdd 100644
--- a/WebCore/svg/SVGUseElement.h
+++ b/WebCore/svg/SVGUseElement.h
@@ -32,6 +32,7 @@ namespace WebCore {
 
     class SVGElementInstance;
     class SVGLength;
+    class SVGShadowTreeRootElement;
 
     class SVGUseElement : public SVGStyledTransformableElement,
                           public SVGTests,
@@ -52,11 +53,9 @@ namespace WebCore {
         virtual void buildPendingResource();
 
         virtual void parseMappedAttribute(MappedAttribute*);
-        virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-
         virtual void svgAttributeChanged(const QualifiedName&);
-        virtual void recalcStyle(StyleChange = NoChange);
 
+        virtual void recalcStyle(StyleChange = NoChange);
         virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
         virtual void attach();
         virtual void detach();
@@ -65,6 +64,12 @@ namespace WebCore {
 
         static void removeDisallowedElementsFromSubtree(Node* element);
         SVGElementInstance* instanceForShadowTreeElement(Node* element) const;
+        void invalidateShadowTree();
+
+    private:
+        friend class RenderSVGShadowTreeRootContainer;
+        bool isPendingResource() const { return m_isPendingResource; }
+        void buildShadowAndInstanceTree(SVGShadowTreeRootElement*);
 
     private:
         virtual bool hasRelativeValues() const;
@@ -88,26 +93,25 @@ namespace WebCore {
         void handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundCycle);
 
         // Shadow tree handling
-        PassRefPtr<SVGSVGElement> buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance);
-        void alterShadowTreeForSVGTag(SVGElement* target);
-
-        void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance);
+        void alterShadowTreeForSVGTag(SVGElement*);
+        void buildShadowTree(SVGShadowTreeRootElement*, SVGElement* target, SVGElementInstance* targetInstance);
 
 #if ENABLE(SVG) && ENABLE(SVG_USE)
-        void expandUseElementsInShadowTree(Node* element);
-        void expandSymbolElementsInShadowTree(Node* element);
+        void expandUseElementsInShadowTree(SVGShadowTreeRootElement*, Node* element);
+        void expandSymbolElementsInShadowTree(SVGShadowTreeRootElement*, Node* element);
 #endif
 
-        void attachShadowTree();
-
         // "Tree connector" 
         void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance);
         SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const;
 
         void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const;
         void transferEventListenersToShadowTree(SVGElementInstance* target);
+        void updateContainerOffsets();
 
-        RefPtr<SVGElement> m_shadowTreeRootElement;
+        bool m_isPendingResource;
+        bool m_needsShadowTreeRecreation;
+        String m_resourceId;
         RefPtr<SVGElementInstance> m_targetElementInstance;
     };
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list