2011-07-29 Rob Buis <rbuis@rim.com>
authorrwlbuis@webkit.org <rwlbuis@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Jul 2011 03:22:56 +0000 (03:22 +0000)
committerrwlbuis@webkit.org <rwlbuis@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Jul 2011 03:22:56 +0000 (03:22 +0000)
        URL references are completely broken in SVG
        https://bugs.webkit.org/show_bug.cgi?id=63283

        Reviewed by Nikolas Zimmermann.

        Change SVGURIElement::getTarget to be more strict about iri resolving and make it serve as a central
        place to resolve a iri to a SVGElement. The iri can be same-document or external, for now we only handle
        the former, the latter will be handled in bug 65344.
        Accept as same-document if the iri combined with the base uri equals the document url (ignoring
        the fragment identifier). For convenience a method is added to lookup the element, if found.

        Tests: svg/custom/external-paintserver-reference.svg
               svg/custom/linking-base-external-reference.xhtml
               svg/custom/uri-reference-handling.svg

        * css/CSSCursorImageValue.cpp:
        (WebCore::resourceReferencedByCursorElement):
        (WebCore::CSSCursorImageValue::~CSSCursorImageValue):
        (WebCore::CSSCursorImageValue::updateIfSVGCursorIsUsed):
        * css/CSSFontFaceSource.cpp:
        (WebCore::CSSFontFaceSource::getFontData):
        * css/CSSFontSelector.h:
        (WebCore::CSSFontSelector::document):
        * css/SVGCSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::applySVGProperty):
        * rendering/svg/RenderSVGTextPath.cpp:
        (WebCore::RenderSVGTextPath::layoutPath):
        * rendering/svg/SVGResources.cpp:
        (WebCore::targetReferenceFromResource):
        (WebCore::paintingResourceFromSVGPaint):
        * svg/SVGAltGlyphElement.cpp:
        (WebCore::SVGAltGlyphElement::hasValidGlyphElements):
        * svg/SVGFEImageElement.cpp:
        (WebCore::SVGFEImageElement::requestImageResource):
        (WebCore::SVGFEImageElement::build):
        * svg/SVGGlyphRefElement.cpp:
        (WebCore::SVGGlyphRefElement::hasValidGlyphElement):
        * svg/SVGLinearGradientElement.cpp:
        (WebCore::SVGLinearGradientElement::collectGradientAttributes):
        * svg/SVGMPathElement.cpp:
        (WebCore::SVGMPathElement::pathElement):
        * svg/SVGPaint.cpp:
        (WebCore::SVGPaint::matchesTargetURI):
        * svg/SVGPatternElement.cpp:
        (WebCore::SVGPatternElement::collectPatternAttributes):
        * svg/SVGRadialGradientElement.cpp:
        (WebCore::SVGRadialGradientElement::collectGradientAttributes):
        * svg/SVGTRefElement.cpp:
        (WebCore::SVGTRefElement::updateReferencedText):
        (WebCore::SVGTRefElement::svgAttributeChanged):
        (WebCore::SVGTRefElement::buildPendingResource):
        * svg/SVGTextPathElement.cpp:
        (WebCore::SVGTextPathElement::insertedIntoDocument):
        * svg/SVGURIReference.cpp:
        (WebCore::SVGURIReference::fragmentIdentifierFromIRIString):
        (WebCore::SVGURIReference::targetElementFromIRIString):
        * svg/SVGURIReference.h:
        * svg/SVGUseElement.cpp:
        (WebCore::SVGUseElement::buildPendingResource):
        (WebCore::SVGUseElement::hasCycleUseReferencing):
        (WebCore::SVGUseElement::expandUseElementsInShadowTree):
        * svg/animation/SVGSMILElement.cpp:
        (WebCore::SVGSMILElement::targetElement):

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

62 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-use-05-b-expected.txt
LayoutTests/platform/mac/svg/batik/filters/feTile-expected.txt
LayoutTests/platform/mac/svg/batik/filters/filterRegions-expected.txt
LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.txt
LayoutTests/platform/mac/svg/batik/paints/gradientLimit-expected.txt
LayoutTests/platform/mac/svg/batik/paints/patternPreserveAspectRatioA-expected.txt
LayoutTests/platform/mac/svg/batik/paints/patternRegionA-expected.txt
LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.txt
LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.txt
LayoutTests/platform/mac/svg/batik/text/longTextOnPath-expected.txt
LayoutTests/platform/mac/svg/batik/text/smallFonts-expected.txt
LayoutTests/platform/mac/svg/batik/text/textAnchor-expected.txt
LayoutTests/platform/mac/svg/batik/text/textDecoration-expected.txt
LayoutTests/platform/mac/svg/batik/text/textEffect-expected.txt
LayoutTests/platform/mac/svg/batik/text/textEffect2-expected.txt
LayoutTests/platform/mac/svg/batik/text/textEffect3-expected.txt
LayoutTests/platform/mac/svg/batik/text/textFeatures-expected.txt
LayoutTests/platform/mac/svg/batik/text/textLayout-expected.txt
LayoutTests/platform/mac/svg/batik/text/textLayout2-expected.txt
LayoutTests/platform/mac/svg/batik/text/textLength-expected.txt
LayoutTests/platform/mac/svg/batik/text/textOnPath-expected.txt
LayoutTests/platform/mac/svg/batik/text/textOnPathSpaces-expected.txt
LayoutTests/platform/mac/svg/batik/text/textPosition-expected.txt
LayoutTests/platform/mac/svg/batik/text/textPosition2-expected.txt
LayoutTests/platform/mac/svg/batik/text/textProperties-expected.txt
LayoutTests/platform/mac/svg/batik/text/textProperties2-expected.txt
LayoutTests/platform/mac/svg/batik/text/textStyles-expected.txt
LayoutTests/platform/mac/svg/batik/text/verticalText-expected.txt
LayoutTests/platform/mac/svg/batik/text/verticalTextOnPath-expected.txt
LayoutTests/platform/mac/svg/hixie/error/014-expected.txt
LayoutTests/platform/mac/svg/hixie/use/002-expected.txt
LayoutTests/svg/custom/external-paintserver-reference-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/external-paintserver-reference-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/external-paintserver-reference.svg [new file with mode: 0644]
LayoutTests/svg/custom/linking-base-external-reference-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/linking-base-external-reference-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/linking-base-external-reference.xhtml [new file with mode: 0644]
LayoutTests/svg/custom/uri-reference-handling-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/uri-reference-handling-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/uri-reference-handling.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSCursorImageValue.cpp
Source/WebCore/css/CSSFontFaceSource.cpp
Source/WebCore/css/CSSFontSelector.h
Source/WebCore/css/SVGCSSStyleSelector.cpp
Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
Source/WebCore/rendering/svg/SVGResources.cpp
Source/WebCore/svg/SVGAltGlyphElement.cpp
Source/WebCore/svg/SVGFEImageElement.cpp
Source/WebCore/svg/SVGGlyphRefElement.cpp
Source/WebCore/svg/SVGLinearGradientElement.cpp
Source/WebCore/svg/SVGMPathElement.cpp
Source/WebCore/svg/SVGPaint.cpp
Source/WebCore/svg/SVGPatternElement.cpp
Source/WebCore/svg/SVGRadialGradientElement.cpp
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/SVGTextPathElement.cpp
Source/WebCore/svg/SVGURIReference.cpp
Source/WebCore/svg/SVGURIReference.h
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/svg/animation/SVGSMILElement.cpp

