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.
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.
<rdar://problem/6142803>
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.)
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/
This bug is also affecting gmail on the iphone/android in some cases.
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.
Created attachment 39938 [details] Patch v1
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.