Add WK2 SPI to prevent the previous back/forward item from remaining in the list
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2014 04:50:57 +0000 (04:50 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 May 2014 04:50:57 +0000 (04:50 +0000)
<rdar://problem/16248710> and https://bugs.webkit.org/show_bug.cgi?id=132636

Reviewed by Sam Weinig.

Source/WebKit2:
Add new PageLoaderClient SPI to keep the current back/forward item from remaining in the list:
* UIProcess/API/APILoaderClient.h:
(API::LoaderClient::shouldKeepCurrentBackForwardListItemInList):
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageLoaderClient):
* UIProcess/API/C/WKPageLoaderClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::shouldKeepCurrentBackForwardListItemInList):
* UIProcess/WebPageProxy.h:

* UIProcess/WebBackForwardList.cpp:
(WebKit::WebBackForwardList::addItem): Use that SPI to determine whether we should insert the new item after
the previous item, or simply replace the previous item.
(WebKit::WebBackForwardList::goToItem): Use that SPI to determine whether the previous item stays or goes.

Tools:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:

* TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp: Added.
(TestWebKitAPI::itemURLLastComponentIsString):
(TestWebKitAPI::didFinishLoadForFrame):
(TestWebKitAPI::willGoToBackForwardListItem):
(TestWebKitAPI::shouldKeepCurrentBackForwardListItemInList):
(TestWebKitAPI::setPageLoaderClient):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKit2/simple2.html: Added.
* TestWebKitAPI/Tests/WebKit2/simple3.html: Added.

* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createWebViewWithOptions): Update for new client layout.

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

13 files changed:
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/APILoaderClient.h
Source/WebKit2/UIProcess/API/C/WKPage.cpp
Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h
Source/WebKit2/UIProcess/WebBackForwardList.cpp
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2/simple2.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2/simple3.html [new file with mode: 0644]
Tools/WebKitTestRunner/TestController.cpp

index 370c82fd1f03fab118c5d641a580682bd6e3c0b1..e39c92f4a4018e81693a3ae19a3edbc6f6284b82 100644 (file)
@@ -1,3 +1,25 @@
+2014-05-06  Brady Eidson  <beidson@apple.com>
+
+        Add WK2 SPI to prevent the previous back/forward item from remaining in the list
+        <rdar://problem/16248710> and https://bugs.webkit.org/show_bug.cgi?id=132636
+
+        Reviewed by Sam Weinig.
+
+        Add new PageLoaderClient SPI to keep the current back/forward item from remaining in the list:
+        * UIProcess/API/APILoaderClient.h:
+        (API::LoaderClient::shouldKeepCurrentBackForwardListItemInList):
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageLoaderClient):
+        * UIProcess/API/C/WKPageLoaderClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::shouldKeepCurrentBackForwardListItemInList):
+        * UIProcess/WebPageProxy.h:
+
+        * UIProcess/WebBackForwardList.cpp:
+        (WebKit::WebBackForwardList::addItem): Use that SPI to determine whether we should insert the new item after
+        the previous item, or simply replace the previous item.
+        (WebKit::WebBackForwardList::goToItem): Use that SPI to determine whether the previous item stays or goes.
+
 2014-05-06  Dan Bernstein  <mitz@apple.com>
 
         -[WKWebView isLoading] is NO immediately after -loadRequest: until the provisional load starts
index ba7c084332a9ffb18cfde99fe9e1c9e03f7f3ba8..5f126c44a9b3627fc474cae8cf14cbecc8ee10da 100644 (file)
@@ -90,6 +90,7 @@ public:
     virtual void processDidCrash(WebKit::WebPageProxy*) { }
 
     virtual void didChangeBackForwardList(WebKit::WebPageProxy*, WebKit::WebBackForwardListItem*, Vector<RefPtr<WebKit::WebBackForwardListItem>>) { }
+    virtual bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy*, WebKit::WebBackForwardListItem*) { return true; }
     virtual void willGoToBackForwardListItem(WebKit::WebPageProxy*, WebKit::WebBackForwardListItem*, API::Object*) { }
 
     virtual PassRefPtr<Data> webCryptoMasterKey(WebKit::WebPageProxy&) { return nullptr; }
index 8ae8c2426675629ac2e840ad84a5e509b4d6583a..763ab43a185640e82c1b3c23ca0343bb43b57244 100644 (file)
@@ -968,6 +968,14 @@ void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase*
             m_client.didChangeBackForwardList(toAPI(page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.base.clientInfo);
         }
 