index 29b4e75..856ec00 100644 (file)
@@ -1,3 +1,51 @@
+2011-07-29  Rob Buis  <rbuis@rim.com>
+
+        URL references are completely broken in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=63283
+
+        Reviewed by Nikolas Zimmermann.
+
+        * platform/mac/svg/W3C-SVG-1.1/struct-use-05-b-expected.txt:
+        * platform/mac/svg/batik/filters/feTile-expected.txt:
+        * platform/mac/svg/batik/filters/filterRegions-expected.txt:
+        * platform/mac/svg/batik/masking/maskRegions-expected.txt:
+        * platform/mac/svg/batik/paints/gradientLimit-expected.txt:
+        * platform/mac/svg/batik/paints/patternPreserveAspectRatioA-expected.txt:
+        * platform/mac/svg/batik/paints/patternRegionA-expected.txt:
+        * platform/mac/svg/batik/paints/patternRegions-expected.txt:
+        * platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.txt:
+        * platform/mac/svg/batik/text/longTextOnPath-expected.txt:
+        * platform/mac/svg/batik/text/smallFonts-expected.txt:
+        * platform/mac/svg/batik/text/textAnchor-expected.txt:
+        * platform/mac/svg/batik/text/textDecoration-expected.txt:
+        * platform/mac/svg/batik/text/textEffect-expected.txt:
+        * platform/mac/svg/batik/text/textEffect2-expected.txt:
+        * platform/mac/svg/batik/text/textEffect3-expected.txt:
+        * platform/mac/svg/batik/text/textFeatures-expected.txt:
+        * platform/mac/svg/batik/text/textLayout-expected.txt:
+        * platform/mac/svg/batik/text/textLayout2-expected.txt:
+        * platform/mac/svg/batik/text/textLength-expected.txt:
+        * platform/mac/svg/batik/text/textOnPath-expected.txt:
+        * platform/mac/svg/batik/text/textOnPathSpaces-expected.txt:
+        * platform/mac/svg/batik/text/textPosition-expected.txt:
+        * platform/mac/svg/batik/text/textPosition2-expected.txt:
+        * platform/mac/svg/batik/text/textProperties-expected.txt:
+        * platform/mac/svg/batik/text/textProperties2-expected.txt:
+        * platform/mac/svg/batik/text/textStyles-expected.txt:
+        * platform/mac/svg/batik/text/verticalText-expected.txt:
+        * platform/mac/svg/batik/text/verticalTextOnPath-expected.txt:
+        * platform/mac/svg/hixie/error/014-expected.txt:
+        * platform/mac/svg/hixie/use/002-expected.txt:
+        * svg/custom/external-paintserver-reference-expected.png: Added.
+        * svg/custom/external-paintserver-reference-expected.txt: Added.
+        * svg/custom/external-paintserver-reference.svg: Added.
+        * svg/custom/linking-base-external-reference-expected.png: Added.
+        * svg/custom/linking-base-external-reference-expected.txt: Added.
+        * svg/custom/linking-base-external-reference.xhtml: Added.
+        * svg/custom/uri-reference-handling-expected.png: Added.
+        * svg/custom/uri-reference-handling-expected.txt: Added.
+        * svg/custom/uri-reference-handling.svg: Added.
+
 2011-07-29  Zhenyao Mo  <zmo@google.com>
 
         Unreviewed, rebaseline, gardener stuff.
