2010-08-13 Mihai Parparita <mihaip@chromium.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Aug 2010 23:35:34 +0000 (23:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Aug 2010 23:35:34 +0000 (23:35 +0000)
        Reviewed by Dimitri Glazkov.

        Session history should skip over JS redirects
        https://bugs.webkit.org/show_bug.cgi?id=42861

        Lock the back/forward list for location changes and form submits that
        happen before the onload event fires that are not the result of user
        gestures.

        http/tests/history tests now pass, their expectations were updated
        accordingly. Other tests needed a setTimeout wrapper around location
        changes and form submits during onload, otherwise they would not
        generate history entries as expected anymore.

        * fast/css/target-fragment-match.html:
        * fast/dom/location-hash.html:
        * fast/dom/Geolocation/resources/cached-page-1.html:
        * fast/dom/Window/timer-resume-on-navigation-back.html:
        * fast/events/pageshow-pagehide-on-back-cached-with-frames-expected.txt:
        * fast/events/pageshow-pagehide-on-back-cached-with-frames.html:
        * fast/forms/button-state-restore.html:
        * fast/forms/state-restore-to-non-autocomplete-form.html:
        * fast/forms/state-restore-to-non-edited-controls.html:
        * fast/frames/resources/cached-page-1.html:
        * fast/frames/resources/cached-page-2.html:
        * fast/harness/resources/cached-page-1.html:
        * fast/harness/resources/cached-page-with-data-urls.html:
        * fast/history/gesture-before-onload-expected.txt: Added.
        * fast/history/gesture-before-onload.html: Added.
        * fast/history/history-length.html:
        * fast/history/resources/gesture-before-onload-target.html: Added.
        * fast/history/saves-state-after-fragment-nav.html:
        * fast/loader/input-element-page-cache-crash.html:
        * fast/loader/stateobjects/document-destroyed-navigate-back.html:
        * fast/loader/stateobjects/pushstate-clears-forward-history.html:
        * fast/loader/subframe-navigate-during-main-frame-load.html:
        * http/tests/history/back-to-post.php:
        * http/tests/history/redirect-js-document-location-before-load-expected.txt:
        * http/tests/history/redirect-js-form-submit-before-load-expected.txt:
        * http/tests/history/redirect-js-location-assign-before-load-expected.txt:
        * http/tests/history/redirect-js-location-before-load-expected.txt:
        * http/tests/history/redirect-js-location-href-before-load-expected.txt:
        * http/tests/loading/307-after-303-after-post-expected.txt:
        * http/tests/loading/redirect-methods-expected.txt:
        * http/tests/navigation/resources/back-send-referrer-helper.php:
        * http/tests/navigation/resources/document-location.js:
        (start):
        * http/tests/navigation/resources/submit-to-fragment.pl:
        * security/autocomplete-cleared-on-back.html:
        * storage/hash-change-with-xhr.js:
        (updateDatabase):
        (invokeBack):
        (runTest):
        (runTestsInner):

2010-08-13  Mihai Parparita  <mihaip@chromium.org>

        Reviewed by Dimitri Glazkov.

        Session history should skip over JS redirects
        https://bugs.webkit.org/show_bug.cgi?id=42861

        Lock the back/forward list for location changes and form submits that
        happen before the onload event fires that are not the result of user
        gestures.

        Made form submission (at the ScheduledFormSubmission level) more similar
        to ScheduledURLNavigation by having it call clientRedirected too, fixing
        a long-standing FIXME.

        Test: fast/history/gesture-before-onload-location-href.html,
        fast/history/gesture-before-onload-form-submit.html and updated
        expectations for http/tests/history tests that used to fail.

        * loader/FormSubmission.cpp:
        (WebCore::FormSubmission::requestURL):
        (WebCore::FormSubmission::populateFrameLoadRequest):
        * loader/FormSubmission.h:
        * loader/RedirectScheduler.cpp:
        (WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
        (WebCore::ScheduledFormSubmission::fire):
        (WebCore::ScheduledFormSubmission::didStartTimer):
        (WebCore::ScheduledFormSubmission::didStopTimer):
        (WebCore::RedirectScheduler::scheduleRedirect):
        (WebCore::RedirectScheduler::mustLockBackForwardList):
        (WebCore::RedirectScheduler::scheduleLocationChange):
        (WebCore::RedirectScheduler::scheduleFormSubmission):
        * loader/RedirectScheduler.h:

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

79 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/target-fragment-match.html
LayoutTests/fast/dom/Geolocation/resources/cached-page-1.html
LayoutTests/fast/dom/Window/timer-resume-on-navigation-back.html
LayoutTests/fast/dom/location-hash.html
LayoutTests/fast/events/pageshow-pagehide-on-back-cached-with-frames-expected.txt
LayoutTests/fast/events/pageshow-pagehide-on-back-cached-with-frames.html
LayoutTests/fast/forms/button-state-restore.html
LayoutTests/fast/forms/state-restore-to-non-autocomplete-form.html
LayoutTests/fast/forms/state-restore-to-non-edited-controls.html
LayoutTests/fast/frames/resources/cached-page-1.html
LayoutTests/fast/frames/resources/cached-page-2.html
LayoutTests/fast/harness/resources/cached-page-1.html
LayoutTests/fast/harness/resources/cached-page-with-data-urls.html
LayoutTests/fast/history/gesture-before-onload-form-submit-expected.txt [new file with mode: 0644]
LayoutTests/fast/history/gesture-before-onload-form-submit.html [new file with mode: 0644]
LayoutTests/fast/history/gesture-before-onload-location-href-expected.txt [new file with mode: 0644]
LayoutTests/fast/history/gesture-before-onload-location-href.html [new file with mode: 0644]
LayoutTests/fast/history/history-length.html
LayoutTests/fast/history/resources/gesture-before-onload-target.html [new file with mode: 0644]
LayoutTests/fast/history/saves-state-after-fragment-nav.html
LayoutTests/fast/loader/input-element-page-cache-crash.html
LayoutTests/fast/loader/stateobjects/document-destroyed-navigate-back.html
LayoutTests/fast/loader/stateobjects/pushstate-clears-forward-history.html
LayoutTests/fast/loader/subframe-navigate-during-main-frame-load.html
LayoutTests/http/tests/history/back-to-post.php
LayoutTests/http/tests/history/redirect-200-refresh-0-seconds.pl
LayoutTests/http/tests/history/redirect-200-refresh-2-seconds.pl
LayoutTests/http/tests/history/redirect-301-expected.txt
LayoutTests/http/tests/history/redirect-301.html [new file with mode: 0644]
LayoutTests/http/tests/history/redirect-301.pl [deleted file]
LayoutTests/http/tests/history/redirect-302-expected.txt
LayoutTests/http/tests/history/redirect-302.html [new file with mode: 0755]
LayoutTests/http/tests/history/redirect-302.pl [deleted file]
LayoutTests/http/tests/history/redirect-303-expected.txt
LayoutTests/http/tests/history/redirect-303.html [new file with mode: 0755]
LayoutTests/http/tests/history/redirect-303.pl [deleted file]
LayoutTests/http/tests/history/redirect-307-expected.txt
LayoutTests/http/tests/history/redirect-307.html [new file with mode: 0755]
LayoutTests/http/tests/history/redirect-307.pl [deleted file]
LayoutTests/http/tests/history/redirect-js-document-location-0-seconds.html
LayoutTests/http/tests/history/redirect-js-document-location-2-seconds.html
LayoutTests/http/tests/history/redirect-js-document-location-before-load-expected.txt
LayoutTests/http/tests/history/redirect-js-document-location-before-load.html
LayoutTests/http/tests/history/redirect-js-form-submit-0-seconds.html
LayoutTests/http/tests/history/redirect-js-form-submit-2-seconds.html
LayoutTests/http/tests/history/redirect-js-form-submit-before-load-expected.txt
LayoutTests/http/tests/history/redirect-js-form-submit-before-load.html
LayoutTests/http/tests/history/redirect-js-location-0-seconds.html
LayoutTests/http/tests/history/redirect-js-location-2-seconds.html
LayoutTests/http/tests/history/redirect-js-location-assign-0-seconds.html
LayoutTests/http/tests/history/redirect-js-location-assign-2-seconds.html
LayoutTests/http/tests/history/redirect-js-location-assign-before-load-expected.txt
LayoutTests/http/tests/history/redirect-js-location-assign-before-load.html
LayoutTests/http/tests/history/redirect-js-location-before-load-expected.txt
LayoutTests/http/tests/history/redirect-js-location-before-load.html
LayoutTests/http/tests/history/redirect-js-location-href-0-seconds.html
LayoutTests/http/tests/history/redirect-js-location-href-2-seconds.html
LayoutTests/http/tests/history/redirect-js-location-href-before-load-expected.txt
LayoutTests/http/tests/history/redirect-js-location-href-before-load.html
LayoutTests/http/tests/history/redirect-js-location-replace-0-seconds.html
LayoutTests/http/tests/history/redirect-js-location-replace-2-seconds.html
LayoutTests/http/tests/history/redirect-js-location-replace-before-load.html
LayoutTests/http/tests/history/redirect-meta-refresh-0-seconds.html
LayoutTests/http/tests/history/redirect-meta-refresh-2-seconds.html
LayoutTests/http/tests/history/resources/redirect-helper.pl [new file with mode: 0755]
LayoutTests/http/tests/history/resources/redirect-target.html
LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt
LayoutTests/http/tests/loading/redirect-methods-expected.txt
LayoutTests/http/tests/navigation/resources/back-send-referrer-helper.php
LayoutTests/http/tests/navigation/resources/document-location.js
LayoutTests/http/tests/navigation/resources/submit-to-fragment.pl
LayoutTests/security/autocomplete-cleared-on-back.html
LayoutTests/storage/hash-change-with-xhr.js
WebCore/ChangeLog
WebCore/loader/FormSubmission.cpp
WebCore/loader/FormSubmission.h
WebCore/loader/RedirectScheduler.cpp
WebCore/loader/RedirectScheduler.h

index 9e3aaf2..2b5fbcf 100644 (file)
@@ -1,3 +1,61 @@
+2010-08-13  Mihai Parparita  <mihaip@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Session history should skip over JS redirects
+        https://bugs.webkit.org/show_bug.cgi?id=42861
+        
+        Lock the back/forward list for location changes and form submits that
+        happen before the onload event fires that are not the result of user
+        gestures.
+        
+        http/tests/history tests now pass, their expectations were updated 
+        accordingly. Other tests needed a setTimeout wrapper around location
+        changes and form submits during onload, otherwise they would not
+        generate history entries as expected anymore.
+        
+        * fast/css/target-fragment-match.html:
+        * fast/dom/location-hash.html:
+        * fast/dom/Geolocation/resources/cached-page-1.html:
+        * fast/dom/Window/timer-resume-on-navigation-back.html:
+        * fast/events/pageshow-pagehide-on-back-cached-with-frames-expected.txt:
+        * fast/events/pageshow-pagehide-on-back-cached-with-frames.html:
+        * fast/forms/button-state-restore.html:
+        * fast/forms/state-restore-to-non-autocomplete-form.html:
+        * fast/forms/state-restore-to-non-edited-controls.html:
+        * fast/frames/resources/cached-page-1.html:
+        * fast/frames/resources/cached-page-2.html:
+        * fast/harness/resources/cached-page-1.html:
+        * fast/harness/resources/cached-page-with-data-urls.html:
+        * fast/history/gesture-before-onload-expected.txt: Added.
+        * fast/history/gesture-before-onload.html: Added.
+        * fast/history/history-length.html:
+        * fast/history/resources/gesture-before-onload-target.html: Added.
+        * fast/history/saves-state-after-fragment-nav.html:
+        * fast/loader/input-element-page-cache-crash.html:
+        * fast/loader/stateobjects/document-destroyed-navigate-back.html:
+        * fast/loader/stateobjects/pushstate-clears-forward-history.html:
+        * fast/loader/subframe-navigate-during-main-frame-load.html:
+        * http/tests/history/back-to-post.php:
+        * http/tests/history/redirect-js-document-location-before-load-expected.txt:
+        * http/tests/history/redirect-js-form-submit-before-load-expected.txt:
+        * http/tests/history/redirect-js-location-assign-before-load-expected.txt:
+        * http/tests/history/redirect-js-location-before-load-expected.txt:
+        * http/tests/history/redirect-js-location-href-before-load-expected.txt:
+        * http/tests/loading/307-after-303-after-post-expected.txt:
+        * http/tests/loading/redirect-methods-expected.txt:
+        * http/tests/navigation/resources/back-send-referrer-helper.php:
+        * http/tests/navigation/resources/document-location.js:
+        (start):
+        * http/tests/navigation/resources/submit-to-fragment.pl:
+        * security/autocomplete-cleared-on-back.html:
+        * storage/hash-change-with-xhr.js:
+        (updateDatabase):
+        (invokeBack):
+        (runTest):
+        (runTestsInner):
+        
+        
 2010-08-13  Sam Weinig  <sam@webkit.org>
 
         Rubber-stamped by Beth Dakin and Ban Bernstein.
index 9e99d47..a2b697f 100644 (file)
@@ -11,6 +11,12 @@ function test()
 {
     if (window.layoutTestController)
         layoutTestController.waitUntilDone();
+
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(runTest, 0);
+}
+
+function runTest() {
     window.location.hash ='#target-01';
     document.body.offsetTop;
     window.history.back(); // This queues up a navigation, so we need to delay the call to notifyDone.
index 305baae..f7ec397 100644 (file)
@@ -3,7 +3,8 @@ function loadNext() {
     var geolocation = navigator.geolocation;
     if (window.opener.reportPageOneOnload() == 1) {
         window.opener.debug('resources/cached-page-1.html about to navigate to resources/cached-page-2.html')
-        location.href = 'cached-page-2.html';
+        // Location changes need to happen outside the onload handler to generate history entries.
+        setTimeout(function() {location.href = 'cached-page-2.html';}, 0);
     }
 }
 </script>
index f7ea76b..b46fb25 100644 (file)
@@ -18,9 +18,12 @@ function runTest() {
       layoutTestController.waitUntilDone();
       layoutTestController.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
     }
-    window.setTimeout("verify()", timeoutValue);
-    timestamp = new Date().getTime();
-    window.location.href = "data:text/html,<body onload='history.back()'></body>";
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {
+      window.setTimeout(verify, timeoutValue);
+      timestamp = new Date().getTime();
+      window.location.href = "data:text/html,<body onload='history.back()'></body>";
+    }, 0);
 }
 
 </script>
index b26e906..f580f52 100644 (file)
@@ -87,8 +87,9 @@
         numErrors = 0;
         originalLocation = window.location.href;
         originalHistoryLength = window.history.length;
-     
-        step();
+
+        // Location changes need to happen outside the onload handler to generate history entries.
+        setTimeout(step, 0);
     }
     </script>
 </head>