+        virtual bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy* page, WebKit::WebBackForwardListItem* item) override
+        {
+            if (!m_client.shouldKeepCurrentBackForwardListItemInList)
+                return false;
+
+            return m_client.shouldKeepCurrentBackForwardListItemInList(toAPI(page), toAPI(item));
+        }
+
         virtual void willGoToBackForwardListItem(WebPageProxy* page, WebBackForwardListItem* item, API::Object* userData) override
         {
             if (m_client.willGoToBackForwardListItem)
index 3cea23e928c834391d776545bb2dd2bd840e51c1..946fbf76e134b50fd90ffc2dfb69ccb67acfd758 100644 (file)
@@ -69,6 +69,7 @@ typedef bool (*WKPageCanAuthenticateAgainstProtectionSpaceInFrameCallback)(WKPag
 typedef void (*WKPageDidReceiveAuthenticationChallengeInFrameCallback)(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo);
 typedef void (*WKPageDidChangeBackForwardListCallback)(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void *clientInfo);
 typedef bool (*WKPageShouldGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, const void *clientInfo);
+typedef bool (*WKPageShouldKeepCurrentBackForwardListItemInListCallback)(WKPageRef page, WKBackForwardListItemRef item);
 typedef void (*WKPageWillGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, WKTypeRef userData, const void *clientInfo);
 typedef void (*WKPageDidLayoutCallback)(WKPageRef page, WKLayoutMilestones milestones, WKTypeRef userData, const void *clientInfo);
 typedef WKPluginLoadPolicy (*WKPagePluginLoadPolicyCallback)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, WKStringRef* unavailabilityDescription, const void* clientInfo);
@@ -332,6 +333,7 @@ typedef struct WKPageLoaderClientV4 {
     // Version 4
     WKPageWebGLLoadPolicyCallback                                       webGLLoadPolicy;
     WKPageWebGLLoadPolicyCallback                                       resolveWebGLLoadPolicy;
+    WKPageShouldKeepCurrentBackForwardListItemInListCallback            shouldKeepCurrentBackForwardListItemInList;
 } WKPageLoaderClientV4;
 
 // FIXME: These should be deprecated.
index 443040766b7d7cfbdc8c2d0882a535cf5397ad82..9c5a2007e6aa0bb87122b22758a1d37addfb4841 100644 (file)
@@ -113,19 +113,34 @@ void WebBackForwardList::addItem(WebBackForwardListItem* newItem)
         }
         m_entries.clear();
     }
-    
+
+    bool shouldKeepCurrentItem = true;
+
     if (!m_hasCurrentIndex) {
         ASSERT(m_entries.isEmpty());
         m_currentIndex = 0;
         m_hasCurrentIndex = true;
-    } else
-        m_currentIndex++;
+    } else {
+        shouldKeepCurrentItem = m_page->shouldKeepCurrentBackForwardListItemInList(m_entries[m_currentIndex].get());
+        if (shouldKeepCurrentItem)
+            m_currentIndex++;
+    }
 
-    // m_current never be pointing more than 1 past the end of the entries Vector.
-    // If it is, something has gone wrong and we should not try to insert the new item.
-    ASSERT(m_currentIndex <= m_entries.size());
-    if (m_currentIndex <= m_entries.size())
-        m_entries.insert(m_currentIndex, newItem);
+    if (!shouldKeepCurrentItem) {
+        // m_current never be pointing past the end of the entries Vector.
+        // If it is, something has gone wrong and we should not try to swap in the new item.
+        ASSERT(m_currentIndex < m_entries.size());
+
+        removedItems.append(m_entries[m_currentIndex]);
+        m_entries[m_currentIndex] = newItem;
+    } else {
+        // m_current never be pointing more than 1 past the end of the entries Vector.
+        // If it is, something has gone wrong and we should not try to insert the new item.
+        ASSERT(m_currentIndex <= m_entries.size());
+
+        if (m_currentIndex <= m_entries.size())
+            m_entries.insert(m_currentIndex, newItem);
+    }
 
     m_page->didChangeBackForwardList(newItem, std::move(removedItems));
 }
@@ -136,16 +151,32 @@ void WebBackForwardList::goToItem(WebBackForwardListItem* item)
 
     if (!m_entries.size() || !item || !m_page || !m_hasCurrentIndex)
         return;
