This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 17041 - Setting location before the page is done loading shouldn't always be a replace load
Summary: Setting location before the page is done loading shouldn't always be a replac...
Status: RESOLVED FIXED
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-12 04:00 UTC by contributor
Modified: 2013-05-31 20:30 UTC (History)
6 users (show)

See Also:


Attachments

Description contributor 2012-05-12 04:00:46 UTC
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html
Multipage: http://www.whatwg.org/C#the-location-interface
Complete: http://www.whatwg.org/c#the-location-interface

Comment:
Setting location before the page is done loading shouldn't always be a replace
load

Posted from: 71.184.125.56 by bzbarsky@mit.edu
User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:15.0) Gecko/15.0 Firefox/15.0a1
Comment 1 Boris Zbarsky 2012-05-12 04:02:01 UTC
See http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-July/027372.html for a survey of browser behavior and https://bugzilla.mozilla.org/show_bug.cgi?id=754029#c5 for the reason why the current spec behavior is not really all that great: it makes user interactions race with page loading in undesirable ways.
Comment 2 contributor 2012-07-18 17:27:41 UTC
This bug was cloned to create bug 18152 as part of operation convergence.
Comment 3 Ian 'Hixie' Hickson 2012-10-19 19:29:26 UTC
How about I just make the location.href setter use assign() rather than replace() if there's a trusted user-interaction event on the stack? (i.e. in response to a click, basically)
Comment 4 Boris Zbarsky 2012-11-26 04:56:30 UTC
I recommend talking this over with "O. Atsushi (Torisugari)" (see linked Mozilla bug), since he's done a lot of thinking about this recently, including testingof behavior across UAs, compat issues, etc.
Comment 5 O. Atsushi 2013-02-06 12:19:07 UTC
Hi,

(In reply to comment #3)
> How about I just make the location.href setter use assign() rather than
> replace() if there's a trusted user-interaction event on the stack? (i.e. in
> response to a click, basically)

Is it easy enough to define "trusted/non-trusted" state in the spec?

For example, if I were a developer working for a search engine like Google or Bing, maybe I want to send HTTP "ping" on every user's link click. Then I might write such a code:

----- FROM HERE ------
<p>
  Hey, click the search results of your input "Fruits"!

  <a href="www.examle.com/banana.html"> BANANA! </a></br>
  <a href="www.examle.com/apple.html" > APPLE!  </a></br>
  <a href="www.examle.com/orange.html"> ORANGE! </a></br>
  ...
</p>

<script>
// Try to listen to user's click...
var anchors = document.getElementsByTagName("a")
for (var anchor in anchors) {
  anchor.addEventListener("click", clickLink, false);
}

// On "click" evnet by user.
function clickLink(aEvent) {
  event.preventDefault();

  // Don't redirect at once.
  // Instead, send the url to seach engine's server.

  var logger = new Image();
  logger.onload = imageLoad;
  logger.src = "http://my.server/logMe?url=" + aEvent.target.href;
}

// On "load" event for dummy 1x1 pixel image.
// Note that this image won't actually be rendered on the monitor.
function imageLoad(aEvent) {
  // Now we've successfully logged the target URL at "my.server".
  // Start the real redirection.

  var url = aEvent.target.src
                  .replace("http://my.server/logMe?url=", "");

  window.location.href = url;
}
</script>
----- TO HERE ------

UAs are supposed to trust |location.href| in the "click" handler, since it's caused by user's action apparently. But should they trust |location.href| in the "load" handler as well? Well, I'm not talking about just an imaginary case. This problem is described in Mozilla's bugzilla, and the page has a "setTimeout(...)" version testcase.

https://bugzilla.mozilla.org/show_bug.cgi?id=825544

I don't know much about DOM3's |Event::isTrusted|, but it seems we need another more complicated (internal) flag to keep our browser backward-compatible, because the html5 spec does want to make |location.href| "replace()", in the document's own "load" listener.
Comment 6 Ian 'Hixie' Hickson 2013-02-06 20:52:27 UTC
O. Atsushi: So what should the spec say?
Comment 7 O. Atsushi 2013-02-07 10:27:32 UTC
I have no idea about it, and that's why my patch for Firefox was backed out. Among the major browsers, only WebKit is handling this issue properly in the way like what you said.

> Interesting, so it seems that Firefox is not taking user gesture into account.
>
> This may be something worth posting to whatwg about for discussion,
https://bugs.webkit.org/show_bug.cgi?id=42861#c12

So as not to confuse web developers, probably we need "standard" way to judge whether or not an event is from user's action (in WebKit's terms, "User Gesture").


Frankly speaking, I'm not yet 100% sure it is really reasonable to change |location.href|'s behavior according to the document's loading state, though I do understand Gecko's implementation played an important role when you wrote it into the spec.
Comment 8 Ian 'Hixie' Hickson 2013-04-12 19:24:41 UTC
Ok well since y'all don't know what you want the spec to say, if, how about this:

| If any of the following conditions are matched, use assign():
|
| * the Location object's relevant Document has completely loaded, or
| * in the task in which the algorithm is running, an activation behavior is
|   currently being processed whose click event was trusted, or
| * in the task in which the algorithm is running, the event listener for a
|   trusted click event is being handled.
|
| Otherwise, use replace().
Comment 9 contributor 2013-05-31 20:30:17 UTC
Checked in as WHATWG revision r7882.
Check-in comment: Keep pages in history even if they were still loaded when the user navigated away (but still not if a script did it on its own).
http://html5.org/tools/web-apps-tracker?from=7881&to=7882