index 1ee69a1..94f24e6 100644 (file)
@@ -1,16 +1,16 @@
+CONSOLE MESSAGE: line 20: ***Top level frame being parsed for the initial page load***
+CONSOLE MESSAGE: line 20: Subsubframe window.onload
+CONSOLE MESSAGE: line 20: Subsubframe window.onpageshow, target = [object HTMLDocument], persisted = false
+CONSOLE MESSAGE: line 20: Subframe window.onload
+CONSOLE MESSAGE: line 20: Subframe window.onpageshow, target = [object HTMLDocument], persisted = false
+CONSOLE MESSAGE: line 20: Main frame window.onload
+CONSOLE MESSAGE: line 20: Main frame window.onpageshow, target = [object HTMLDocument], persisted = false
+CONSOLE MESSAGE: line 20: ***Navigating top-level frame to a page that will immediately navigate back to this one***
+CONSOLE MESSAGE: line 20: Main frame window.onpagehide, target = [object HTMLDocument], persisted = true
+CONSOLE MESSAGE: line 20: Subframe window.onpagehide, target = [object HTMLDocument], persisted = true
+CONSOLE MESSAGE: line 20: Subsubframe window.onpagehide, target = [object HTMLDocument], persisted = true
+CONSOLE MESSAGE: line 20: Subsubframe window.onpageshow, target = [object HTMLDocument], persisted = true
+CONSOLE MESSAGE: line 20: Subframe window.onpageshow, target = [object HTMLDocument], persisted = true
+CONSOLE MESSAGE: line 20: Main frame window.onpageshow, target = [object HTMLDocument], persisted = true
 Test pageshow/pagehide event behavior when navigating away from a page with frames, putting the page in the page cache, then back to it.
