2011-05-16 Ian Henderson <ianh@apple.com>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 May 2011 00:50:20 +0000 (00:50 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 May 2011 00:50:20 +0000 (00:50 +0000)
        Reviewed by Joseph Pecoraro.

        Page::goToItem doesn't work while loading is deferred
        https://bugs.webkit.org/show_bug.cgi?id=60412

        * loader/navigation-while-deferring-loads-expected.txt: Added.
        * loader/navigation-while-deferring-loads.html: Added.
        * platform/gtk/Skipped:
        * platform/qt/Skipped:
        * platform/win/Skipped:
2011-05-16  Ian Henderson  <ianh@apple.com>

        Reviewed by Joseph Pecoraro.

        Page::goToItem doesn't work while loading is deferred
        https://bugs.webkit.org/show_bug.cgi?id=60412

        If goToItem is called while loading is deferred, save the arguments
        and try again later instead of doing nothing.

        Test: loader/navigation-while-deferring-loads.html

        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::setDefersLoading):
        Pipe the "defersLoading" state into HistoryController.
        * loader/HistoryController.cpp:
        (WebCore::HistoryController::HistoryController):
        (WebCore::HistoryController::goToItem):
        Save the HistoryItem and FrameLoadType if loading is deferred.
        (WebCore::HistoryController::setDefersLoading):
        If we have a saved HistoryItem after resuming, try going to it.
        * loader/HistoryController.h:
        * page/Page.cpp:
        (WebCore::Page::goToItem):
        No longer bail early if loading is deferred, since HistoryController
        now handles this case.
2011-05-16  Ian Henderson  <ianh@apple.com>

        Reviewed by Joseph Pecoraro.

        Page::goToItem doesn't work while loading is deferred
        https://bugs.webkit.org/show_bug.cgi?id=60412

        Add setDefersLoading and goBack methods to LayoutTestController.  We
        need to use goBack() instead of history.back() because the latter goes
        through NavigationScheduler, hence doesn't exhibit the bug.

        * DumpRenderTree/LayoutTestController.cpp:
        (goBackCallback):
        (setDefersLoadingCallback):
        (LayoutTestController::staticFunctions):
        * DumpRenderTree/LayoutTestController.h:
        * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
        (LayoutTestController::goBack):
        (LayoutTestController::setDefersLoading):
        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
        (LayoutTestController::goBack):
        (LayoutTestController::setDefersLoading):
        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
        (LayoutTestController::goBack):
        (LayoutTestController::setDefersLoading):
        * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
        (LayoutTestController::goBack):
        (LayoutTestController::setDefersLoading):

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/loader/navigation-while-deferring-loads-expected.txt [new file with mode: 0644]
LayoutTests/loader/navigation-while-deferring-loads.html [new file with mode: 0644]
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/qt/Skipped
LayoutTests/platform/win/Skipped
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/HistoryController.cpp
Source/WebCore/loader/HistoryController.h
Source/WebCore/page/Page.cpp
Tools/ChangeLog
Tools/DumpRenderTree/LayoutTestController.cpp
Tools/DumpRenderTree/LayoutTestController.h
Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm
Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp
Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp

index 9b88f17..f580576 100644 (file)
@@ -1,3 +1,16 @@
+2011-05-16  Ian Henderson  <ianh@apple.com>
+
+        Reviewed by Joseph Pecoraro.
+
+        Page::goToItem doesn't work while loading is deferred
+        https://bugs.webkit.org/show_bug.cgi?id=60412
+
+        * loader/navigation-while-deferring-loads-expected.txt: Added.
+        * loader/navigation-while-deferring-loads.html: Added.
+        * platform/gtk/Skipped:
+        * platform/qt/Skipped:
+        * platform/win/Skipped:
+
 2011-05-16  Andrew Scherkus  <scherkus@chromium.org>
 
         Unreviewed, checking in new baselines for media/video-canvas-alpha.html for chromium-gpu-{linux,win}.