index 76f6254..79bec3f 100644 (file)
@@ -17,9 +17,13 @@ layer at (0,0) size 480x360
           RenderSVGGradientStop {stop} [offset=0.66] [color=#FFFFFF]
           RenderSVGGradientStop {stop} [offset=1.00] [color=#4169E1]
       RenderSVGContainer {use} 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
       RenderSVGContainer {use} 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 (40,13) size 400x28 contains 1 chunk(s)
       RenderSVGInlineText {#text} at (0,0) size 400x28
         chunk 1 (middle anchor) text run 1 at (40.00,35.00) startOffset 0 endOffset 39 width 400.00: "External references and computed values"
index ea1bbf3..87ac172 100644 (file)
@@ -91,3 +91,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 161x18
           chunk 1 text run 1 at (20.00,475.00) startOffset 0 endOffset 26 width 161.00: "How it should look like..."
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 4783062..356d5fa 100644 (file)
@@ -170,3 +170,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 132x21
             chunk 1 (middle anchor) text run 1 at (-21.00,25.00) startOffset 0 endOffset 16 width 132.00: "filterRegion_3_3"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index c2a4e53..27ed12d 100644 (file)
@@ -71,3 +71,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 52x19
             chunk 1 (middle anchor) text run 1 at (24.50,-3.00) startOffset 0 endOffset 6 width 51.00: "Mask 4"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 6246f25..d1be324 100644 (file)
@@ -77,3 +77,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 120x19
             chunk 1 (middle anchor) text run 1 at (15.50,150.00) startOffset 0 endOffset 16 width 119.00: "<radialGradient>"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index c425f37..cb7a541 100644 (file)
@@ -951,3 +951,4 @@ layer at (0,0) size 450x500
             RenderSVGContainer {g} at (294,444) size 92x32 [transform={m=((1.00,0.00)(0.00,1.00)) t=(200.00,0.00)}] [start marker=startEndMarker] [end marker=startEndMarker]
               RenderSVGPath {rect} at (294,444) size 92x32 [transform={m=((1.00,0.00)(0.00,1.00)) t=(45.00,5.00)}] [stroke={[type=SOLID] [color=#000000]}] [fill={[type=PATTERN] [id="noneNone"]}] [start marker=startEndMarker] [end marker=startEndMarker] [x=0.00] [y=0.00] [width=90.00] [height=30.00]
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 26297aa..461f514 100644 (file)
@@ -205,3 +205,4 @@ layer at (0,0) size 450x500
           RenderSVGPath {rect} at (254,339) size 102x52 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=PATTERN] [id="patternWiderHigherRegion"]}] [x=0.00] [y=0.00] [width=100.00] [height=50.00]
           RenderSVGPath {rect} at (254,339) size 42x42 [stroke={[type=SOLID] [color=#FFFFFF]}] [fill={[type=SOLID] [color=#000000] [opacity=0.12]}] [x=0.00] [y=0.00] [width=40.00] [height=40.00]
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index de2791f..5c66963 100644 (file)
@@ -159,3 +159,4 @@ layer at (0,0) size 450x500
               RenderSVGInlineText {#text} at (0,0) size 68x13
                 chunk 1 text run 1 at (0.00,10.00) startOffset 0 endOffset 16 width 68.00: "overflow=visible"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 3d6375c..e0c87f4 100644 (file)
@@ -168,3 +168,4 @@ layer at (0,0) size 450x500
                 RenderSVGInlineText {#text} at (0,0) size 68x13
                   chunk 1 text run 1 at (0.00,10.00) startOffset 0 endOffset 16 width 68.00: "overflow=visible"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 43c986b..f46dba8 100644 (file)
@@ -661,3 +661,4 @@ layer at (0,0) size 450x500
             chunk 1 text run 70 at (289.50,390.00) startOffset 69 endOffset 70 width 5.00: "."
         RenderSVGInlineText {#text} at (0,0) size 0x0
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index c4e4e5c..cb9e505 100644 (file)
@@ -171,3 +171,4 @@ layer at (0,0) size 450x500
                   chunk 1 text run 7 at (2.28,0.45) startOffset 6 endOffset 7 width 0.16: "h"
             RenderSVGInlineText {#text} at (0,0) size 0x0
     RenderSVGContainer {use} at (0,0) size 0x0 [transform={m=((0.02,0.00)(0.00,0.02)) t=(0.00,0.00)}]
+      RenderSVGContainer {g} at (0,0) size 0x0
index 32282a1..773a292 100644 (file)
@@ -161,3 +161,4 @@ layer at (0,0) size 450x500
                 chunk 1 (end anchor) text run 1 at (204.00,30.00) startOffset 0 endOffset 18 width 116.00: "another text chunk"
             RenderSVGInlineText {#text} at (0,0) size 0x0
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 04baacd..8fad800 100644 (file)
@@ -96,3 +96,4 @@ layer at (0,0) size 450x500
             RenderSVGInlineText {#text} at (154,0) size 49x23
               chunk 1 text run 1 at (204.00,460.00) startOffset 0 endOffset 6 width 49.00: "ations"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 7ab4a52..11a1fae 100644 (file)
@@ -50,3 +50,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 56x14
           chunk 1 (middle anchor) text run 1 at (302.50,400.00) startOffset 0 endOffset 10 width 55.00: "(SVG font)"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 37d78d8..d792bcb 100644 (file)
@@ -33,3 +33,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 55x14
           chunk 1 text run 1 at (300.00,300.00) startOffset 0 endOffset 10 width 55.00: "(SVG font)"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 83af6cb..a633660 100644 (file)
@@ -126,3 +126,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 56x14
           chunk 1 (middle anchor) text run 1 at (302.50,400.00) startOffset 0 endOffset 10 width 55.00: "(SVG font)"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 6a00ed5..669a8fb 100644 (file)
@@ -154,3 +154,4 @@ layer at (0,0) size 450x500
             RenderSVGInlineText {#text} at (0,0) size 129x46
               chunk 1 text run 1 at (0.00,0.00) startOffset 0 endOffset 6 width 129.00: "Shadow"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 93c3c58..f4d394d 100644 (file)
@@ -239,3 +239,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 239x9
             chunk 1 text run 1 at (40.00,455.00) startOffset 0 endOffset 66 width 239.00: "textLength=\"350\" lengthAdjust=\"spacingAndGlyphs\" word-spacing=\"-5\""
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index bab2762..1606d46 100644 (file)
@@ -129,3 +129,4 @@ layer at (0,0) size 450x500
           chunk 1 (middle anchor) text run 18 at (274.00,465.00) startOffset 17 endOffset 18 width 8.00: "h"
           chunk 1 (middle anchor) text run 19 at (282.00,465.00) startOffset 18 endOffset 19 width 6.00: "s"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 218eb15..35ea64d 100644 (file)
@@ -172,3 +172,4 @@ layer at (0,0) size 450x500
             RenderSVGInlineText {#text} at (0,28) size 76x15
               chunk 1 text run 1 at (160.00,68.80) startOffset 0 endOffset 15 width 76.00: "font-size=\"100\""
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index daaac97..c75288a 100644 (file)
@@ -361,3 +361,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 98x13
             chunk 1 text run 1 at (15.00,40.00) startOffset 0 endOffset 26 width 98.00: "text before/after textPath"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 6337618..d244bbe 100644 (file)
@@ -264,3 +264,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 84x13
             chunk 1 text run 1 at (35.00,90.00) startOffset 0 endOffset 18 width 84.00: "\"spacingAndGlyphs\""
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index f45d41f..01a7288 100644 (file)
@@ -136,3 +136,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 114x13
           chunk 1 text run 1 at (240.00,400.00) startOffset 0 endOffset 22 width 114.00: "Empty Preceeding tspan"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index cf33483..e3fb48c 100644 (file)
@@ -113,3 +113,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (33,11) size 158x13
             chunk 1 text run 1 at (273.00,351.00) startOffset 0 endOffset 34 width 158.00: "y=\"320\" style=\"letter-spacing:10\">"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 065da64..39f75d0 100644 (file)
@@ -165,3 +165,4 @@ layer at (0,0) size 450x500
         RenderSVGInlineText {#text} at (0,0) size 148x18
           chunk 1 (middle anchor) text run 1 at (226.00,465.00) startOffset 0 endOffset 22 width 148.00: "stroke-linecap=\"round\""
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 88189d0..cd320d3 100644 (file)
@@ -139,3 +139,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (33,0) size 67x19
             chunk 1 text run 1 at (53.60,230.00) startOffset 0 endOffset 11 width 66.40: "finish text"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 8406944..b7595d0 100644 (file)
@@ -180,3 +180,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 322x36
             chunk 1 (middle anchor) text run 1 at (-160.50,15.00) startOffset 0 endOffset 25 width 321.00: "AvantGarde (line-through)"
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 4fc65b8..275d94d 100644 (file)
@@ -269,3 +269,4 @@ layer at (0,0) size 450x500
               chunk 1 (vertical) text run 25 at (298.36,17.42) startOffset 24 endOffset 25 height 14.00: "\x{50CF}"
           RenderSVGInlineText {#text} at (0,0) size 0x0
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 9364aa2..f7e0f7d 100644 (file)
@@ -402,3 +402,4 @@ layer at (0,0) size 450x500
           RenderSVGInlineText {#text} at (0,0) size 100x13
             chunk 1 text run 1 at (0.00,110.00) startOffset 0 endOffset 24 width 100.00: "glyph-orientation=\"auto\""
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 9ea87c0..ed59409 100644 (file)
@@ -4,3 +4,4 @@ layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 200x200
     RenderSVGPath {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=200.00] [height=200.00]
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
index 8cf362a..511b820 100644 (file)
@@ -4,3 +4,4 @@ layer at (0,0) size 800x600
   RenderSVGRoot {svg} at (0,0) size 200x200
     RenderSVGPath {rect} at (0,0) size 200x200 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=200.00] [height=200.00]
     RenderSVGContainer {use} at (0,0) size 0x0
+      RenderSVGContainer {g} at (0,0) size 0x0
diff --git a/LayoutTests/svg/custom/external-paintserver-reference-expected.png b/LayoutTests/svg/custom/external-paintserver-reference-expected.png
new file mode 100644 (file)
index 0000000..97b69e6
Binary files /dev/null and b/LayoutTests/svg/custom/external-paintserver-reference-expected.png differ
diff --git a/LayoutTests/svg/custom/external-paintserver-reference-expected.txt b/LayoutTests/svg/custom/external-paintserver-reference-expected.txt
new file mode 100644 (file)
index 0000000..fe76fd6
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 785x604
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x604
+  RenderBlock {html} at (0,0) size 785x604
+    RenderSVGRoot {svg} at (0,0) size 100x100
+      RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+        RenderSVGResourceLinearGradient {linearGradient} [id="orange_red"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,0)]
+          RenderSVGGradientStop {stop} [offset=0.00] [color=#FF0000]
+          RenderSVGGradientStop {stop} [offset=1.00] [color=#FF0000]
+      RenderSVGPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+    RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/svg/custom/external-paintserver-reference.svg b/LayoutTests/svg/custom/external-paintserver-reference.svg
new file mode 100644 (file)
index 0000000..8ca2d27
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" standalone="no"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <!-- There should be no red on the page -->
+  <svg width="100%" height="100%" version="1.1"
+       xmlns="http://www.w3.org/2000/svg">
+
+    <defs>
+      <linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
+        <stop offset="0%" style="stop-color:red;"/>
+        <stop offset="100%" style="stop-color:red;"/>
+      </linearGradient>
+    </defs>
+
+    <rect x="0" y="0" width="100" height="100" style="fill: url(http://www.example.com/something#orange_red)"/>
+  </svg>
+</html>
diff --git a/LayoutTests/svg/custom/linking-base-external-reference-expected.png b/LayoutTests/svg/custom/linking-base-external-reference-expected.png
new file mode 100644 (file)
index 0000000..97b69e6
Binary files /dev/null and b/LayoutTests/svg/custom/linking-base-external-reference-expected.png differ
diff --git a/LayoutTests/svg/custom/linking-base-external-reference-expected.txt b/LayoutTests/svg/custom/linking-base-external-reference-expected.txt
new file mode 100644 (file)
index 0000000..bb5bff5
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 785x604
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x604
+  RenderBlock {html} at (0,0) size 785x604
+    RenderInline {base} at (0,0) size 0x0
+    RenderText {#text} at (0,0) size 0x0
+    RenderText {#text} at (0,0) size 0x0
+    RenderSVGRoot {svg} at (0,0) size 100x100
+      RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+        RenderSVGResourceLinearGradient {linearGradient} [id="orange_red"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,0)]
+          RenderSVGGradientStop {stop} [offset=0.00] [color=#FF0000]
+          RenderSVGGradientStop {stop} [offset=1.00] [color=#FF0000]
+      RenderSVGPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+    RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/svg/custom/linking-base-external-reference.xhtml b/LayoutTests/svg/custom/linking-base-external-reference.xhtml
new file mode 100644 (file)
index 0000000..b83a639
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" standalone="no"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <base href="http://www.example.com"/>
+  <!-- There should be no red -->
+  <svg width="100%" height="100%" version="1.1"
+       xmlns="http://www.w3.org/2000/svg">
+
+    <defs>
+      <linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
+        <stop offset="0%" style="stop-color:red;"/>
+        <stop offset="100%" style="stop-color:red;"/>
+      </linearGradient>
+
+    </defs>
+
+    <rect x="0" y="0" width="100" height="100" style="fill: url(#orange_red)"/>
+  </svg>
+</html>
diff --git a/LayoutTests/svg/custom/uri-reference-handling-expected.png b/LayoutTests/svg/custom/uri-reference-handling-expected.png
new file mode 100644 (file)
index 0000000..df1f0c7
Binary files /dev/null and b/LayoutTests/svg/custom/uri-reference-handling-expected.png differ
diff --git a/LayoutTests/svg/custom/uri-reference-handling-expected.txt b/LayoutTests/svg/custom/uri-reference-handling-expected.txt
new file mode 100644 (file)
index 0000000..162d988
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 110x110
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceLinearGradient {linearGradient} [id="green"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,1)]
+        RenderSVGGradientStop {stop} [offset=0.50] [color=#008000]
+      RenderSVGResourceLinearGradient {linearGradient} [id="red"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,1)]
+        RenderSVGGradientStop {stop} [offset=0.00] [color=#FF0000]
+    RenderSVGPath {rect} at (0,0) size 50x50 [fill={[type=LINEAR-GRADIENT] [id="green"]}] [x=0.00] [y=0.00] [width=50.00] [height=50.00]
+    RenderSVGPath {rect} at (60,0) size 50x50 [fill={[type=SOLID] [color=#008000]}] [x=60.00] [y=0.00] [width=50.00] [height=50.00]
+    RenderSVGPath {rect} at (0,60) size 50x50 [fill={[type=LINEAR-GRADIENT] [id="green"]}] [x=0.00] [y=60.00] [width=50.00] [height=50.00]
+    RenderSVGPath {rect} at (60,60) size 50x50 [fill={[type=SOLID] [color=#008000]}] [x=60.00] [y=60.00] [width=50.00] [height=50.00]
diff --git a/LayoutTests/svg/custom/uri-reference-handling.svg b/LayoutTests/svg/custom/uri-reference-handling.svg
new file mode 100644 (file)
index 0000000..7917960
--- /dev/null
@@ -0,0 +1,19 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runTest()">
+<script>
+  function runTest() {
+    document.getElementById("rect3").setAttribute("fill", "url(" + document.baseURI + "#green)");
+  }
+</script>
+<defs>
+  <linearGradient id="green" x1="0%" y1="0%" x2="100%" y2="100%">
+    <stop offset="50%" style="stop-color:green"/>
+  </linearGradient>
+  <linearGradient id="red" x1="0%" y1="0%" x2="100%" y2="100%">
+    <stop offset="0%" style="stop-color:rgb(255,0, 0);"/>
+  </linearGradient>
+</defs>
+<rect width="50" height="50" fill="url(../custom/uri-reference-handling.svg#green)"/>
+<rect x="60" width="50" height="50" fill="url(http://www.example.org/test#red) green"/>
+<rect id="rect3" y="60" width="50" height="50" fill="red"/>
+<rect x="60" y="60" width="50" height="50" fill="url(no_fragment_identifier) green"/>
+</svg>
index c689a3d..9984751 100644 (file)
@@ -1,3 +1,69 @@
+2011-07-29  Rob Buis  <rbuis@rim.com>
+
+        URL references are completely broken in SVG
+        https://bugs.webkit.org/show_bug.cgi?id=63283
+
+        Reviewed by Nikolas Zimmermann.
+
+        Change SVGURIElement::getTarget to be more strict about iri resolving and make it serve as a central
+        place to resolve a iri to a SVGElement. The iri can be same-document or external, for now we only handle
+        the former, the latter will be handled in bug 65344.
+        Accept as same-document if the iri combined with the base uri equals the document url (ignoring
+        the fragment identifier). For convenience a method is added to lookup the element, if found.
+
+        Tests: svg/custom/external-paintserver-reference.svg
+               svg/custom/linking-base-external-reference.xhtml
+               svg/custom/uri-reference-handling.svg
+
+        * css/CSSCursorImageValue.cpp:
+        (WebCore::resourceReferencedByCursorElement):
+        (WebCore::CSSCursorImageValue::~CSSCursorImageValue):
+        (WebCore::CSSCursorImageValue::updateIfSVGCursorIsUsed):
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::getFontData):
+        * css/CSSFontSelector.h:
+        (WebCore::CSSFontSelector::document):
+        * css/SVGCSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::applySVGProperty):
+        * rendering/svg/RenderSVGTextPath.cpp:
+        (WebCore::RenderSVGTextPath::layoutPath):
+        * rendering/svg/SVGResources.cpp:
+        (WebCore::targetReferenceFromResource):
+        (WebCore::paintingResourceFromSVGPaint):
+        * svg/SVGAltGlyphElement.cpp:
+        (WebCore::SVGAltGlyphElement::hasValidGlyphElements):
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::requestImageResource):
+        (WebCore::SVGFEImageElement::build):
+        * svg/SVGGlyphRefElement.cpp:
+        (WebCore::SVGGlyphRefElement::hasValidGlyphElement):
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::collectGradientAttributes):
+        * svg/SVGMPathElement.cpp:
+        (WebCore::SVGMPathElement::pathElement):
+        * svg/SVGPaint.cpp:
+        (WebCore::SVGPaint::matchesTargetURI):
+        * svg/SVGPatternElement.cpp:
+        (WebCore::SVGPatternElement::collectPatternAttributes):
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::collectGradientAttributes):
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::updateReferencedText):
+        (WebCore::SVGTRefElement::svgAttributeChanged):
+        (WebCore::SVGTRefElement::buildPendingResource):
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::insertedIntoDocument):
+        * svg/SVGURIReference.cpp:
+        (WebCore::SVGURIReference::fragmentIdentifierFromIRIString):
+        (WebCore::SVGURIReference::targetElementFromIRIString):
+        * svg/SVGURIReference.h:
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::buildPendingResource):
+        (WebCore::SVGUseElement::hasCycleUseReferencing):
+        (WebCore::SVGUseElement::expandUseElementsInShadowTree):
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::SVGSMILElement::targetElement):
+
 2011-07-29  James Simonsen  <simonjam@chromium.org>
 
         Remove zipcar.com site specific hack added in r87361
index 3f2316d..db92a75 100644 (file)
@@ -43,9 +43,9 @@ static inline bool isSVGCursorIdentifier(const String& url)
     return kurl.hasFragmentIdentifier();
 }
 
-static inline SVGCursorElement* resourceReferencedByCursorElement(const String& fragmentId, TreeScope* scope)
+static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, Document* document)
 {
-    Element* element = scope->getElementById(SVGURIReference::getTarget(fragmentId));
+    Element* element = SVGURIReference::targetElementFromIRIString(url, document);
     if (element && element->hasTagName(SVGNames::cursorTag))
         return static_cast<SVGCursorElement*>(element);
 
@@ -72,7 +72,7 @@ CSSCursorImageValue::~CSSCursorImageValue()
     for (; it != end; ++it) {
         SVGElement* referencedElement = *it;
         referencedElement->cursorImageValueRemoved();
-        if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->treeScope()))
+        if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document()))
             cursorElement->removeClient(referencedElement);
     }
 #endif
@@ -90,7 +90,7 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
     if (!isSVGCursorIdentifier(url))
         return false;
 
-    if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->treeScope())) {
+    if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->document())) {
         // FIXME: This will override hot spot specified in CSS, which is probably incorrect.
         float x = roundf(cursorElement->x().value(0));
         m_hotSpot.setX(static_cast<int>(x));
index ab29a3e..d77fcda 100644 (file)
@@ -131,8 +131,13 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri
                 if (!m_font->ensureSVGFontData())
                     return 0;
 
-                if (!m_externalSVGFontElement)
-                    m_externalSVGFontElement = m_font->getSVGFontById(SVGURIReference::getTarget(m_string));
+                if (!m_externalSVGFontElement) {
+                    String fragmentIdentifier;
+                    size_t start = m_string.find('#');
+                    if (start != notFound)
+                        fragmentIdentifier = m_string.string().substring(start + 1);
+                    m_externalSVGFontElement = m_font->getSVGFontById(fragmentIdentifier);
+                }
 
                 if (!m_externalSVGFontElement)
                     return 0;
index f50ea42..61baa9f 100644 (file)
@@ -66,6 +66,8 @@ public:
     virtual void registerForInvalidationCallbacks(FontSelectorClient*);
     virtual void unregisterForInvalidationCallbacks(FontSelectorClient*);
 
+    Document* document() const { return m_document; }
+
 private:
     CSSFontSelector(Document*);
 
index d8284f8..4f663af 100644 (file)
@@ -361,7 +361,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
 
-            svgstyle->setMarkerStartResource(SVGURIReference::getTarget(s));
+            svgstyle->setMarkerStartResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyMarkerMid:
@@ -377,7 +377,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
 
-            svgstyle->setMarkerMidResource(SVGURIReference::getTarget(s));
+            svgstyle->setMarkerMidResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyMarkerEnd:
@@ -393,7 +393,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
 
-            svgstyle->setMarkerEndResource(SVGURIReference::getTarget(s));
+            svgstyle->setMarkerEndResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyStrokeLinecap:
@@ -432,7 +432,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
 
-            svgstyle->setFilterResource(SVGURIReference::getTarget(s));
+            svgstyle->setFilterResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyMask:
@@ -448,7 +448,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
             
-            svgstyle->setMaskerResource(SVGURIReference::getTarget(s));
+            svgstyle->setMaskerResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyClipPath:
@@ -464,7 +464,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             else
                 return;
 
-            svgstyle->setClipperResource(SVGURIReference::getTarget(s));
+            svgstyle->setClipperResource(SVGURIReference::fragmentIdentifierFromIRIString(s, m_element->document()));
             break;
         }
         case CSSPropertyTextAnchor:
index 8682fb1..db2922b 100644 (file)
@@ -44,8 +44,7 @@ RenderSVGTextPath::RenderSVGTextPath(Node* n)
 Path RenderSVGTextPath::layoutPath() const
 {
     SVGTextPathElement* textPathElement = static_cast<SVGTextPathElement*>(node());
-        String pathId = SVGURIReference::getTarget(textPathElement->href());
-    Element* targetElement = textPathElement->treeScope()->getElementById(pathId);    
+    Element* targetElement = SVGURIReference::targetElementFromIRIString(textPathElement->href(), textPathElement->document());
     if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
         return Path();
     
index 59f442a..478b48e 100644 (file)
@@ -150,7 +150,7 @@ static inline String targetReferenceFromResource(SVGElement* element)
     else
         ASSERT_NOT_REACHED();
 
-    return SVGURIReference::getTarget(target);
+    return SVGURIReference::fragmentIdentifierFromIRIString(target, element->document());
 }
 
 static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, const SVGPaint::SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource)
@@ -158,7 +158,7 @@ static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document*
     if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
         return 0;
 
-    id = SVGURIReference::getTarget(paintUri);
+    id = SVGURIReference::fragmentIdentifierFromIRIString(paintUri, document);
     RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id);
     if (!container) {
         hasPendingResource = true;
index fb65681..a6ce49a 100644 (file)
@@ -89,8 +89,8 @@ RenderObject* SVGAltGlyphElement::createRenderer(RenderArena* arena, RenderStyle
 
 bool SVGAltGlyphElement::hasValidGlyphElements(Vector<String>& glyphNames) const
 {
-    String target = getTarget(fastGetAttribute(XLinkNames::hrefAttr));
-    Element* element = treeScope()->getElementById(target);
+    String target;
+    Element* element = targetElementFromIRIString(fastGetAttribute(XLinkNames::hrefAttr), document(), &target);
     if (!element)
         return false;
 
index fe2cd80..7d356f4 100644 (file)
@@ -76,7 +76,7 @@ void SVGFEImageElement::requestImageResource()
         m_cachedImage = 0;
     }
 
-    Element* hrefElement = treeScope()->getElementById(SVGURIReference::getTarget(href()));
+    Element* hrefElement = SVGURIReference::targetElementFromIRIString(href(), document());
     if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
         return;
 
@@ -163,7 +163,7 @@ void SVGFEImageElement::notifyFinished(CachedResource*)
 PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter* filter)
 {
     if (!m_cachedImage && !m_targetImage) {
-        Element* hrefElement = treeScope()->getElementById(SVGURIReference::getTarget(href()));
+        Element* hrefElement = SVGURIReference::targetElementFromIRIString(href(), document());
         if (!hrefElement || !hrefElement->isSVGElement())
             return 0;
 
index 9c1a4e3..cec11ae 100644 (file)
@@ -58,8 +58,7 @@ bool SVGGlyphRefElement::hasValidGlyphElement(String& glyphName) const
 {
     // FIXME: We only support xlink:href so far.
     // https://bugs.webkit.org/show_bug.cgi?id=64787
-    glyphName = getTarget(fastGetAttribute(XLinkNames::hrefAttr));
-    Element* element = treeScope()->getElementById(glyphName);
+    Element* element = targetElementFromIRIString(fastGetAttribute(XLinkNames::hrefAttr), document(), &glyphName);
     if (!element || !element->hasTagName(SVGNames::glyphTag))
         return false;
     return true;
index 1185923..cf71af3 100644 (file)
@@ -181,7 +181,7 @@ bool SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttribute
         processedGradients.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = treeScope()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = SVGURIReference::targetElementFromIRIString(current->href(), document());
         if (refNode && (refNode->hasTagName(SVGNames::linearGradientTag) || refNode->hasTagName(SVGNames::radialGradientTag))) {
             current = static_cast<SVGGradientElement*>(refNode);
 
index e92c9b7..54455c1 100644 (file)
@@ -76,7 +76,7 @@ void SVGMPathElement::parseMappedAttribute(Attribute* attr)
 
 SVGPathElement* SVGMPathElement::pathElement()
 {
-    Element* target = treeScope()->getElementById(getTarget(href()));
+    Element* target = targetElementFromIRIString(href(), document());
     if (target && target->hasTagName(SVGNames::pathTag))
         return static_cast<SVGPathElement*>(target);
     return 0;
index 6bc3370..565aa08 100644 (file)
@@ -165,7 +165,7 @@ bool SVGPaint::matchesTargetURI(const String& referenceId)
     case SVG_PAINTTYPE_URI_RGBCOLOR:
     case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
     case SVG_PAINTTYPE_URI:
-        return referenceId == SVGURIReference::getTarget(m_uri);
+        return referenceId == SVGURIReference::fragmentIdentifierFromIRIString(m_uri, node() ? node()->document() : 0);
     }
 
     ASSERT_NOT_REACHED();
index 6707256..5bfaffe 100644 (file)
@@ -255,7 +255,7 @@ void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes)
         processedPatterns.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = treeScope()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = SVGURIReference::targetElementFromIRIString(current->href(), document());
         if (refNode && refNode->hasTagName(SVGNames::patternTag)) {
             current = static_cast<const SVGPatternElement*>(const_cast<const Node*>(refNode));
 
index 86e20cf..1c0c30b 100644 (file)
@@ -195,7 +195,7 @@ bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute
         processedGradients.add(current);
 
         // Respect xlink:href, take attributes from referenced element
-        Node* refNode = treeScope()->getElementById(SVGURIReference::getTarget(current->href()));
+        Node* refNode = SVGURIReference::targetElementFromIRIString(current->href(), document());
         if (refNode && (refNode->hasTagName(SVGNames::radialGradientTag) || refNode->hasTagName(SVGNames::linearGradientTag))) {
             current = static_cast<SVGGradientElement*>(refNode);
 
index a69f372..6c7bbb3 100644 (file)
@@ -138,7 +138,7 @@ void SVGShadowText::recalcStyle(StyleChange change)
 
 void SVGTRefElement::updateReferencedText()
 {
-    Element* target = treeScope()->getElementById(SVGURIReference::getTarget(href()));
+    Element* target = SVGURIReference::targetElementFromIRIString(href(), document());
     ASSERT(target);
     String textContent;
     if (target->parentNode())
@@ -186,8 +186,8 @@ void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName)
             m_eventListener->removeFromTarget();
             m_eventListener = 0;
         }
-        String id = SVGURIReference::getTarget(href());
-        Element* target = treeScope()->getElementById(id);
+        String id;
+        Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
         if (!target) {
             document()->accessSVGExtensions()->addPendingResource(id, this);
             return;
@@ -232,10 +232,9 @@ bool SVGTRefElement::rendererIsNeeded(const NodeRenderingContext& context)
 void SVGTRefElement::buildPendingResource()
 {
     updateReferencedText();
-    String id = SVGURIReference::getTarget(href());
-    if (Element* target = treeScope()->getElementById(id)) {
+    if (Element* target = SVGURIReference::targetElementFromIRIString(href(), document())) {
         ASSERT(!m_eventListener);
-        m_eventListener = SubtreeModificationEventListener::create(this, id);
+        m_eventListener = SubtreeModificationEventListener::create(this, target->getIdAttribute());
         ASSERT(target->parentNode());
         target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
     }
index f946f5a..a92d606 100644 (file)
@@ -151,8 +151,8 @@ void SVGTextPathElement::insertedIntoDocument()
 {
     SVGTextContentElement::insertedIntoDocument();
 
-    String id = SVGURIReference::getTarget(href());
-    Element* targetElement = treeScope()->getElementById(id);
+    String id;
+    Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
     if (!targetElement) {
         document()->accessSVGExtensions()->addPendingResource(id, this);
         return;
index 6f1adfe..6efda19 100644 (file)
@@ -24,6 +24,9 @@
 #include "SVGURIReference.h"
 
 #include "Attribute.h"
+#include "Document.h"
+#include "Element.h"
+#include "KURL.h"
 
 namespace WebCore {
 
@@ -42,20 +45,30 @@ bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName)
     return attrName.matches(XLinkNames::hrefAttr);
 }
 
-String SVGURIReference::getTarget(const String& url)
+String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, Document* document)
 {
-    if (url.startsWith("url(")) { // URI References, ie. fill:url(#target)
-        size_t start = url.find('#') + 1;
-        size_t end = url.reverseFind(')');
-        return url.substring(start, end - start);
-    }
-    if (url.find('#') != notFound) { // format is #target
-        size_t start = url.find('#') + 1;
-        return url.substring(start, url.length() - start);
-    }
+    ASSERT(document);
+    size_t start = url.find('#');
+    if (start == notFound)
+        return emptyString();
+
+    KURL base = start ? KURL(document->baseURI(), url.substring(0, start)) : document->baseURI();
+    String fragmentIdentifier = url.substring(start);
+    KURL kurl(base, fragmentIdentifier);
+    if (equalIgnoringFragmentIdentifier(kurl, document->url()))
+        return fragmentIdentifier.substring(1);
 
-    // The url doesn't have any target.
-    return String();
+    // The url doesn't have any fragment identifier.
+    return emptyString();
+}
+
+Element* SVGURIReference::targetElementFromIRIString(const String& iri, Document* document, String* fragmentIdentifier)
+{
+    String id = fragmentIdentifierFromIRIString(iri, document);
+    if (fragmentIdentifier)
+        *fragmentIdentifier = id;
+    // FIXME: Handle external references (Bug 65344).
+    return document->getElementById(id);
 }
 
 void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
index 9cd1529..45816dd 100644 (file)
@@ -28,6 +28,8 @@
 namespace WebCore {
 
 class Attribute;
+class Document;
+class Element;
 
 class SVGURIReference {
 public:
@@ -37,7 +39,8 @@ public:
     bool isKnownAttribute(const QualifiedName&);
     void addSupportedAttributes(HashSet<QualifiedName>&);
 
-    static String getTarget(const String& url);
+    static String fragmentIdentifierFromIRIString(const String&, Document*);
+    static Element* targetElementFromIRIString(const String&, Document*, String* = 0);
 
 protected:
     virtual void setHrefBaseValue(const String&) = 0;
index 38db682..f3f28a6 100644 (file)
@@ -476,8 +476,8 @@ 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 = treeScope()->getElementById(id);
+    String id;
+    Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
     ASSERT(!m_targetElementInstance);
 
     if (!targetElement) {
@@ -521,8 +521,7 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowR
     // Solution: block any updates to the shadow tree while we're building it.
     ShadowTreeUpdateBlocker blocker(this);
 
-    String id = SVGURIReference::getTarget(href());
-    Element* targetElement = treeScope()->getElementById(id);
+    Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document());
     if (!targetElement) {
         // The only time we should get here is when the use element has not been
         // given a resource to target.
@@ -773,8 +772,7 @@ void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* ta
 
 bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, SVGElement*& newTarget)
 {
-    String id = SVGURIReference::getTarget(use->href());
-    Element* targetElement = treeScope()->getElementById(id); 
+    Element* targetElement = SVGURIReference::targetElementFromIRIString(use->href(), document());
     newTarget = 0;
     if (targetElement && targetElement->isSVGElement())
         newTarget = static_cast<SVGElement*>(targetElement);
@@ -791,7 +789,7 @@ bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
         SVGElement* element = instance->correspondingElement();
 
         // FIXME: This should probably be using getIdAttribute instead of idForStyleResolution.
-        if (element->hasID() && element->idForStyleResolution() == id)
+        if (element->hasID() && element->idForStyleResolution() == newTarget->getIdAttribute())
             return true;
     
         instance = instance->parentNode();
@@ -854,8 +852,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
     if (element->hasTagName(SVGNames::useTag)) {
         SVGUseElement* use = static_cast<SVGUseElement*>(element);
 
-        String id = SVGURIReference::getTarget(use->href());
-        Element* targetElement = treeScope()->getElementById(id); 
+        Element* targetElement = SVGURIReference::targetElementFromIRIString(use->href(), document());
         SVGElement* target = 0;
         if (targetElement && targetElement->isSVGElement())
             target = static_cast<SVGElement*>(targetElement);
index 48f9c51..29e9645 100644 (file)
@@ -495,7 +495,7 @@ SVGElement* SVGSMILElement::targetElement()
         return m_targetElement;
 
     String href = xlinkHref();
-    ContainerNode* target = href.isEmpty() ? parentNode() : treeScope()->getElementById(SVGURIReference::getTarget(href));
+    ContainerNode* target = href.isEmpty() ? parentNode() : SVGURIReference::targetElementFromIRIString(href, document());
     if (!target || !target->isSVGElement())
         return 0;