-***Top level frame being parsed for the initial page load***
-Subsubframe window.onload
-Subsubframe window.onpageshow, target = [object HTMLDocument], persisted = false
-Subframe window.onload
-Subframe window.onpageshow, target = [object HTMLDocument], persisted = false
-Main frame window.onload
-Main frame window.onpageshow, target = [object HTMLDocument], persisted = false
-***Navigating top-level frame to a page that will immediately navigate back to this one***
-Main frame window.onpagehide, target = [object HTMLDocument], persisted = true
-Subframe window.onpagehide, target = [object HTMLDocument], persisted = true
-Subsubframe window.onpagehide, target = [object HTMLDocument], persisted = true
-Subsubframe window.onpageshow, target = [object HTMLDocument], persisted = true
-Subframe window.onpageshow, target = [object HTMLDocument], persisted = true
-Main frame window.onpageshow, target = [object HTMLDocument], persisted = true
 
index 72e1658..489c090 100644 (file)
@@ -14,8 +14,10 @@ if (window.layoutTestController) {
 
 function log(message)
 {
-    var log = document.getElementById("log");
-    log.innerHTML += message + "\n";
+    // Logging to the console instead of the "log" DIV in the DOM because
+    // otherwise we trigger the assert mentioned at http://webkit.org/b/43152
+    // (since we log during pagehide)
+    console.log(message);
 }
 
 log("***Top level frame being parsed for the initial page load***");
@@ -31,7 +33,8 @@ window.onpageshow = function(evt) {
             layoutTestController.notifyDone();
     } else {
         log("***Navigating top-level frame to a page that will immediately navigate back to this one***");
-        window.location.href = "data:text/html,<script>history.back();</scr" + "ipt>";
+        // Location changes need to happen outside the onload handler to generate history entries.
+        setTimeout(function() {window.location.href = "data:text/html,<script>history.back();</scr" + "ipt>";}, 0);
     }
 }
 
index 2f97f7e..4368a49 100644 (file)
@@ -31,7 +31,9 @@
             input.value = "FAIL";
 
             var form = document.getElementById("form");
-            form.submit();
+            
+            // Submit form in a timeout to make sure that we create a new back/forward list item.            
+            setTimeout(function() {form.submit();}, 0);
         }
     </script>
 </head>
index f0099b5..dee5c37 100644 (file)
@@ -38,7 +38,8 @@ if (!state.value) {
     document.getElementById('input2').value = 'value2';
     document.getElementById('textarea2').value = 'good';
     document.getElementById('select2').value = 'BSD';
-    document.getElementById('form2').submit();
+    // Submit form in a timeout to make sure that we create a new back/forward list item.            
+    setTimeout(function() {document.getElementById('form2').submit();}, 0);
 } else {
     // Second visit.
     debug('Controls in the first form should have their default values:');
index e2aa7e9..b3b25bd 100644 (file)
@@ -37,7 +37,8 @@ if (!state.value) {
     makeForm(parent, '1', '1', '1', '1', '1', '1', '1', '1');
 
     document.getElementById('text1').value = 'edit';
-    document.getElementById('form1').submit();
+    // Submit form in a timeout to make sure that we create a new back/forward list item.            
+    setTimeout(function() {document.getElementById('form1').submit();}, 0);
 } else {
     // Second visit.
     makeForm(parent, '2', '2', '2', '2', '2', '2', '2', '2');
index 610c8d4..2715102 100644 (file)
@@ -17,7 +17,8 @@ function loadNext() {
     intervalId = setInterval(endTest, 100);
 
     window.opener.log("page-1, about to navigate to page-2.")
-    location.href = "cached-page-2.html";
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {location.href = "cached-page-2.html";}, 0);
 }
 
 // This unload handler exists just to make sure this page is not added
index fd4f272..b159242 100644 (file)
@@ -19,7 +19,8 @@ function loadNext() {
     intervalId = setInterval(goBack, 20);
 
     window.opener.log("page-2, about to navigate to page-3.")
-    location.href = "cached-page-3.html";
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {location.href = "cached-page-3.html";}, 0);
 }
 </script>
 <body onload="loadNext()">
index 9b66a65..0dbfd4d 100755 (executable)
@@ -22,7 +22,8 @@ function loadNext()
     intervalId = setInterval(check, 10);
 
     window.opener.log("page-1, about to navigate to page-2.")
-    location.href = "cached-page-2.html";
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {location.href = "cached-page-2.html";}, 0);
 }
 </script>
 <body onload="loadNext()"></body>
index f85166d..f20ec0b 100644 (file)
@@ -18,7 +18,8 @@ function loadNext()
     intervalId = setInterval(check, 10);
 
     window.opener.log("page with data urls, about to navigate to page-2.")
-    location.href = "cached-page-2.html";
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {location.href = "cached-page-2.html";}, 0);
 }
 </script>
 <body onload="loadNext()">
