2011-01-19 Darin Fisher <darin@chromium.org>
authordarin@chromium.org <darin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Jan 2011 05:49:51 +0000 (05:49 +0000)
committerdarin@chromium.org <darin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Jan 2011 05:49:51 +0000 (05:49 +0000)
        Reviewed by Mihai Parparita.

        Re-initialize the HistoryItem fully when navigating to a HistoryItem,
        or replacing a HistoryItem, results in a different URL.

        https://bugs.webkit.org/show_bug.cgi?id=49654

        This patch also forces all HistoryItems to record the post-redirect
        URL.  Previously, frames would remember the pre-redirect URL.  This is
        problematic since other members of the HistoryItem correspond to the
        post-redirect URL.

        Tests: fast/history/history-replace-updates-current-item.html
               http/tests/navigation/redirect-on-back-updates-history-item.html
               http/tests/navigation/redirect-on-reload-updates-history-item.html

        * history/HistoryItem.cpp:
        (WebCore::HistoryItem::HistoryItem):
        (WebCore::HistoryItem::reset):
        * history/HistoryItem.h:
        * loader/HistoryController.cpp:
        (WebCore::HistoryController::updateForBackForwardNavigation):
        (WebCore::HistoryController::updateForReload):
        (WebCore::HistoryController::updateForStandardLoad):
        (WebCore::HistoryController::updateForRedirectWithLockedBackForwardList):
        (WebCore::HistoryController::initializeItem):
        (WebCore::HistoryController::createItem):
        (WebCore::HistoryController::createItemTree):
        (WebCore::HistoryController::updateCurrentItem):
        * loader/HistoryController.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@76205 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/history/history-replace-updates-current-item-expected.txt [new file with mode: 0644]