-        
-    unsigned index = 0;
-    for (; index < m_entries.size(); ++index) {
-        if (m_entries[index] == item)
-            break;
-    }
-    if (index < m_entries.size()) {
-        m_currentIndex = index;
-        m_page->didChangeBackForwardList(nullptr, { });
+
+    size_t targetIndex = m_entries.find(item);
+
+    // If the target item wasn't even in the list, there's nothing else to do.
+    if (targetIndex == notFound)
+        return;
+
+    // If we're going to an item different from the current item, ask the client if the current
+    // item should remain in the list.
+    WebBackForwardListItem* currentItem = m_entries[m_currentIndex].get();
+    bool shouldKeepCurrentItem = true;
+    if (currentItem != item)
+        shouldKeepCurrentItem = m_page->shouldKeepCurrentBackForwardListItemInList(m_entries[m_currentIndex].get());
+
+    // If the client said to remove the current item, remove it and then update the target index.
+    Vector<RefPtr<WebBackForwardListItem>> removedItems;
+    if (!shouldKeepCurrentItem) {
+        removedItems.append(currentItem);
+        m_entries.remove(m_currentIndex);
+        targetIndex = m_entries.find(item);
+
+        ASSERT(targetIndex != notFound);
     }
+
+    m_currentIndex = targetIndex;
+    m_page->didChangeBackForwardList(nullptr, removedItems);
 }
 
 WebBackForwardListItem* WebBackForwardList::currentItem() const
index 7fd1bb3413b05d85f023c2b400d620b7b60ae575..fd30def33c457b912331b510f2b43b5fd2fba98f 100644 (file)
@@ -908,6 +908,11 @@ void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDeco
         m_loaderClient->willGoToBackForwardListItem(this, item, userData.get());
 }
 
+bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
+{
+    return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(this, item);
+}
+
 bool WebPageProxy::canShowMIMEType(const String& mimeType)
 {
     if (MIMETypeRegistry::canShowMIMEType(mimeType))
index 4c478209dcf2e4925ced25ef916c09ceb19e5b1c..b9669f408a70afa6c5f8c95a4f8b8d08fdcae463 100644 (file)
@@ -524,6 +524,8 @@ public:
     void didChangeBackForwardList(WebBackForwardListItem* addedItem, Vector<RefPtr<WebBackForwardListItem>> removed);
     void willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder&);
 
+    bool shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem*);
+
     bool willHandleHorizontalScrollEvents() const;
 
     bool canShowMIMEType(const String& mimeType);
index 72191428cb2ecb8779af7a93a308f09229da1fac..8c54afe1b55cea753fc37633a647212e9542a701 100644 (file)
@@ -1,3 +1,25 @@
+2014-05-06  Brady Eidson  <beidson@apple.com>
+
+        Add WK2 SPI to prevent the previous back/forward item from remaining in the list
+        <rdar://problem/16248710> and https://bugs.webkit.org/show_bug.cgi?id=132636
+
+        Reviewed by Sam Weinig.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
+        * TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp: Added.
+        (TestWebKitAPI::itemURLLastComponentIsString):
+        (TestWebKitAPI::didFinishLoadForFrame):
+        (TestWebKitAPI::willGoToBackForwardListItem):
+        (TestWebKitAPI::shouldKeepCurrentBackForwardListItemInList):
+        (TestWebKitAPI::setPageLoaderClient):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKit2/simple2.html: Added.
+        * TestWebKitAPI/Tests/WebKit2/simple3.html: Added.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::createWebViewWithOptions): Update for new client layout.
+
 2014-05-06  Darin Adler  <darin@apple.com>
 
         Try to fix iOS build.
index c727ccac4a0bd4bccd53fd1450e8bcfa6ae883e2..dcffbe019834a0c4440ca738ae3980feaa73babf 100644 (file)
@@ -96,6 +96,9 @@
                5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */; };
                517E7DFC15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */; };
                517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */; };
+               51E5C7021919C3B200D8B3E1 /* simple2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780361919AFF8001829A2 /* simple2.html */; };
+               51E5C7031919C3B200D8B3E1 /* simple3.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780371919AFF8001829A2 /* simple3.html */; };
+               51E5C7051919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E5C7041919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp */; };
                51E93017156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E93016156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp */; };
                51FBBB4D1513D4E900822738 /* WebViewCanPasteURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */; };
                51FCF79A1534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               51E5C7021919C3B200D8B3E1 /* simple2.html in Copy Resources */,
+                               51E5C7031919C3B200D8B3E1 /* simple3.html in Copy Resources */,
                                290A9BB91735F63800D71BBC /* OpenNewWindow.html in Copy Resources */,
                                290F4275172A221C00939FF0 /* custom-protocol-sync-xhr.html in Copy Resources */,
                                C2CF975B16CEC71B0054E99D /* JSContextBackForwardCache1.html in Copy Resources */,
                5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ContextMenuCanCopyURL.html; sourceTree = "<group>"; };
                517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCachePruneWithinResourceLoadDelegate.mm; sourceTree = "<group>"; };
                517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = MemoryCachePruneWithinResourceLoadDelegate.html; sourceTree = "<group>"; };