diff --git a/LayoutTests/fast/history/gesture-before-onload-form-submit-expected.txt b/LayoutTests/fast/history/gesture-before-onload-form-submit-expected.txt
new file mode 100644 (file)
index 0000000..9f968dc
--- /dev/null
@@ -0,0 +1,9 @@
+This page is the target of a redirect.
+
+PASS: History item count should be 2 and is.
+
+
+============== Back Forward List ==============
+        (file test):fast/history/gesture-before-onload-form-submit.html  **nav target**
+curr->  (file test):fast/history/resources/gesture-before-onload-target.html?#2  **nav target**
+===============================================
diff --git a/LayoutTests/fast/history/gesture-before-onload-form-submit.html b/LayoutTests/fast/history/gesture-before-onload-form-submit.html
new file mode 100644 (file)
index 0000000..85f2688
--- /dev/null
@@ -0,0 +1,30 @@
+<head>
+</head>
+<body onload="onload()">
+  <form action="resources/gesture-before-onload-target.html#2">
+    <input type="submit" id="nav-button" value="Navigate">
+  </form>
+  <div id="manual-explanation" style="display: none; color: blue">When running this test outside of DRT, please click on the "Navigate" button.</div>
+</body>
+<script>
+  if (window.layoutTestController) {
+      layoutTestController.clearBackForwardList();
+      layoutTestController.waitUntilDone();
+  }
+
+  if (window.eventSender) {
+      var navButtonNode = document.getElementById('nav-button');
+      eventSender.mouseMoveTo(
+          navButtonNode.offsetLeft + navButtonNode.offsetWidth / 2,
+          navButtonNode.offsetTop + navButtonNode.offsetHeight / 2);
+      eventSender.mouseDown();
+      eventSender.mouseUp();
+  } else {
+      document.getElementById('manual-explanation').style.display = '';
+  }
+
+  function onload() {
+      window.console.log('FAIL: Should not have reached onload before navigating away');
+  }
+</script>
+
diff --git a/LayoutTests/fast/history/gesture-before-onload-location-href-expected.txt b/LayoutTests/fast/history/gesture-before-onload-location-href-expected.txt
new file mode 100644 (file)
index 0000000..94fea11
--- /dev/null
@@ -0,0 +1,9 @@
+This page is the target of a redirect.
+
+PASS: History item count should be 2 and is.
+
+
+============== Back Forward List ==============
+        (file test):fast/history/gesture-before-onload-location-href.html  **nav target**
+curr->  (file test):fast/history/resources/gesture-before-onload-target.html#2  **nav target**
+===============================================
diff --git a/LayoutTests/fast/history/gesture-before-onload-location-href.html b/LayoutTests/fast/history/gesture-before-onload-location-href.html
new file mode 100644 (file)
index 0000000..560adcb
--- /dev/null
@@ -0,0 +1,32 @@
+<head>
+</head>
+<body onload="onload()">
+  <button id="nav-button" onclick="nav();">Navigate</button>
+  <div id="manual-explanation" style="display: none; color: blue">When running this test outside of DRT, please click on the "Navigate" button.</div>
+</body>
+<script>
+  if (window.layoutTestController) {
+      layoutTestController.clearBackForwardList();
+      layoutTestController.waitUntilDone();
+  }
+
+  if (window.eventSender) {
+      var navButtonNode = document.getElementById('nav-button');
+      eventSender.mouseMoveTo(
+          navButtonNode.offsetLeft + navButtonNode.offsetWidth / 2,
+          navButtonNode.offsetTop + navButtonNode.offsetHeight / 2);
+      eventSender.mouseDown();
+      eventSender.mouseUp();
+  } else {
+      document.getElementById('manual-explanation').style.display = '';
+  }
+
+  function nav() {
+      window.location.href = 'resources/gesture-before-onload-target.html#2';
+  }
+
+  function onload() {
+      window.console.log('FAIL: Should not have reached onload before navigating away');
+  }
+</script>
+
index 4baa7e7..94f507d 100644 (file)
@@ -8,30 +8,34 @@ onload = function() {
       layoutTestController.waitUntilDone();
     }
   }
-  // This test advances history by 2 pages, then navigates back one, and
-  // records history.length.  We expect history.length to indicate the total
-  // length of session history.  At the end of the test, it should be 2 greater
-  // than it was at the start of the test.
-  switch (sessionStorage.testStage++) {
-  case 0:
-    sessionStorage.initialLength = history.length;
-    location = "?a";
-    break;
-  case 1:
-    location = "?b";
-    break;
-  case 2:
-    history.back();
-    break;
-  case 3:
-    if (history.length == (sessionStorage.initialLength - 0) + 2)
-      document.body.innerHTML = "PASS";
-    else
-      document.body.innerHTML = "FAIL: initialLength=" + sessionStorage.initialLength + ", history.length=" + history.length;
-    if (window.layoutTestController)
-      layoutTestController.notifyDone();
-    break;
-  }
+
+  // Location changes need to happen outside the onload handler to generate history entries.
+  setTimeout(function() {
+    // This test advances history by 2 pages, then navigates back one, and
+    // records history.length.  We expect history.length to indicate the total
+    // length of session history.  At the end of the test, it should be 2 greater
+    // than it was at the start of the test.
+    switch (sessionStorage.testStage++) {
+    case 0:
+      sessionStorage.initialLength = history.length;
+      location = "?a";
+      break;
+    case 1:
+      location = "?b";
+      break;
+    case 2:
+      history.back();
+      break;
+    case 3:
+      if (history.length == (sessionStorage.initialLength - 0) + 2)
+        document.body.innerHTML = "PASS";
+      else
+        document.body.innerHTML = "FAIL: initialLength=" + sessionStorage.initialLength + ", history.length=" + history.length;
+      if (window.layoutTestController)
+        layoutTestController.notifyDone();
+      break;
+    }
+  }, 0);
 }
 onunload = function() {
   // disable page cache
diff --git a/LayoutTests/fast/history/resources/gesture-before-onload-target.html b/LayoutTests/fast/history/resources/gesture-before-onload-target.html
new file mode 100644 (file)
index 0000000..2f43ec9
--- /dev/null
@@ -0,0 +1,41 @@
+<!-- This page accepts a query string specifying how many history items should
+be present once it finishes loading. -->
+
+<html>
+<head>
+<title>Redirect Target</title>
+
+<script>
+function log(s)
+{
+    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
+}
+
+function testHistoryItemCount()
+{
+    var expected = parseInt(location.hash.slice(1));
+    var actual = history.length;
+    if (actual === expected)
+        log("PASS: History item count should be " + expected + " and is.");
+    else
+        log("FAIL: History item count should be " + expected + " but instead is " + actual + ".");
+}
+
+window.addEventListener("load", function () {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        testHistoryItemCount();
+        layoutTestController.dumpBackForwardList();
+        layoutTestController.notifyDone();
+    } else {
+        testHistoryItemCount();
+    }
+}, false);
+</script>
+</head>
+
+<body>
+<p>This page is the target of a redirect.</p>
+<pre id="console"></pre>
+</body>
+</html>
index 0644df8..60dec93 100644 (file)
@@ -30,8 +30,11 @@ function runTestStep() {
       layoutTestController.dumpAsText();
       layoutTestController.waitUntilDone();
     }
-    navigateToHash(field);
-    navigateAwayAndBack();
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {
+      navigateToHash(field);
+      navigateAwayAndBack();
+    }, 0);
   } else {
     document.body.innerHTML = (field.value == '') ? 'FAIL' : 'PASS';
     if (window.layoutTestController)
index ee69355..2493272 100644 (file)
@@ -13,8 +13,9 @@ function runTest()
     var input = document.getElementById("testinput");
     input.setAttribute("autocomplete", "on");
     input.parentNode.removeChild(input);
-    
-    window.location = "data:text/html,<script>history.back();</scrip" + "t>";
+
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {window.location = "data:text/html,<script>history.back();</scrip" + "t>";}, 0);
 }
 
 function pageHidden()