diff --git a/LayoutTests/loader/navigation-while-deferring-loads-expected.txt b/LayoutTests/loader/navigation-while-deferring-loads-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/loader/navigation-while-deferring-loads.html b/LayoutTests/loader/navigation-while-deferring-loads.html
new file mode 100644 (file)
index 0000000..42172fb
--- /dev/null
@@ -0,0 +1,23 @@
+<html>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+function run() {
+    if (history.length > 1) {
+        document.body.innerHTML = 'PASS';
+        if (window.layoutTestController)
+          layoutTestController.notifyDone();
+        return;
+    }
+    var evt = document.createEvent("MouseEvents"); 
+    evt.initMouseEvent("click", true, true, window,
+      0, 0, 0, 0, 0, false, false, false, false, 0, null); 
+    document.getElementById('anchor').dispatchEvent(evt);
+}
+</script>
+<body onload='run()'>
+    <a id='anchor' href='data:text/html,<script>function deferCallbacks(defer){layoutTestController.setDefersLoading(defer)}</script><body onload="if(window.layoutTestController){deferCallbacks(true);layoutTestController.goBack();deferCallbacks(false)}">FAIL</body>'>go to second page</a>
+</body>
+</html>
index 0ee13fa..90f1f99 100644 (file)
@@ -206,6 +206,9 @@ BUGCR61676 SKIP : storage/storageinfo-query-usage.html = FAIL
 // Animation API is disabled
 WONTFIX SKIP : animations/animation-api-1.html = FAIL
 
+// Unskip after implementing LayoutTestController::setDefersLoading and ::goBack.
+BUGWK60877 SKIP : loader/navigation-while-deferring-loads.html = FAIL
+
 // -----------------------------------------------------------------
 // WONTFIX TESTS
 // -----------------------------------------------------------------
index 36b401c..3e4a8ed 100644 (file)
@@ -1421,6 +1421,9 @@ tables/mozilla_expected_failures/bugs/bug85016.html
 # https://bugs.webkit.org/show_bug.cgi?id=60206
 http/tests/navigation/response204.html
 
+# Unskip after implementing LayoutTestController::setDefersLoading and ::goBack.
+loader/navigation-while-deferring-loads.html
+
 # This platform does not support the Page Visibility API.
 fast/events/page-visibility-iframe-delete-test.html
 fast/events/page-visibility-iframe-move-test.html
index 9f1264d..18989d5 100644 (file)
@@ -2591,6 +2591,9 @@ fast/events/page-visibility-transition-test.html
 http/tests/inspector/network/download.html
 http/tests/inspector/network/x-frame-options-deny.html
 
+# Unskip after implementing LayoutTestController::setDefersLoading and ::goBack.
+loader/navigation-while-deferring-loads.html
+
 # [Qt] fast/events/backspace-nagivates-back fails on Qt bots (Mac and Linux)
 # https://bugs.webkit.org/show_bug.cgi?id=60311
 fast/events/backspace-navigates-back.html
index 05958fa..fdccf49 100644 (file)
@@ -1295,3 +1295,6 @@ fast/events/page-visibility-iframe-delete-test.html
 fast/events/page-visibility-iframe-move-test.html
 fast/events/page-visibility-iframe-propagation-test.html
 fast/events/page-visibility-transition-test.html
+
+# Unskip after implementing LayoutTestController::setDefersLoading and ::goBack.
+loader/navigation-while-deferring-loads.html
index 0795394..c1c383e 100644 (file)
@@ -1,3 +1,30 @@
+2011-05-16  Ian Henderson  <ianh@apple.com>
+
+        Reviewed by Joseph Pecoraro.
+
+        Page::goToItem doesn't work while loading is deferred
+        https://bugs.webkit.org/show_bug.cgi?id=60412
+
+        If goToItem is called while loading is deferred, save the arguments
+        and try again later instead of doing nothing.
+
+        Test: loader/navigation-while-deferring-loads.html
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::setDefersLoading):
+        Pipe the "defersLoading" state into HistoryController.
+        * loader/HistoryController.cpp:
+        (WebCore::HistoryController::HistoryController):
+        (WebCore::HistoryController::goToItem):
+        Save the HistoryItem and FrameLoadType if loading is deferred.
+        (WebCore::HistoryController::setDefersLoading):
+        If we have a saved HistoryItem after resuming, try going to it.
+        * loader/HistoryController.h:
+        * page/Page.cpp:
+        (WebCore::Page::goToItem):
+        No longer bail early if loading is deferred, since HistoryController
+        now handles this case.
+
 2011-05-16  Andrew Wilson  <atwilson@chromium.org>
 
         Unreviewed, rolling out r86625.