+               51E5C7041919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldKeepCurrentBackForwardListItemInList.cpp; sourceTree = "<group>"; };
+               51E780361919AFF8001829A2 /* simple2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = simple2.html; sourceTree = "<group>"; };
+               51E780371919AFF8001829A2 /* simple3.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = simple3.html; sourceTree = "<group>"; };
                51E93016156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKPageGetScaleFactorNotZero.cpp; sourceTree = "<group>"; };
                51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewCanPasteURL.mm; sourceTree = "<group>"; };
                51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldGoToBackForwardListItem_Bundle.cpp; sourceTree = "<group>"; };
                BCC8B95A12611F4700DE46A4 /* FailedLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FailedLoad.cpp; sourceTree = "<group>"; };
                C01363C713C3997300EF3964 /* StringOperators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringOperators.cpp; sourceTree = "<group>"; };
                C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpacebarScrolling.cpp; sourceTree = "<group>"; };
-               C02B7853126613AE0026BF0F /* Carbon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Carbon.framework; sourceTree = SDKROOT; };
+               C02B7853126613AE0026BF0F /* Carbon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Carbon.framework; sourceTree = SDKROOT; };
                C02B7882126615410026BF0F /* spacebar-scrolling.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "spacebar-scrolling.html"; sourceTree = "<group>"; };
                C045F9441385C2E900C0F3CD /* DownloadDecideDestinationCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DownloadDecideDestinationCrash.cpp; sourceTree = "<group>"; };
                C045F9461385C2F800C0F3CD /* 18-characters.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "18-characters.html"; sourceTree = "<group>"; };
                                2D640B5417875DFF00BFAF99 /* ScrollPinningBehaviors.cpp */,
                                51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */,
                                51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */,
+                               51E5C7041919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp */,
                                C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */,
                                1AE72F47173EB214006362F0 /* TerminateTwice.cpp */,
                                BC22D31314DC689800FFB1DD /* UserMessage.cpp */,
                                33DC890E1419539300747EF7 /* simple-iframe.html */,
                                BCAA485514A021640088FAC4 /* simple-tall.html */,
                                BC909778125571AB00083756 /* simple.html */,
+                               51E780361919AFF8001829A2 /* simple2.html */,
+                               51E780371919AFF8001829A2 /* simple3.html */,
                                C02B7882126615410026BF0F /* spacebar-scrolling.html */,
                        );
                        name = Resources;
                                52E5CE4614D21E9D003B2BD8 /* ParentFrame.cpp in Sources */,
                                C54237F016B8955800E638FC /* PasteboardNotifications.mm in Sources */,
                                BC575BC0126F5752006F0F12 /* PlatformUtilities.cpp in Sources */,
+                               51E5C7051919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp in Sources */,
                                BC131885117114B600B69727 /* PlatformUtilitiesMac.mm in Sources */,
                                BC90955D125548AA00083756 /* PlatformWebViewMac.mm in Sources */,
                                333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp
new file mode 100644 (file)
index 0000000..f133b4c
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformUtilities.h"
+#include "PlatformWebView.h"
+#include "Test.h"
+
+// This test navigates from simple.html, to simple2.html, to simple3.html
+// When navigating from simple2 to simple3, it disallows the simple2 back/forward list item from staying in the list
+// It then navigates back from simple3, expecting to land at simple.
+
+namespace TestWebKitAPI {
+
+static bool finished = false;
+static bool successfulSoFar = true;
+static int navigationNumber = 0;
+
+static bool itemURLLastComponentIsString(WKBackForwardListItemRef item, const char* string)
+{
+    WKRetainPtr<WKURLRef> url = adoptWK(WKBackForwardListItemCopyURL(item));
+    WKRetainPtr<WKStringRef> path = adoptWK(WKURLCopyLastPathComponent(url.get()));
+
+    return WKStringIsEqualToUTF8CString(path.get(), string);
+}
+
+static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void*)
+{
+    // Only mark finished when the main frame loads
+    if (!WKFrameIsMainFrame(frame))
+        return;
+
+    finished = true;
+    navigationNumber++;
+
+    WKBackForwardListRef list = WKPageGetBackForwardList(page);
+    WKBackForwardListItemRef currentItem = WKBackForwardListGetCurrentItem(list);
+    WKBackForwardListItemRef backItem = WKBackForwardListGetBackItem(list);
+    WKBackForwardListItemRef forwardItem = WKBackForwardListGetForwardItem(list);
+    unsigned forwardCount = WKBackForwardListGetForwardListCount(list);
+
+    // This test should never have a forward list.
+    if (forwardCount)
+        successfulSoFar = false;
+
+    if (navigationNumber == 1) {
+        // We've only performed 1 navigation, we should only have a current item.
+        if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple.html"))
+            successfulSoFar = false;
+        if (backItem || forwardItem)
+            successfulSoFar = false;
+    } else if (navigationNumber == 2) {
+        // On the second navigation, simple2 should be current and simple should be the back item.
+        if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple2.html"))
+            successfulSoFar = false;
+        if (!backItem || !itemURLLastComponentIsString(backItem, "simple.html"))
+            successfulSoFar = false;
+        if (forwardItem)
+            successfulSoFar = false;
+    } else if (navigationNumber == 3) {
+        // On the third navigation the item for simple2 should have been removed.
+        // So simple3 should be current and simple should still be the back item.
+        if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple3.html"))
+            successfulSoFar = false;
+        if (!backItem || !itemURLLastComponentIsString(backItem, "simple.html"))
+            successfulSoFar = false;
+        if (forwardItem)
+            successfulSoFar = false;
+    } else if (navigationNumber == 4) {
+        // After the fourth navigation (which was a "back" navigation), the item for simple3 should have been removed.
+        // So simple should be current and there should be no other items.
+        if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple.html"))
+            successfulSoFar = false;
+        if (backItem || forwardItem)
+            successfulSoFar = false;
+    }
+}
+
+static void willGoToBackForwardListItem(WKPageRef, WKBackForwardListItemRef item, WKTypeRef userData, const void*)
+{
+    if (!itemURLLastComponentIsString(item, "simple.html"))
+        successfulSoFar = false;
+}
+
+static bool shouldKeepCurrentBackForwardListItemInList(WKPageRef page, WKBackForwardListItemRef item)
+{
+    // We make sure the item for "simple2.html" is removed when we navigate to "simple3.html"
+    // We also want to make sure the item for "simple3.html" is removed when we go back to "simple.html"
+    // So we only want to keep "simple.html"
+    return itemURLLastComponentIsString(item, "simple.html");
+}
+
+static void setPageLoaderClient(WKPageRef page)
+{
+    WKPageLoaderClientV4 loaderClient;
+    memset(&loaderClient, 0, sizeof(loaderClient));
+
+    loaderClient.base.version = 4;
+    loaderClient.didFinishLoadForFrame = didFinishLoadForFrame;
+    loaderClient.shouldKeepCurrentBackForwardListItemInList = shouldKeepCurrentBackForwardListItemInList;
+    loaderClient.willGoToBackForwardListItem = willGoToBackForwardListItem;
+
+    WKPageSetPageLoaderClient(page, &loaderClient.base);
+}
+
+TEST(WebKit2, ShouldKeepCurrentBackForwardListItemInList)
+{
+    WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate());
+
+    PlatformWebView webView(context.get());
+    setPageLoaderClient(webView.page());
+
+    WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple", "html")).get());
+    Util::run(&finished);
+    EXPECT_EQ(successfulSoFar, true);
+
+    finished = false;
+    WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple2", "html")).get());
+    Util::run(&finished);
+    EXPECT_EQ(successfulSoFar, true);
+
+    finished = false;
+    WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple3", "html")).get());
+    Util::run(&finished);
+    EXPECT_EQ(successfulSoFar, true);
+
+    finished = false;
+    WKPageGoBack(webView.page());
+    Util::run(&finished);
+
+    EXPECT_EQ(successfulSoFar, true);
+    EXPECT_EQ(navigationNumber, 4);
+}
+
+} // namespace TestWebKitAPI
+
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/simple2.html b/Tools/TestWebKitAPI/Tests/WebKit2/simple2.html
new file mode 100644 (file)
index 0000000..1dcbfdd
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+  Second simple HTML file.
+</body>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/simple3.html b/Tools/TestWebKitAPI/Tests/WebKit2/simple3.html
new file mode 100644 (file)
index 0000000..786516e
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+  Third simple HTML file.
+</body>
+</html>
index 786e1a1388e7319ee0706584a37ab3f3b4d7e2fd..e20dcea2e2d9ae3d0c8ef26931716ad20c1496d9 100644 (file)
@@ -499,6 +499,7 @@ void TestController::createWebViewWithOptions(WKDictionaryRef options)
         pluginLoadPolicy, // pluginLoadPolicy
         0, // webGLLoadPolicy
         0, // resolveWebGLLoadPolicy
+        0, // shouldKeepCurrentBackForwardListItemInList
     };
     WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient.base);