index 7dca361..edbb1c2 100644 (file)
@@ -33,9 +33,10 @@ function runThirdStageOfTest()
 
 function loaded()
 {
-    if (!sessionStorage.stage)
-        runFirstStageOfTest();
-    else if (sessionStorage.stage == 2)
+    if (!sessionStorage.stage) {
+        // Location changes need to happen outside the onload handler to generate history entries.
+        setTimeout(runFirstStageOfTest, 0);
+    } else if (sessionStorage.stage == 2)
         runSecondStageOfTest();
     else if (sessionStorage.stage == 3)
         runThirdStageOfTest();
index b08c5a5..bbb4479 100644 (file)
@@ -8,22 +8,26 @@ onload = function() {
       layoutTestController.waitUntilDone();
     }
   }
-  switch (sessionStorage.testStage++) {
-  case 0:
-    location = "?a";
-    break;
-  case 1:
-    location = "?b";
-    break;
-  case 2:
-    history.back();
-    break;
-  case 3:
-    history.pushState(null, null);
-    if (window.layoutTestController)
-      layoutTestController.notifyDone();
-    break;
-  }
+
+  // Location changes need to happen outside the onload handler to generate history entries.
+  setTimeout(function() {
+      switch (sessionStorage.testStage++) {
+      case 0:
+        location = "?a";
+        break;
+      case 1:
+        location = "?b";
+        break;
+      case 2:
+        history.back();
+        break;
+      case 3:
+        history.pushState(null, null);
+        if (window.layoutTestController)
+          layoutTestController.notifyDone();
+        break;
+      }
+    }, 0);
 }
 onunload = function() {
   // disable page cache
index 2852381..2ab12cc 100644 (file)
@@ -9,8 +9,9 @@ function runTest()
         layoutTestController.dumpBackForwardList();
         layoutTestController.waitUntilDone();
     }
-    
-    location='resources/subframe-navigate-during-main-frame-load2.html';
+
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(function() {location='resources/subframe-navigate-during-main-frame-load2.html';}, 0);
 }
 
 </script>
index 884b32b..960b04b 100644 (file)
@@ -14,6 +14,13 @@ Getting an error page instead of login page navigating back in gmail.</p>
 <input id="mysubmit" type="submit" name="Submit" value="Submit">
 </form>
 <script>
+
+function submitForm()
+{
+    // Submit form in a timeout to make sure that we create a new back/forward list item.
+    setTimeout(function() {document.forms[0].submit()}, 0);
+}
+
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
@@ -25,7 +32,7 @@ if (!window.layoutTestController)
 
 if (document.location.search == "") {
     window.name = ""; // Use window.name to communicate between steps.
-    document.forms[0].submit();
+    submitForm();
 } else if (document.location.search == "?1") {
     if (window.name == "finish") {
         window.name = "";
@@ -34,7 +41,7 @@ if (document.location.search == "") {
             layoutTestController.notifyDone();
     } else {
         document.forms[0].action = "?2";
-        document.forms[0].submit();
+        submitForm();
     }
 } else {
     // Test that going back to form submission result works.
index db2340e..9f0bf3d 100755 (executable)
@@ -12,7 +12,7 @@ print <<HERE_DOC_END
 <title>200 Refresh Redirect</title>
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index 734443a..f11cb6b 100755 (executable)
@@ -12,7 +12,7 @@ print <<HERE_DOC_END
 <title>200 Refresh Redirect</title>
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index 062b69b..77a6ef6 100644 (file)
@@ -1,8 +1,9 @@
 This page is the target of a redirect.
 
-PASS: History item count should be 1 and is.
+PASS: History item count should be 2 and is.
 
 
 ============== Back Forward List ==============
-curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
+        http://127.0.0.1:8000/history/redirect-301.html  **nav target**
+curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#2  **nav target**
 ===============================================
diff --git a/LayoutTests/http/tests/history/redirect-301.html b/LayoutTests/http/tests/history/redirect-301.html
new file mode 100644 (file)
index 0000000..43f9520
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>301 Redirect</title>
+<script>
+  function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.clearBackForwardList();
+        layoutTestController.waitUntilDone();
+    }
+    window.setTimeout(function() {window.location = 'resources/redirect-helper.pl?301';}, 0);
+  }
+</script>
+
+<body onload="runTest()">This page is a 301 redirect.</body>
+</html>
diff --git a/LayoutTests/http/tests/history/redirect-301.pl b/LayoutTests/http/tests/history/redirect-301.pl
deleted file mode 100755 (executable)
index f0f15ec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/perl
-# Script to generate a 301 HTTP redirect
-
-print "Status: 301 Moved Permanently\r\n";
-print "Location: resources/redirect-target.html#1\r\n";
-print "Content-type: text/html\r\n";
-print "\r\n";
-
-print <<HERE_DOC_END
-<html>
-<head>
-<title>301 Redirect</title>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
-    layoutTestController.waitUntilDone();
-}
-</script>
-
-<body>This page is a 301 redirect.</body>
-</html>
-HERE_DOC_END
index 062b69b..4d69275 100644 (file)
@@ -1,8 +1,9 @@
 This page is the target of a redirect.
 
-PASS: History item count should be 1 and is.
+PASS: History item count should be 2 and is.
 
 
 ============== Back Forward List ==============
-curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
+        http://127.0.0.1:8000/history/redirect-302.html  **nav target**
+curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#2  **nav target**
 ===============================================
diff --git a/LayoutTests/http/tests/history/redirect-302.html b/LayoutTests/http/tests/history/redirect-302.html
new file mode 100755 (executable)
index 0000000..e83c792
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>302 Redirect</title>
+<script>
+  function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.clearBackForwardList();
+        layoutTestController.waitUntilDone();
+    }
+    window.setTimeout(function() {window.location = 'resources/redirect-helper.pl?302';}, 0);
+  }
+</script>
+
+<body onload="runTest()">This page is a 302 redirect.</body>
+</html>
diff --git a/LayoutTests/http/tests/history/redirect-302.pl b/LayoutTests/http/tests/history/redirect-302.pl
deleted file mode 100755 (executable)
index e06310f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/perl
-# Script to generate a 302 HTTP redirect
-
-print "Status: 302 Moved Temporarily\r\n";
-print "Location: resources/redirect-target.html#1\r\n";
-print "Content-type: text/html\r\n";
-print "\r\n";
-
-print <<HERE_DOC_END
-<html>
-<head>
-<title>302 Redirect</title>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
-    layoutTestController.waitUntilDone();
-}
-</script>
-
-<body>This page is a 302 redirect.</body>
-</html>
-HERE_DOC_END
index 062b69b..9d7e86e 100644 (file)
@@ -1,8 +1,9 @@
 This page is the target of a redirect.
 
-PASS: History item count should be 1 and is.
+PASS: History item count should be 2 and is.
 
 
 ============== Back Forward List ==============
-curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
+        http://127.0.0.1:8000/history/redirect-303.html  **nav target**
+curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#2  **nav target**
 ===============================================