index f5bc94d..a6e6a95 100644 (file)
@@ -252,6 +252,7 @@ void FrameLoader::setDefersLoading(bool defers)
         m_provisionalDocumentLoader->setDefersLoading(defers);
     if (m_policyDocumentLoader)
         m_policyDocumentLoader->setDefersLoading(defers);
+    history()->setDefersLoading(defers);
 
     if (!defers) {
         m_frame->navigationScheduler()->startTimer();
index e7e1d61..84503c7 100644 (file)
@@ -68,6 +68,7 @@ static inline void addVisitedLink(Page* page, const KURL& url)
 HistoryController::HistoryController(Frame* frame)
     : m_frame(frame)
     , m_frameLoadComplete(true)
+    , m_defersLoading(false)
 {
 }
 
@@ -248,6 +249,11 @@ void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
         return;
     if (!m_frame->loader()->client()->shouldGoToHistoryItem(targetItem))
         return;
+    if (m_defersLoading) {
+        m_deferredItem = targetItem;
+        m_deferredFrameLoadType = type;
+        return;
+    }
 
     // Set the BF cursor before commit, which lets the user quickly click back/forward again.
     // - plus, it only makes sense for the top level of the operation through the frametree,
@@ -265,6 +271,15 @@ void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
     recursiveGoToItem(targetItem, currentItem.get(), type);
 }
 
+void HistoryController::setDefersLoading(bool defer)
+{
+    m_defersLoading = defer;
+    if (!defer && m_deferredItem) {
+        goToItem(m_deferredItem.get(), m_deferredFrameLoadType);
+        m_deferredItem = 0;
+    }
+}
+
 void HistoryController::updateForBackForwardNavigation()
 {
 #if !LOG_DISABLED
index 9be7410..3b31e92 100644 (file)
@@ -84,6 +84,8 @@ public:
     void pushState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url);
     void replaceState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url);
 
+    void setDefersLoading(bool);
+
 private:
     friend class Page;
     bool shouldStopLoadingForHistoryItem(HistoryItem*) const;
@@ -110,6 +112,10 @@ private:
     RefPtr<HistoryItem> m_provisionalItem;
 
     bool m_frameLoadComplete;
+
+    bool m_defersLoading;
+    RefPtr<HistoryItem> m_deferredItem;
+    FrameLoadType m_deferredFrameLoadType;
 };
 
 } // namespace WebCore
index f07591b..24bd325 100644 (file)
@@ -338,9 +338,6 @@ void Page::goBackOrForward(int distance)
 
 void Page::goToItem(HistoryItem* item, FrameLoadType type)
 {
-    if (defersLoading())
-        return;
-
     // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
     // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
     RefPtr<HistoryItem> protector(item);
index f27b7b6..c026744 100644 (file)
@@ -1,3 +1,32 @@
+2011-05-16  Ian Henderson  <ianh@apple.com>
+
+        Reviewed by Joseph Pecoraro.
+
+        Page::goToItem doesn't work while loading is deferred
+        https://bugs.webkit.org/show_bug.cgi?id=60412
+
+        Add setDefersLoading and goBack methods to LayoutTestController.  We
+        need to use goBack() instead of history.back() because the latter goes
+        through NavigationScheduler, hence doesn't exhibit the bug.
+
+        * DumpRenderTree/LayoutTestController.cpp:
+        (goBackCallback):
+        (setDefersLoadingCallback):
+        (LayoutTestController::staticFunctions):
+        * DumpRenderTree/LayoutTestController.h:
+        * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+        (LayoutTestController::goBack):
+        (LayoutTestController::setDefersLoading):
+        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+        (LayoutTestController::goBack):
+        (LayoutTestController::setDefersLoading):
+        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+        (LayoutTestController::goBack):
+        (LayoutTestController::setDefersLoading):
+        * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+        (LayoutTestController::goBack):
+        (LayoutTestController::setDefersLoading):
+
 2011-05-16  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Anders Carlsson.
index b1050b1..d69feb9 100644 (file)
@@ -656,6 +656,14 @@ static JSValueRef counterValueForElementByIdCallback(JSContextRef context, JSObj
     return JSValueMakeString(context, counterValue.get());
 }
 
+static JSValueRef goBackCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->goBack();
+    
+    return JSValueMakeUndefined(context);
+}
+
 static JSValueRef grantDesktopNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     // Has Windows implementation