LayoutTests/fast/history/history-replace-updates-current-item.html [new file with mode: 0644]
LayoutTests/fast/history/resources/history-replace-updates-current-item-done.html [new file with mode: 0644]
LayoutTests/fast/history/resources/history-replace-updates-current-item-goback.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/postredirect-frames-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/postredirect-frames-goback1-expected.txt
LayoutTests/http/tests/navigation/postredirect-frames.html
LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/redirect302-frames-expected.txt
LayoutTests/http/tests/navigation/redirect302-subframeload-expected.txt
LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item-goback.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item.php [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item-goback.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item.php [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-to-cookie.php [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-updates-history-item-done.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/redirect-updates-history-item.js [new file with mode: 0644]
LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.checksum [deleted file]
LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.png [deleted file]
LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.checksum [deleted file]
LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.png [deleted file]
LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.txt [deleted file]
LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.checksum [deleted file]
LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.png [deleted file]
LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.txt [deleted file]
LayoutTests/platform/qt/http/tests/navigation/postredirect-frames-expected.txt [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/history/HistoryItem.cpp
Source/WebCore/history/HistoryItem.h
Source/WebCore/loader/HistoryController.cpp
Source/WebCore/loader/HistoryController.h

index f61fc3603b876f9b3491893f08ef2309193afa7e..e8c116e5f375184a83a4217cfcb2e2e5314d5c0d 100644 (file)
@@ -1,3 +1,53 @@
+2011-01-14  Darin Fisher  <darin@chromium.org>
+
+        Reviewed by Mihai Parparita.
+
+        Update expectations for existing tests that expect us to record pre-redirect
+        URLs for frames.  We are now recording post-redirect URLs in HistoryItems.
+
+        Add new tests to confirm that we re-initialize the current HistoryItem properly
+        in the following cases:
+
+        1- Navigating back in history to an URL that redirects someplace else this time.
+        2- Reloading an URL that redirects someplace else this time.
+        3- Replacing the current history item with a different URL.
+
+        https://bugs.webkit.org/show_bug.cgi?id=49654
+
+        * fast/history/history-replace-updates-current-item-expected.txt: Added.
+        * fast/history/history-replace-updates-current-item.html: Added.
+        * fast/history/resources/history-replace-updates-current-item-done.html: Added.
+        * fast/history/resources/history-replace-updates-current-item-goback.html: Added.
+        * http/tests/navigation/postredirect-frames-expected.txt: Added.
+        * http/tests/navigation/postredirect-frames-goback1-expected.txt:
+        * http/tests/navigation/postredirect-frames.html:
+        * http/tests/navigation/redirect-on-back-updates-history-item-expected.txt: Added.
+        * http/tests/navigation/redirect-on-back-updates-history-item.html: Added.
+        * http/tests/navigation/redirect-on-reload-updates-history-item-expected.txt: Added.
+        * http/tests/navigation/redirect-on-reload-updates-history-item.html: Added.
+        * http/tests/navigation/redirect302-frames-expected.txt:
+        * http/tests/navigation/redirect302-subframeload-expected.txt:
+        * http/tests/navigation/resources/redirect-on-back-updates-history-item-goback.html: Added.
+        * http/tests/navigation/resources/redirect-on-back-updates-history-item.php: Added.
+        * http/tests/navigation/resources/redirect-on-reload-updates-history-item-goback.html: Added.
+        * http/tests/navigation/resources/redirect-on-reload-updates-history-item.php: Added.
+        * http/tests/navigation/resources/redirect-to-cookie.php: Added.
+        * http/tests/navigation/resources/redirect-updates-history-item-done.html: Added.
+        * http/tests/navigation/resources/redirect-updates-history-item.js: Added.
+        (clearLocationCookie):
+        (setLocationCookie):
+        (log):
+        (onpopstate):
+        * platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.checksum: Removed.
+        * platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.png: Removed.
+        * platform/chromium-win/http/tests/navigation/postredirect-frames-expected.checksum: Removed.
+        * platform/chromium-win/http/tests/navigation/postredirect-frames-expected.png: Removed.
+        * platform/chromium-win/http/tests/navigation/postredirect-frames-expected.txt: Removed.
+        * platform/mac/http/tests/navigation/postredirect-frames-expected.checksum: Removed.
+        * platform/mac/http/tests/navigation/postredirect-frames-expected.png: Removed.
+        * platform/mac/http/tests/navigation/postredirect-frames-expected.txt: Removed.
+        * platform/qt/http/tests/navigation/postredirect-frames-expected.txt: Removed.
+
 2011-01-19  Dmitry Titov  <dimich@chromium.org>
 
         [Chromium] Unreviewed, update of test expectations.
diff --git a/LayoutTests/fast/history/history-replace-updates-current-item-expected.txt b/LayoutTests/fast/history/history-replace-updates-current-item-expected.txt
new file mode 100644 (file)
index 0000000..1edd009
--- /dev/null
@@ -0,0 +1,7 @@
+main frame - has 1 onunload handler(s)
+PASS
+
+============== Back Forward List ==============
+curr->  (file test):fast/history/resources/history-replace-updates-current-item-done.html  **nav target**
+        (file test):fast/history/resources/history-replace-updates-current-item-goback.html  **nav target**
+===============================================
diff --git a/LayoutTests/fast/history/history-replace-updates-current-item.html b/LayoutTests/fast/history/history-replace-updates-current-item.html
new file mode 100644 (file)
index 0000000..a06a516
--- /dev/null
@@ -0,0 +1,32 @@
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpBackForwardList();
+    layoutTestController.waitUntilDone();
+}
+
+onunload = function() {
+    // no page cache
+}
+
+onload = function() {
+    setTimeout(function() {
+        // This code inserts a new history item using pushState, and then it
+        // replaces that history item with a navigation to a page that just
+        // navigates us back to this page.  However, before that, we replace
+        // the URL of the initial page to point at the "done" page such that
+        // navigating back takes us to that document instead.
+        // 
+        // This test ensures that we do not treat the initial document and the
+        // document created by the location.replace command as the same
+        // document when navigating back.  If we treat them the same, then we
+        // will fail to load the "done" page.
+
+        history.replaceState(null, null, 'resources/history-replace-updates-current-item-done.html');
+        
+        history.pushState(null, null, '?dummystate');
+        location.replace('history-replace-updates-current-item-goback.html');
+    }, 0);
+}
+</script>
+<body>history-replace-updates-current-item.html: You should not see this text!</body>
diff --git a/LayoutTests/fast/history/resources/history-replace-updates-current-item-done.html b/LayoutTests/fast/history/resources/history-replace-updates-current-item-done.html
new file mode 100644 (file)
index 0000000..18e64c8
--- /dev/null
@@ -0,0 +1,7 @@
+<script>
+onload = function() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+<body>PASS</body>
diff --git a/LayoutTests/fast/history/resources/history-replace-updates-current-item-goback.html b/LayoutTests/fast/history/resources/history-replace-updates-current-item-goback.html
new file mode 100644 (file)
index 0000000..f244778
--- /dev/null
@@ -0,0 +1,6 @@
+<script>
+onload = function() {
+    history.back();
+}
+</script>
+<body>history-replace-updates-current-item-goback.html: You should not see this text!</body>
diff --git a/LayoutTests/http/tests/navigation/postredirect-frames-expected.txt b/LayoutTests/http/tests/navigation/postredirect-frames-expected.txt
new file mode 100644 (file)
index 0000000..ee7e9cd
--- /dev/null
@@ -0,0 +1,26 @@
+
+
+--------
+Frame: 'main'
+--------
+This is just a minimal page that we navigate in response to an HTTP POST. 
+
+If the next line is empty after the colon, it probably means that we made a mistake and requested this page with a GET with no query instead of a POST. 
+
+The first text field contained: New form text from user 
+This page was requested with an HTTP GET
+
+--------
+Frame: 'footer'
+--------
+This is just a minimal page that we navigate to as part of testing back/forward.
+
+============== Back Forward List ==============
+        http://127.0.0.1:8000/navigation/postredirect-frames.html  **nav target**
+        http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html  **nav target**
+            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
+            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
+curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html
+            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
+            http://127.0.0.1:8000/navigation/resources/postresult.pl?submitwithpostredirect=Submit%20with%20POST%20followed%20by%20a%20redirect&textfield1=New%20form%20text%20from%20user&textfield2=&radiogroup1=female&checkbox2=on&selectgroup1=fiat&textarea1=More%20new%20form%20text%20from%20user%2C%20which%20should%20be%20restored%20when%20we%20return%20to%20this%20page.&redirectHappened=true (in frame "main")  **nav target**
+===============================================
index cefcabd6e191a165fd665cddf0e4e238462fd26b..522786afbe887b9f670f31a347e4eb1382e626d8 100644 (file)
@@ -16,6 +16,6 @@ Target of redirect after POST request.
 
 ============== Back Forward List ==============
 curr->  http://127.0.0.1:8000/navigation/postredirect-frames-goback1.html  **nav target**
-            http://127.0.0.1:8000/navigation/resources/redirect-to-go-back.pl (in frame "target-frame")
+            http://127.0.0.1:8000/navigation/resources/top-go-back.html (in frame "target-frame")
         http://127.0.0.1:8000/navigation/resources/go-back.html  **nav target**
 ===============================================
index 650923d8e2511c9b2c1d8adeb429dfe937a1a552..90183f2db8ff9f196c0cb115c7d71b2b4b556966 100644 (file)
@@ -1,5 +1,9 @@
 <script type="text/javascript" src="resources/testcode.js"></script>
 <script>
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.dumpChildFramesAsText();
+    }
     runBasicTest("resources/frameset.pl?frameURL=success200.html", "postredirect");
 </script>
 This page just kicks off a test, and should not appear in the expected test output.
diff --git a/LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item-expected.txt b/LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item-expected.txt
new file mode 100644 (file)
index 0000000..d2476ff
--- /dev/null
@@ -0,0 +1,10 @@
+main frame - has 1 onunload handler(s)
+PASS
+popstate: null
+
+
+============== Back Forward List ==============
+        http://127.0.0.1:8000/navigation/redirect-on-back-updates-history-item.html  **nav target**
+curr->  http://127.0.0.1:8000/navigation/resources/redirect-updates-history-item-done.html  **nav target**
+        http://127.0.0.1:8000/navigation/resources/redirect-on-back-updates-history-item-goback.html  **nav target**
+===============================================
diff --git a/LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item.html b/LayoutTests/http/tests/navigation/redirect-on-back-updates-history-item.html
new file mode 100644 (file)
index 0000000..346bcf5
--- /dev/null
@@ -0,0 +1,21 @@
+<script src="resources/redirect-updates-history-item.js"></script>
+<script>
+
+// Test that we properly update a history item when returning to the history
+// item results in a redirect to a different document.  We verify that the
+// resulting document is not treated as the same document as the original
+// document in history.  See redirect-on-back-updates-history-item.php for more
+// details.
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpBackForwardList();
+    layoutTestController.waitUntilDone();
+}
+onload = function() {
+    setTimeout(function() {
+        clearLocationCookie();
+        location = 'resources/redirect-on-back-updates-history-item.php';
+    }, 0);
+}
+</script>
diff --git a/LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item-expected.txt b/LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item-expected.txt
new file mode 100644 (file)
index 0000000..12e7dcc
--- /dev/null
@@ -0,0 +1,11 @@
+main frame - has 1 onunload handler(s)
+main frame - has 1 onunload handler(s)
+PASS
+popstate: null
+
+
+============== Back Forward List ==============
+        http://127.0.0.1:8000/navigation/redirect-on-reload-updates-history-item.html  **nav target**
+curr->  http://127.0.0.1:8000/navigation/resources/redirect-updates-history-item-done.html  **nav target**
+        http://127.0.0.1:8000/navigation/resources/redirect-on-reload-updates-history-item-goback.html  **nav target**
+===============================================
diff --git a/LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item.html b/LayoutTests/http/tests/navigation/redirect-on-reload-updates-history-item.html
new file mode 100644 (file)
index 0000000..a521f5c
--- /dev/null
@@ -0,0 +1,24 @@
+<script src="resources/redirect-updates-history-item.js"></script>
+<script>
+
+// Test that we properly update a history item when reloading the history item
+// results in a redirect to a different document.  We verify that the resulting
+// document is not treated as the same document as the original document in
+// history.  See redirect-on-reload-updates-history-item.php for more details.
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpBackForwardList();
+    layoutTestController.waitUntilDone();
+}
+onload = function() {
+    setTimeout(function() {
+        // These fields are used by subsequent pages in this test.  Clear them
+        // to avoid confusing the test with old state.
+        clearLocationCookie();
+        delete sessionStorage.done;
+
+        location = 'resources/redirect-on-reload-updates-history-item.php';
+    }, 0);
+}
+</script>
index 5edfe00d76a2b7c8c37ac5813c13019761c76170..d7d68566378f04744b396832bb7651e346738468 100644 (file)
@@ -4,5 +4,5 @@
         http://127.0.0.1:8000/navigation/redirect302-frames.html  **nav target**
 curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=redirect302.pl  **nav target**
             http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/redirect302.pl (in frame "main")