diff --git a/LayoutTests/http/tests/history/redirect-303.html b/LayoutTests/http/tests/history/redirect-303.html
new file mode 100755 (executable)
index 0000000..1107adb
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>303 Redirect</title>
+<script>
+  function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.clearBackForwardList();
+        layoutTestController.waitUntilDone();
+    }
+    window.setTimeout(function() {window.location = 'resources/redirect-helper.pl?303';}, 0);
+  }
+</script>
+
+<body onload="runTest()">This page is a 303 redirect.</body>
+</html>
diff --git a/LayoutTests/http/tests/history/redirect-303.pl b/LayoutTests/http/tests/history/redirect-303.pl
deleted file mode 100755 (executable)
index c7891bf..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/perl
-# Script to generate a 303 HTTP redirect
-
-print "Status: 303 See Other\r\n";
-print "Location: resources/redirect-target.html#1\r\n";
-print "Content-type: text/html\r\n";
-print "\r\n";
-
-print <<HERE_DOC_END
-<html>
-<head>
-<title>303 Redirect</title>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
-    layoutTestController.waitUntilDone();
-}
-</script>
-
-<body>This page is a 303 redirect.</body>
-</html>
-HERE_DOC_END
index 062b69b..721ed2e 100644 (file)
@@ -1,8 +1,9 @@
 This page is the target of a redirect.
 
-PASS: History item count should be 1 and is.
+PASS: History item count should be 2 and is.
 
 
 ============== Back Forward List ==============
-curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
+        http://127.0.0.1:8000/history/redirect-307.html  **nav target**
+curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#2  **nav target**
 ===============================================
diff --git a/LayoutTests/http/tests/history/redirect-307.html b/LayoutTests/http/tests/history/redirect-307.html
new file mode 100755 (executable)
index 0000000..c34ca77
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>307 Redirect</title>
+<script>
+  function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.clearBackForwardList();
+        layoutTestController.waitUntilDone();
+    }
+    window.setTimeout(function() {window.location = 'resources/redirect-helper.pl?307';}, 0);
+  }
+</script>
+
+<body onload="runTest()">This page is a 307 redirect.</body>
+</html>
diff --git a/LayoutTests/http/tests/history/redirect-307.pl b/LayoutTests/http/tests/history/redirect-307.pl
deleted file mode 100755 (executable)
index c44db9e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/perl
-# Script to generate a 307 HTTP redirect
-
-print "Status: 307 Moved Temporarily\r\n";
-print "Location: resources/redirect-target.html#1\r\n";
-print "Content-type: text/html\r\n";
-print "\r\n";
-
-print <<HERE_DOC_END
-<html>
-<head>
-<title>307 Redirect</title>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
-    layoutTestController.waitUntilDone();
-}
-</script>
-</head>
-
-<body>This page is a 307 redirect.</body>
-</html>
-HERE_DOC_END
index 513305b..0ce306e 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { document.location = "resources/redirect-target.html#1"; }, 0);
index f175e51..99ba397 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { document.location = "resources/redirect-target.html#1"; }, 2000);
index efbe835..062b69b 100644 (file)
@@ -1,9 +1,8 @@
 This page is the target of a redirect.
 
-FAIL: History item count should be 1 but instead is 2.
+PASS: History item count should be 1 and is.
 
 
 ============== Back Forward List ==============
-        http://127.0.0.1:8000/history/redirect-js-document-location-before-load.html  **nav target**
 curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
 ===============================================
index f6240eb..26b0c57 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 document.location = "resources/redirect-target.html#1";
index d62c631..cf46247 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index a49b51d..eafde40 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index 759b4c8..4cba496 100644 (file)
@@ -1,9 +1,8 @@
 This page is the target of a redirect.
 
-FAIL: History item count should be 1 but instead is 2.
+PASS: History item count should be 1 and is.
 
 
 ============== Back Forward List ==============
-        http://127.0.0.1:8000/history/redirect-js-form-submit-before-load.html  **nav target**
 curr->  http://127.0.0.1:8000/history/resources/redirect-target.html?#1  **nav target**
 ===============================================
index c336b7a..bca6d77 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index 3259d64..1fd7b6f 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location = "resources/redirect-target.html#1"; }, 0);
index 4b1e76c..ab05ba4 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location = "resources/redirect-target.html#1"; }, 2000);
index 5c0bd67..07bf3aa 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.assign("resources/redirect-target.html#1"); }, 0);
index c8b2e28..6499aff 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.assign("resources/redirect-target.html#1"); }, 2000);
index 42a1259..062b69b 100644 (file)
@@ -1,9 +1,8 @@
 This page is the target of a redirect.
 
-FAIL: History item count should be 1 but instead is 2.
+PASS: History item count should be 1 and is.
 
 
 ============== Back Forward List ==============
-        http://127.0.0.1:8000/history/redirect-js-location-assign-before-load.html  **nav target**
 curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
 ===============================================
index 7717b04..75173ec 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 location.assign("resources/redirect-target.html#1");
index b6daf9e..062b69b 100644 (file)
@@ -1,9 +1,8 @@
 This page is the target of a redirect.
 
-FAIL: History item count should be 1 but instead is 2.
+PASS: History item count should be 1 and is.
 
 
 ============== Back Forward List ==============
-        http://127.0.0.1:8000/history/redirect-js-location-before-load.html  **nav target**
 curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
 ===============================================
index 722c75b..fe204df 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 location = "resources/redirect-target.html#1";
index 3e84d1e..104d0e5 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.href = "resources/redirect-target.html#1"; }, 0);
index 8083185..299a449 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.href = "resources/redirect-target.html#1"; }, 2000);
index 3cc9c6b..062b69b 100644 (file)
@@ -1,9 +1,8 @@
 This page is the target of a redirect.
 
-FAIL: History item count should be 1 but instead is 2.
+PASS: History item count should be 1 and is.
 
 
 ============== Back Forward List ==============
-        http://127.0.0.1:8000/history/redirect-js-location-href-before-load.html  **nav target**
 curr->  http://127.0.0.1:8000/history/resources/redirect-target.html#1  **nav target**
 ===============================================
index b963ccd..6862ed5 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 location.href = "resources/redirect-target.html#1";
index 05c0ca4..9a7057b 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.replace("resources/redirect-target.html#1"); }, 0);
index 2c31588..0fa448e 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 setTimeout(function () { location.replace("resources/redirect-target.html#1"); }, 2000);
index 32266a6..33d5ea0 100644 (file)
@@ -4,7 +4,7 @@
 
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 location.replace("resources/redirect-target.html#1");
index 6e78ec5..0f0e171 100644 (file)
@@ -4,7 +4,7 @@
 <title>Meta Refresh Redirect</title>
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
index b9f6549..e8d7833 100644 (file)
@@ -4,7 +4,7 @@
 <title>Meta Refresh Redirect</title>
 <script>
 if (window.layoutTestController) {
-    layoutTestController.keepWebHistory();
+    layoutTestController.clearBackForwardList();
     layoutTestController.waitUntilDone();
 }
 </script>