@@ -1235,6 +1243,17 @@ static JSValueRef setDeferMainResourceDataLoadCallback(JSContextRef context, JSO
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef setDefersLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->setDefersLoading(JSValueToBoolean(context, arguments[0]));
+
+    return JSValueMakeUndefined(context);
+}
+
 static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     // Has Mac and Windows implementation
@@ -2290,6 +2309,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "findString", findStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "originsWithApplicationCache", originsWithApplicationCacheCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "goBack", goBackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
         { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
         { "hasSpellingMarker", hasSpellingMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "hasGrammarMarker", hasGrammarMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -2343,6 +2363,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
         { "setDeferMainResourceDataLoad", setDeferMainResourceDataLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "setDefersLoading", setDefersLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setEditingBehavior", setEditingBehaviorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
index 834c128..c3ee808 100644 (file)
@@ -63,6 +63,7 @@ public:
     void displayInvalidatedRegion();
     void execCommand(JSStringRef name, JSStringRef value);
     bool findString(JSContextRef, JSStringRef, JSObjectRef optionsArray);
+    void goBack();
     JSValueRef originsWithApplicationCache(JSContextRef);
     long long applicationCacheDiskUsageForOrigin(JSStringRef name);
     bool isCommandEnabled(JSStringRef name);
@@ -99,6 +100,7 @@ public:
     void setCustomPolicyDelegate(bool setDelegate, bool permissive);
     void setDatabaseQuota(unsigned long long quota);
     void setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme);
+    void setDefersLoading(bool);
     void setIconDatabaseEnabled(bool iconDatabaseEnabled);
     void setJavaScriptProfilingEnabled(bool profilingEnabled);
     void setJavaScriptCanAccessClipboard(bool flag);
index 8cb84a4..391261e 100644 (file)
@@ -720,6 +720,16 @@ void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool, JSStri
     // FIXME: implement
 }
 
+void LayoutTestController::goBack()
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
+void LayoutTestController::setDefersLoading(bool)
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size)
 {
     webkit_application_cache_set_maximum_size(size);
index 1b67ceb..65edc1a 100644 (file)
@@ -433,6 +433,16 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota)
     [origin release];
 }
 
+void LayoutTestController::goBack()
+{
+    [[mainFrame webView] goBack];
+}
+
+void LayoutTestController::setDefersLoading(bool defers)
+{
+    [[mainFrame webView] setDefersCallbacks:defers];
+}
+
 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
 {
     RetainPtr<CFStringRef> schemeCFString(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, scheme));
index d96bc3f..6a5e7f0 100644 (file)
@@ -1047,6 +1047,16 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota)
     databaseManager->setQuota(TEXT("file:///"), quota);
 }
 
+void LayoutTestController::goBack()
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
+void LayoutTestController::setDefersLoading(bool)
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
 {
     COMPtr<IWebViewPrivate> webView;
index 2d5f38e..f609951 100644 (file)
@@ -287,6 +287,16 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota)
     // FIXME: implement
 }
 
+void LayoutTestController::goBack()
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
+void LayoutTestController::setDefersLoading(bool)
+{
+    // FIXME: implement to enable loader/navigation-while-deferring-loads.html
+}
+
 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool, JSStringRef)
 {
     // FIXME: implement