Closed Bug 1121708 Opened 5 years ago Closed 5 years ago

base tag breaks svg xlink to local id

Categories

(Core :: SVG, defect)

defect
Not set

Tracking

()

RESOLVED DUPLICATE of bug 1357432

People

(Reporter: snadrus, Unassigned)

References

()

Details

(Keywords: reproducible, testcase)

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.69 Safari/537.36

Steps to reproduce:

1. Compare in FF 33 vs FF 35:
   http://plnkr.co/edit/mVAgHE2VprEaV8tg2yvG?p=preview 



Actual results:

1. I see 1 blue box.
Specifically: 
  The <base> tag shouldn't break xlink references to IDs within this document.


Expected results:

1. I see 2 blue boxes.
Attached file Testcase
Component: Untriaged → SVG
OS: Linux → All
Product: Firefox → Core
Hardware: x86_64 → All
Attachment #8549260 - Attachment mime type: text/plain → text/html
(In reply to Andy Jackson from comment #0)
> 1. Compare in FF 33 vs FF 35:
>    http://plnkr.co/edit/mVAgHE2VprEaV8tg2yvG?p=preview 
> Actual results:
> 1. I see 1 blue box.
> Expected results:
> 1. I see 2 blue boxes.

I see 1 box in 28, 33.1.1, and 35. When did this work, according to you?
Flags: needinfo?(snadrus)
I don't think this ever worked. (This seems essentially the same as bug 402521, which is quite old.)

Quoting the testcase, for discussion purposes:
>     <base href="/foo" />   <!-- This base tag... -->
>     <svg viewBox="0 0 400 100">
>       <rect id="original-rect" [...SNIP...] />
>                           <!-- ...hides this element: -->
>      <use xlink:href="#original-rect" x="150" y="10" />

Discussed this a bit with longsonr.  Here, "#original-rect" is resolved under the influence of the <base> tag, and is treated as "/foo#original-rect", because that's how the <base> tag is defined as working:  https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

The SVG spec has language about "local IRI reference", which it says "does not include [anything before the #] thus represents a reference to an element within the current document":
 http://www.w3.org/TR/SVG11/single-page.html#intro-TermLocalIRIReference

So the SVG spec seems to be oblivious about the effects of <base>, given its "thus...current document" language.

I think our behavior here is probably correct, and the SVG spec is just overly sanguine about whether "#foo" is unambiguously a reference to the local document.  bz, do you have any thoughts on this? This seems like the sort of thing you might've considered/debated in the past.
Flags: needinfo?(snadrus) → needinfo?(bzbarsky)
Version: 35 Branch → Trunk
This has in fact been discussed at length; the SVG specs are collectively somewhat mutually contradictory, and the behavior of CSS url() definitely takes <base> into account, so for consistency we always do that.

What we do in practice is resolve the xlink:href to an absolute URI (something the SVG specs _definitely_ assume gets done) and then compare to the document URI to see whether it's just a #something.  This, as noted, breaks down when the base URI is not the document URI.

And yes, bug 402521 is very much this issue.
Flags: needinfo?(bzbarsky)
Duplicate of this bug: 402521
Thanks. I think this is INVALID, then, because we're following the specs on this as best we can, while striving for consistency & trying to resolve contradictions between bits of spec (per comment 4).

So, I think Chrome's behavior is arguably a bug (and we should probably strive for interoperability).  I'll file this in their issue-tracker.
Resolving as INVALID per previous comment.

I filed https://code.google.com/p/chromium/issues/detail?id=449027 on the Chrome/Blink behavior.
Status: UNCONFIRMED → RESOLVED
Closed: 5 years ago
Resolution: --- → INVALID
...and I filed https://bugs.webkit.org/show_bug.cgi?id=140488 on WebKit (which behaves the same as Blink on this testcase).
Duplicate of this bug: 1135077
It looks like Chrome marked the bug as fixed, but the current behavior of both Chrome (59) and Safari (10.1) is to show two blue boxes in these scenarios.

I think you should reconsider this bug, because it makes working with inline-SVGs on a webpage that uses the History API quite difficult.

For example, the popular web framework Angular.js recommends adding a base tag as best practice[1][2], so HTML5-history based changes can reliably be moved to different URLs and still operate fine--as well as to handle IE9 behavior better. 

With Firefox's current behavior, it seems that SVG ID references ( xlink:href="#" attributes or url(#) references) will only work when the document URL matches the <base> href perfectly at the time when the SVG is added to the DOM. For any HTML5-routed angular application, this will be exactly one page on the website where these can be used.

Angular's users reported an issue with base tags and SVGs on firefox[3], and their response was to allow developers to relax angular's requirements for a <base> tag. Since the <base> tag behavior was still desirable, users in the issue thread shared a number of workarounds involving dynamically rewriting xlink:href and other url reference attributes based on the current page's absolute URL.


For some consideration about the difference between "file#id-selector" as a URL refrence: If I am on a page with a base tag pointing to something other than the current URL, where should a <a href="#some-id">Link</a> navigate the user? If it is supposed to be resolved relative to the base, then this should send the user to a different URL. Yet, current firefox behavior seems to keep the user on the same page and append the hash to the URL.

I read the W3 group meeting notes[4] linked on the webkit issue, and while that seems to demonstrate some consensus or official answer, there are not satisfactory alternatives for developers. For example, the SVG <mask>[5][6] feature must use a "url()" reference "to another graphical object within the same SVG document fragment". It does not seem reasonable that a feature that is already restricted to the current document fragment should have any concern for the overall URL of its document. This is the only interface possible for using a mask in an SVG.

There is updated discussion about this on chromium's bugtracker: https://bugs.chromium.org/p/chromium/issues/detail?id=109212

I'd be happy to produce some sample HTML or a live webpage if that would help. I already posted some examples on https://bugzilla.mozilla.org/show_bug.cgi?id=652991


[1] https://docs.angularjs.org/error/$location/nobase
[2] https://docs.angularjs.org/guide/$location
[3] https://github.com/angular/angular.js/issues/8934
[4] https://www.w3.org/2015/08/25-svg-minutes.html#item08
[5] https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask
[6] https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/mask
> If I am on a page with a base tag pointing to something other than the current URL, where should a
> <a href="#some-id">Link</a> navigate the user?

To the other URL.

> Yet, current firefox behavior seems to keep the user on the same page and append the hash to the URL.

Are you sure?  I just tried this testcase:

  <!DOCTYPE html>
  <base href="http://example.com">
  <a href="#hey">Click me</a>

loaded from a file:// URI.  Clicking the link takes me to <http://example.com/#hey>, as expected and as the specs say should happen.  This is also the behavior in Chrome and Safari; I don't have Edge on hand right this second.
(In reply to Boris Zbarsky [:bz] (still a bit busy) (if a patch has no decent message, automatic r-) from comment #11)
> 
> Are you sure?  I just tried this testcase:
> 
>   <!DOCTYPE html>
>   <base href="http://example.com">
>   <a href="#hey">Click me</a>
> 

I stand corrected. I do see the same behavior. When I tested previously, I had Angular.js on the page and it was actually intercepting the click on the <a> and performing the URL change.
:rik blogged ( https://ricaud.me/blog/post/2017/04/On-the-utility-of-filing-bugs , which showed up on planet.m.o) about bug 1357432, which seems... surprisingly similar... to this bug, and that got marked fixed just before the weekend. And indeed, the testcase on this bug shows 2 blue boxes for me in Nightly today. Given comment #4 and comment #11 I am a bit surprised by this. Did bug 1357432 also change the behaviour of CSS url(), or not, and/or should we just dupe this bug over, or back out the changes from 1357432, or something else?
Flags: needinfo?(bzbarsky)
See Also: → 1357432
> Did bug 1357432 also change the behaviour of CSS url()

No.  However that might be changing independently anyway.  Worth checking.

At this point, this bug should in fact get marked as dup of bug 1357432.  Note the bits about a spec change in that blog post, by the way...
Flags: needinfo?(bzbarsky)
Resolution: INVALID → DUPLICATE
Duplicate of bug: 1357432
You need to log in before you can comment on or make changes to this bug.