Changeset 53446 in webkit
- Timestamp:
- Jan 18, 2010 6:17:28 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r53445 r53446 1 2010-01-18 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Reviewed by Dirk Schulze. 4 5 Rewrite SVG <use> support in a modern-fashion 6 https://bugs.webkit.org/show_bug.cgi?id=33776 7 8 Update some test results, after rewriting <use> support. 9 10 * platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt: 11 * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.checksum: Added. 12 * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.png: Added. 13 * platform/mac/svg/custom/relative-sized-deep-shadow-tree-content-expected.txt: Added. 14 * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.checksum: Added. 15 * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.png: Added. 16 * platform/mac/svg/custom/relative-sized-shadow-tree-content-expected.txt: Added. 17 * platform/mac/svg/custom/use-events-crash-expected.txt: 18 * platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt: 19 * platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt: 20 * platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt: 21 * platform/mac/svg/custom/use-recursion-1-expected.txt: 22 * platform/mac/svg/custom/use-recursion-2-expected.txt: 23 * platform/mac/svg/custom/use-recursion-3-expected.txt: 24 * platform/mac/svg/custom/use-recursion-4-expected.txt: 25 * platform/mac/svg/hixie/error/017-expected.txt: 26 * platform/mac/svg/text/text-text-05-t-expected.checksum: 27 * platform/mac/svg/text/text-text-05-t-expected.png: 28 * svg/custom/relative-sized-deep-shadow-tree-content.xhtml: Added. 29 * svg/custom/relative-sized-shadow-tree-content.xhtml: Added. 30 * svg/text/text-text-05-t.svg: Remove possible race-condition, between selecting & dumping. 31 1 32 2010-01-18 Kent Tamura <tkent@chromium.org> 2 33 -
trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-40-t-expected.txt
r42840 r53446 13 13 RenderSVGContainer {use} at (-18.50,-18.50) size 7x7 14 14 RenderSVGContainer {g} at (-18.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-15.00,-15.00)}] 15 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"]15 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"] 16 16 RenderSVGContainer {use} at (11.50,-18.50) size 7x7 17 17 RenderSVGContainer {g} at (11.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(15.00,-15.00)}] … … 113 113 RenderSVGContainer {use} at (-18.50,-18.50) size 7x7 114 114 RenderSVGContainer {g} at (-18.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(-15.00,-15.00)}] 115 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"]115 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"] 116 116 RenderSVGContainer {use} at (11.50,-18.50) size 7x7 117 117 RenderSVGContainer {g} at (11.50,-18.50) size 7x7 [transform={m=((1.00,0.00)(0.00,1.00)) t=(15.00,-15.00)}] -
trunk/LayoutTests/platform/mac/svg/custom/use-events-crash-expected.txt
r38794 r53446 20 20 RenderSVGContainer {g} at (350,25) size 40x40 21 21 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"] 22 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 -
trunk/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-1-expected.txt
r30635 r53446 8 8 text run at (0,0) width 244: "You should only see this string ONCE" 9 9 RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}] 10 RenderSVGContainer {g} at (250,- 35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]10 RenderSVGContainer {g} at (250,-50) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-3-expected.txt
r30635 r53446 8 8 text run at (0,0) width 244: "You should only see this string ONCE" 9 9 RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}] 10 RenderSVGContainer {g} at (250,- 35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]10 RenderSVGContainer {g} at (250,-50) size 0x0 11 11 RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}] 12 12 RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}] 13 RenderSVGContainer {g} at (4 52.13,115.56) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-35.86)}]13 RenderSVGContainer {g} at (462.13,119.71) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(260.00,-40.00)}] -
trunk/LayoutTests/platform/mac/svg/custom/use-on-disallowed-foreign-object-4-expected.txt
r30635 r53446 15 15 RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}] 16 16 RenderSVGContainer {g} at (250,-35.86) size 0x0 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}] 17 RenderSVGContainer {g} at (4 52.13,115.56) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-35.86)}]18 RenderSVGContainer {g} at (4 52.13,115.56) size 0x019 RenderSVGContainer {g} at (4 52.13,115.56) size 0x017 RenderSVGContainer {g} at (462.13,119.71) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(260.00,-40.00)}] 18 RenderSVGContainer {g} at (462.13,119.71) size 0x0 19 RenderSVGContainer {g} at (462.13,119.71) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-on-non-svg-namespaced-element-expected.txt
r30635 r53446 8 8 text run at (0,0) width 244: "You should only see this string ONCE" 9 9 RenderSVGContainer {use} at (250,-50) size 0x0 [transform={m=((0.71,0.71)(-0.71,0.71)) t=(250.00,-50.00)}] 10 RenderSVGContainer {g} at (250,-50) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-recursion-1-expected.txt
r38794 r53446 7 7 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"] 8 8 RenderSVGContainer {use} at (0,0) size 0x0 9 RenderSVGContainer {g} at (0,0) size 0x0 9 10 RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s) 10 11 RenderSVGInlineText {#text} at (0,-14) size 139x18 11 12 chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash." 12 13 RenderSVGContainer {use} at (0,0) size 0x0 14 RenderSVGContainer {g} at (0,0) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-recursion-2-expected.txt
r30635 r53446 7 7 chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash." 8 8 RenderSVGContainer {use} at (0,0) size 0x0 9 RenderSVGContainer {g} at (0,0) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-recursion-3-expected.txt
r38794 r53446 7 7 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"] 8 8 RenderSVGContainer {use} at (0,0) size 0x0 9 RenderSVGContainer {g} at (0,0) size 0x0 9 10 RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s) 10 11 RenderSVGInlineText {#text} at (0,-14) size 139x18 11 12 chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash." 12 13 RenderSVGContainer {use} at (0,0) size 0x0 14 RenderSVGContainer {g} at (0,0) size 0x0 -
trunk/LayoutTests/platform/mac/svg/custom/use-recursion-4-expected.txt
r38794 r53446 11 11 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"] 12 12 RenderSVGContainer {use} at (0,0) size 0x0 13 RenderSVGContainer {g} at (0,0) size 0x0 13 14 RenderSVGText {text} at (10,60) size 139x18 contains 1 chunk(s) 14 15 RenderSVGInlineText {#text} at (0,-14) size 139x18 15 16 chunk 1 text run 1 at (10.00,60.00) startOffset 0 endOffset 22 width 139.00: "This should not crash." 16 17 RenderSVGContainer {use} at (0,0) size 0x0 18 RenderSVGContainer {g} at (0,0) size 0x0 -
trunk/LayoutTests/platform/mac/svg/hixie/error/017-expected.txt
r38794 r53446 18 18 RenderSVGContainer {g} at (0,0) size 0x0 19 19 RenderSVGContainer {use} at (0,0) size 0x0 20 RenderSVGContainer {g} at (0,0) size 0x0 20 21 RenderSVGText {text} at (20,220) size 444x230 contains 1 chunk(s) 21 22 RenderSVGInlineText {#text} at (0,-180) size 444x230 -
trunk/LayoutTests/platform/mac/svg/text/text-text-05-t-expected.checksum
r40949 r53446 1 0571a94f26afb9720655647261fc786c 1 db9ca27ce7850c95e06bb13bbcf32246 -
trunk/LayoutTests/svg/text/text-text-05-t.svg
r28763 r53446 160 160 161 161 <script> 162 if (window.layoutTestController) 163 window.layoutTestController.dumpSelectionRect(); 164 document.execCommand("SelectAll"); 162 if (window.layoutTestController) { 163 layoutTestController.waitUntilDone(); 164 layoutTestController.dumpSelectionRect(); 165 } 166 167 setTimeout(function() { 168 document.execCommand("SelectAll"); 169 if (window.layoutTestController) 170 layoutTestController.notifyDone(); 171 }, 0); 165 172 </script> 166 173 </svg> -
trunk/WebCore/Android.mk
r52949 r53446 597 597 rendering/RenderSVGModelObject.cpp \ 598 598 rendering/RenderSVGRoot.cpp \ 599 rendering/RenderSVGShadowTreeRootContainer.cpp \ 599 600 rendering/RenderSVGTSpan.cpp \ 600 601 rendering/RenderSVGText.cpp \ … … 635 636 rendering/SVGRenderSupport.cpp \ 636 637 rendering/SVGRenderTreeAsText.cpp \ 637 rendering/SVGRootInlineBox.cpp 638 rendering/SVGRootInlineBox.cpp \ 639 rendering/SVGShadowTreeElements.cpp 638 640 endif 639 641 -
trunk/WebCore/ChangeLog
r53445 r53446 1 2010-01-18 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Reviewed by Dirk Schulze. 4 5 Rewrite SVG <use> support in a modern-fashion 6 https://bugs.webkit.org/show_bug.cgi?id=33776 7 8 Tests: svg/custom/relative-sized-deep-shadow-tree-content.xhtml 9 svg/custom/relative-sized-shadow-tree-content.xhtml 10 11 Fixes: svg/W3C-SVG-1.1/animate-elem-30-t.svg (animated circle sometimes takes wrong path) 12 13 Rewrite <use> support in less intrusive way. Try hard to avoid recloning where possible, and do it lazily. 14 Introduce RenderSVGShadowTreeRootContainer as special renderer for SVGUseElement, that now manages the 15 render tree, instead of SVGUseElement manually hacking around it's own renderer from the DOM side. 16 17 Instead of recloning the whole shadow tree for every attribute change (DOM setAttribute / SVG DOM changes / CSS changes / childrenChanged()...) 18 just notify the RenderSVGShadowTreeRootContainer that it's supposed to reclone the tree upon the next updateFromElement() call. 19 20 updateFromElement() is fired from SVGUseElement::attach() / recalcStyle(), as it's done for HTMLFormControlElement/HTMLMediaElement, thus 21 lazily recloning the shadow tree if necessary. 22 23 Animations for <use> elements was a real performance bottlenck as the tree got recloned on every attribute change. Reclones are _completly_ 24 avoided for animations now - the SVGAnim*Element classes already updated the instances of an element manually, though that resulted in a reclone 25 nontheless, and thus killing performance. <use> elements can only be recloned through mutations of the elements that they reference to. 26 For example referencing a <rect> element from a <use> element and scripting the <rect> element (setAttribute, or child tree mutations etc.). 27 We reclone instead of trying to synchronize trees - as it's currenty implemented - because it's very hard to do it right. 28 29 Any DOM / SVG DOM / CSS change on the <use> element don't reclone the tree anymore, this is a huge speed benefit. 30 x/y attribute changes are correctly handled in the render tree now (by an additional local transformation), now percentual values work 31 as expected, and resize on window changes - affecting lots of testcases. 32 33 The <use> implementation is much safer now, not doing any mutations synchronously from svgAttributeChanged etc. 34 Remove hack to force garbage collection on SVGElementInstance destruction - can't reproduce it anymore. 35 36 * Android.mk: Add new files to build. 37 * GNUmakefile.am: Ditto. 38 * WebCore.gypi: Ditto. 39 * WebCore.pro: Ditto. 40 * WebCore.vcproj/WebCore.vcproj: Ditto. 41 * WebCore.xcodeproj/project.pbxproj: Ditto. 42 * rendering/RenderSVGShadowTreeRootContainer.cpp: Added. This is the rendered now created by SVGUseElement. 43 (WebCore::RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer): 44 (WebCore::RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer): 45 (WebCore::RenderSVGShadowTreeRootContainer::updateStyle): Used form SVGUseElement to request style recalculations for the shadow tree renderers 46 (WebCore::RenderSVGShadowTreeRootContainer::updateFromElement): Used from SVGUseElement attach/recalcStyle to eventually request shadow tree updates. 47 (WebCore::RenderSVGShadowTreeRootContainer::styleDidChange): Used to propage style updates across shadow tree boundaries. 48 * rendering/RenderSVGShadowTreeRootContainer.h: Added. 49 (WebCore::RenderSVGShadowTreeRootContainer::markShadowTreeForRecreation): Marks the shadow tree for a reclone, next time updateFromElement is used. 50 * rendering/RenderSVGTransformableContainer.cpp: 51 (WebCore::RenderSVGTransformableContainer::calculateLocalTransform): Take containerTranslation() into account, supplied by RenderSVGSDhadowTreeContainer. 52 * rendering/SVGShadowTreeElements.cpp: Added. This is the root element of the SVG shadow tree residing as (hidden) child of SVGUseElement (DOM wise). 53 (WebCore::SVGShadowTreeContainerElement::SVGShadowTreeContainerElement): 54 (WebCore::SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement): 55 (WebCore::SVGShadowTreeContainerElement::containerTranslation): Used from calculateLocalTransform() to take x/y translation into account for shadow tree container elements. 56 (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): 57 (WebCore::SVGShadowTreeRootElement::~SVGShadowTreeRootElement): 58 (WebCore::SVGShadowTreeRootElement::attachElement): Used by RenderSVGShadowTreeRootContainer, instead of attach(), as we're a shadow tree root node. 59 * 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). 60 (WebCore::SVGShadowTreeContainerElement::isShadowTreeContainerElement): Return true here. 61 (WebCore::SVGShadowTreeContainerElement::setContainerOffset): Used from SVGUseElement to propagate x/y translation values set on <use> elements in the shadow tree. 62 (WebCore::SVGShadowTreeRootElement::isShadowNode): Identify us as shadow node. 63 (WebCore::SVGShadowTreeRootElement::shadowParentNode): Ditto. Return actual shadow parent node (== corresponding use element). 64 * svg/SVGElement.cpp: Shrink size of all SVG*Elements, by removing the m_shadowParent parent. SVGShadowTreeRootElement is the new base class for shadow tree. 65 (WebCore::SVGElement::SVGElement): 66 (WebCore::SVGElement::eventParentNode): Call virtual shadowParentNode() method, instead of accessing m_shadowParent. 67 * svg/SVGElement.h: Remove isShadowNode() / shadowParentNode() / setShadowParentNode(). 68 * svg/SVGElementInstance.cpp: Remove the hack, calling garbage collection before destruction. Can't reproduce this anymore, let's see what the bots say. 69 (WebCore::SVGElementInstance::SVGElementInstance): Remove now unnecessary m_needsUpdate flag. 70 (WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Don't invalidate if instance updates are blocked (see SVGStyledElement changes) 71 * svg/SVGElementInstance.h: Remove m_needsUpdate, and forgetWrapper() method. 72 * svg/SVGGElement.h: 73 (WebCore::SVGGElement::isShadowTreeContainerElement): Add new virtual method here returning false by default, SVGShadowTreeContainerElement will override it. 74 * svg/SVGStyledElement.cpp: Remove gElementsWithInstanceUpdatesBlocked HashSet tracking the state of instancesUpdatesBlocked() per SVGStyledElement - make it a member variable. 75 * svg/SVGStyledElement.h: Add inline getter/setters around m_instanceUpdatesBlocked. 76 (WebCore::SVGStyledElement::instanceUpdatesBlocked): 77 (WebCore::SVGStyledElement::setInstanceUpdatesBlocked): 78 * svg/SVGUseElement.cpp: Full rewrite of <use> support, a detailed discussion would blow the ChangeLog - see short version above. 79 (WebCore::SVGUseElement::SVGUseElement): 80 (WebCore::SVGUseElement::instanceRoot): 81 (WebCore::SVGUseElement::insertedIntoDocument): 82 (WebCore::SVGUseElement::removedFromDocument): 83 (WebCore::SVGUseElement::svgAttributeChanged): 84 (WebCore::updateContainerOffset): 85 (WebCore::SVGUseElement::updateContainerOffsets): 86 (WebCore::SVGUseElement::recalcStyle): 87 (WebCore::dumpInstanceTree): 88 (WebCore::SVGUseElement::buildPendingResource): 89 (WebCore::SVGUseElement::buildShadowAndInstanceTree): 90 (WebCore::SVGUseElement::createRenderer): 91 (WebCore::updateFromElementCallback): 92 (WebCore::SVGUseElement::attach): 93 (WebCore::SVGUseElement::detach): 94 (WebCore::SVGUseElement::toClipPath): 95 (WebCore::SVGUseElement::buildInstanceTree): 96 (WebCore::SVGUseElement::handleDeepUseReferencing): 97 (WebCore::SVGUseElement::buildShadowTree): 98 (WebCore::SVGUseElement::expandUseElementsInShadowTree): 99 (WebCore::SVGUseElement::expandSymbolElementsInShadowTree): 100 (WebCore::SVGUseElement::instanceForShadowTreeElement): 101 (WebCore::SVGUseElement::invalidateShadowTree): 102 (WebCore::SVGUseElement::transferUseAttributesToReplacedElement): 103 * svg/SVGUseElement.h: 104 (WebCore::SVGUseElement::isPendingResource): 105 1 106 2010-01-18 Kent Tamura <tkent@chromium.org> 2 107 -
trunk/WebCore/GNUmakefile.am
r53443 r53446 2948 2948 WebCore/rendering/RenderSVGRoot.cpp \ 2949 2949 WebCore/rendering/RenderSVGRoot.h \ 2950 WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp \ 2951 WebCore/rendering/RenderSVGShadowTreeRootContainer.h \ 2950 2952 WebCore/rendering/RenderSVGTSpan.cpp \ 2951 2953 WebCore/rendering/RenderSVGTSpan.h \ … … 2973 2975 WebCore/rendering/SVGRootInlineBox.cpp \ 2974 2976 WebCore/rendering/SVGRootInlineBox.h \ 2977 WebCore/rendering/SVGShadowTreeElements.cpp \ 2978 WebCore/rendering/SVGShadowTreeElements.h \ 2975 2979 WebCore/rendering/style/SVGRenderStyle.cpp \ 2976 2980 WebCore/rendering/style/SVGRenderStyle.h \ -
trunk/WebCore/WebCore.gypi
r53406 r53446 3057 3057 'rendering/RenderSVGRoot.cpp', 3058 3058 'rendering/RenderSVGRoot.h', 3059 'rendering/RenderSVGShadowTreeRootContainer.cpp', 3060 'rendering/RenderSVGShadowTreeRootContainer.h', 3059 3061 'rendering/RenderSVGTSpan.cpp', 3060 3062 'rendering/RenderSVGTSpan.h', … … 3141 3143 'rendering/SVGRootInlineBox.cpp', 3142 3144 'rendering/SVGRootInlineBox.h', 3145 'rendering/SVGShadowTreeElements.cpp', 3146 'rendering/SVGShadowTreeElements.h', 3143 3147 'rendering/TableLayout.h', 3144 3148 'rendering/TextControlInnerElements.cpp', -
trunk/WebCore/WebCore.pro
r53394 r53446 1635 1635 rendering/RenderSVGModelObject.h \ 1636 1636 rendering/RenderSVGRoot.h \ 1637 rendering/RenderSVGShadowTreeRootContainer.h \ 1637 1638 rendering/RenderSVGText.h \ 1638 1639 rendering/RenderSVGTextPath.h \ … … 1692 1693 rendering/SVGRenderTreeAsText.h \ 1693 1694 rendering/SVGRootInlineBox.h \ 1695 rendering/SVGShadowTreeElements.h \ 1694 1696 rendering/TextControlInnerElements.h \ 1695 1697 rendering/TransformState.h \ … … 2579 2581 rendering/RenderSVGModelObject.cpp \ 2580 2582 rendering/RenderSVGRoot.cpp \ 2583 rendering/RenderSVGShadowTreeRootContainer.cpp \ 2581 2584 rendering/RenderSVGText.cpp \ 2582 2585 rendering/RenderSVGTextPath.cpp \ … … 2589 2592 rendering/SVGMarkerLayoutInfo.cpp \ 2590 2593 rendering/SVGRenderSupport.cpp \ 2591 rendering/SVGRootInlineBox.cpp 2594 rendering/SVGRootInlineBox.cpp \ 2595 rendering/SVGShadowTreeElements.cpp 2592 2596 } 2593 2597 -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r53429 r53446 27466 27466 </File> 27467 27467 <File 27468 RelativePath="..\rendering\RenderSVGShadowTreeRootContainer.cpp" 27469 > 27470 </File> 27471 <File 27472 RelativePath="..\rendering\RenderSVGShadowTreeRootContainer.h" 27473 > 27474 </File> 27475 <File 27468 27476 RelativePath="..\rendering\RenderSVGText.cpp" 27469 27477 > … … 27793 27801 <File 27794 27802 RelativePath="..\rendering\SVGRootInlineBox.h" 27803 > 27804 </File> 27805 <File 27806 RelativePath="..\rendering\SVGShadowTreeElements.cpp" 27807 > 27808 </File> 27809 <File 27810 RelativePath="..\rendering\SVGShadowTreeElements.h" 27795 27811 > 27796 27812 </File> -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r53443 r53446 145 145 08CD61BC0ED3929C002DDF51 /* WMLTaskElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08CD61B80ED3929C002DDF51 /* WMLTaskElement.cpp */; }; 146 146 08CD61BD0ED3929C002DDF51 /* WMLTaskElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08CD61B90ED3929C002DDF51 /* WMLTaskElement.h */; }; 147 08DAB9BA1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */; }; 148 08DAB9BB1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */; }; 149 08DAB9C21103D9C1003E7ABA /* SVGShadowTreeElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */; }; 150 08DAB9C31103D9C1003E7ABA /* SVGShadowTreeElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */; }; 147 151 08E192530EDE0C3A0087B780 /* WMLErrorHandling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08E192510EDE0C390087B780 /* WMLErrorHandling.cpp */; }; 148 152 08E192540EDE0C3A0087B780 /* WMLErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E192520EDE0C3A0087B780 /* WMLErrorHandling.h */; }; … … 5369 5373 08CD61B80ED3929C002DDF51 /* WMLTaskElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLTaskElement.cpp; sourceTree = "<group>"; }; 5370 5374 08CD61B90ED3929C002DDF51 /* WMLTaskElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLTaskElement.h; sourceTree = "<group>"; }; 5375 08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGShadowTreeRootContainer.cpp; sourceTree = "<group>"; }; 5376 08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGShadowTreeRootContainer.h; sourceTree = "<group>"; }; 5377 08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGShadowTreeElements.cpp; sourceTree = "<group>"; }; 5378 08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGShadowTreeElements.h; sourceTree = "<group>"; }; 5371 5379 08E192510EDE0C390087B780 /* WMLErrorHandling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLErrorHandling.cpp; sourceTree = "<group>"; }; 5372 5380 08E192520EDE0C3A0087B780 /* WMLErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLErrorHandling.h; sourceTree = "<group>"; }; … … 15582 15590 AA31B5B20C1DFD1000AE7083 /* RenderSVGRoot.cpp */, 15583 15591 AA31B5B30C1DFD1000AE7083 /* RenderSVGRoot.h */, 15592 08DAB9B81103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp */, 15593 08DAB9B91103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h */, 15584 15594 853CA9D20AEEC5E9002372DC /* RenderSVGText.cpp */, 15585 15595 853CA9D30AEEC5E9002372DC /* RenderSVGText.h */, … … 15645 15655 853CA9E40AEEC608002372DC /* SVGRootInlineBox.cpp */, 15646 15656 853CA9E50AEEC608002372DC /* SVGRootInlineBox.h */, 15657 08DAB9C01103D9C1003E7ABA /* SVGShadowTreeElements.cpp */, 15658 08DAB9C11103D9C1003E7ABA /* SVGShadowTreeElements.h */, 15647 15659 A8CFF04C0A154F09000A4234 /* TableLayout.h */, 15648 15660 AB014DE10E689A4300E10445 /* TextControlInnerElements.cpp */, … … 18356 18368 6E4E91AF10F7FB3100A2779C /* WebGLContextAttributes.h in Headers */, 18357 18369 6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */, 18370 08DAB9BB1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.h in Headers */, 18371 08DAB9C31103D9C1003E7ABA /* SVGShadowTreeElements.h in Headers */, 18358 18372 E15A36D71104572000B7B639 /* XMLNSNames.h in Headers */, 18359 18373 59A9E7B21104759400DFB4C1 /* JavaInstanceJSC.h in Headers */, … … 20521 20535 6E4E91AE10F7FB3100A2779C /* WebGLContextAttributes.cpp in Sources */, 20522 20536 6EE8A77210F803F3005A4A24 /* JSWebGLContextAttributes.cpp in Sources */, 20537 08DAB9BA1103D9A5003E7ABA /* RenderSVGShadowTreeRootContainer.cpp in Sources */, 20538 08DAB9C21103D9C1003E7ABA /* SVGShadowTreeElements.cpp in Sources */, 20523 20539 E15A36D91104572700B7B639 /* XMLNSNames.cpp in Sources */, 20524 20540 59A9E7B01104758800DFB4C1 /* JavaInstanceJSC.cpp in Sources */, -
trunk/WebCore/rendering/RenderSVGTransformableContainer.cpp
r53365 r53446 1 1 /* 2 Copyright (C) 2004, 2005 Nikolas Zimmermann < wildfox@kde.org>2 Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 3 3 2004, 2005, 2006 Rob Buis <buis@kde.org> 4 4 2009 Google, Inc. … … 21 21 22 22 #include "config.h" 23 23 24 #if ENABLE(SVG) 24 25 25 #include "RenderSVGTransformableContainer.h" 26 26 27 #include "SVGShadowTreeElements.h" 27 28 #include "SVGStyledTransformableElement.h" 28 #include "SVGTransformList.h"29 29 30 30 namespace WebCore { … … 48 48 { 49 49 m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform(); 50 if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement()) 51 return; 52 53 FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(node())->containerTranslation(); 54 if (translation.width() == 0 && translation.height() == 0) 55 return; 56 57 m_localTransform.translateRight(translation.width(), translation.height()); 50 58 } 51 59 -
trunk/WebCore/svg/SVGElement.cpp
r52312 r53446 55 55 SVGElement::SVGElement(const QualifiedName& tagName, Document* document) 56 56 : StyledElement(tagName, document, CreateElementZeroRefCount) 57 , m_shadowParent(0)58 57 , m_cursorElement(0) 59 58 , m_cursorImageValue(0) … … 286 285 ContainerNode* SVGElement::eventParentNode() 287 286 { 288 return m_shadowParent ? m_shadowParent : StyledElement::eventParentNode(); 287 if (Node* shadowParent = shadowParentNode()) { 288 ASSERT(shadowParent->isContainerNode()); 289 return static_cast<ContainerNode*>(shadowParent); 290 } 291 return StyledElement::eventParentNode(); 289 292 } 290 293 -
trunk/WebCore/svg/SVGElement.h
r49745 r53446 61 61 virtual bool isTextContent() const { return false; } 62 62 63 void setShadowParentNode(ContainerNode* node) { m_shadowParent = node; }64 65 63 // For SVGTests 66 64 virtual bool isValid() const { return true; } … … 96 94 97 95 virtual bool isSVGElement() const { return true; } 96 virtual bool isSupported(StringImpl* feature, StringImpl* version) const; 98 97 99 virtual bool isSupported(StringImpl* feature, StringImpl* version) const;100 101 virtual bool isShadowNode() const { return m_shadowParent; }102 virtual Node* shadowParentNode() { return m_shadowParent; }103 98 virtual ContainerNode* eventParentNode(); 104 105 99 virtual void buildPendingResource() { } 106 100 … … 110 104 virtual bool haveLoadedRequiredResources(); 111 105 112 ContainerNode* m_shadowParent;113 106 mutable SynchronizablePropertyController m_propertyController; 114 107 -
trunk/WebCore/svg/SVGElementInstance.cpp
r48701 r53446 34 34 #include <wtf/RefCountedLeakCounter.h> 35 35 36 #if USE(JSC)37 #include "GCController.h"38 #endif39 40 36 namespace WebCore { 41 37 … … 52 48 53 49 SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement) 54 : m_needsUpdate(false) 55 , m_useElement(useElement) 50 : m_useElement(useElement) 56 51 , m_element(originalElement) 57 52 , m_previousSibling(0) … … 94 89 } 95 90 96 void SVGElementInstance::forgetWrapper()97 {98 #if USE(JSC)99 // FIXME: This is fragile, as discussed with Sam. Need to find a better solution.100 // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;".101 // We still have to recreate this wrapper somehow. The gc collection below, won't catch it.102 103 // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects104 // are still holding RefPtrs of SVGElementInstance objects, which prevent us to105 // be deleted (and the shadow tree is not destructed as well). Force JS GC.106 gcController().garbageCollectNow();107 #endif108 }109 110 91 void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) 111 92 { … … 115 96 void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) 116 97 { 117 if (!element) 98 if (!element || !element->isStyled()) 99 return; 100 101 if (static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked()) 118 102 return; 119 103 … … 122 106 return; 123 107 124 // Find all use elements referencing the instances - ask them _once_ to rebuild.108 // Mark all use elements referencing 'element' for rebuilding 125 109 HashSet<SVGElementInstance*>::const_iterator it = set.begin(); 126 110 const HashSet<SVGElementInstance*>::const_iterator end = set.end(); 127 111 128 for (; it != end; ++it) 129 (*it)->setNeedsUpdate(true); 130 } 131 132 void SVGElementInstance::setNeedsUpdate(bool value) 133 { 134 m_needsUpdate = value; 135 136 if (m_needsUpdate) 137 correspondingUseElement()->setNeedsStyleRecalc(); 112 for (; it != end; ++it) { 113 ASSERT((*it)->correspondingElement() == element); 114 (*it)->correspondingUseElement()->invalidateShadowTree(); 115 } 138 116 } 139 117 -
trunk/WebCore/svg/SVGElementInstance.h
r48701 r53446 46 46 47 47 virtual ~SVGElementInstance(); 48 49 bool needsUpdate() const { return m_needsUpdate; }50 void setNeedsUpdate(bool);51 48 52 49 virtual ScriptExecutionContext* scriptExecutionContext() const; … … 130 127 void appendChild(PassRefPtr<SVGElementInstance> child); 131 128 void setShadowTreeElement(SVGElement*); 132 void forgetWrapper();133 129 134 130 template<class GenericNode, class GenericNodeContainer> … … 154 150 virtual EventTargetData* ensureEventTargetData(); 155 151 156 bool m_needsUpdate : 1;157 158 152 SVGUseElement* m_useElement; 159 153 RefPtr<SVGElement> m_element; -
trunk/WebCore/svg/SVGGElement.h
r53229 r53446 38 38 virtual ~SVGGElement(); 39 39 40 virtual bool isShadowTreeContainerElement() const { return false; } 40 41 virtual bool isValid() const { return SVGTests::isValid(); } 41 42 -
trunk/WebCore/svg/SVGStyledElement.cpp
r52709 r53446 48 48 49 49 char SVGStyledElementIdentifier[] = "SVGStyledElement"; 50 static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0;51 50 52 51 void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) … … 60 59 : SVGElement(tagName, doc) 61 60 , m_className(this, HTMLNames::classAttr) 61 , m_instanceUpdatesBlocked(false) 62 62 { 63 63 } … … 222 222 223 223 if (document->parsing()) 224 return; 224 return; 225 225 226 226 #if ENABLE(FILTERS) … … 303 303 SVGElement::detach(); 304 304 } 305 306 void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates)307 {308 if (blockUpdates) {309 if (!gElementsWithInstanceUpdatesBlocked)310 gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>;311 gElementsWithInstanceUpdatesBlocked->add(this);312 } else {313 ASSERT(gElementsWithInstanceUpdatesBlocked);314 ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this));315 gElementsWithInstanceUpdatesBlocked->remove(this);316 }317 }318 305 319 306 } -
trunk/WebCore/svg/SVGStyledElement.h
r53229 r53446 51 51 virtual bool rendererIsNeeded(RenderStyle*); 52 52 virtual SVGResource* canvasResource(const RenderObject*) { return 0; } 53 53 54 54 virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; 55 55 virtual void parseMappedAttribute(MappedAttribute*); 56 57 56 virtual void svgAttributeChanged(const QualifiedName&); 58 57 … … 66 65 67 66 virtual void detach(); 68 69 void setInstanceUpdatesBlocked(bool); 67 68 bool instanceUpdatesBlocked() const { return m_instanceUpdatesBlocked; } 69 void setInstanceUpdatesBlocked(bool value) { m_instanceUpdatesBlocked = value; } 70 70 71 71 protected: … … 74 74 private: 75 75 ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className) 76 bool m_instanceUpdatesBlocked; 76 77 }; 77 78 -
trunk/WebCore/svg/SVGUseElement.cpp
r53229 r53446 2 2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 3 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 4 Copyright (C) Research In Motion Limited 2009 . All rights reserved.4 Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 5 5 6 6 This library is free software; you can redistribute it and/or … … 34 34 #include "NodeRenderStyle.h" 35 35 #include "RegisteredEventListener.h" 36 #include "RenderSVG TransformableContainer.h"36 #include "RenderSVGShadowTreeRootContainer.h" 37 37 #include "SVGElementInstance.h" 38 38 #include "SVGElementInstanceList.h" … … 40 40 #include "SVGLength.h" 41 41 #include "SVGPreserveAspectRatio.h" 42 #include "SVGShadowTreeElements.h" 42 43 #include "SVGSMILElement.h" 43 44 #include "SVGSVGElement.h" … … 66 67 , m_href(this, XLinkNames::hrefAttr) 67 68 , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) 69 , m_isPendingResource(false) 70 , m_needsShadowTreeRecreation(false) 68 71 { 69 72 } … … 75 78 SVGElementInstance* SVGUseElement::instanceRoot() const 76 79 { 80 // If there is no element instance tree, force immediate SVGElementInstance tree 81 // creation, as we can't wait for the lazy creation to happen if ie. JS wants to 82 // access the instanceRoot object right after creating the element on-the-fly 83 if (!m_targetElementInstance) { 84 if (RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer())) { 85 shadowRoot->markShadowTreeForRecreation(); 86 shadowRoot->updateFromElement(); 87 } 88 } 89 77 90 return m_targetElementInstance.get(); 78 91 } … … 113 126 void SVGUseElement::insertedIntoDocument() 114 127 { 128 // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. 115 129 SVGElement::insertedIntoDocument(); 116 buildPendingResource(); 130 ASSERT(!m_targetElementInstance); 131 ASSERT(!m_isPendingResource); 117 132 } 118 133 … … 120 135 { 121 136 m_targetElementInstance = 0; 122 m_shadowTreeRootElement = 0;123 137 SVGElement::removedFromDocument(); 124 138 } … … 128 142 SVGStyledTransformableElement::svgAttributeChanged(attrName); 129 143 130 if (!attached()) 131 return; 132 133 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || 134 attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || 135 SVGTests::isKnownAttribute(attrName) || 136 SVGLangSpace::isKnownAttribute(attrName) || 137 SVGExternalResourcesRequired::isKnownAttribute(attrName) || 138 SVGURIReference::isKnownAttribute(attrName) || 139 SVGStyledTransformableElement::isKnownAttribute(attrName)) { 140 buildPendingResource(); 141 142 if (m_shadowTreeRootElement) 143 m_shadowTreeRootElement->setNeedsStyleRecalc(); 144 } 145 } 146 147 void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 148 { 149 SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 150 151 if (!attached()) 152 return; 153 154 buildPendingResource(); 155 156 if (m_shadowTreeRootElement) 157 m_shadowTreeRootElement->setNeedsStyleRecalc(); 158 } 159 160 static bool shadowTreeContainsChangedNodes(SVGElementInstance* target) 161 { 162 if (!target) // when use is referencing an non-existing element, there will be no Instance tree built 163 return false; 164 165 if (target->needsUpdate()) 166 return true; 167 168 for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) 169 if (shadowTreeContainsChangedNodes(instance)) 170 return true; 171 172 return false; 144 if (!renderer()) 145 return; 146 147 if (SVGURIReference::isKnownAttribute(attrName)) { 148 if (m_isPendingResource) { 149 document()->accessSVGExtensions()->removePendingResource(m_resourceId); 150 m_resourceId = String(); 151 m_isPendingResource = false; 152 } 153 154 invalidateShadowTree(); 155 return; 156 } 157 158 if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { 159 updateContainerOffsets(); 160 return; 161 } 162 163 // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! 164 if (SVGStyledElement::isKnownAttribute(attrName)) { 165 setNeedsStyleRecalc(); 166 return; 167 } 168 169 // TODO: We should be able to remove the need for width/height to require a reclone, similar to the x/y logic. 170 if (attrName == SVGNames::widthAttr 171 || attrName == SVGNames::heightAttr 172 || SVGTests::isKnownAttribute(attrName) 173 || SVGLangSpace::isKnownAttribute(attrName) 174 || SVGExternalResourcesRequired::isKnownAttribute(attrName) 175 || SVGStyledTransformableElement::isKnownAttribute(attrName)) { 176 invalidateShadowTree(); 177 } 178 } 179 180 static void updateContainerOffset(SVGElementInstance* targetInstance) 181 { 182 // Depth-first used to write the method in early exit style, no particular other reason. 183 for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) 184 updateContainerOffset(instance); 185 186 SVGElement* correspondingElement = targetInstance->correspondingElement(); 187 ASSERT(correspondingElement); 188 189 if (!correspondingElement->hasTagName(SVGNames::useTag)) 190 return; 191 192 SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); 193 ASSERT(shadowTreeElement); 194 ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag)); 195 196 if (!static_cast<SVGGElement*>(shadowTreeElement)->isShadowTreeContainerElement()) 197 return; 198 199 // Spec: An additional transformation translate(x,y) is appended to the end 200 // (i.e., right-side) of the transform attribute on the generated 'g', where x 201 // and y represent the values of the x and y attributes on the 'use' element. 202 SVGUseElement* useElement = static_cast<SVGUseElement*>(correspondingElement); 203 SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(shadowTreeElement); 204 containerElement->setContainerOffset(useElement->x(), useElement->y()); 205 } 206 207 void SVGUseElement::updateContainerOffsets() 208 { 209 if (!m_targetElementInstance) 210 return; 211 212 // Update root container offset (not reachable through instance tree) 213 SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement(); 214 ASSERT(shadowRoot); 215 216 Node* parentNode = shadowRoot->parentNode(); 217 ASSERT(parentNode); 218 ASSERT(parentNode->isSVGElement()); 219 ASSERT(parentNode->hasTagName(SVGNames::gTag)); 220 ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement()); 221 222 SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode); 223 containerElement->setContainerOffset(x(), y()); 224 225 // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree 226 updateContainerOffset(m_targetElementInstance.get()); 227 228 if (renderer()) 229 renderer()->setNeedsLayout(true); 173 230 } 174 231 175 232 void SVGUseElement::recalcStyle(StyleChange change) 176 233 { 177 if (attached() && needsStyleRecalc() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) { 178 buildPendingResource(); 179 180 if (m_shadowTreeRootElement) 181 m_shadowTreeRootElement->setNeedsStyleRecalc(); 182 } 183 184 SVGStyledElement::recalcStyle(change); 185 186 // The shadow tree root element is NOT a direct child element of us. 187 // So we have to take care it receives style updates, manually. 188 if (!m_shadowTreeRootElement || !m_shadowTreeRootElement->attached()) 189 return; 190 191 // Mimic Element::recalcStyle(). The main difference is that we don't call attach() on the 192 // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash 193 // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky. 194 if (change >= Inherit || m_shadowTreeRootElement->needsStyleRecalc()) { 195 RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get()); 196 StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get()); 197 if (ch == Detach) { 198 ASSERT(m_shadowTreeRootElement->attached()); 199 m_shadowTreeRootElement->detach(); 200 attachShadowTree(); 201 202 // attach recalulates the style for all children. No need to do it twice. 203 m_shadowTreeRootElement->setNeedsStyleRecalc(NoStyleChange); 204 m_shadowTreeRootElement->setChildNeedsStyleRecalc(false); 205 return; 206 } 207 } 208 209 // Only change==Detach needs special treatment, for anything else recalcStyle() works. 210 m_shadowTreeRootElement->recalcStyle(change); 234 // Eventually mark shadow root element needing style recalc 235 if (needsStyleRecalc() && m_targetElementInstance) { 236 if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement()) 237 shadowRoot->setNeedsStyleRecalc(); 238 } 239 240 SVGStyledTransformableElement::recalcStyle(change); 241 242 bool needsStyleUpdate = !m_needsShadowTreeRecreation; 243 if (m_needsShadowTreeRecreation) { 244 static_cast<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation(); 245 m_needsShadowTreeRecreation = false; 246 } 247 248 RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer()); 249 if (!shadowRoot) 250 return; 251 252 shadowRoot->updateFromElement(); 253 254 if (!needsStyleUpdate) 255 return; 256 257 shadowRoot->updateStyle(change); 211 258 } 212 259 … … 217 264 ASSERT(element); 218 265 266 SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); 267 ASSERT(shadowTreeElement); 268 219 269 String elementId = element->getIDAttribute(); 220 270 String elementNodeName = element->nodeName(); 271 String shadowTreeElementNodeName = shadowTreeElement->nodeName(); 221 272 String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null"; 222 273 String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null"; … … 225 276 text += " "; 226 277 227 text += String::format("SVGElementInstance this=%p, (parentNode=%s , firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n",228 targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(),229 element , targetInstance->shadowTreeElement(), elementId.latin1().data());278 text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n", 279 targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(), 280 elementNodeName.latin1().data(), element, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data()); 230 281 231 282 for (unsigned int i = 0; i < depth; ++i) … … 283 334 void SVGUseElement::buildPendingResource() 284 335 { 336 // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer) 337 // we either determine that our target is available or not - then we add ourselves to the pending resource list 338 // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time. 285 339 String id = SVGURIReference::getTarget(href()); 286 340 Element* targetElement = document()->getElementById(id); 341 ASSERT(!m_targetElementInstance); 287 342 288 343 if (!targetElement) { 289 // TODO: We want to deregister as pending resource, if our href() changed! 290 // TODO: Move to svgAttributeChanged, once we're fixing use & the new dynamic update concept. 344 if (m_isPendingResource) 345 return; 346 347 m_isPendingResource = true; 348 m_resourceId = id; 291 349 document()->accessSVGExtensions()->addPendingResource(id, this); 292 350 return; 293 351 } 352 353 if (m_isPendingResource) { 354 ASSERT(!m_targetElementInstance); 355 m_isPendingResource = false; 356 invalidateShadowTree(); 357 } 358 } 359 360 void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowRoot) 361 { 362 String id = SVGURIReference::getTarget(href()); 363 Element* targetElement = document()->getElementById(id); 364 ASSERT(targetElement); 294 365 295 366 // Do not build the shadow/instance tree for <use> elements living in a shadow tree. … … 307 378 target = static_cast<SVGElement*>(targetElement); 308 379 309 if (m_targetElementInstance) { 310 m_targetElementInstance->forgetWrapper(); 380 if (m_targetElementInstance) 311 381 m_targetElementInstance = 0; 312 }313 382 314 383 // Do not allow self-referencing. 315 384 // 'target' may be null, if it's a non SVG namespaced element. 316 if (!target || target == this) { 317 m_shadowTreeRootElement = 0; 318 return; 319 } 385 if (!target || target == this) 386 return; 320 387 321 388 // Why a seperated instance/shadow tree? SVG demands it: … … 339 406 if (foundProblem) { 340 407 m_targetElementInstance = 0; 341 m_shadowTreeRootElement = 0;342 408 return; 343 409 } … … 345 411 // Assure instance tree building was successfull 346 412 ASSERT(m_targetElementInstance); 413 ASSERT(!m_targetElementInstance->shadowTreeElement()); 347 414 ASSERT(m_targetElementInstance->correspondingUseElement() == this); 348 349 // Safe destruction, of the old shadow tree root element 350 if (m_shadowTreeRootElement) { 351 m_shadowTreeRootElement->detach(); 352 m_shadowTreeRootElement = 0; 353 } 354 355 // Setup shadow tree root node 356 m_shadowTreeRootElement = new SVGGElement(SVGNames::gTag, document()); 357 m_shadowTreeRootElement->setInDocument(); 358 m_shadowTreeRootElement->setShadowParentNode(this); 359 360 // Spec: An additional transformation translate(x,y) is appended to the end 361 // (i.e., right-side) of the transform attribute on the generated 'g', where x 362 // and y represent the values of the x and y attributes on the 'use' element. 363 if (x().value(this) != 0.0 || y().value(this) != 0.0) { 364 String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this)); 365 m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString); 366 } 415 ASSERT(m_targetElementInstance->correspondingElement() == target); 367 416 368 417 // Build shadow tree from instance tree 369 418 // This also handles the special cases: <use> on <symbol>, <use> on <svg>. 370 buildShadowTree( target, m_targetElementInstance.get());419 buildShadowTree(shadowRoot, target, m_targetElementInstance.get()); 371 420 372 421 #if ENABLE(SVG) && ENABLE(SVG_USE) 373 422 // Expand all <use> elements in the shadow tree. 374 423 // Expand means: replace the actual <use> element by what it references. 375 expandUseElementsInShadowTree( m_shadowTreeRootElement.get());424 expandUseElementsInShadowTree(shadowRoot, shadowRoot); 376 425 377 426 // Expand all <symbol> elements in the shadow tree. 378 427 // Expand means: replace the actual <symbol> element by the <svg> element. 379 expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get()); 380 428 expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); 381 429 #endif 382 430 383 431 // Now that the shadow tree is completly expanded, we can associate 384 432 // shadow tree elements <-> instances in the instance tree. 385 associateInstancesWithShadowTreeElements(m_shadowTreeRootElement->firstChild(), m_targetElementInstance.get()); 433 associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetElementInstance.get()); 434 435 // If no shadow tree element is present, this means that the reference root 436 // element was removed, as it is disallowed (ie. <use> on <foreignObject>) 437 // Do NOT leave an inconsistent instance tree around, instead destruct it. 438 if (!m_targetElementInstance->shadowTreeElement()) { 439 shadowRoot->removeAllChildren(); 440 m_targetElementInstance = 0; 441 return; 442 } 443 444 // Consistency checks - this is assumed in updateContainerOffset(). 445 ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowRoot); 386 446 387 447 // Eventually dump instance tree … … 400 460 PassRefPtr<XMLSerializer> serializer = XMLSerializer::create(); 401 461 402 String markup = serializer->serializeToString( m_shadowTreeRootElement.get(), ec);403 ASSERT( ec == 0);462 String markup = serializer->serializeToString(shadowRoot, ec); 463 ASSERT(!ec); 404 464 405 465 fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data()); … … 409 469 transferEventListenersToShadowTree(m_targetElementInstance.get()); 410 470 411 // The DOM side is setup properly. Now we have to attach the root shadow 412 // tree element manually - using attach() won't work for "shadow nodes". 413 attachShadowTree(); 471 // Update container translation offsets 472 updateContainerOffsets(); 414 473 } 415 474 416 475 RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*) 417 476 { 418 return new (arena) RenderSVGTransformableContainer(this); 477 return new (arena) RenderSVGShadowTreeRootContainer(this); 478 } 479 480 static void updateFromElementCallback(Node* node) 481 { 482 if (RenderObject* renderer = node->renderer()) 483 renderer->updateFromElement(); 419 484 } 420 485 … … 423 488 SVGStyledTransformableElement::attach(); 424 489 425 // If we're a pending resource, this doesn't have any effect.426 attachShadowTree();490 if (renderer()) 491 queuePostAttachCallback(updateFromElementCallback, this); 427 492 } 428 493 … … 430 495 { 431 496 SVGStyledTransformableElement::detach(); 432 433 if (m_shadowTreeRootElement) 434 m_shadowTreeRootElement->detach(); 497 m_targetElementInstance = 0; 435 498 } 436 499 … … 448 511 Path SVGUseElement::toClipPath() const 449 512 { 450 if (!m_shadowTreeRootElement) 451 const_cast<SVGUseElement*>(this)->buildPendingResource(); 452 453 if (!m_shadowTreeRootElement) 513 Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0; 514 if (!n) 454 515 return Path(); 455 516 456 Node* n = m_shadowTreeRootElement->firstChild();457 517 if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { 458 518 if (!isDirectReference(n)) … … 488 548 489 549 // Create SVGElementInstance object, for both container/non-container nodes. 490 RefPtr<SVGElementInstance> instancePtr = SVGElementInstance::create(this, element); 491 targetInstance->appendChild(instancePtr.get()); 550 RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, element); 551 SVGElementInstance* instancePtr = instance.get(); 552 targetInstance->appendChild(instance.release()); 492 553 493 554 // Enter recursion, appending new instance tree nodes to the "instance" object. 494 buildInstanceTree(element, instancePtr .get(), foundProblem);555 buildInstanceTree(element, instancePtr, foundProblem); 495 556 } 496 557 … … 533 594 // Create an instance object, even if we're dealing with a cycle 534 595 RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, target); 535 targetInstance->appendChild(newInstance); 596 SVGElementInstance* newInstancePtr = newInstance.get(); 597 targetInstance->appendChild(newInstance.release()); 536 598 537 599 // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children 538 buildInstanceTree(target, newInstance .get(), foundProblem);600 buildInstanceTree(target, newInstancePtr, foundProblem); 539 601 } 540 602 … … 567 629 } 568 630 569 void SVGUseElement::buildShadowTree(SVG Element* target, SVGElementInstance* targetInstance)631 void SVGUseElement::buildShadowTree(SVGShadowTreeRootElement* shadowRoot, SVGElement* target, SVGElementInstance* targetInstance) 570 632 { 571 633 // For instance <use> on <foreignObject> (direct case). … … 589 651 590 652 ExceptionCode ec = 0; 591 m_shadowTreeRootElement->appendChild(newChild.release(), ec);592 ASSERT( ec == 0);653 shadowRoot->appendChild(newChild.release(), ec); 654 ASSERT(!ec); 593 655 594 656 // Handle use referencing <svg> special case … … 598 660 599 661 #if ENABLE(SVG) && ENABLE(SVG_USE) 600 void SVGUseElement::expandUseElementsInShadowTree( Node* element)662 void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) 601 663 { 602 664 // Why expand the <use> elements in the shadow tree here, and not just … … 619 681 if (target) { 620 682 // Setup sub-shadow tree root node 621 RefPtr<SVG Element> cloneParent = new SVGGElement(SVGNames::gTag,document());683 RefPtr<SVGShadowTreeContainerElement> cloneParent = new SVGShadowTreeContainerElement(document()); 622 684 623 685 // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the … … 625 687 transferUseAttributesToReplacedElement(use, cloneParent.get()); 626 688 627 // Spec: An additional transformation translate(x,y) is appended to the end628 // (i.e., right-side) of the transform attribute on the generated 'g', where x629 // and y represent the values of the x and y attributes on the 'use' element.630 if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) {631 if (!cloneParent->hasAttribute(SVGNames::transformAttr)) {632 String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this));633 cloneParent->setAttribute(SVGNames::transformAttr, transformString);634 } else {635 String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this));636 const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr);637 cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString);638 }639 }640 641 689 ExceptionCode ec = 0; 642 690 643 691 // For instance <use> on <foreignObject> (direct case). 644 692 if (isDisallowedElement(target)) { … … 648 696 ASSERT(use->parentNode()); 649 697 use->parentNode()->replaceChild(cloneParent.release(), use, ec); 650 ASSERT( ec == 0);698 ASSERT(!ec); 651 699 return; 652 700 } … … 668 716 669 717 cloneParent->appendChild(newChild.release(), ec); 670 ASSERT( ec == 0);718 ASSERT(!ec); 671 719 672 720 // Replace <use> with referenced content. 673 721 ASSERT(use->parentNode()); 674 722 use->parentNode()->replaceChild(cloneParent.release(), use, ec); 675 ASSERT( ec == 0);723 ASSERT(!ec); 676 724 677 725 // Handle use referencing <svg> special case … … 680 728 681 729 // Immediately stop here, and restart expanding. 682 expandUseElementsInShadowTree( m_shadowTreeRootElement.get());730 expandUseElementsInShadowTree(shadowRoot, shadowRoot); 683 731 return; 684 732 } … … 686 734 687 735 for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) 688 expandUseElementsInShadowTree( child.get());689 } 690 691 void SVGUseElement::expandSymbolElementsInShadowTree( Node* element)736 expandUseElementsInShadowTree(shadowRoot, child.get()); 737 } 738 739 void SVGUseElement::expandSymbolElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) 692 740 { 693 741 if (element->hasTagName(SVGNames::symbolTag)) { … … 716 764 RefPtr<Node> newChild = child->cloneNode(true); 717 765 svgElement->appendChild(newChild.release(), ec); 718 ASSERT( ec == 0);766 ASSERT(!ec); 719 767 } 720 768 … … 730 778 ASSERT(element->parentNode()); 731 779 element->parentNode()->replaceChild(svgElement.release(), element, ec); 732 ASSERT( ec == 0);780 ASSERT(!ec); 733 781 734 782 // Immediately stop here, and restart expanding. 735 expandSymbolElementsInShadowTree( m_shadowTreeRootElement.get());783 expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); 736 784 return; 737 785 } 738 786 739 787 for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) 740 expandSymbolElementsInShadowTree( child.get());788 expandSymbolElementsInShadowTree(shadowRoot, child.get()); 741 789 } 742 790 743 791 #endif 744 745 void SVGUseElement::attachShadowTree() 746 { 747 if (!m_shadowTreeRootElement || m_shadowTreeRootElement->attached() || !document()->shouldCreateRenderers() || !attached() || !renderer()) 748 return; 749 750 // Inspired by RenderTextControl::createSubtreeIfNeeded(). 751 if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) { 752 RefPtr<RenderStyle> style = m_shadowTreeRootElement->styleForRenderer(); 753 754 if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) { 755 m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get())); 756 if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) { 757 shadowRenderer->setStyle(style.release()); 758 renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer()); 759 m_shadowTreeRootElement->setAttached(); 760 } 761 } 762 763 // This will take care of attaching all shadow tree child nodes. 764 for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling()) 765 child->attach(); 766 } 767 } 768 792 769 793 void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target) 770 794 { … … 854 878 855 879 for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) { 856 SVGElementInstance* search = instanceForShadowTreeElement(element, current); 857 if (search) 880 if (SVGElementInstance* search = instanceForShadowTreeElement(element, current)) 858 881 return search; 859 882 } 860 883 861 884 return 0; 885 } 886 887 void SVGUseElement::invalidateShadowTree() 888 { 889 m_needsShadowTreeRecreation = true; 890 setNeedsStyleRecalc(); 862 891 } 863 892 … … 872 901 873 902 to->removeAttribute(SVGNames::xAttr, ec); 874 ASSERT( ec == 0);903 ASSERT(!ec); 875 904 876 905 to->removeAttribute(SVGNames::yAttr, ec); 877 ASSERT( ec == 0);906 ASSERT(!ec); 878 907 879 908 to->removeAttribute(SVGNames::widthAttr, ec); 880 ASSERT( ec == 0);909 ASSERT(!ec); 881 910 882 911 to->removeAttribute(SVGNames::heightAttr, ec); 883 ASSERT( ec == 0);912 ASSERT(!ec); 884 913 885 914 to->removeAttribute(XLinkNames::hrefAttr, ec); 886 ASSERT( ec == 0);915 ASSERT(!ec); 887 916 } 888 917 -
trunk/WebCore/svg/SVGUseElement.h
r53229 r53446 33 33 class SVGElementInstance; 34 34 class SVGLength; 35 class SVGShadowTreeRootElement; 35 36 36 37 class SVGUseElement : public SVGStyledTransformableElement, … … 53 54 54 55 virtual void parseMappedAttribute(MappedAttribute*); 55 virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);56 virtual void svgAttributeChanged(const QualifiedName&); 56 57 57 virtual void svgAttributeChanged(const QualifiedName&);58 58 virtual void recalcStyle(StyleChange = NoChange); 59 60 59 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); 61 60 virtual void attach(); … … 66 65 static void removeDisallowedElementsFromSubtree(Node* element); 67 66 SVGElementInstance* instanceForShadowTreeElement(Node* element) const; 67 void invalidateShadowTree(); 68 69 private: 70 friend class RenderSVGShadowTreeRootContainer; 71 bool isPendingResource() const { return m_isPendingResource; } 72 void buildShadowAndInstanceTree(SVGShadowTreeRootElement*); 68 73 69 74 private: … … 89 94 90 95 // Shadow tree handling 91 PassRefPtr<SVGSVGElement> buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance); 92 void alterShadowTreeForSVGTag(SVGElement* target); 93 94 void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance); 96 void alterShadowTreeForSVGTag(SVGElement*); 97 void buildShadowTree(SVGShadowTreeRootElement*, SVGElement* target, SVGElementInstance* targetInstance); 95 98 96 99 #if ENABLE(SVG) && ENABLE(SVG_USE) 97 void expandUseElementsInShadowTree( Node* element);98 void expandSymbolElementsInShadowTree( Node* element);100 void expandUseElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); 101 void expandSymbolElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); 99 102 #endif 100 101 void attachShadowTree();102 103 103 104 // "Tree connector" … … 107 108 void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const; 108 109 void transferEventListenersToShadowTree(SVGElementInstance* target); 110 void updateContainerOffsets(); 109 111 110 RefPtr<SVGElement> m_shadowTreeRootElement; 112 bool m_isPendingResource; 113 bool m_needsShadowTreeRecreation; 114 String m_resourceId; 111 115 RefPtr<SVGElementInstance> m_targetElementInstance; 112 116 };
Note: See TracChangeset
for help on using the changeset viewer.