[whatwg] Document's base URI should use the document's *current* address

On 16/02/12 5:03 PM, Justin Lebar wrote:
> On Wed, Feb 15, 2012 at 5:31 PM, Ian Hickson<ian at hixie.ch>  wrote:
>> On Wed, 15 Feb 2012, Justin Lebar wrote:
>>>>   - It sets "the document's current address" to ".../page.html#foo".
>>> Well, this is pretty bad.  document.location is the document's current
>>> address [1].  So clicking #foo changed document.location from page2.html
>>> to page.html#foo, which I certainly wouldn't expect (and does not match
>>> implementations).
>> Seems to me we should change the implementations then. There isn't any
>> fundamental difference between linking to #foo and linking to
>> page.html#foo if the base URL is page.html, as far as I can tell.
>>
>> If the implementations can't change, then I'll change the spec, but it
>> really seems bad to me that relative URLs will break depending on when
>> they are resolved relative to pushState() changes.
> When I implemented pushState, I explicitly didn't want authors to have
> to rewrite all their anchor links after they changed the document's
> current URI.
>
> > From an author's point of view, there's no such thing as the
> document's original URI and, unless you're a nerd, you've never heard
> of the base URI.  There's just the document's URI, modified by
> pushState.
>
> > From this point of view, I'd say it's less surprising that relative
> URIs would break when you change directories (hey, you *asked* for it)
> than that anchor refs would update the browser's address bar and
> document.location relative to the old URI.

I share your perspective, Justin (if I'm interpreting it correctly).

An obvious use-case for pushState() is facilitating an enhanced 
user-experience for page navigation within a site. In this case the 
process of document updates + pushState({},null, "foo/bar.html") should 
result in the same DOM as if foo/bar.html was browsed to directly.

For example, imagine a site that has some pages amenable to this usage:

/page1.html
/page2.html
/subdir/page3.html

These contain some page specific content wrapped in some generic page 
template.
(I'm assuming that pages amenable to document updates + pushState() have 
a lot in common, otherwise why use pushState().)

<!DOCTYPE html>
<head>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<p>I hope you are not distracted by my enormous banner. You may want to 
<a href="#content">skip</a> directly to the main content of this page. </p>
<div id="banner">
<h1>
<img src="logo.png" /> My Site
</h1>
</div>
<nav id="nav">
<a href="page1.html">Page 1</a>
<a href="page2.html">Page 2</a>
<a href="subdir/page3.html">Page 3</a>
</nav>
<div id="content">
<!-- Page specific content here -->
</div>
</body>
</html>


The following stylesheets and images are used:
/style.css
/logo.png


If page creation was all performed on the server using this template then...
- /page1.html & /page2.html would be okay
- /subdir/page3.html would be broken:
   1. <img src="logo.png" /> has a relative path and refs the 
non-existant /subdir/logo.png
   2. Similarly, <a href=""> with #nav all have rel paths to nowhere
   3. Note that the top skip link is OK in all pages

If a pushState() facilitated mechanism was used for navigation
(a naive implementation which just inserts page-specific content inside 
<div id="content"></div>)
and navigation started at /page1.html, thence to /page2.html and 
/subdir/page3.html,
the images and hyperlinks in /subdir/page3.html would be fine...
except for the top skip link which references the #content anchor.

Obviously this page template needs fixing and for this example, simply 
changing rel paths to absolute will be sufficient for both the server 
generated and browser updated documents. Except that pushState() 
assisted navigation would break the top skip link (assuming the current 
SPECIFIED behavior).

For all the issues in this example I think Justin's proposal is 
preferable to what is currently specified.

By the way, this doesn't quite match what is currently implemented in 
Firefox and Webkit. According to my testing, although the baseURI after 
pushState() is the same as the documentURI (so far I've tested <img>, 
<link> and <a> elts) the actual images and stylesheets used for 
rendering aren't updated by the pushState() - they should be updated if 
@src, @href is a rel path. If they were updated then the ones relying on 
rel paths would often break, which I consider a good behavior - an 
obvious visual cue to the page author, etc that something was 
implemented wrongly.

Sean

Received on Sunday, 19 February 2012 19:35:36 UTC