diff --git a/LayoutTests/http/tests/history/resources/redirect-helper.pl b/LayoutTests/http/tests/history/resources/redirect-helper.pl
new file mode 100755 (executable)
index 0000000..80f2e7d
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+# Script to generate a 30x HTTP redirect (determined by the query parameter)
+
+$REDIRECT_CODE = $ENV{'QUERY_STRING'} || '301';
+
+$STATUS_TEXTS = {
+  '301' => 'Moved Permanently',
+  '302' => 'Moved Temporarily',
+  '303' => 'See Other',
+  '307' => 'Moved Temporarily'
+};
+
+print "Status: $REDIRECT_CODE $STATUS_TEXTS{$REDIRECT_CODE}\r\n";
+print "Location: redirect-target.html#2\r\n";
+print "Content-type: text/html\r\n";
+print "\r\n";
+
+print <<HERE_DOC_END
+<html>
+<head>
+<title>$REDIRECT_CODE Redirect</title>
+
+<body>This page is a $REDIRECT_CODE redirect.</body>
+</html>
+HERE_DOC_END
index b3ea4ee..92059ae 100644 (file)
@@ -14,7 +14,7 @@ function log(s)
 function testHistoryItemCount()
 {
     var expected = parseInt(location.hash.slice(1));
-    var actual = layoutTestController.webHistoryItemCount + 1; // Add one to include the referring page, which loaded before we started recording history.
+    var actual = history.length;
     if (actual === expected)
         log("PASS: History item count should be " + expected + " and is.");
     else
index a0ad674..cf00ef8 100644 (file)
@@ -1,6 +1,7 @@
 main frame - didStartProvisionalLoadForFrame
 main frame - didCommitLoadForFrame
 main frame - didFinishDocumentLoadForFrame
+main frame - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/post-to-303-target.php 
 main frame - didHandleOnloadEventsForFrame
 main frame - didFinishLoadForFrame
 <unknown> - didFinishLoading
@@ -11,6 +12,7 @@ main frame - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, main document URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/303-to-307-target.php, http status code 307>
 main frame - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http status code 200>
+main frame - didCancelClientRedirectForFrame
 main frame - didCommitLoadForFrame
 main frame - didFinishDocumentLoadForFrame
 main frame - didHandleOnloadEventsForFrame
index 8ada636..049f4be 100644 (file)
@@ -19,6 +19,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveR
 frame "0" - didCancelClientRedirectForFrame
 frame "0" - didCommitLoadForFrame
 frame "0" - didFinishDocumentLoadForFrame
+frame "0" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-result.php 
 frame "0" - didHandleOnloadEventsForFrame
 frame "0" - didFinishLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
@@ -27,6 +28,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRe
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 301>
 frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "0" - didCancelClientRedirectForFrame
 frame "0" - didCommitLoadForFrame
 frame "0" - didFinishDocumentLoadForFrame
 frame "1" - didStartProvisionalLoadForFrame
@@ -47,6 +49,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveR
 frame "1" - didCancelClientRedirectForFrame
 frame "1" - didCommitLoadForFrame
 frame "1" - didFinishDocumentLoadForFrame
+frame "1" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-result.php 
 frame "1" - didHandleOnloadEventsForFrame
 frame "1" - didFinishLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
@@ -55,6 +58,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRe
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 302>
 frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "1" - didCancelClientRedirectForFrame
 frame "1" - didCommitLoadForFrame
 frame "1" - didFinishDocumentLoadForFrame
 frame "2" - didStartProvisionalLoadForFrame
@@ -75,6 +79,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveR
 frame "2" - didCancelClientRedirectForFrame
 frame "2" - didCommitLoadForFrame
 frame "2" - didFinishDocumentLoadForFrame
+frame "2" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-result.php 
 frame "2" - didHandleOnloadEventsForFrame
 frame "2" - didFinishLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
@@ -83,6 +88,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRe
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 303>
 frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "2" - didCancelClientRedirectForFrame
 frame "2" - didCommitLoadForFrame
 frame "2" - didFinishDocumentLoadForFrame
 frame "3" - didStartProvisionalLoadForFrame
@@ -103,6 +109,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveR
 frame "3" - didCancelClientRedirectForFrame
 frame "3" - didCommitLoadForFrame
 frame "3" - didFinishDocumentLoadForFrame
+frame "3" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-result.php 
 frame "3" - didHandleOnloadEventsForFrame
 frame "3" - didFinishLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
@@ -111,6 +118,7 @@ http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRe
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 307>
 frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "3" - didCancelClientRedirectForFrame
 frame "3" - didCommitLoadForFrame
 frame "3" - didFinishDocumentLoadForFrame
 frame "3" - didHandleOnloadEventsForFrame
index bf629ef..b54956a 100644 (file)
@@ -18,8 +18,8 @@ window.name: <script>document.write(window.name)</script>
 
 <script>
     if (window.name == 1) {
-        // Navigate once more to add a history entry.
-        document.loopback.submit();
+        // Navigate once more (in a timeout) to add a history entry.
+        setTimeout(function() {document.loopback.submit();}, 0);
     } else if (window.name == 2) {
         history.go(-1);
     } else {
index 1db48cd..a0ab4d8 100644 (file)
@@ -7,7 +7,8 @@ function start() {
       layoutTestController.dumpAsText();
       layoutTestController.waitUntilDone();
 
-      runTest();
+      // Location changes need to happen outside the onload handler to generate history entries.
+      setTimeout(runTest, 0);
     } else {
       // loaded the ?1 navigation
       layoutTestController.notifyDone();
index 30bf156..97ee97b 100755 (executable)
@@ -22,7 +22,8 @@ onload = function() {
   alert("stage: " + sessionStorage.stage);
   switch (sessionStorage.stage++) {
   case 1:
-    document.forms[0].submit();
+    // Submit form in a timeout to make sure that we create a new back/forward list item.
+    setTimeout(function() {document.forms[0].submit();}, 0);
     break;
   case 2:
     history.back();
index 0801881..96c9d81 100644 (file)
@@ -19,7 +19,8 @@ function runTest()
     if (!sessionStorage.secondPageReached) {
         document.getElementById("firstInput").value = "SuperSeekritValue";
         document.getElementById("secondInput").value = "SuperSeekritValue";
-        window.location = "resources/autocomplete-cleared-on-back2.html";
+        // Location changes need to happen outside the onload handler to generate history entries.
+        setTimeout(function() {window.location = "resources/autocomplete-cleared-on-back2.html";}, 0);
         return;
     }
     
index 4290681..7f56f79 100644 (file)
@@ -81,6 +81,12 @@ function invokeBack()
 
 function runTest()
 {
+    // Location changes need to happen outside the onload handler to generate history entries.
+    setTimeout(runTestsInner, 0);
+}
+
+function runTestsInner()
+{
     backIterations = 10;
     consecutiveFailures = 0;
     successes = 0;
index 0910284..b820ecf 100644 (file)
@@ -1,3 +1,37 @@
+2010-08-13  Mihai Parparita  <mihaip@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Session history should skip over JS redirects
+        https://bugs.webkit.org/show_bug.cgi?id=42861
+        
+        Lock the back/forward list for location changes and form submits that
+        happen before the onload event fires that are not the result of user
+        gestures.
+        
+        Made form submission (at the ScheduledFormSubmission level) more similar
+        to ScheduledURLNavigation by having it call clientRedirected too, fixing
+        a long-standing FIXME.
+
+        Test: fast/history/gesture-before-onload-location-href.html,
+        fast/history/gesture-before-onload-form-submit.html and updated
+        expectations for http/tests/history tests that used to fail.
+
+        * loader/FormSubmission.cpp:
+        (WebCore::FormSubmission::requestURL): 
+        (WebCore::FormSubmission::populateFrameLoadRequest):
+        * loader/FormSubmission.h:
+        * loader/RedirectScheduler.cpp:
+        (WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
+        (WebCore::ScheduledFormSubmission::fire):
+        (WebCore::ScheduledFormSubmission::didStartTimer):
+        (WebCore::ScheduledFormSubmission::didStopTimer):
+        (WebCore::RedirectScheduler::scheduleRedirect):
+        (WebCore::RedirectScheduler::mustLockBackForwardList):
+        (WebCore::RedirectScheduler::scheduleLocationChange):
+        (WebCore::RedirectScheduler::scheduleFormSubmission):
+        * loader/RedirectScheduler.h:
+
 2010-08-13  Leandro Pereira  <leandro@profusion.mobi>
 
         [EFL] Unreviewed build fix.
index f661273..22e89d7 100644 (file)
@@ -179,6 +179,16 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
     return adoptRef(new FormSubmission(attributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event));
 }
 
+KURL FormSubmission::requestURL() const
+{
+    if (m_method == FormSubmission::PostMethod)
+        return m_action;
+
+    KURL requestURL(m_action);
+    requestURL.setQuery(m_formData->flattenToString());    
+    return requestURL;
+}
+
 void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
 {
     if (!m_target.isEmpty())
@@ -187,9 +197,7 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
     if (!m_referrer.isEmpty())
         frameRequest.resourceRequest().setHTTPReferrer(m_referrer);
 
-    if (m_method == FormSubmission::GetMethod)
-        m_action.setQuery(m_formData->flattenToString());
-    else {
+    if (m_method == FormSubmission::PostMethod) {
         frameRequest.resourceRequest().setHTTPMethod("POST");
         frameRequest.resourceRequest().setHTTPBody(m_formData);
 
@@ -200,7 +208,7 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
             frameRequest.resourceRequest().setHTTPContentType(m_contentType + "; boundary=" + m_boundary);
     }
 
-    frameRequest.resourceRequest().setURL(m_action);
+    frameRequest.resourceRequest().setURL(requestURL());
     FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), m_origin);
 }
 
index bee4e71..b935882 100644 (file)
@@ -85,6 +85,8 @@ public:
     static PassRefPtr<FormSubmission> create(HTMLFormElement*, const Attributes&, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger);
 
     void populateFrameLoadRequest(FrameLoadRequest&);
+    
+    KURL requestURL() const;
 
     Method method() const { return m_method; }
     const KURL& action() const { return m_action; }
index 3cfe61a..aa02c30 100644 (file)
@@ -175,15 +175,13 @@ public:
     ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList, bool duringLoad)
         : ScheduledNavigation(0, submission->lockHistory(), lockBackForwardList, duringLoad, true)
         , m_submission(submission)
-        , m_wasProcessingUserGesture(UserGestureIndicator::processingUserGesture())
+        , m_haveToldClient(false)
     {
         ASSERT(m_submission->state());
     }
 
     virtual void fire(Frame* frame)
     {
-        UserGestureIndicator gestureIndicator(m_wasProcessingUserGesture ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
-
         // The submitForm function will find a target frame before using the redirection timer.
         // Now that the timer has fired, we need to repeat the security check which normally is done when
         // selecting a target, in case conditions have changed. Other code paths avoid this by targeting
@@ -194,15 +192,25 @@ public:
         m_submission->populateFrameLoadRequest(frameRequest);
         frame->loader()->loadFrameRequest(frameRequest, lockHistory(), lockBackForwardList(), m_submission->event(), m_submission->state(), SendReferrer);
     }
+    
+    virtual void didStartTimer(Frame* frame, Timer<RedirectScheduler>* timer)
+    {
+        if (m_haveToldClient)
+            return;
+        m_haveToldClient = true;
+        frame->loader()->clientRedirected(m_submission->requestURL(), delay(), currentTime() + timer->nextFireInterval(), lockBackForwardList());
+    }
 
-    // FIXME: Implement didStartTimer? It would make sense to report form
-    // submissions as client redirects too. But we didn't do that in the past
-    // when form submission used a separate delay mechanism, so doing it will
-    // be a behavior change.
+    virtual void didStopTimer(Frame* frame, bool newLoadInProgress)
+    {
+        if (!m_haveToldClient)
+            return;
+        frame->loader()->clientRedirectCancelledOrFinished(newLoadInProgress);
+    }
 
 private:
     RefPtr<FormSubmission> m_submission;
-    bool m_wasProcessingUserGesture;
+    bool m_haveToldClient;
 };
 
 RedirectScheduler::RedirectScheduler(Frame* frame)
@@ -240,17 +248,21 @@ void RedirectScheduler::scheduleRedirect(double delay, const String& url)
     if (url.isEmpty())
         return;
 
-    // We want a new history item if the refresh timeout is > 1 second.
+    // We want a new back/forward list item if the refresh timeout is > 1 second.
     if (!m_redirect || delay <= m_redirect->delay())
         schedule(new ScheduledRedirect(delay, url, true, delay <= 1, false));
 }
 
-bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame)
+bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame, bool wasUserGesture)
 {
+    // Non-user navigation before the page has loaded should not create a new back/forward item.
+    // See https://webkit.org/b/42861 for the original motivation for this.    
+    if (!wasUserGesture && targetFrame->loader()->documentLoader() && targetFrame->loader()->documentLoader()->isLoadingInAPISense())
+        return true;
+    
     // Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item.
     // The definition of "during load" is any time before all handlers for the load event have been run.
     // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this.
-
     for (Frame* ancestor = targetFrame->tree()->parent(); ancestor; ancestor = ancestor->tree()->parent()) {
         Document* document = ancestor->document();
         if (!ancestor->loader()->isComplete() || (document && document->processingLoadEvent()))
@@ -266,7 +278,7 @@ void RedirectScheduler::scheduleLocationChange(const String& url, const String&
     if (url.isEmpty())
         return;
 
-    lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame);
+    lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame, wasUserGesture);
 
     FrameLoader* loader = m_frame->loader();
     
@@ -300,7 +312,7 @@ void RedirectScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submis
     // to match IE and Opera.
     // See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this.
 
-    bool lockBackForwardList = mustLockBackForwardList(m_frame) || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
+    bool lockBackForwardList = mustLockBackForwardList(m_frame, UserGestureIndicator::processingUserGesture()) || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
 
     schedule(new ScheduledFormSubmission(submission, lockBackForwardList, duringLoad));
 }
index 0203e08..70b0202 100644 (file)
@@ -70,7 +70,7 @@ private:
     void timerFired(Timer<RedirectScheduler>*);
     void schedule(PassOwnPtr<ScheduledNavigation>);
 
-    static bool mustLockBackForwardList(Frame* targetFrame);
+    static bool mustLockBackForwardList(Frame* targetFrame, bool mustLockIfDuringLoad);
 
     Frame* m_frame;
     Timer<RedirectScheduler> m_timer;
@@ -79,4 +79,4 @@ private:
 
 } // namespace WebCore
 
-#endif // FrameLoader_h
+#endif // RedirectScheduler_h