This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
Specification: http://www.whatwg.org/specs/web-apps/current-work/ Multipage: http://www.whatwg.org/C#the-element's-base-url Complete: http://www.whatwg.org/c#the-element's-base-url Comment: There is a mismatch here with the DOM concept of a node's base URL. Not sure what the right way to address it would be. Posted from: 207.218.72.65 User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.30 (KHTML, like Gecko) Chrome/26.0.1403.0 Safari/537.30
What's the mismatch exactly?
DOM has: "Each |node| also has an associated |base URL|." And "The baseURI attribute must return the associated base URL." I guess the DOM should maybe be updated to reflect that we only need base URLs for Document and Element (and DocumentFragment?). And maybe DOM should supersede http://www.w3.org/TR/xmlbase/ to use http://url.spec.whatwg.org/ for URL parsing and make it clear the attributes works in an HTML environment.
If you want to define "the element's base URL", that's fine by me. Reassign the bug to me once I need to update HTML to point to DOM instead of XML Base.
*** Bug 22983 has been marked as a duplicate of this bug. ***
Removing xml:base: https://bugzilla.mozilla.org/show_bug.cgi?id=903372
xml:base will go away. Node.baseURI will stay. <base> will stay. Base URL will be scoped to a document. In Chrome http://software.hixie.ch/utilities/js/live-dom-viewer/ .<script> var a = document.createElement("a") w(a.baseURI) a.href = "/test" w(a.href) </script> will log "", followed by "http://software.hixie.ch/test", which makes no sense. So it seems that nodes should have the base URL of their node document. Base URL of nodes will change once they are adopted. Does all of this make sense?
Assuming we can get rid of xml:base, I believe it does.
This has come up recently with developers using Shadow DOM and Web Components who wish to be able to scope elements with the base uri of the HTML import that defined them. Specifically they want to be able to make a custom element defined in an imported document use the correct baseURI when instances are created and their ShadowRoots are populated with <img>'s or nested stylesheets are processed. After a lot of discussion it seems Node.baesURI is the best approach for them (and provides the most flexibility). We'd like to change the spec to: Node.baseURI on reading: - walks up the tree until it encounters: a ShadowRoot with a baseURI property that is not empty. a Element with a base attribute that is not empty. - else it returns the Document's baseURI (as computed with <base>). Node.baseURI on setting: - If ShadowRoot then set the property. - If Element then set the base attribute. - else throw an exception. We can also fix the nonsensical result upon reading as observed in Anne's comment.
Does the setter in your proposal allow relative URIs?
(In reply to Boris Zbarsky from comment #9) > Does the setter in your proposal allow relative URIs? Yes, but the value should be resolved to an absolute URL when stored (ex. set in the attribute) just like <base>.
In webdevdata's june data set I see 100 base attributes, on embed (49), span (27), img (6), a (6), object (3), and a few others. e.g. <embed src='/Noor/Images/Login/intro.swf' quality='high' bgcolor='#ffffff' width='100%' height='250' name='EWIntro' align='left' allowScriptAccess='always' swLiveConnect='true' type='application/x-shockwave-flash' pluginspage='https://www.macromedia.com/go/getflashplayer' base=''/> <span id="" class="trcLink en" base="mobile" type="" onclick="sm(this,0,['home','changeLanguage.html?language=en'],'/')" nw="0" lang="de" mode=""><i> </i>English</span> vote+="<div class='castingvote star_yellow' base='star_yellow' value='"+i+"'></"+"div>";for(;i<=6;i++)
So comment 8 seems to be proposing to reintroduce xml:base under a different name. Do we really want to go there given the performance issues and issues with dynamic updates?
> So comment 8 seems to be proposing to reintroduce xml:base under a different > name. Not quite. For example, the proposed behavior for relative URIs is radically different from xml:base (which reevaluates them all the time against the scoping base URI), and is much saner imo. The dynamic update issues remain, of course.
So nodes have a base URL which is either "inherit" or a parsed URL. Note: a document's base URL can never be "inherit". To get a node's parsed base URL you return the closest inclusive ancestor's base URL that is not "inherit". If there is no such ancestor you return the node's node document's base URL. --- Node.prototype.baseURI returns the result of getting a node's parsed base URL, serialized. Setting Node.prototype.baseURI on /node/ to /value/ run these steps: 1. Let /base/ be the result of getting /node/'s parsed base URL. 2. Let /url/ be the result of running the URL parser for /value/ against /base/. 3. If /node/ is a ShadowRoot, set it's base URL to /url/. 4. Otherwise, if /node/ is an Element, set /node/'s "base" attribute to /url/, serialized. 5. Otherwise, throw a JavaScript TypeError exception. Note: Changing a document's base URL can only be done through the HTML base element. --- Either when an element is created that has a "base" attribute or when an element's "base" attribute is set, run these steps: 1. Let /base/ be the result of getting element's parsed base URL. 2. Let /url/ be the result of running the URL parser for /value/ against /base/. 3. Set element's base URL to /url/. When an element's "base" attribute is removed, set element's base URL to "inherit".
(Just to be clear, I'm not sure whether it's a good idea, but I thought it'd be worthwhile to spell out the specifics. Note that the above omits invoking http://dom.spec.whatwg.org/#base-url-change-steps whenever the base URL is set which it would need to do in the end.)
Another thing we need to consider is what http://dom.spec.whatwg.org/#concept-node-adopt and http://dom.spec.whatwg.org/#concept-node-clone do with the base URL. I guess if there is a non-"inherit" base URL we want it to be kept, same for ShadowRoot?
The need to walk up the DOM on every single base URI lookup is pretty annoying. :(
Does the use case really need a base attribute on all elements? Or just ability to set baseURI on ShadowRoot? I don't really understand the use case.
(In reply to Simon Pieters from comment #18) > Does the use case really need a base attribute on all elements? Or just > ability to set baseURI on ShadowRoot? I don't really understand the use case. One might want to use Nodes defined in an HTMLImport in the main document without using shadow dom.
I talked with folks over here and adding baseURI to ShadowRoot is enough for all the current use cases except the one Erik mentioned. Since we can always add the attribute version of baseURI in the future on top of ShadowRoot's support I think we should go that route. Walking up the tree of containing ShadowRoots can also be made faster than walking up the tree of parent Elements. I also think we should avoid speccing this to be dynamic. In practice browsers are not very dynamic with resource urls already. Instead, at the point where a resource is fetched, we should resolve the URL against the current baseURI of the scope (ShadowRoot or Document). ex. root.baseURI = "http://foo/" img1.src = "a.png"; root.appendChild(img1); root.baseURI = "http://bar/" img2.src = "b.png"; root.appendChild(img2); img1.src == "http://foo/a.png" img2.src == "http://bar/b.png" How does that sound Anne/Boris?
That sounds fairly reasonable to me, I guess. I don't think it's too much worse than what we have with document's baseURI right now.
So let's see. We make baseURI read-write on Document and ShadowRoot. We make writing throw for other nodes. Whenever you resolve a URL you take the current base URL in scope. Would it make sense to keep baseURI readonly and introduce Document.baseURL / ShadowRoot.baseURL as read-write? Also, are we sure we want read-write for Document given <base>? It seems somewhat confusing to have two independent points in control of a document's base URL.
Reviving this thread as I've been working on implementing this in Blink. (In reply to Elliott Sprehn from comment #20) > root.baseURI = "http://foo/" > img1.src = "a.png"; > root.appendChild(img1); > root.baseURI = "http://bar/" > img2.src = "b.png"; > root.appendChild(img2); > > img1.src == "http://foo/a.png" > img2.src == "http://bar/b.png" I'm not sure this example works correctly. Let's say that root, img1, and img2 all share an ownerDocument whose baseURI is "http://baz.com/". Resource loads for http://baz.com/a.png and http://baz.com/b.png will be initiated, since at the point when img1 and img2 have their src property set they are not descendants of root, and thus they get their baseURI from their ownerDocument. Moreover, to get the "right" images to load, we'll need more dynamism in the system, so that becoming a descendant of a ShadowRoot causes a base URL change. (Note that the HTML spec (which I can't get to at the moment) says that <img> elements don't reload their resources when switching Documents, but WebKit, Blink, and Gecko all seem to do a reload (haven't tried IE). It would be nice to fix that alongside getting ShadowRoot.baseURI's dynamism specified.)
It sounds bad to design a system where you first load the wrong resource and then after appending it loads the correct one. The <img> scenario is interesting however. Do you know the <img> is going to be used inside a ShadowRoot? When you do new Image() there's no such association, unless we had actual isolation.
(In reply to Anne from comment #24) > The <img> scenario is interesting however. Do you know the <img> is going to > be used inside a ShadowRoot? When you do new Image() there's no such > association, unless we had actual isolation. This is off-topic for this bug, but yes, in discussing this last night with some folks I came to the same conclusion: that to get this really right you want iframe-like isolation.
(In reply to Adam Klein from comment #23) > Reviving this thread as I've been working on implementing this in Blink. > > (In reply to Elliott Sprehn from comment #20) > > root.baseURI = "http://foo/" > > img1.src = "a.png"; > > root.appendChild(img1); > > root.baseURI = "http://bar/" > > img2.src = "b.png"; > > root.appendChild(img2); > > > > img1.src == "http://foo/a.png" > > img2.src == "http://bar/b.png" > > I'm not sure this example works correctly. [...] Yeah I fumbled my example, you need to appendChild() first before assigning the src.
(In reply to Elliott Sprehn from comment #26) > (In reply to Adam Klein from comment #23) > > Reviving this thread as I've been working on implementing this in Blink. > > > > (In reply to Elliott Sprehn from comment #20) > > > root.baseURI = "http://foo/" > > > img1.src = "a.png"; > > > root.appendChild(img1); > > > root.baseURI = "http://bar/" > > > img2.src = "b.png"; > > > root.appendChild(img2); > > > > > > img1.src == "http://foo/a.png" > > > img2.src == "http://bar/b.png" > > > > I'm not sure this example works correctly. [...] > > Yeah I fumbled my example, you need to appendChild() first before assigning > the src. Seems like a bit of a footgun. And note that root.innerHTML = '<img src="a.png">' doesn't even give you the option of doing the right thing (unless we somehow change how ShadowRoot.innerHTML works).
So I think for now we are back to the situation in comment 6. Once we have declarative components or isolated components, we can revisit making base URLs more complicated.
And until then the URL API can be used to create absolute URLs.
`innerHTML` and similar are not the problem, IMHO. To use relative URLs in <script>s within HTML imports, use the URL API, e.g.: var importBaseURL = document.currentScript.ownerDocument.baseURI; var url = new URL('foo.png', importBaseURL).toString(); // Now, use `url` in `innerHTML` all you want. The problem that still lacks a good solution: authors want to use things like `<link rel=stylesheet href=bar>` expecting `bar` to always be relative to the HTML import that includes it (without having to script it all). Same for `<img>`, references in `<style>` blocks, etc. Consider this document, located at `https://example.com/some-component/import-me.html`: <img src=foo> It would be nice if the import process would *somehow* turn that into… <img src=https://example.com/some-component/foo> …before inserting it into the parent document. If setting `shadowRoot.baseURI = document.currentScript.ownerDocument.baseURI` would have this effect, that’d be a fair solution for shadow roots. But IMHO this is a problem for all imports, regardless of whether they use shadow roots or not.
xml:base is now gone from Blink: https://code.google.com/p/chromium/issues/detail?id=341854 If that isn't reverted, what's the next step for this bug?
I will make comment 6 the new reality specification-wise and try to get all browsers to implement that. And get HTML to define its base URL stuff in terms of the new DOM base URL stuff.
That sounds good to me, in particular making Node.baseURI be the node document's base URL would make sense to me.
https://github.com/whatwg/dom/commit/8ca4959505f531663bc91f064a19762e8b90b810
Note that I opened https://github.com/whatwg/dom/issues/61 to design the base URL change notification system, which we'll use for setting a document's base URL and adopting. It has one open question about when it should run relative to the adoption specification callback. Input welcome there.