Bug 20355

Summary: Back list isn't properly updated for fragment changes after a redirect
Product: WebKit Reporter: Ben Mathews <mathewsb>
Component: HistoryAssignee: Brady Eidson <beidson>
Status: RESOLVED FIXED    
Severity: Normal CC: adele, agrieve, beidson, grahamperrin, rostislav.hristov
Priority: P2 Keywords: HasReduction, InRadar
Version: 528+ (Nightly build)   
Hardware: Mac   
OS: OS X 10.5   
Attachments:
Description Flags
Patch v1 darin: review+, beidson: commit-queue-

Description Ben Mathews 2008-08-11 19:08:25 PDT
After a redirect by window.location.replace(), changes to the URI fragment don't insert new history entries.  The problem continues until you change to a new page.

For instance suppose you have these two files:

a.html:
<script>window.location.replace('b.html');</script>

b.html:
<a href="#asdf">Click this link to demonstrate the problem.</a>

If you load a.html, you will be redirected to b.html.  If you click on the link, then the location bar is updated, but no history entry is added.

However, if you load b.html directly, then clicking on the link *does* insert a history entry.

This happens for me on Safari 3.1.2, and on the WebKit nightly r35666.
Comment 1 Ben Mathews 2008-08-11 19:12:37 PDT
By the way, this bug may seem trivial, but it causes issues for our JS history management library on Facebook.  I would guess that it causes problems for other history management libraries, too.
Comment 2 Mark Rowe (bdash) 2008-08-11 21:55:46 PDT
<rdar://problem/6142803>
Comment 3 Ben Mathews 2008-09-17 10:38:26 PDT
A real-world description of how this affects end users:

1. User gets an email that says "X tagged a photo of you on Facebook."  Has a link that looks like this:  http://www.facebook.com/n/?photo.php&pid=XXXXXXXX&op=1&view=all&subj=XXXXXXX&id=XXXX

2. User clicks on the link, is taken to the photo.

3. User clicks on the photo to go to the next photo.

4. At this point, the back button doesn't work.  (Normally, on other browsers, it would take you back to the first photo.  In Safari, it might not do anything, or it might take you back to what you were viewing before you clicked on the Facebook link.)
Comment 4 Rostislav Hristov 2008-12-04 04:18:17 PST
The problem applies also to meta redirects like:
<meta http-equiv="refresh" content="0;url=b.html" />

Check how the following sample behaves in Safari and the other browsers:
http://www.asual.com/swfaddress/samples/ajax/history/
Comment 5 Andrew Grieve 2009-07-29 11:24:26 PDT
This bug is also affecting gmail on the iphone/android in some cases.
Comment 6 Brady Eidson 2009-09-22 10:36:06 PDT
In:
void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
...we check the FrameLoadType to see if we should change the back/forward list or not.

The FrameLoadType is set in the various forms of loads that go through a new DocumentLoader, but is never set in the synchronous anchor scroll case.  So the old FrameLoadType from the a.html -> b.html redirect is still sticking around, preventing the back/forward entry from being made.
Comment 7 Brady Eidson 2009-09-22 12:39:33 PDT
Created attachment 39938 [details]
Patch v1
Comment 8 Brady Eidson 2009-09-22 13:04:56 PDT
Sending        LayoutTests/ChangeLog
Adding         LayoutTests/fast/loader/fragment-after-redirect-gets-back-entry-expected.txt
Adding         LayoutTests/fast/loader/fragment-after-redirect-gets-back-entry.html
Adding         LayoutTests/fast/loader/resources/click-fragment-link.html
Sending        LayoutTests/http/tests/navigation/relativeanchor-frames-expected.txt
Sending        WebCore/ChangeLog
Sending        WebCore/loader/FrameLoader.cpp
Transmitting file data .......
Committed revision 48644.