+            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
 ===============================================
index 499a3d8adc2391c7ad5d6055282c8a6976392c6c..c1eba08fa8b454ad86a14f01a97ca4603974925d 100644 (file)
@@ -7,5 +7,5 @@
             http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "main")
 curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=otherpage.html
             http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/redirect302.pl (in frame "main")  **nav target**
+            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")  **nav target**
 ===============================================
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item-goback.html b/LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item-goback.html
new file mode 100644 (file)
index 0000000..5b9e12a
--- /dev/null
@@ -0,0 +1,7 @@
+<script src="redirect-updates-history-item.js"></script>
+<script>
+onload = function() {
+    history.back();
+}
+</script>
+<p>redirect-on-back-updates-history-item-goback.html: You should not see this text!</p>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item.php b/LayoutTests/http/tests/navigation/resources/redirect-on-back-updates-history-item.php
new file mode 100644 (file)
index 0000000..e306f3b
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+header('cache-control: no-store');
+
+$location=$_COOKIE['location'];
+if ($location!="") {
+  header('Status: 303 See Other');
+  header('Location: '.$location);
+  exit;
+}
+?>
+
+<script src='redirect-updates-history-item.js'></script>
+<script>
+onunload = function() {
+    // no page cache
+}
+
+onload = function() {
+    setTimeout(function() {
+        // This code inserts a new history item using pushState, and then it
+        // replaces that history item with a navigation to a page that just
+        // navigates us back to this page.  However, we set the "location"
+        // cookie so that when we navigate back to this page, we actually
+        // redirect to the value of the "location" cookie.
+
+        setLocationCookie("redirect-updates-history-item-done.html");
+
+        history.pushState(null, null, "");
+        location.replace("redirect-on-back-updates-history-item-goback.html");
+    }, 0);
+}
+</script>
+
+<p>redirect-on-back-updates-history-item.php: You should not see this text!</p>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item-goback.html b/LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item-goback.html
new file mode 100644 (file)
index 0000000..60fab62
--- /dev/null
@@ -0,0 +1,10 @@
+<script src="redirect-updates-history-item.js"></script>
+<script>
+onload = function() {
+    clearLocationCookie();
+    sessionStorage.done = true;
+
+    history.back();
+}
+</script>
+<body>redirect-on-reload-updates-history-item-goback.html: You should not see this text!</body>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item.php b/LayoutTests/http/tests/navigation/resources/redirect-on-reload-updates-history-item.php
new file mode 100644 (file)
index 0000000..1f9f317
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+header('cache-control: no-store');
+
+$location=$_COOKIE['location'];
+if ($location!="") {
+    header('Status: 303 See Other');
+    header('Location: '.$location);
+    exit;
+}
+?>
+
+<script src='redirect-updates-history-item.js'></script>
+<script>
+onunload = function() {
+  // no page cache
+}
+
+onload = function() {
+    setTimeout(function() {
+        // The first time through here (sessionStorage.done is false), this
+        // code inserts a new history item using pushState, and then it
+        // triggers a reload of the history item.  However, we set the
+        // "location" cookie so that when we reload this page, we actually
+        // redirect to the value of the "location" cookie.
+        //
+        // This loads the "goback" page, which bounces us back here after
+        // setting sessionStorage.done to true.  The point of this test is to
+        // ensure that going back actually performs a real navigation as
+        // opposed to performing a "same document navigation" as would normally
+        // be done when navigating back after a pushState.
+
+        if (sessionStorage.done) {
+            location.replace("redirect-updates-history-item-done.html"); 
+        } else {
+            history.pushState(null, null, "");
+
+            setLocationCookie("redirect-on-reload-updates-history-item-goback.html");
+            location.reload();
+        }
+    }, 0);
+}
+</script>
+
+<p>redirect-on-reload-updates-history-item.php: You should not see this text!</p>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-to-cookie.php b/LayoutTests/http/tests/navigation/resources/redirect-to-cookie.php
new file mode 100644 (file)
index 0000000..f5b1522
--- /dev/null
@@ -0,0 +1,4 @@
+<?
+header('Status: 303 See Other');
+header('Location: '.$_COOKIE['location']);
+?>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-updates-history-item-done.html b/LayoutTests/http/tests/navigation/resources/redirect-updates-history-item-done.html
new file mode 100644 (file)
index 0000000..b310309
--- /dev/null
@@ -0,0 +1,8 @@
+<script src="redirect-updates-history-item.js"></script>
+<script>
+onload = function() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+<body>PASS</body>
diff --git a/LayoutTests/http/tests/navigation/resources/redirect-updates-history-item.js b/LayoutTests/http/tests/navigation/resources/redirect-updates-history-item.js
new file mode 100644 (file)
index 0000000..f736f76
--- /dev/null
@@ -0,0 +1,21 @@
+function clearLocationCookie(url) {
+    document.cookie = 'location=;path=/;expires=' + (new Date()).toGMTString() + ';';
+}
+
+function setLocationCookie(url) {
+    clearLocationCookie(url);
+    document.cookie = 'location=' + url + ';path=/';
+}
+
+function log(s) {
+    var console = document.getElementById("console");
+    if (!console) {
+        console = document.createElement("pre");
+        document.body.appendChild(console);
+    }
+    console.innerText += s + "\n";
+}
+
+onpopstate = function() {
+    log("popstate: " + event.state);
+}
diff --git a/LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.checksum b/LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.checksum
deleted file mode 100644 (file)
index 5e1eaee..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bf7439813ccdee61bb802c28aa51bd4d
\ No newline at end of file
diff --git a/LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.png b/LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.png
deleted file mode 100644 (file)
index 04edf14..0000000
Binary files a/LayoutTests/platform/chromium-linux/http/tests/navigation/postredirect-frames-expected.png and /dev/null differ
diff --git a/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.checksum b/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.checksum
deleted file mode 100644 (file)
index e29d435..0000000
+++ /dev/null
@@ -1 +0,0 @@
-c9a08eee879d109d84450bc31f5c7a06
\ No newline at end of file
diff --git a/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.png b/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.png
deleted file mode 100644 (file)
index 3e5e582..0000000
Binary files a/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.png and /dev/null differ
diff --git a/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.txt b/LayoutTests/platform/chromium-win/http/tests/navigation/postredirect-frames-expected.txt
deleted file mode 100644 (file)
index 5cef0c3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderFrameSet {FRAMESET} at (0,0) size 800x600
-      RenderFrame {FRAME} at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderView at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderBlock {HTML} at (0,0) size 800x534
-            RenderBody {BODY} at (8,8) size 784x518
-              RenderText {#text} at (0,0) size 764x73
-                text run at (0,0) width 764: "This is just a minimal page that we navigate in response to an"
-                text run at (0,37) width 181: "HTTP POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,74) size 0x36
-              RenderText {#text} at (0,111) size 781x110
-                text run at (0,111) width 781: "If the next line is empty after the colon, it probably means that"
-                text run at (0,148) width 120: "we made "
-                text run at (120,148) width 638: "a mistake and requested this page with a GET with"
-                text run at (0,185) width 364: "no query instead of a POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,222) size 0x36
-              RenderText {#text} at (0,259) size 692x36
-                text run at (0,259) width 692: "The first text field contained: New form text from user "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderText {#text} at (0,296) size 563x36
-                text run at (0,296) width 563: "This page was requested with an HTTP GET"
-      RenderFrame {FRAME} at (0,540) size 800x60
-        layer at (0,0) size 785x90
-          RenderView at (0,0) size 785x60
-        layer at (0,0) size 785x90
-          RenderBlock {HTML} at (0,0) size 785x90
-            RenderBody {BODY} at (8,8) size 769x74
-              RenderText {#text} at (0,0) size 704x73
-                text run at (0,0) width 704: "This is just a minimal page that we navigate to as part of"
-                text run at (0,37) width 268: "testing back/forward."
-
-============== Back Forward List ==============
-        http://127.0.0.1:8000/navigation/postredirect-frames.html  **nav target**
-        http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html  **nav target**
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
-curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/postresult.pl (in frame "main")  **nav target**
-===============================================
diff --git a/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.checksum b/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.checksum
deleted file mode 100644 (file)
index de6420b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-4c52813662ebbedd8bfeebbdc2c1a0e1
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.png b/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.png
deleted file mode 100644 (file)
index b751865..0000000
Binary files a/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.png and /dev/null differ
diff --git a/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.txt b/LayoutTests/platform/mac/http/tests/navigation/postredirect-frames-expected.txt
deleted file mode 100644 (file)
index bcf663e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderFrameSet {FRAMESET} at (0,0) size 800x600
-      RenderFrame {FRAME} at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderView at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderBlock {HTML} at (0,0) size 800x534
-            RenderBody {BODY} at (8,8) size 784x518
-              RenderText {#text} at (0,0) size 747x74
-                text run at (0,0) width 747: "This is just a minimal page that we navigate in response to"
-                text run at (0,37) width 222: "an HTTP POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,74) size 0x37
-              RenderText {#text} at (0,111) size 763x111
-                text run at (0,111) width 743: "If the next line is empty after the colon, it probably means"
-                text run at (0,148) width 178: "that we made "
-                text run at (178,148) width 585: "a mistake and requested this page with a GET"
-                text run at (0,185) width 436: "with no query instead of a POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,222) size 0x37
-              RenderText {#text} at (0,259) size 709x37
-                text run at (0,259) width 709: "The first text field contained: New form text from user "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderText {#text} at (0,296) size 575x37
-                text run at (0,296) width 575: "This page was requested with an HTTP GET"
-      RenderFrame {FRAME} at (0,540) size 800x60
-        layer at (0,0) size 785x90
-          RenderView at (0,0) size 785x60
-        layer at (0,0) size 785x90
-          RenderBlock {HTML} at (0,0) size 785x90
-            RenderBody {BODY} at (8,8) size 769x74
-              RenderText {#text} at (0,0) size 722x74
-                text run at (0,0) width 722: "This is just a minimal page that we navigate to as part of"
-                text run at (0,37) width 272: "testing back/forward."
-
-============== Back Forward List ==============
-        http://127.0.0.1:8000/navigation/postredirect-frames.html  **nav target**
-        http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html  **nav target**
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
-curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/postresult.pl (in frame "main")  **nav target**
-===============================================
diff --git a/LayoutTests/platform/qt/http/tests/navigation/postredirect-frames-expected.txt b/LayoutTests/platform/qt/http/tests/navigation/postredirect-frames-expected.txt
deleted file mode 100644 (file)
index 414a44b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-layer at (0,0) size 800x600
-  RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  RenderBlock {HTML} at (0,0) size 800x600
-    RenderFrameSet {FRAMESET} at (0,0) size 800x600
-      RenderFrame {FRAME} at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderView at (0,0) size 800x534
-        layer at (0,0) size 800x534
-          RenderBlock {HTML} at (0,0) size 800x534
-            RenderBody {BODY} at (8,8) size 784x518
-              RenderText {#text} at (0,0) size 762x83
-                text run at (0,0) width 762: "This is just a minimal page that we navigate in response"
-                text run at (0,42) width 272: "to an HTTP POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,84) size 0x41
-              RenderText {#text} at (0,126) size 749x125
-                text run at (0,126) width 697: "If the next line is empty after the colon, it probably"
-                text run at (0,168) width 287: "means that we made "
-                text run at (287,168) width 462: "a mistake and requested this page"
-                text run at (0,210) width 632: "with a GET with no query instead of a POST. "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderBR {BR} at (0,252) size 0x41
-              RenderText {#text} at (0,294) size 754x41
-                text run at (0,294) width 754: "The first text field contained: New form text from user "
-              RenderBR {BR} at (0,0) size 0x0
-              RenderText {#text} at (0,336) size 613x41
-                text run at (0,336) width 613: "This page was requested with an HTTP GET"
-      RenderFrame {FRAME} at (0,540) size 800x60
-        layer at (0,0) size 784x100
-          RenderView at (0,0) size 784x60
-        layer at (0,0) size 784x100
-          RenderBlock {HTML} at (0,0) size 784x100
-            RenderBody {BODY} at (8,8) size 768x84
-              RenderText {#text} at (0,0) size 739x83
-                text run at (0,0) width 739: "This is just a minimal page that we navigate to as part"
-                text run at (0,42) width 329: "of testing back/forward."
-
-============== Back Forward List ==============
-        http://127.0.0.1:8000/navigation/postredirect-frames.html  **nav target**
-        http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html  **nav target**
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/success200.html (in frame "main")
-curr->  http://127.0.0.1:8000/navigation/resources/frameset.pl?frameURL=success200.html
-            http://127.0.0.1:8000/navigation/resources/otherpage.html (in frame "footer")
-            http://127.0.0.1:8000/navigation/resources/postresult.pl (in frame "main")  **nav target**
-===============================================
index 3e3283521c50fd559ae9d18fc9d9834589fd563c..0594c66deb6df4c046013b747d748c8b103f40a7 100644 (file)
@@ -1,3 +1,36 @@
+2011-01-19  Darin Fisher  <darin@chromium.org>
+
+        Reviewed by Mihai Parparita.
+
+        Re-initialize the HistoryItem fully when navigating to a HistoryItem,
+        or replacing a HistoryItem, results in a different URL.
+
+        https://bugs.webkit.org/show_bug.cgi?id=49654
+
+        This patch also forces all HistoryItems to record the post-redirect
+        URL.  Previously, frames would remember the pre-redirect URL.  This is
+        problematic since other members of the HistoryItem correspond to the
+        post-redirect URL.
+
+        Tests: fast/history/history-replace-updates-current-item.html
+               http/tests/navigation/redirect-on-back-updates-history-item.html
+               http/tests/navigation/redirect-on-reload-updates-history-item.html
+
+        * history/HistoryItem.cpp:
+        (WebCore::HistoryItem::HistoryItem):
+        (WebCore::HistoryItem::reset):
+        * history/HistoryItem.h:
+        * loader/HistoryController.cpp:
+        (WebCore::HistoryController::updateForBackForwardNavigation):
+        (WebCore::HistoryController::updateForReload):
+        (WebCore::HistoryController::updateForStandardLoad):
+        (WebCore::HistoryController::updateForRedirectWithLockedBackForwardList):
+        (WebCore::HistoryController::initializeItem):
+        (WebCore::HistoryController::createItem):
+        (WebCore::HistoryController::createItemTree):
+        (WebCore::HistoryController::updateCurrentItem):
+        * loader/HistoryController.h:
+
 2011-01-19  Adam Klein  <adamk@chromium.org>
 
         Reviewed by Darin Fisher.
index f9e6c96a3ca26cd565b7d7e7b21bc4f6760c95aa..805d5aa748df616f8ab9768afcf981db75ea6360 100644 (file)
@@ -65,6 +65,8 @@ HistoryItem::HistoryItem()
     , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
+    , m_next(0)
+    , m_prev(0)
 {
 }
 
@@ -80,6 +82,8 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, double ti
     , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
+    , m_next(0)
+    , m_prev(0)
 {    
     iconDatabase()->retainIconForPageURL(m_urlString);
 }
@@ -97,6 +101,8 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, const Str
     , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
+    , m_next(0)
+    , m_prev(0)
 {
     iconDatabase()->retainIconForPageURL(m_urlString);
 }
@@ -115,6 +121,8 @@ HistoryItem::HistoryItem(const KURL& url, const String& target, const String& pa
     , m_visitCount(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
+    , m_next(0)
+    , m_prev(0)
 {    
     iconDatabase()->retainIconForPageURL(m_urlString);
 }
@@ -168,6 +176,38 @@ PassRefPtr<HistoryItem> HistoryItem::copy() const
     return adoptRef(new HistoryItem(*this));
 }
 
+void HistoryItem::reset()
+{
+    iconDatabase()->releaseIconForPageURL(m_urlString);
+
+    m_urlString = String();
+    m_originalURLString = String();
+    m_referrer = String();
+    m_target = String();
+    m_parent = String();
+    m_title = String();
+    m_displayTitle = String();
+
+    m_lastVisitedTime = 0;
+    m_lastVisitWasHTTPNonGet = false;
+
+    m_lastVisitWasFailure = false;
+    m_isTargetItem = false;
+    m_visitCount = 0;
+    m_dailyVisitCounts.clear();
+    m_weeklyVisitCounts.clear();
+
+    m_redirectURLs.clear();
+
+    m_itemSequenceNumber = generateSequenceNumber();
+
+    m_stateObject = 0;
+    m_documentSequenceNumber = generateSequenceNumber();
+
+    m_formData = 0;
+    m_formContentType = String();
+}
+
 const String& HistoryItem::urlString() const
 {
     return m_urlString;
index a4622c0238cae49936e9bd9dc8537651412af0d0..526cae2eb96c6d479ba1ab8ea127f988c6bfdc7d 100644 (file)
@@ -88,6 +88,9 @@ public:
 
     PassRefPtr<HistoryItem> copy() const;
 
+    // Resets the HistoryItem to its initial state, as returned by create().
+    void reset();
+    
     void encodeBackForwardTree(Encoder&) const;
     static PassRefPtr<HistoryItem> decodeBackForwardTree(const String& urlString, const String& title, const String& originalURLString, Decoder&);
 
@@ -148,7 +151,7 @@ public:
 
     void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; }
     long long documentSequenceNumber() const { return m_documentSequenceNumber; }
-    
+
     void setFormInfoFromRequest(const ResourceRequest&);
     void setFormData(PassRefPtr<FormData>);
     void setFormContentType(const String&);
@@ -262,11 +265,19 @@ private:
 
     OwnPtr<Vector<String> > m_redirectURLs;
 
+    // If two HistoryItems have the same item sequence number, then they are
+    // clones of one another.  Traversing history from one such HistoryItem to
+    // another is a no-op.  HistoryItem clones are created for parent and
+    // sibling frames when only a subframe navigates.
     int64_t m_itemSequenceNumber;
 
+    // If two HistoryItems have the same document sequence number, then they
+    // refer to the same instance of a document.  Traversing history from one
+    // such HistoryItem to another preserves the document.
+    int64_t m_documentSequenceNumber;
+
     // Support for HTML5 History
     RefPtr<SerializedScriptValue> m_stateObject;
-    int64_t m_documentSequenceNumber;
     
     // info used to repost form data
     RefPtr<FormData> m_formData;
index dda4e56918b8709f98e226a4c353ac7e195a6cc2..a7bfd11eaac8b8200ba7d6ddf1a1483e3c3a8dd2 100644 (file)
@@ -260,6 +260,10 @@ void HistoryController::updateForBackForwardNavigation()
     // Must grab the current scroll position before disturbing it
     if (!m_frameLoadComplete)
         saveScrollPositionAndViewStateToItem(m_previousItem.get());
+
+    // When traversing history, we may end up redirecting to a different URL
+    // this time (e.g., due to cookies).  See http://webkit.org/b/49654.
+    updateCurrentItem();
 }
 
 void HistoryController::updateForReload()
@@ -274,11 +278,11 @@ void HistoryController::updateForReload()
     
         if (m_frame->loader()->loadType() == FrameLoadTypeReload || m_frame->loader()->loadType() == FrameLoadTypeReloadFromOrigin)
             saveScrollPositionAndViewStateToItem(m_currentItem.get());
-    
-        // Sometimes loading a page again leads to a different result because of cookies. Bugzilla 4072
-        if (m_frame->loader()->documentLoader()->unreachableURL().isEmpty())
-            m_currentItem->setURL(m_frame->loader()->documentLoader()->requestURL());
     }
+
+    // When reloading the page, we may end up redirecting to a different URL
+    // this time (e.g., due to cookies).  See http://webkit.org/b/4072.
+    updateCurrentItem();
 }
 
 // There are 3 things you might think of as "history", all of which are handled by these functions.
@@ -310,9 +314,9 @@ void HistoryController::updateForStandardLoad(HistoryUpdateType updateType)
             if (Page* page = m_frame->page())
                 page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem());
         }
-    } else if (frameLoader->documentLoader()->unreachableURL().isEmpty() && m_currentItem) {
-        m_currentItem->setURL(frameLoader->documentLoader()->url());
-        m_currentItem->setFormInfoFromRequest(frameLoader->documentLoader()->request());
+    } else {
+        // The client redirect replaces the current history item.
+        updateCurrentItem();
     }
 
     if (!historyURL.isEmpty() && !needPrivacy) {
@@ -349,14 +353,12 @@ void HistoryController::updateForRedirectWithLockedBackForwardList()
                     page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForward()->currentItem());
             }
         }
-        if (m_currentItem) {
-            m_currentItem->setURL(m_frame->loader()->documentLoader()->url());
-            m_currentItem->setFormInfoFromRequest(m_frame->loader()->documentLoader()->request());
-        }
+        // The client redirect replaces the current history item.
+        updateCurrentItem();
     } else {
         Frame* parentFrame = m_frame->tree()->parent();
         if (parentFrame && parentFrame->loader()->history()->m_currentItem)
-            parentFrame->loader()->history()->m_currentItem->setChildItem(createItem(true));
+            parentFrame->loader()->history()->m_currentItem->setChildItem(createItem());
     }
 
     if (!historyURL.isEmpty() && !needPrivacy) {
@@ -506,12 +508,13 @@ void HistoryController::setProvisionalItem(HistoryItem* item)
     m_provisionalItem = item;
 }
 
-PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
+void HistoryController::initializeItem(HistoryItem* item)
 {
     DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
-    
-    KURL unreachableURL = documentLoader ? documentLoader->unreachableURL() : KURL();
-    
+    ASSERT(documentLoader);
+
+    KURL unreachableURL = documentLoader->unreachableURL();
+
     KURL url;
     KURL originalURL;
 
@@ -519,15 +522,10 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
         url = unreachableURL;
         originalURL = unreachableURL;
     } else {
-        originalURL = documentLoader ? documentLoader->originalURL() : KURL();
-        if (useOriginal)
-            url = originalURL;
-        else if (documentLoader)
-            url = documentLoader->requestURL();
+        url = documentLoader->url();
+        originalURL = documentLoader->originalURL();
     }
 
-    LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data());
-    
     // Frames that have never successfully loaded any content
     // may have no URL at all. Currently our history code can't
     // deal with such things, so we nip that in the bud here.
@@ -540,21 +538,25 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
     
     Frame* parentFrame = m_frame->tree()->parent();
     String parent = parentFrame ? parentFrame->tree()->uniqueName() : "";
-    String title = documentLoader ? documentLoader->title() : "";
+    String title = documentLoader->title();
 
-    RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->uniqueName(), parent, title);
+    item->setURL(url);
+    item->setTarget(m_frame->tree()->uniqueName());
+    item->setParent(parent);
+    item->setTitle(title);
     item->setOriginalURLString(originalURL.string());
 
-    if (!unreachableURL.isEmpty() || !documentLoader || documentLoader->response().httpStatusCode() >= 400)
+    if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode() >= 400)
         item->setLastVisitWasFailure(true);
 
     // Save form state if this is a POST
-    if (documentLoader) {
-        if (useOriginal)
-            item->setFormInfoFromRequest(documentLoader->originalRequest());
-        else
-            item->setFormInfoFromRequest(documentLoader->request());
-    }
+    item->setFormInfoFromRequest(documentLoader->request());
+}
+
+PassRefPtr<HistoryItem> HistoryController::createItem()
+{
+    RefPtr<HistoryItem> item = HistoryItem::create();
+    initializeItem(item.get());
     
     // Set the item for which we will save document state
     m_frameLoadComplete = false;
@@ -566,7 +568,7 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
 
 PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bool clipAtTarget)
 {
-    RefPtr<HistoryItem> bfItem = createItem(m_frame->tree()->parent() ? true : false);
+    RefPtr<HistoryItem> bfItem = createItem();
     if (!m_frameLoadComplete)
         saveScrollPositionAndViewStateToItem(m_previousItem.get());
 
@@ -713,6 +715,31 @@ void HistoryController::updateBackForwardListClippedAtTarget(bool doClip)
     page->backForward()->addItem(topItem.release());
 }
 
+void HistoryController::updateCurrentItem()
+{
+    if (!m_currentItem)
+        return;
+
+    DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
+
+    if (!documentLoader->unreachableURL().isEmpty())
+        return;
+
+    if (m_currentItem->url() != documentLoader->url()) {
+        // We ended up on a completely different URL this time, so the HistoryItem
+        // needs to be re-initialized.  Preserve the isTargetItem flag as it is a
+        // property of how this HistoryItem was originally created and is not
+        // dependent on the document.
+        bool isTargetItem = m_currentItem->isTargetItem();
+        m_currentItem->reset();
+        initializeItem(m_currentItem.get());
+        m_currentItem->setIsTargetItem(isTargetItem);
+    } else {
+        // Even if the final URL didn't change, the form data may have changed.
+        m_currentItem->setFormInfoFromRequest(documentLoader->request());
+    }
+}
+
 void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString)
 {
     if (!m_currentItem)
index 9923179a46d6b138a9021e6850fed185b7e93418..17f80eb4cd189f7673a2d80501ac3afed9003f34 100644 (file)
@@ -84,7 +84,8 @@ public:
     void replaceState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url);
 
 private:
-    PassRefPtr<HistoryItem> createItem(bool useOriginal);
+    void initializeItem(HistoryItem*);
+    PassRefPtr<HistoryItem> createItem();
     PassRefPtr<HistoryItem> createItemTree(Frame* targetFrame, bool clipAtTarget);
 
     void recursiveSetProvisionalItem(HistoryItem*, HistoryItem*, FrameLoadType);
@@ -93,6 +94,7 @@ private:
     bool itemsAreClones(HistoryItem*, HistoryItem*) const;
     bool currentFramesMatchItem(HistoryItem*) const;
     void updateBackForwardListClippedAtTarget(bool doClip);
+    void updateCurrentItem();
 
     Frame* m_frame;