Title: [240280] branches/safari-607-branch
Revision
240280
Author
alanc...@apple.com
Date
2019-01-22 12:58:17 -0800 (Tue, 22 Jan 2019)

Log Message

Revert r240262. rdar://problem/47099573

Modified Paths

Added Paths

Diff

Modified: branches/safari-607-branch/LayoutTests/ChangeLog (240279 => 240280)


--- branches/safari-607-branch/LayoutTests/ChangeLog	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/LayoutTests/ChangeLog	2019-01-22 20:58:17 UTC (rev 240280)
@@ -1,5 +1,9 @@
 2019-01-22  Alan Coon  <alanc...@apple.com>
 
+        Revert r240262. rdar://problem/47099573
+
+2019-01-22  Alan Coon  <alanc...@apple.com>
+
         Revert r240263. rdar://problem/47099573
 
 2019-01-22  Alan Coon  <alanc...@apple.com>

Modified: branches/safari-607-branch/LayoutTests/platform/wk2/TestExpectations (240279 => 240280)


--- branches/safari-607-branch/LayoutTests/platform/wk2/TestExpectations	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/LayoutTests/platform/wk2/TestExpectations	2019-01-22 20:58:17 UTC (rev 240280)
@@ -733,8 +733,8 @@
 http/tests/resourceLoadStatistics/non-prevalent-resources-can-access-cookies-in-a-third-party-context.html [ Skip ]
 http/tests/resourceLoadStatistics/cap-cache-max-age-for-prevalent-resource.html [ Skip ]
 
-# Process swapping is only implemented on WebKit2.
-http/tests/navigation/process-swap-window-open.html [ Pass ]
+# This feature is currently disabled by default and unfinished <rdar://problem/38925077>.
+http/tests/navigation/process-swap-window-open.html [ Skip ]
 
 # Cross-Origin-Resource-Policy response header is only implemented in WebKit2.
 http/wpt/cross-origin-resource-policy/ [ Pass ]

Modified: branches/safari-607-branch/Source/WebCore/ChangeLog (240279 => 240280)


--- branches/safari-607-branch/Source/WebCore/ChangeLog	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebCore/ChangeLog	2019-01-22 20:58:17 UTC (rev 240280)
@@ -1,5 +1,9 @@
 2019-01-22  Alan Coon  <alanc...@apple.com>
 
+        Revert r240262. rdar://problem/47099573
+
+2019-01-22  Alan Coon  <alanc...@apple.com>
+
         Revert r240263. rdar://problem/47099573
 
 2019-01-22  Alan Coon  <alanc...@apple.com>

Modified: branches/safari-607-branch/Source/WebCore/loader/FrameLoader.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebCore/loader/FrameLoader.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebCore/loader/FrameLoader.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -2032,11 +2032,11 @@
 
         Optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
 
+        dispatchDidCommitLoad(hasInsecureContent);
+
         // FIXME: This API should be turned around so that we ground CachedPage into the Page.
         cachedPage->restore(*m_frame.page());
 
-        dispatchDidCommitLoad(hasInsecureContent);
-
 #if PLATFORM(IOS_FAMILY)
         m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
         m_frame.page()->chrome().dispatchViewportPropertiesDidChange(m_frame.page()->viewportArguments());

Modified: branches/safari-607-branch/Source/WebKit/ChangeLog (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/ChangeLog	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/ChangeLog	2019-01-22 20:58:17 UTC (rev 240280)
@@ -1,5 +1,9 @@
 2019-01-22  Alan Coon  <alanc...@apple.com>
 
+        Revert r240262. rdar://problem/47099573
+
+2019-01-22  Alan Coon  <alanc...@apple.com>
+
         Revert r240263. rdar://problem/47099573
 
 2019-01-22  Alan Coon  <alanc...@apple.com>

Modified: branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -73,7 +73,7 @@
     encoder.encodeEnum(layerHostingMode);
     encoder << mimeTypesWithCustomContentProviders;
     encoder << controlledByAutomation;
-    encoder << isSwapFromSuspended;
+    encoder << isProcessSwap;
 
 #if PLATFORM(MAC)
     encoder << colorSpace;
@@ -227,7 +227,7 @@
         return WTF::nullopt;
     if (!decoder.decode(parameters.controlledByAutomation))
         return WTF::nullopt;
-    if (!decoder.decode(parameters.isSwapFromSuspended))
+    if (!decoder.decode(parameters.isProcessSwap))
         return WTF::nullopt;
 
 #if PLATFORM(MAC)

Modified: branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/Shared/WebPageCreationParameters.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -129,7 +129,7 @@
     Vector<String> mimeTypesWithCustomContentProviders;
 
     bool controlledByAutomation;
-    bool isSwapFromSuspended { false };
+    bool isProcessSwap { false };
 
 #if PLATFORM(MAC)
     ColorSpaceData colorSpace;

Modified: branches/safari-607-branch/Source/WebKit/Shared/WebPolicyAction.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/Shared/WebPolicyAction.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/Shared/WebPolicyAction.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -29,11 +29,11 @@
 
 namespace WebKit {
 
+// FIXME: Remove this type and use WebCore::PolicyAction instead.
 enum class WebPolicyAction : uint8_t {
     Use,
     Download,
-    Ignore,
-    Suspend
+    Ignore
 };
 
 }
@@ -45,8 +45,7 @@
         WebKit::WebPolicyAction,
         WebKit::WebPolicyAction::Use,
         WebKit::WebPolicyAction::Download,
-        WebKit::WebPolicyAction::Ignore,
-        WebKit::WebPolicyAction::Suspend
+        WebKit::WebPolicyAction::Ignore
     >;
 };
 

Modified: branches/safari-607-branch/Source/WebKit/Sources.txt (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/Sources.txt	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/Sources.txt	2019-01-22 20:58:17 UTC (rev 240280)
@@ -228,6 +228,7 @@
 UIProcess/PersistencyUtils.cpp
 UIProcess/ProcessAssertion.cpp
 UIProcess/ProcessThrottler.cpp
+UIProcess/ProvisionalPageProxy.cpp
 UIProcess/RemoteWebInspectorProxy.cpp
 UIProcess/ResourceLoadStatisticsMemoryStore.cpp
 UIProcess/ResourceLoadStatisticsPersistentStorage.cpp

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2019-01-22 20:58:17 UTC (rev 240280)
@@ -44,6 +44,7 @@
 #import "NavigationState.h"
 #import "ObjCObjectGraph.h"
 #import "PageClient.h"
+#import "ProvisionalPageProxy.h"
 #import "RemoteLayerTreeScrollingPerformanceData.h"
 #import "RemoteLayerTreeTransaction.h"
 #import "RemoteObjectRegistry.h"
@@ -4682,6 +4683,11 @@
 {
     Ref<WebKit::WebProcessProxy> protectedProcessProxy(_page->process());
     protectedProcessProxy->requestTermination(WebKit::ProcessTerminationReason::RequestedByClient);
+
+    if (auto* provisionalPageProxy = _page->provisionalPageProxy()) {
+        Ref<WebKit::WebProcessProxy> protectedProcessProxy(provisionalPageProxy->process());
+        protectedProcessProxy->requestTermination(WebKit::ProcessTerminationReason::RequestedByClient);
+    }
 }
 
 #if PLATFORM(MAC)

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/PageClient.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/PageClient.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/PageClient.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -48,6 +48,7 @@
 
 OBJC_CLASS CALayer;
 OBJC_CLASS NSFileWrapper;
+OBJC_CLASS NSMenu;
 OBJC_CLASS NSSet;
 OBJC_CLASS WKDrawingView;
 OBJC_CLASS _WKRemoteObjectRegistry;

Added: branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (0 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp	                        (rev 0)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2019 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 "ProvisionalPageProxy.h"
+
+#include "APINavigation.h"
+#include "DrawingAreaProxy.h"
+#include "Logging.h"
+#include "PageClient.h"
+#include "WebBackForwardList.h"
+#include "WebBackForwardListItem.h"
+#include "WebErrors.h"
+#include "WebNavigationState.h"
+#include "WebPageMessages.h"
+#include "WebPageProxy.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcessMessages.h"
+#include "WebProcessProxy.h"
+#include <WebCore/ShouldTreatAsContinuingLoad.h>
+
+namespace WebKit {
+
+#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(m_page.isAlwaysOnLoggingAllowed(), channel, "%p - ProvisionalPageProxy::" fmt, this, ##__VA_ARGS__)
+#define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(m_page.isAlwaysOnLoggingAllowed(), channel, "%p - ProvisionalPageProxy::" fmt, this, ##__VA_ARGS__)
+
+ProvisionalPageProxy::ProvisionalPageProxy(WebPageProxy& page, Ref<WebProcessProxy>&& process, std::unique_ptr<SuspendedPageProxy> suspendedPage, uint64_t navigationID, bool isServerRedirect, const WebCore::ResourceRequest& request, ProcessSwapRequestedByClient processSwapRequestedByClient)
+    : m_page(page)
+    , m_process(WTFMove(process))
+    , m_navigationID(navigationID)
+    , m_isServerRedirect(isServerRedirect)
+    , m_request(request)
+    , m_processSwapRequestedByClient(processSwapRequestedByClient)
+#if PLATFORM(IOS_FAMILY)
+    , m_suspensionToken(m_process->throttler().foregroundActivityToken())
+#endif
+{
+    m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID(), *this);
+    m_process->addProvisionalPageProxy(*this);
+
+    // If we are reattaching to a SuspendedPage, then the WebProcess' WebPage already exists and
+    // WebPageProxy::didCreateMainFrame() will not be called to initialize m_mainFrame. In such
+    // case, we need to initialize m_mainFrame to reflect the fact the the WebProcess' WebPage
+    // already exists and already has a main frame.
+    if (suspendedPage) {
+        ASSERT(&suspendedPage->process() == m_process.ptr());
+        suspendedPage->unsuspend();
+        m_mainFrame = WebFrameProxy::create(m_page, suspendedPage->mainFrameID());
+        m_process->frameCreated(suspendedPage->mainFrameID(), *m_mainFrame);
+    }
+
+    initializeWebPage();
+}
+
+ProvisionalPageProxy::~ProvisionalPageProxy()
+{
+    m_process->removeProvisionalPageProxy(*this);
+
+    if (m_wasCommitted)
+        return;
+
+    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
+    m_process->send(Messages::WebPage::Close(), m_page.pageID());
+
+    if (m_drawingArea) {
+        auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+        m_drawingArea = nullptr;
+    }
+
+    RunLoop::main().dispatch([process = m_process.copyRef()] {
+        process->maybeShutDown();
+    });
+}
+
+void ProvisionalPageProxy::processDidTerminate()
+{
+    RELEASE_LOG_ERROR_IF_ALLOWED(ProcessSwapping, "processDidTerminate: pageID = %" PRIu64, m_page.pageID());
+    m_page.provisionalProcessDidTerminate();
+}
+
+std::unique_ptr<DrawingAreaProxy> ProvisionalPageProxy::takeDrawingArea()
+{
+    return WTFMove(m_drawingArea);
+}
+
+void ProvisionalPageProxy::cancel()
+{
+    // If the provisional load started, then indicate that it failed due to cancellation by calling didFailProvisionalLoadForFrame().
+    if (m_provisionalLoadURL.isEmpty())
+        return;
+
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "cancel: Simulating a didFailProvisionalLoadForFrame for pageID = %" PRIu64, m_page.pageID());
+    ASSERT(m_mainFrame);
+    auto error = WebKit::cancelledError(m_request);
+    error.setType(WebCore::ResourceError::Type::Cancellation);
+    didFailProvisionalLoadForFrame(m_mainFrame->frameID(), { }, m_navigationID, m_provisionalLoadURL, error, UserData { }); // Will delete |this|.
+}
+
+void ProvisionalPageProxy::processDidFinishLaunching()
+{
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "processDidFinishLaunching: pageID = %" PRIu64, m_page.pageID());
+    finishInitializingWebPageAfterProcessLaunch();
+}
+
+void ProvisionalPageProxy::finishInitializingWebPageAfterProcessLaunch()
+{
+    ASSERT(m_process->state() == WebProcessProxy::State::Running);
+
+    // FIXME: The WebPageProxy delays adding the visited link store until after the process has launched
+    // so the ProvisionalPageProxy does the same. However, do we really need to?
+    m_process->addVisitedLinkStore(m_page.visitedLinkStore());
+}
+
+void ProvisionalPageProxy::initializeWebPage()
+{
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+    m_drawingArea = m_page.pageClient().createDrawingAreaProxy();
+
+    auto parameters = m_page.creationParameters();
+    parameters.isProcessSwap = true;
+    m_process->send(Messages::WebProcess::CreateWebPage(m_page.pageID(), parameters), 0);
+
+    if (m_process->state() == WebProcessProxy::State::Running)
+        finishInitializingWebPageAfterProcessLaunch();
+}
+
+void ProvisionalPageProxy::loadDataWithNavigation(API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<WebsitePoliciesData>&& websitePolicies)
+{
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadDataWithNavigation: pageID = %" PRIu64, m_page.pageID());
+
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+    m_page.loadDataWithNavigation(navigation, data, MIMEType, encoding, baseURL, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies));
+}
+
+void ProvisionalPageProxy::loadRequestWithNavigation(API::Navigation& navigation, WebCore::ResourceRequest&& request, WebCore::ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData, Optional<WebsitePoliciesData>&& websitePolicies)
+{
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "loadRequestWithNavigation: pageID = %" PRIu64, m_page.pageID());
+
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+    m_page.loadRequestWithNavigation(navigation, WTFMove(request), shouldOpenExternalURLsPolicy, userData, WebCore::ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies));
+}
+
+void ProvisionalPageProxy::goToBackForwardItem(API::Navigation& navigation, WebBackForwardListItem& item, Optional<WebsitePoliciesData>&& websitePolicies)
+{
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "goToBackForwardItem: pageID = %" PRIu64, m_page.pageID());
+
+    auto itemStates = m_page.backForwardList().filteredItemStates([this, targetItem = &item](auto& item) {
+        if (auto* page = item.suspendedPage()) {
+            if (&page->process() == m_process.ptr())
+                return false;
+        }
+        return &item != targetItem;
+    });
+    m_process->send(Messages::WebPage::UpdateBackForwardListForReattach(WTFMove(itemStates)), m_page.pageID());
+    m_process->send(Messages::WebPage::GoToBackForwardItem(navigation.navigationID(), item.itemID(), *navigation.backForwardFrameLoadType(), WebCore::ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies)), m_page.pageID());
+    m_process->responsivenessTimer().start();
+}
+
+void ProvisionalPageProxy::didCreateMainFrame(uint64_t frameID)
+{
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "didCreateMainFrame: pageID = %" PRIu64 ", frameID = %" PRIu64, m_page.pageID(), frameID);
+    ASSERT(!m_mainFrame);
+
+    m_mainFrame = WebFrameProxy::create(m_page, frameID);
+
+    // Add the frame to the process wide map.
+    m_process->frameCreated(frameID, *m_mainFrame);
+
+    // This navigation was destroyed so no need to notify of redirect.
+    if (!m_page.navigationState().hasNavigation(m_navigationID))
+        return;
+
+    // Restore the main frame's committed URL as some clients may rely on it until the next load is committed.
+    if (auto* mainFrame = m_page.mainFrame())
+        m_mainFrame->frameLoadState().setURL(mainFrame->frameLoadState().url());
+
+    // Normally, notification of a server redirect comes from the WebContent process.
+    // If we are process swapping in response to a server redirect then that notification will not come from the new WebContent process.
+    // In this case we have the UIProcess synthesize the redirect notification at the appropriate time.
+    if (m_isServerRedirect) {
+        m_mainFrame->frameLoadState().didStartProvisionalLoad(m_request.url());
+
+        auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+        m_page.didReceiveServerRedirectForProvisionalLoadForFrame(m_mainFrame->frameID(), m_navigationID, WTFMove(m_request), { });
+    }
+}
+
+void ProvisionalPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, URL&& url, URL&& unreachableURL, const UserData& userData)
+{
+    // If the previous provisional load used the same process, we may receive IPC for this previous provisional's main frame that we need to ignore.
+    if (!m_mainFrame || m_mainFrame->frameID() != frameID)
+        return;
+
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "didStartProvisionalLoadForFrame: pageID = %" PRIu64 ", frameID = %" PRIu64 ", navigationID = %" PRIu64, m_page.pageID(), frameID, navigationID);
+    ASSERT(m_provisionalLoadURL.isNull());
+    m_provisionalLoadURL = url;
+
+    // Merely following a server side redirect so there is no need to send a didStartProvisionalLoad again.
+    if (m_isServerRedirect)
+        return;
+
+    // Clients expect the Page's main frame's expectedURL to be the provisional one when a provisional load is started.
+    if (auto* pageMainFrame = m_page.mainFrame())
+        pageMainFrame->didStartProvisionalLoad(url);
+
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+    m_page.didStartProvisionalLoadForFrame(frameID, navigationID, WTFMove(url), WTFMove(unreachableURL), userData);
+}
+
+void ProvisionalPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError& error, const UserData& userData)
+{
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+
+    RELEASE_LOG_ERROR_IF_ALLOWED(ProcessSwapping, "didFailProvisionalLoadForFrame: pageID = %" PRIu64 ", frameID = %" PRIu64 ", navigationID = %" PRIu64, m_page.pageID(), frameID, navigationID);
+    m_provisionalLoadURL = { };
+
+    // Make sure the Page's main frame's expectedURL gets cleared since we updated it in didStartProvisionalLoad.
+    if (auto* pageMainFrame = m_page.mainFrame())
+        pageMainFrame->didFailProvisionalLoad();
+
+    m_page.didFailProvisionalLoadForFrame(frameID, frameSecurityOrigin, navigationID, provisionalURL, error, userData); // Will delete |this|.
+}
+
+void ProvisionalPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
+{
+    // If the previous provisional load used the same process, we may receive IPC for this previous provisional's main frame that we need to ignore.
+    if (!m_mainFrame || m_mainFrame->frameID() != frameID)
+        return;
+
+    RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "didCommitLoadForFrame: pageID = %" PRIu64 ", frameID = %" PRIu64 ", navigationID = %" PRIu64, m_page.pageID(), frameID, navigationID);
+    m_provisionalLoadURL = { };
+    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
+
+    m_wasCommitted = true;
+    m_page.commitProvisionalPage(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, containsPluginDocument, forcedHasInsecureContent, userData); // Will delete |this|.
+}
+
+void ProvisionalPageProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
+{
+    ASSERT(decoder.messageReceiverName() == Messages::WebPageProxy::messageReceiverName());
+
+    if (decoder.messageName() == Messages::WebPageProxy::DidStartProgress::name()
+        || decoder.messageName() == Messages::WebPageProxy::DidChangeProgress::name()
+        || decoder.messageName() == Messages::WebPageProxy::BackForwardAddItem::name()
+        || decoder.messageName() == Messages::WebPageProxy::LogDiagnosticMessage::name()
+        || decoder.messageName() == Messages::WebPageProxy::LogDiagnosticMessageWithEnhancedPrivacy::name()
+        || decoder.messageName() == Messages::WebPageProxy::SetNetworkRequestsInProgress::name()
+#if PLATFORM(COCOA)
+        || decoder.messageName() == Messages::WebPageProxy::RegisterWebProcessAccessibilityToken::name()
+#endif
+        || decoder.messageName() == Messages::WebPageProxy::DecidePolicyForNavigationActionAsync::name()
+        || decoder.messageName() == Messages::WebPageProxy::StartURLSchemeTask::name()
+        || decoder.messageName() == Messages::WebPageProxy::DecidePolicyForResponse::name()
+        || decoder.messageName() == Messages::WebPageProxy::DidPerformClientRedirect::name()
+        || decoder.messageName() == Messages::WebPageProxy::DidChangeProvisionalURLForFrame::name()
+        || decoder.messageName() == Messages::WebPageProxy::DidNavigateWithNavigationData::name())
+    {
+        auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+        m_page.didReceiveMessage(connection, decoder);
+        return;
+    }
+
+    if (decoder.messageName() == Messages::WebPageProxy::DidCreateMainFrame::name()) {
+        IPC::handleMessage<Messages::WebPageProxy::DidCreateMainFrame>(decoder, this, &ProvisionalPageProxy::didCreateMainFrame);
+        return;
+    }
+
+    if (decoder.messageName() == Messages::WebPageProxy::DidStartProvisionalLoadForFrame::name()) {
+        IPC::handleMessage<Messages::WebPageProxy::DidStartProvisionalLoadForFrame>(decoder, this, &ProvisionalPageProxy::didStartProvisionalLoadForFrame);
+        return;
+    }
+
+    if (decoder.messageName() == Messages::WebPageProxy::DidFailProvisionalLoadForFrame::name()) {
+        IPC::handleMessage<Messages::WebPageProxy::DidFailProvisionalLoadForFrame>(decoder, this, &ProvisionalPageProxy::didFailProvisionalLoadForFrame);
+        return;
+    }
+
+    if (decoder.messageName() == Messages::WebPageProxy::DidCommitLoadForFrame::name()) {
+        IPC::handleMessage<Messages::WebPageProxy::DidCommitLoadForFrame>(decoder, this, &ProvisionalPageProxy::didCommitLoadForFrame);
+        return;
+    }
+
+    LOG(ProcessSwapping, "Unhandled message %s::%s from provisional process", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
+}
+
+void ProvisionalPageProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& encoder)
+{
+    auto pageProcessOverride = m_page.temporarilyOverrideProcess(m_process);
+    m_page.didReceiveSyncMessage(connection, decoder, encoder);
+}
+
+} // namespace WebKit

Added: branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h (0 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h	                        (rev 0)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/ProvisionalPageProxy.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include "MessageReceiver.h"
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+class ResourceRequest;
+}
+
+namespace WebKit {
+
+class DrawingAreaProxy;
+class SuspendedPageProxy;
+class WebFrameProxy;
+class WebPageProxy;
+class WebProcessProxy;
+
+class ProvisionalPageProxy : public IPC::MessageReceiver, public CanMakeWeakPtr<ProvisionalPageProxy> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ProvisionalPageProxy(WebPageProxy&, Ref<WebProcessProxy>&&, std::unique_ptr<SuspendedPageProxy>, uint64_t navigationID, bool isServerRedirect, const WebCore::ResourceRequest&, ProcessSwapRequestedByClient);
+    ~ProvisionalPageProxy();
+
+    WebPageProxy& page() { return m_page; }
+    WebFrameProxy* mainFrame() const { return m_mainFrame.get(); }
+    WebProcessProxy& process() { return m_process.get(); }
+    ProcessSwapRequestedByClient processSwapRequestedByClient() const { return m_processSwapRequestedByClient; }
+    uint64_t navigationID() const { return m_navigationID; }
+
+    DrawingAreaProxy* drawingArea() const { return m_drawingArea.get(); }
+    std::unique_ptr<DrawingAreaProxy> takeDrawingArea();
+
+    void loadDataWithNavigation(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+    void loadRequestWithNavigation(API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+    void goToBackForwardItem(API::Navigation&, WebBackForwardListItem&, Optional<WebsitePoliciesData>&&);
+    void cancel();
+
+    void processDidFinishLaunching();
+    void processDidTerminate();
+
+private:
+    // IPC::MessageReceiver
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
+    void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) final;
+
+    void didCreateMainFrame(uint64_t frameID);
+    void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
+    void didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
+    void didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
+
+    void initializeWebPage();
+    void finishInitializingWebPageAfterProcessLaunch();
+
+    WebPageProxy& m_page;
+    Ref<WebProcessProxy> m_process;
+    std::unique_ptr<DrawingAreaProxy> m_drawingArea;
+    RefPtr<WebFrameProxy> m_mainFrame;
+    uint64_t m_navigationID;
+    bool m_isServerRedirect;
+    WebCore::ResourceRequest m_request;
+    ProcessSwapRequestedByClient m_processSwapRequestedByClient;
+    bool m_wasCommitted { false };
+    URL m_provisionalLoadURL;
+
+#if PLATFORM(IOS_FAMILY)
+    ProcessThrottler::ForegroundActivityToken m_suspensionToken;
+#endif
+};
+
+} // namespace WebKit

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/SuspendedPageProxy.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/SuspendedPageProxy.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/SuspendedPageProxy.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -100,8 +100,10 @@
     // If the suspended page was not consumed before getting destroyed, then close the corresponding page
     // on the WebProcess side.
     m_process->send(Messages::WebPage::Close(), m_page.pageID());
-    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
 
+    if (m_suspensionState == SuspensionState::Suspending)
+        m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
+
     // We call maybeShutDown() asynchronously since the SuspendedPage is currently being removed from the WebProcessPool
     // and we want to avoid re-entering WebProcessPool methods.
     RunLoop::main().dispatch([process = m_process.copyRef()] {
@@ -134,7 +136,6 @@
     ASSERT(m_suspensionState == SuspensionState::Suspended);
 
     m_suspensionState = SuspensionState::Resumed;
-    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
     m_process->send(Messages::WebPage::SetIsSuspended(false), m_page.pageID());
 }
 
@@ -151,6 +152,8 @@
     m_suspensionToken = nullptr;
 #endif
 
+    m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_page.pageID());
+
     if (m_readyToUnsuspendHandler)
         m_readyToUnsuspendHandler(this);
 }

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/WebFrameProxy.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/WebFrameProxy.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/WebFrameProxy.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -27,6 +27,7 @@
 #include "WebFrameProxy.h"
 
 #include "APINavigation.h"
+#include "ProvisionalPageProxy.h"
 #include "WebCertificateInfo.h"
 #include "WebFramePolicyListenerProxy.h"
 #include "WebPageMessages.h"
@@ -74,7 +75,7 @@
     if (!m_page)
         return false;
 
-    return this == m_page->mainFrame();
+    return this == m_page->mainFrame() || (m_page->provisionalPageProxy() && this == m_page->provisionalPageProxy()->mainFrame());
 }
 
 void WebFrameProxy::loadURL(const URL& url)

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -77,6 +77,7 @@
 #include "PluginInformation.h"
 #include "PluginProcessManager.h"
 #include "PrintInfo.h"
+#include "ProvisionalPageProxy.h"
 #include "SafeBrowsingWarning.h"
 #include "ShareSheetCallbackID.h"
 #include "SharedBufferDataReference.h"
@@ -549,6 +550,13 @@
     return m_websiteDataStore->sessionID();
 }
 
+DrawingAreaProxy* WebPageProxy::drawingArea() const
+{
+    if (m_provisionalPage && m_process.ptr() == &m_provisionalPage->process() && m_provisionalPage->drawingArea())
+        return m_provisionalPage->drawingArea();
+    return m_drawingArea.get();
+}
+
 void WebPageProxy::changeWebsiteDataStore(WebsiteDataStore& websiteDataStore)
 {
     m_process->processPool().pageEndUsingWebsiteDataStore(*this);
@@ -772,38 +780,26 @@
     return true;
 }
 
-void WebPageProxy::swapToWebProcess(Ref<WebProcessProxy>&& process, std::unique_ptr<SuspendedPageProxy>&& destinationSuspendedPage, IsSwapFromSuspended isSwapFromSuspended)
+void WebPageProxy::swapToWebProcess(Ref<WebProcessProxy>&& process, std::unique_ptr<DrawingAreaProxy>&& drawingArea, RefPtr<WebFrameProxy>&& mainFrame)
 {
     ASSERT(!m_isClosed);
     RELEASE_LOG_IF_ALLOWED(Loading, "swapToWebProcess: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
 
     m_process = WTFMove(process);
+    ASSERT(!m_drawingArea);
+    setDrawingArea(WTFMove(drawingArea));
+    ASSERT(!m_mainFrame);
+    m_mainFrame = WTFMove(mainFrame);
     m_isValid = true;
 
-    // If we are reattaching to a SuspendedPage, then the WebProcess' WebPage already exists and
-    // WebPageProxy::didCreateMainFrame() will not be called to initialize m_mainFrame. In such
-    // case, we need to initialize m_mainFrame to reflect the fact the the WebProcess' WebPage
-    // already exists and already has a main frame.
-    if (destinationSuspendedPage) {
-        if (!destinationSuspendedPage->failedToSuspend()) {
-            ASSERT(!m_mainFrame);
-            ASSERT(&destinationSuspendedPage->process() == m_process.ptr());
-            destinationSuspendedPage->unsuspend();
-            m_mainFrame = WebFrameProxy::create(*this, destinationSuspendedPage->mainFrameID());
-            m_process->frameCreated(destinationSuspendedPage->mainFrameID(), *m_mainFrame);
-        } else {
-            // We failed to suspend the page so destroy it now and merely reuse its WebContent process.
-            destinationSuspendedPage = nullptr;
-        }
-    }
-
     m_process->addExistingWebPage(*this, m_pageID, WebProcessProxy::BeginsUsingDataStore::No);
     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
 
-    finishAttachingToWebProcess(isSwapFromSuspended);
+    // No need to initialize the WebPage since it was created when we created the ProvisionalPageProxy.
+    finishAttachingToWebProcess(ShouldInitializeWebPage::No);
 }
 
-void WebPageProxy::finishAttachingToWebProcess(IsSwapFromSuspended isSwapFromSuspended)
+void WebPageProxy::finishAttachingToWebProcess(ShouldInitializeWebPage shouldInitializePage)
 {
     ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
 
@@ -839,7 +835,8 @@
     m_editableImageController = std::make_unique<EditableImageController>(*this);
 #endif
 
-    initializeWebPage(isSwapFromSuspended);
+    if (shouldInitializePage == ShouldInitializeWebPage::Yes)
+        initializeWebPage();
 
     m_inspector->updateForNewPageProcess(this);
 
@@ -904,13 +901,12 @@
     return WTFMove(navigation);
 }
 
-void WebPageProxy::initializeWebPage(IsSwapFromSuspended isSwapFromSuspended)
+void WebPageProxy::setDrawingArea(std::unique_ptr<DrawingAreaProxy>&& drawingArea)
 {
-    ASSERT(isValid());
+    m_drawingArea = WTFMove(drawingArea);
+    if (!m_drawingArea)
+        return;
 
-    m_drawingArea = pageClient().createDrawingAreaProxy();
-    ASSERT(m_drawingArea);
-
 #if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
     if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
         m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
@@ -920,15 +916,16 @@
 #endif
     }
 #endif
+}
 
-    auto parameters = creationParameters();
-    parameters.isSwapFromSuspended = isSwapFromSuspended == IsSwapFromSuspended::Yes;
+void WebPageProxy::initializeWebPage()
+{
+    ASSERT(isValid());
 
-#if ENABLE(SERVICE_WORKER)
-    parameters.hasRegisteredServiceWorkers = process().processPool().mayHaveRegisteredServiceWorkers(m_websiteDataStore);
-#endif
+    setDrawingArea(pageClient().createDrawingAreaProxy());
+    ASSERT(m_drawingArea);
 
-    process().send(Messages::WebProcess::CreateWebPage(m_pageID, parameters), 0);
+    process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
 
     m_needsToFinishInitializingWebPageAfterProcessLaunch = true;
     finishInitializingWebPageAfterProcessLaunch();
@@ -1080,7 +1077,8 @@
     auto transaction = m_pageLoadState.transaction();
 
     auto url = ""
-    m_pageLoadState.setPendingAPIRequestURL(transaction, url);
+    if (shouldTreatAsContinuingLoad != ShouldTreatAsContinuingLoad::Yes)
+        m_pageLoadState.setPendingAPIRequestURL(transaction, url);
 
     if (!isValid())
         reattachToWebProcess();
@@ -1298,6 +1296,10 @@
     }
 
     m_process->send(Messages::WebPage::StopLoading(), m_pageID);
+    if (m_provisionalPage) {
+        m_provisionalPage->cancel();
+        m_provisionalPage = nullptr;
+    }
     m_process->responsivenessTimer().start();
 }
 
@@ -2696,7 +2698,7 @@
         }
 
         if (processForNavigation.ptr() != &process()) {
-            policyAction = isPageOpenedByDOMShowingInitialEmptyDocument() ? WebPolicyAction::Ignore : WebPolicyAction::Suspend;
+            policyAction = WebPolicyAction::Ignore;
             RELEASE_LOG_IF_ALLOWED(ProcessSwapping, "decidePolicyForNavigationAction, swapping process %i with process %i for navigation, reason: %{public}s", processIdentifier(), processForNavigation->processIdentifier(), reason.utf8().data());
             LOG(ProcessSwapping, "(ProcessSwapping) Switching from process %i to new process (%i) for navigation %" PRIu64 " '%s'", processIdentifier(), processForNavigation->processIdentifier(), navigation->navigationID(), navigation->loggingString());
         } else
@@ -2705,8 +2707,14 @@
         bool shouldProcessSwap = processForNavigation.ptr() != &process();
         receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? WTF::nullopt : WTFMove(data), WTFMove(sender));
 
-        if (shouldProcessSwap)
-            continueNavigationInNewProcess(navigation, destinationSuspendedPage ? process().processPool().takeSuspendedPage(*destinationSuspendedPage) : nullptr, WTFMove(processForNavigation), processSwapRequestedByClient, WTFMove(data));
+        if (!shouldProcessSwap)
+            return;
+
+        auto suspendedPage = destinationSuspendedPage ? process().processPool().takeSuspendedPage(*destinationSuspendedPage) : nullptr;
+        if (suspendedPage && suspendedPage->failedToSuspend())
+            suspendedPage = nullptr;
+
+        continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, WTFMove(data));
     });
 }
 
@@ -2742,25 +2750,46 @@
     sender->send(action, navigation ? navigation->navigationID() : 0, downloadID, WTFMove(websitePolicies));
 }
 
-void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPageProxy, Ref<WebProcessProxy>&& process, ProcessSwapRequestedByClient processSwapRequestedByClient, Optional<WebsitePoliciesData>&& websitePolicies)
+void WebPageProxy::commitProvisionalPage(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData& userData)
 {
-    RELEASE_LOG_IF_ALLOWED(Loading, "continueNavigationInNewProcess: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
-    LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString());
+    ASSERT(m_provisionalPage);
+    RELEASE_LOG_IF_ALLOWED(Loading, "commitProvisionalPage: previousPID = %i, newPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_provisionalPage->process().processIdentifier(), m_pageID);
 
-    Ref<WebProcessProxy> previousProcess = m_process.copyRef();
     Optional<uint64_t> mainFrameIDInPreviousProcess = m_mainFrame ? makeOptional(m_mainFrame->frameID()) : WTF::nullopt;
-    auto mainFrameURL = m_mainFrame ? m_mainFrame->url() : URL();
 
-    ASSERT(m_process.ptr() != process.ptr());
+    ASSERT(m_process.ptr() != &m_provisionalPage->process());
 
     processDidTerminate(ProcessTerminationReason::NavigationSwap);
 
     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
-    bool didSuspendPreviousPage = suspendCurrentPageIfPossible(navigation, mainFrameIDInPreviousProcess, processSwapRequestedByClient);
+    auto* navigation = navigationState().navigation(m_provisionalPage->navigationID());
+    bool didSuspendPreviousPage = navigation ? suspendCurrentPageIfPossible(*navigation, mainFrameIDInPreviousProcess, m_provisionalPage->processSwapRequestedByClient()) : false;
     m_process->removeWebPage(*this, m_pageID, WebProcessProxy::EndsUsingDataStore::No);
 
-    swapToWebProcess(WTFMove(process), WTFMove(suspendedPageProxy), didSuspendPreviousPage ? IsSwapFromSuspended::Yes : IsSwapFromSuspended::No);
+    // There is no way we'll be able to return to the page in the previous page so close it.
+    if (!didSuspendPreviousPage)
+        m_process->send(Messages::WebPage::Close(), pageID());
 
+    swapToWebProcess(m_provisionalPage->process(), m_provisionalPage->takeDrawingArea(), m_provisionalPage->mainFrame());
+
+    didCommitLoadForFrame(frameID, navigationID, mimeType, frameHasCustomContentProvider, frameLoadType, certificateInfo, containsPluginDocument, forcedHasInsecureContent, userData);
+
+    m_provisionalPage = nullptr;
+}
+
+void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPageProxy, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, Optional<WebsitePoliciesData>&& websitePolicies)
+{
+    RELEASE_LOG_IF_ALLOWED(Loading, "continueNavigationInNewProcess: webPID = %i, pageID = %" PRIu64, m_process->processIdentifier(), m_pageID);
+    LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString());
+
+    if (m_provisionalPage) {
+        if (m_provisionalPage->navigationID() != navigation.navigationID())
+            m_provisionalPage->cancel();
+        m_provisionalPage = nullptr;
+    }
+
+    m_provisionalPage = std::make_unique<ProvisionalPageProxy>(*this, newProcess.copyRef(), WTFMove(suspendedPageProxy), navigation.navigationID(), navigation.currentRequestIsRedirect(), navigation.currentRequest(), processSwapRequestedByClient);
+
     if (auto* item = navigation.targetItem()) {
         LOG(Loading, "WebPageProxy %p continueNavigationInNewProcess to back item URL %s", this, item->url().utf8().data());
 
@@ -2767,17 +2796,7 @@
         auto transaction = m_pageLoadState.transaction();
         m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
 
-        auto itemStates = m_backForwardList->filteredItemStates([this, targetItem = item](WebBackForwardListItem& item) {
-            if (auto* page = item.suspendedPage()) {
-                if (&page->process() == m_process.ptr())
-                    return false;
-            }
-            return &item != targetItem;
-        });
-        m_process->send(Messages::WebPage::UpdateBackForwardListForReattach(WTFMove(itemStates)), m_pageID);
-        m_process->send(Messages::WebPage::GoToBackForwardItem(navigation.navigationID(), item->itemID(), *navigation.backForwardFrameLoadType(), ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies)), m_pageID);
-        m_process->responsivenessTimer().start();
-
+        m_provisionalPage->goToBackForwardItem(navigation, *item, WTFMove(websitePolicies));
         return;
     }
 
@@ -2784,50 +2803,15 @@
     if (m_backForwardList->currentItem() && (navigation.lockBackForwardList() == LockBackForwardList::Yes || navigation.lockHistory() == LockHistory::Yes)) {
         // If WebCore is supposed to lock the history for this load, then the new process needs to know about the current history item so it can update
         // it instead of creating a new one.
-        m_process->send(Messages::WebPage::SetCurrentHistoryItemForReattach(m_backForwardList->currentItem()->itemState()), m_pageID);
+        newProcess->send(Messages::WebPage::SetCurrentHistoryItemForReattach(m_backForwardList->currentItem()->itemState()), m_pageID);
     }
 
     // FIXME: Work out timing of responding with the last policy delegate, etc
     ASSERT(!navigation.currentRequest().isEmpty());
     if (auto& substituteData = navigation.substituteData())
-        loadDataWithNavigation(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies));
+        m_provisionalPage->loadDataWithNavigation(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get(), WTFMove(websitePolicies));
     else
-        loadRequestWithNavigation(navigation, ResourceRequest { navigation.currentRequest() }, WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, nullptr, ShouldTreatAsContinuingLoad::Yes, WTFMove(websitePolicies));
-
-    ASSERT(!m_mainFrame);
-    m_mainFrameCreationHandler = [this, weakThis = makeWeakPtr(*this), navigationID = navigation.navigationID(), request =  navigation.currentRequest(), mainFrameURL, isServerRedirect = navigation.currentRequestIsRedirect()]() mutable {
-        if (!weakThis)
-            return;
-
-        ASSERT(m_mainFrame);
-        // This navigation was destroyed so no need to notify of redirect.
-        if (!navigationState().navigation(navigationID))
-            return;
-
-        // Restore the main frame's committed URL as some clients may rely on it until the next load is committed.
-        m_mainFrame->frameLoadState().setURL(mainFrameURL);
-
-        // Normally, notification of a server redirect comes from the WebContent process.
-        // If we are process swapping in response to a server redirect then that notification will not come from the new WebContent process.
-        // In this case we have the UIProcess synthesize the redirect notification at the appropriate time.
-        if (isServerRedirect) {
-            m_mainFrame->frameLoadState().didStartProvisionalLoad(request.url());
-            didReceiveServerRedirectForProvisionalLoadForFrame(m_mainFrame->frameID(), navigationID, WTFMove(request), { });
-        }
-    };
-
-    if (!m_process->processPool().configuration().processSwapsOnWindowOpenWithOpener() || !isPageOpenedByDOMShowingInitialEmptyDocument() || !mainFrameIDInPreviousProcess) {
-        // There is no way we'll be able to return to the page in the previous page so close it.
-        if (!didSuspendPreviousPage)
-            previousProcess->send(Messages::WebPage::Close(), m_pageID);
-        return;
-    }
-
-    m_mainFrameWindowCreationHandler = [this, previousProcess = WTFMove(previousProcess), mainFrameIDInPreviousProcess = *mainFrameIDInPreviousProcess](const GlobalWindowIdentifier& windowIdentifier) {
-        ASSERT(m_mainFrame);
-        GlobalFrameIdentifier navigatedFrameIdentifierInNewProcess { pageID(), m_mainFrame->frameID() };
-        previousProcess->send(Messages::WebPage::FrameBecameRemote(mainFrameIDInPreviousProcess, navigatedFrameIdentifierInNewProcess, windowIdentifier), pageID());
-    };
+        m_provisionalPage->loadRequestWithNavigation(navigation, ResourceRequest { navigation.currentRequest() }, WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, nullptr, WTFMove(websitePolicies));
 }
 
 bool WebPageProxy::isPageOpenedByDOMShowingInitialEmptyDocument() const
@@ -3692,11 +3676,6 @@
 
     // Add the frame to the process wide map.
     m_process->frameCreated(frameID, *m_mainFrame);
-
-    if (m_mainFrameCreationHandler) {
-        m_mainFrameCreationHandler();
-        m_mainFrameCreationHandler = nullptr;
-    }
 }
 
 void WebPageProxy::didCreateSubframe(uint64_t frameID)
@@ -3721,10 +3700,6 @@
 
 void WebPageProxy::didCreateWindow(uint64_t frameID, GlobalWindowIdentifier&& windowIdentifier)
 {
-    if (m_mainFrame && m_mainFrame->frameID() == frameID) {
-        if (auto mainFrameWindowCreationHandler = WTFMove(m_mainFrameWindowCreationHandler))
-            mainFrameWindowCreationHandler(windowIdentifier);
-    }
 }
 
 double WebPageProxy::estimatedProgress() const
@@ -3777,6 +3752,10 @@
 {
     PageClientProtector protector(pageClient());
 
+    // On process-swap, the previous process tries to destroy the navigation but the provisional process is actually taking over the navigation.
+    if (m_provisionalPage && m_provisionalPage->navigationID() == navigationID)
+        return;
+
     // FIXME: Message check the navigationID.
     m_navigationState->didDestroyNavigation(navigationID);
 }
@@ -3794,14 +3773,6 @@
     if (frame->isMainFrame() && navigationID)
         navigation = navigationState().navigation(navigationID);
 
-    // If this seemingly new load is actually continuing a server redirect for a previous navigation in a new process,
-    // then we ignore this notification.
-    if (navigation && navigation->currentRequestIsRedirect()) {
-        auto navigationProcessIdentifier = navigation->currentRequestProcessIdentifier();
-        if (navigationProcessIdentifier && *navigationProcessIdentifier != m_process->coreProcessIdentifier())
-            return;
-    }
-
     LOG(Loading, "WebPageProxy %" PRIu64 " in process pid %i didStartProvisionalLoadForFrame to frameID %" PRIu64 ", navigationID %" PRIu64 ", url %s", m_pageID, m_process->processIdentifier(), frameID, navigationID, url.string().utf8().data());
     RELEASE_LOG_IF_ALLOWED(Loading, "didStartProvisionalLoadForFrame: webPID = %i, pageID = %" PRIu64 ", frameID = %" PRIu64, m_process->processIdentifier(), m_pageID, frameID);
 
@@ -3909,6 +3880,11 @@
 
     PageClientProtector protector(pageClient());
 
+    if (m_provisionalPage && m_provisionalPage->navigationID() == navigationID && &m_provisionalPage->process() != m_process.ptr()) {
+        // The load did not fail, it is merely happening in a new provisional process.
+        return;
+    }
+
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
@@ -3947,6 +3923,10 @@
     }
 
     m_failingProvisionalLoadURL = { };
+
+    // If the provisional page's load fails then we destroy the provisional page.
+    if (m_provisionalPage && m_provisionalPage->mainFrame() == frame)
+        m_provisionalPage = nullptr;
 }
 
 void WebPageProxy::clearLoadDependentCallbacks()
@@ -4338,8 +4318,8 @@
     auto* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
-    decidePolicyForNavigationAction(*frame, WTFMove(frameSecurityOrigin), navigationID, WTFMove(navigationActionData), WTFMove(frameInfoData), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, PolicyDecisionSender::create([this, protectedThis = makeRef(*this), frameID, listenerID] (auto... args) {
-        m_process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, args...), m_pageID);
+    decidePolicyForNavigationAction(*frame, WTFMove(frameSecurityOrigin), navigationID, WTFMove(navigationActionData), WTFMove(frameInfoData), originatingPageID, originalRequest, WTFMove(request), WTFMove(requestBody), WTFMove(redirectResponse), userData, PolicyDecisionSender::create([this, protectedThis = makeRef(*this), frameID, listenerID, process = m_process.copyRef()] (auto... args) {
+        process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, args...), m_pageID);
     }));
 }
 
@@ -4538,12 +4518,12 @@
     MESSAGE_CHECK_URL(response.url());
 
     RefPtr<API::Navigation> navigation = navigationID ? m_navigationState->navigation(navigationID) : nullptr;
-    auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frameID, listenerID, navigation = WTFMove(navigation)] (WebPolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
+    auto listener = makeRef(frame->setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frameID, listenerID, navigation = WTFMove(navigation), process = m_process.copyRef()] (WebPolicyAction policyAction, API::WebsitePolicies*, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning) mutable {
         // FIXME: Assert the API::WebsitePolicies* is nullptr here once clients of WKFramePolicyListenerUseWithPolicies go away.
         RELEASE_ASSERT(processSwapRequestedByClient == ProcessSwapRequestedByClient::No);
         ASSERT_UNUSED(safeBrowsingWarning, !safeBrowsingWarning);
-        receivedPolicyDecision(policyAction, navigation.get(), WTF::nullopt, PolicyDecisionSender::create([this, protectedThis = WTFMove(protectedThis), frameID, listenerID] (auto... args) {
-            m_process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, args...), m_pageID);
+        receivedPolicyDecision(policyAction, navigation.get(), WTF::nullopt, PolicyDecisionSender::create([this, protectedThis = WTFMove(protectedThis), frameID, listenerID, process = WTFMove(process)] (auto... args) {
+            process->send(Messages::WebPage::DidReceivePolicyDecision(frameID, listenerID, args...), m_pageID);
         }));
     }, ShouldExpectSafeBrowsingResult::No));
 
@@ -6363,6 +6343,13 @@
     stopAllURLSchemeTasks();
 }
 
+void WebPageProxy::provisionalProcessDidTerminate()
+{
+    ASSERT(m_provisionalPage);
+    m_provisionalPage->cancel();
+    m_provisionalPage = nullptr;
+}
+
 static bool shouldReloadAfterProcessTermination(ProcessTerminationReason reason)
 {
     switch (reason) {
@@ -6450,8 +6437,6 @@
 void WebPageProxy::resetState(ResetStateReason resetStateReason)
 {
     m_mainFrame = nullptr;
-    m_mainFrameCreationHandler = nullptr;
-    m_mainFrameWindowCreationHandler = nullptr;
 
 #if PLATFORM(COCOA)
     m_scrollingPerformanceData = nullptr;
@@ -6742,6 +6727,10 @@
     parameters.applicationManifest = m_configuration->applicationManifest() ? Optional<WebCore::ApplicationManifest>(m_configuration->applicationManifest()->applicationManifest()) : WTF::nullopt;
 #endif
 
+#if ENABLE(SERVICE_WORKER)
+    parameters.hasRegisteredServiceWorkers = process().processPool().mayHaveRegisteredServiceWorkers(m_websiteDataStore);
+#endif
+
     parameters.needsFontAttributes = m_needsFontAttributes;
 
     m_process->addWebUserContentControllerProxy(m_userContentController, parameters);
@@ -8503,6 +8492,21 @@
     m_process->send(Messages::WebPage::SimulateDeviceOrientationChange(alpha, beta, gamma), m_pageID);
 }
 
+WebPageProxy::PageProcessOverride::PageProcessOverride(WebPageProxy& page, WebProcessProxy& newProcess)
+    : m_page(&page)
+    , m_previousProcess(page.process())
+{
+    page.m_process = newProcess;
+}
+
+WebPageProxy::PageProcessOverride::PageProcessOverride(PageProcessOverride&&) = default;
+
+WebPageProxy::PageProcessOverride::~PageProcessOverride()
+{
+    if (m_page)
+        m_page->m_process = WTFMove(m_previousProcess);
+}
+
 #if ENABLE(DATA_DETECTION)
 
 void WebPageProxy::detectDataInAllFrames(WebCore::DataDetectorTypes types, CompletionHandler<void(const DataDetectionResult&)>&& completionHandler)

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/WebPageProxy.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -225,6 +225,7 @@
 class NativeWebMouseEvent;
 class NativeWebWheelEvent;
 class PageClient;
+class ProvisionalPageProxy;
 class RemoteLayerTreeHost;
 class RemoteLayerTreeScrollingPerformanceData;
 class RemoteLayerTreeTransaction;
@@ -356,7 +357,7 @@
     WebFrameProxy* focusedFrame() const { return m_focusedFrame.get(); }
     WebFrameProxy* frameSetLargestFrame() const { return m_frameSetLargestFrame.get(); }
 
-    DrawingAreaProxy* drawingArea() const { return m_drawingArea.get(); }
+    DrawingAreaProxy* drawingArea() const;
 
     WebNavigationState& navigationState() { return *m_navigationState.get(); }
 
@@ -379,6 +380,7 @@
 
     bool addsVisitedLinks() const { return m_addsVisitedLinks; }
     void setAddsVisitedLinks(bool addsVisitedLinks) { m_addsVisitedLinks = addsVisitedLinks; }
+    VisitedLinkStore& visitedLinkStore() { return m_visitedLinkStore; }
 
     void exitFullscreenImmediately();
     void fullscreenMayReturnToInline();
@@ -458,8 +460,8 @@
     API::IconLoadingClient& iconLoadingClient() { return *m_iconLoadingClient; }
     void setIconLoadingClient(std::unique_ptr<API::IconLoadingClient>&&);
 
-    enum class IsSwapFromSuspended { No, Yes };
-    void initializeWebPage(IsSwapFromSuspended = IsSwapFromSuspended::No);
+    void initializeWebPage();
+    void setDrawingArea(std::unique_ptr<DrawingAreaProxy>&&);
 
     WeakPtr<SecKeyProxyStore> secKeyProxyStore(const WebCore::AuthenticationChallenge&);
         
@@ -997,6 +999,7 @@
     void processDidBecomeUnresponsive();
     void processDidBecomeResponsive();
     void processDidTerminate(ProcessTerminationReason);
+    void provisionalProcessDidTerminate();
     void dispatchProcessDidTerminate(ProcessTerminationReason);
     void willChangeProcessIsResponsive();
     void didChangeProcessIsResponsive();
@@ -1025,6 +1028,19 @@
     WebProcessProxy& process() { return m_process; }
     ProcessID processIdentifier() const;
 
+    class PageProcessOverride {
+    public:
+        PageProcessOverride(WebPageProxy&, WebProcessProxy& newProcess);
+        PageProcessOverride(PageProcessOverride&&);
+        ~PageProcessOverride();
+
+    private:
+        RefPtr<WebPageProxy> m_page;
+        Ref<WebProcessProxy> m_previousProcess;
+    };
+
+    PageProcessOverride temporarilyOverrideProcess(WebProcessProxy& newProcess) { return PageProcessOverride(*this, newProcess); }
+
     WebPreferences& preferences() { return m_preferences; }
     void setPreferences(WebPreferences&);
 
@@ -1414,6 +1430,21 @@
     EditableImageController& editableImageController() { return *m_editableImageController; }
 #endif
 
+    ProvisionalPageProxy* provisionalPageProxy() const { return m_provisionalPage.get(); }
+    void commitProvisionalPage(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
+
+    void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
+    void didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
+    void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
+
+    void loadDataWithNavigation(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+    void loadRequestWithNavigation(API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
+
+    // IPC::MessageReceiver
+    // Implemented in generated WebPageProxyMessageReceiver.cpp
+    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+    void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     void platformInitialize();
@@ -1438,12 +1469,6 @@
 
     void setUserAgent(String&&);
 
-    // IPC::MessageReceiver
-    // Implemented in generated WebPageProxyMessageReceiver.cpp
-    void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
-    void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
-
-
     // IPC::MessageSender
     bool sendMessage(std::unique_ptr<IPC::Encoder>, OptionSet<IPC::SendOption>) override;
     IPC::Connection* messageSenderConnection() override;
@@ -1465,12 +1490,9 @@
     void didCreateSubframe(uint64_t frameID);
     void didCreateWindow(uint64_t frameID, WebCore::GlobalWindowIdentifier&&);
 
-    void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, URL&&, URL&& unreachableURL, const UserData&);
-    void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
     void willPerformClientRedirectForFrame(uint64_t frameID, const String& url, double delay, WebCore::LockBackForwardList);
     void didCancelClientRedirectForFrame(uint64_t frameID);
     void didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, URL&&);
-    void didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&);
     void didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, Optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&);
     void didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&);
     void didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&);
@@ -1574,18 +1596,16 @@
     void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; }
 
     void reattachToWebProcess();
-    void swapToWebProcess(Ref<WebProcessProxy>&&, std::unique_ptr<SuspendedPageProxy>&&, IsSwapFromSuspended);
+    void swapToWebProcess(Ref<WebProcessProxy>&&, std::unique_ptr<DrawingAreaProxy>&&, RefPtr<WebFrameProxy>&& mainFrame);
     void didFailToSuspendAfterProcessSwap();
     void didSuspendAfterProcessSwap();
 
-    void finishAttachingToWebProcess(IsSwapFromSuspended = IsSwapFromSuspended::No);
+    enum class ShouldInitializeWebPage { No, Yes };
+    void finishAttachingToWebProcess(ShouldInitializeWebPage = ShouldInitializeWebPage::Yes);
 
     RefPtr<API::Navigation> reattachToWebProcessForReload();
     RefPtr<API::Navigation> reattachToWebProcessWithItem(WebBackForwardListItem&);
 
-    void loadDataWithNavigation(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
-    void loadRequestWithNavigation(API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
-
     void requestNotificationPermission(uint64_t notificationID, const String& originString);
     void showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, WebCore::NotificationDirection, const String& originString, uint64_t notificationID);
     void cancelNotification(uint64_t notificationID);
@@ -1947,8 +1967,6 @@
     Ref<WebsiteDataStore> m_websiteDataStore;
 
     RefPtr<WebFrameProxy> m_mainFrame;
-    Function<void()> m_mainFrameCreationHandler;
-    Function<void(const WebCore::GlobalWindowIdentifier&)> m_mainFrameWindowCreationHandler;
 
     RefPtr<WebFrameProxy> m_focusedFrame;
     RefPtr<WebFrameProxy> m_frameSetLargestFrame;
@@ -2318,6 +2336,8 @@
     bool m_needsFontAttributes { false };
     bool m_mayHaveUniversalFileReadSandboxExtension { false };
 
+    std::unique_ptr<ProvisionalPageProxy> m_provisionalPage;
+
 #if HAVE(PENCILKIT)
     std::unique_ptr<EditableImageController> m_editableImageController;
 #endif

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -34,6 +34,7 @@
 #include "Logging.h"
 #include "PluginInfoStore.h"
 #include "PluginProcessManager.h"
+#include "ProvisionalPageProxy.h"
 #include "TextChecker.h"
 #include "TextCheckerState.h"
 #include "UIMessagePortChannelProvider.h"
@@ -584,6 +585,15 @@
 }
 #endif
 
+bool WebProcessProxy::hasProvisionalPageWithID(uint64_t pageID) const
+{
+    for (auto* provisionalPage : m_provisionalPages) {
+        if (provisionalPage->page().pageID() == pageID)
+            return true;
+    }
+    return false;
+}
+
 void WebProcessProxy::updateBackForwardItem(const BackForwardListItemState& itemState)
 {
     if (auto* item = WebBackForwardListItem::itemForID(itemState.identifier)) {
@@ -591,7 +601,7 @@
         // the back/forward items page.
         // e.g. The old web process is navigating to about:blank for suspension.
         // We ignore these updates.
-        if (m_pageMap.contains(item->pageID()))
+        if (m_pageMap.contains(item->pageID()) || hasProvisionalPageWithID(item->pageID()))
             item->setPageState(itemState.pageState);
     }
 }
@@ -694,6 +704,7 @@
         webConnection->didClose();
 
     auto pages = copyToVectorOf<RefPtr<WebPageProxy>>(m_pageMap.values());
+    auto provisionalPages = WTF::map(m_provisionalPages, [](auto* provisionalPage) { return makeWeakPtr(provisionalPage); });
 
     shutDown();
 
@@ -708,6 +719,11 @@
 
     for (auto& page : pages)
         page->processDidTerminate(ProcessTerminationReason::Crash);
+
+    for (auto& provisionalPage : provisionalPages) {
+        if (provisionalPage)
+            provisionalPage->processDidTerminate();
+    }
 }
 
 void WebProcessProxy::didReceiveInvalidMessage(IPC::Connection& connection, IPC::StringReference messageReceiverName, IPC::StringReference messageName)
@@ -780,6 +796,12 @@
         page->processDidFinishLaunching();
     }
 
+    for (auto* provisionalPage : m_provisionalPages) {
+        ASSERT(this == &provisionalPage->process());
+        provisionalPage->processDidFinishLaunching();
+    }
+
+
     RELEASE_ASSERT(!m_webConnection);
     m_webConnection = WebConnectionToWebProcess::create(this);
 
@@ -873,7 +895,7 @@
 
 bool WebProcessProxy::canTerminateChildProcess()
 {
-    if (!m_pageMap.isEmpty() || m_processPool->hasSuspendedPageFor(*this))
+    if (!m_pageMap.isEmpty() || m_processPool->hasSuspendedPageFor(*this) || !m_provisionalPages.isEmpty())
         return false;
 
     if (!m_processPool->shouldTerminate(this))

Modified: branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/UIProcess/WebProcessProxy.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -70,6 +70,7 @@
 class NetworkProcessProxy;
 class ObjCObjectGraph;
 class PageClient;
+class ProvisionalPageProxy;
 class UserMediaCaptureManagerProxy;
 class VisitedLinkStore;
 class WebBackForwardListItem;
@@ -124,6 +125,9 @@
     enum class EndsUsingDataStore : bool { No, Yes };
     void removeWebPage(WebPageProxy&, uint64_t pageID, EndsUsingDataStore);
 
+    void addProvisionalPageProxy(ProvisionalPageProxy& provisionalPage) { ASSERT(!m_provisionalPages.contains(&provisionalPage)); m_provisionalPages.add(&provisionalPage); }
+    void removeProvisionalPageProxy(ProvisionalPageProxy& provisionalPage) { ASSERT(m_provisionalPages.contains(&provisionalPage)); m_provisionalPages.remove(&provisionalPage); }
+
     typename WebPageProxyMap::ValuesConstIteratorRange pages() const { return m_pageMap.values(); }
     unsigned pageCount() const { return m_pageMap.size(); }
     unsigned visiblePageCount() const { return m_visiblePageCounter.value(); }
@@ -330,6 +334,8 @@
 
     void logDiagnosticMessageForResourceLimitTermination(const String& limitKey);
 
+    bool hasProvisionalPageWithID(uint64_t pageID) const;
+
     enum class IsWeak { No, Yes };
     template<typename T> class WeakOrStrongPtr {
     public:
@@ -373,6 +379,7 @@
 
     WebPageProxyMap m_pageMap;
     WebFrameProxyMap m_frameMap;
+    HashSet<ProvisionalPageProxy*> m_provisionalPages;
     UserInitiatedActionMap m_userInitiatedActionMap;
 
     HashSet<VisitedLinkStore*> m_visitedLinkStores;

Modified: branches/safari-607-branch/Source/WebKit/WebKit.xcodeproj/project.pbxproj (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2019-01-22 20:58:17 UTC (rev 240280)
@@ -3095,6 +3095,8 @@
 		466BC0381FA266C9002FA9C1 /* WebSWContextManagerConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSWContextManagerConnection.cpp; sourceTree = "<group>"; };
 		466BC0391FA266C9002FA9C1 /* WebSWContextManagerConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSWContextManagerConnection.h; sourceTree = "<group>"; };
 		466BC03A1FA266C9002FA9C1 /* WebSWContextManagerConnection.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebSWContextManagerConnection.messages.in; sourceTree = "<group>"; };
+		4683569A21E81CC7006E27A3 /* ProvisionalPageProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProvisionalPageProxy.h; sourceTree = "<group>"; };
+		4683569B21E81CC7006E27A3 /* ProvisionalPageProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProvisionalPageProxy.cpp; sourceTree = "<group>"; };
 		46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackgroundProcessResponsivenessTimer.cpp; sourceTree = "<group>"; };
 		46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundProcessResponsivenessTimer.h; sourceTree = "<group>"; };
 		46DF06391F3905E5001980BB /* NetworkCORSPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCORSPreflightChecker.cpp; sourceTree = "<group>"; };
@@ -7320,6 +7322,8 @@
 				86E67A22190F411800004AB7 /* ProcessThrottler.cpp */,
 				86E67A21190F411800004AB7 /* ProcessThrottler.h */,
 				83048AE51ACA45DC0082C832 /* ProcessThrottlerClient.h */,
+				4683569B21E81CC7006E27A3 /* ProvisionalPageProxy.cpp */,
+				4683569A21E81CC7006E27A3 /* ProvisionalPageProxy.h */,
 				A55BA81B1BA25B1E007CD33D /* RemoteWebInspectorProxy.cpp */,
 				A55BA8191BA25B1E007CD33D /* RemoteWebInspectorProxy.h */,
 				A55BA81A1BA25B1E007CD33D /* RemoteWebInspectorProxy.messages.in */,

Modified: branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebFrame.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebFrame.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebFrame.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -263,8 +263,6 @@
         return WebCore::PolicyAction::Ignore;
     case WebPolicyAction::Download:
         return WebCore::PolicyAction::Download;
-    case WebPolicyAction::Suspend:
-        break;
     }
     ASSERT_NOT_REACHED();
     return WebCore::PolicyAction::Ignore;
@@ -272,11 +270,8 @@
 
 void WebFrame::didReceivePolicyDecision(uint64_t listenerID, WebPolicyAction action, uint64_t navigationID, DownloadID downloadID, Optional<WebsitePoliciesData>&& websitePolicies)
 {
-    if (!m_coreFrame || !m_policyListenerID || listenerID != m_policyListenerID || !m_policyFunction) {
-        if (action == WebPolicyAction::Suspend)
-            page()->send(Messages::WebPageProxy::DidFailToSuspendAfterProcessSwap());
+    if (!m_coreFrame || !m_policyListenerID || listenerID != m_policyListenerID || !m_policyFunction)
         return;
-    }
 
     FramePolicyFunction function = WTFMove(m_policyFunction);
     bool forNavigationAction = m_policyFunctionForNavigationAction == ForNavigationAction::Yes;
@@ -292,16 +287,7 @@
             documentLoader->setNavigationID(navigationID);
     }
 
-    bool shouldSuspend = false;
-    if (action == WebPolicyAction::Suspend) {
-        shouldSuspend = true;
-        action = ""
-    }
-
     function(toPolicyAction(action));
-
-    if (shouldSuspend)
-        page()->suspendForProcessSwap();
 }
 
 void WebFrame::startDownload(const WebCore::ResourceRequest& request, const String& suggestedName)

Modified: branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2019-01-22 20:58:17 UTC (rev 240280)
@@ -402,7 +402,7 @@
     , m_overrideContentSecurityPolicy { parameters.overrideContentSecurityPolicy }
     , m_cpuLimit(parameters.cpuLimit)
 #if PLATFORM(MAC)
-    , m_shouldAttachDrawingAreaOnPageTransition(parameters.isSwapFromSuspended)
+    , m_shouldAttachDrawingAreaOnPageTransition(parameters.isProcessSwap)
 #endif
 {
     ASSERT(m_pageID);
@@ -472,8 +472,8 @@
     m_drawingArea->setPaintingEnabled(false);
     m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
 
-    if (parameters.isSwapFromSuspended)
-        freezeLayerTree(LayerTreeFreezeReason::SwapFromSuspended);
+    if (parameters.isProcessSwap)
+        freezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
 
 #if ENABLE(ASYNC_SCROLLING)
     m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
@@ -697,7 +697,7 @@
         m_drawingArea->updatePreferences(parameters.store);
         m_drawingArea->setPaintingEnabled(true);
 #if PLATFORM(MAC)
-        m_shouldAttachDrawingAreaOnPageTransition = parameters.isSwapFromSuspended;
+        m_shouldAttachDrawingAreaOnPageTransition = parameters.isProcessSwap;
 #endif
         unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended);
     }
@@ -3056,12 +3056,6 @@
     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
     if (!frame)
         return;
-    if (policyAction == WebPolicyAction::Suspend) {
-        ASSERT(frame == m_mainFrame);
-        setIsSuspended(true);
-
-        WebProcess::singleton().sendPrewarmInformation(mainWebFrame()->url());
-    }
     frame->didReceivePolicyDecision(listenerID, policyAction, navigationID, downloadID, WTFMove(websitePolicies));
 }
 
@@ -3103,7 +3097,7 @@
 
     bool isInitialEmptyDocument = !m_mainFrame;
     if (!isInitialEmptyDocument)
-        unfreezeLayerTree(LayerTreeFreezeReason::SwapFromSuspended);
+        unfreezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
 
 #if PLATFORM(MAC)
     if (m_shouldAttachDrawingAreaOnPageTransition && !isInitialEmptyDocument) {
@@ -6315,6 +6309,10 @@
     if (m_isSuspended) {
         // Unfrozen on drawing area reset.
         freezeLayerTree(LayerTreeFreezeReason::PageSuspended);
+
+        WebProcess::singleton().sendPrewarmInformation(mainWebFrame()->url());
+
+        suspendForProcessSwap();
     } else
         m_shouldResetDrawingAreaAfterSuspend = true;
 }

Modified: branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-01-22 20:58:17 UTC (rev 240280)
@@ -696,7 +696,7 @@
         ProcessSuspended        = 1 << 2,
         PageSuspended           = 1 << 3,
         Printing                = 1 << 4,
-        SwapFromSuspended       = 1 << 5,
+        ProcessSwap             = 1 << 5,
     };
     void freezeLayerTree(LayerTreeFreezeReason);
     void unfreezeLayerTree(LayerTreeFreezeReason);

Modified: branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm (240279 => 240280)


--- branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm	2019-01-22 20:58:17 UTC (rev 240280)
@@ -97,7 +97,7 @@
     updateLayerHostingContext();
     setColorSpace(parameters.colorSpace);
 
-    if (!parameters.isSwapFromSuspended)
+    if (!parameters.isProcessSwap)
         attach();
 }
 

Modified: branches/safari-607-branch/Tools/ChangeLog (240279 => 240280)


--- branches/safari-607-branch/Tools/ChangeLog	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Tools/ChangeLog	2019-01-22 20:58:17 UTC (rev 240280)
@@ -1,5 +1,9 @@
 2019-01-22  Alan Coon  <alanc...@apple.com>
 
+        Revert r240262. rdar://problem/47099573
+
+2019-01-22  Alan Coon  <alanc...@apple.com>
+
         Revert r240263. rdar://problem/47099573
 
 2019-01-22  Alan Coon  <alanc...@apple.com>

Modified: branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (240279 => 240280)


--- branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2019-01-22 20:58:07 UTC (rev 240279)
+++ branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2019-01-22 20:58:17 UTC (rev 240280)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -72,6 +72,7 @@
 static HashSet<pid_t> seenPIDs;
 static bool willPerformClientRedirect;
 static bool didPerformClientRedirect;
+static bool shouldConvertToDownload;
 static RetainPtr<NSURL> clientRedirectSourceURL;
 static RetainPtr<NSURL> clientRedirectDestinationURL;
 
@@ -128,6 +129,11 @@
     didRepondToPolicyDecisionCall = true;
 }
 
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
+{
+    decisionHandler(shouldConvertToDownload ? _WKNavigationResponsePolicyBecomeDownload : WKNavigationResponsePolicyAllow);
+}
+
 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
 {
     seenPIDs.add([webView _webProcessIdentifier]);
@@ -1405,7 +1411,7 @@
 
     EXPECT_FALSE(serverRedirected);
     EXPECT_EQ(3, numberOfDecidePolicyCalls);
-    EXPECT_EQ(2u, seenPIDs.size());
+    EXPECT_EQ(3u, seenPIDs.size());
 }
 
 TEST(ProcessSwap, ServerRedirect2)
@@ -1467,6 +1473,109 @@
     EXPECT_WK_STREQ(@"pson://www.webkit.org/main1.html", [[webView URL] absoluteString]);
 }
 
+static const char* linkToWebKitBytes = R"PSONRESOURCE(
+<body>
+  <a id="testLink" href=""
+</body>
+)PSONRESOURCE";
+
+TEST(ProcessSwap, PolicyCancelAfterServerRedirect)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.google.com/main.html" toData:linkToWebKitBytes];
+    [handler addRedirectFromURLString:@"pson://www.webkit.org/main.html" toURLString:@"pson://www.apple.com/ignore.html"];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    navigationDelegate->decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
+        if ([action.request.URL.absoluteString hasSuffix:@"ignore.html"]) {
+            decisionHandler(WKNavigationActionPolicyCancel);
+            return;
+        }
+        decisionHandler(WKNavigationActionPolicyAllow);
+    };
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.google.com/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+    auto pidAfterFirstLoad = [webView _webProcessIdentifier];
+
+    EXPECT_EQ(1, numberOfDecidePolicyCalls);
+
+    [webView evaluateJavaScript:@"testLink.click()" completionHandler:nil];
+
+    TestWebKitAPI::Util::run(&failed);
+    failed = false;
+    done = false;
+
+    EXPECT_EQ(3, numberOfDecidePolicyCalls);
+
+    // We should still be on google.com.
+    EXPECT_EQ(pidAfterFirstLoad, [webView _webProcessIdentifier]);
+    EXPECT_WK_STREQ(@"pson://www.google.com/main.html", [[webView URL] absoluteString]);
+
+    [webView evaluateJavaScript:@"testLink.innerText" completionHandler: [&] (id innerText, NSError *error) {
+        EXPECT_WK_STREQ(@"Link", innerText);
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+}
+
+TEST(ProcessSwap, CrossSiteDownload)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    processPoolConfiguration.get().processSwapsOnNavigation = YES;
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [handler addMappingFromURLString:@"pson://www.google.com/main.html" toData:linkToWebKitBytes];
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main.html" toData:"Hello"];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.google.com/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+    auto pidAfterFirstLoad = [webView _webProcessIdentifier];
+
+    shouldConvertToDownload = true;
+    [webView evaluateJavaScript:@"testLink.click()" completionHandler:nil];
+
+    TestWebKitAPI::Util::run(&failed);
+    failed = false;
+    shouldConvertToDownload = false;
+
+    // We should still be on google.com.
+    EXPECT_EQ(pidAfterFirstLoad, [webView _webProcessIdentifier]);
+    EXPECT_WK_STREQ(@"pson://www.google.com/main.html", [[webView URL] absoluteString]);
+
+    [webView evaluateJavaScript:@"testLink.innerText" completionHandler: [&] (id innerText, NSError *error) {
+        EXPECT_WK_STREQ(@"Link", innerText);
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+}
+
 enum class ShouldEnablePSON { No, Yes };
 static void runClientSideRedirectTest(ShouldEnablePSON shouldEnablePSON)
 {
@@ -2232,12 +2341,27 @@
 
     EXPECT_EQ(7u, [receivedMessages count]);
     EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pageshow NOT persisted", receivedMessages.get()[0]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[1]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow NOT persisted", receivedMessages.get()[2]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pagehide persisted", receivedMessages.get()[3]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pageshow persisted", receivedMessages.get()[4]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[5]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow persisted", receivedMessages.get()[6]);
+    if ([receivedMessages.get()[1] hasPrefix:@"pson://www.webkit.org/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[1]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow NOT persisted", receivedMessages.get()[2]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow NOT persisted", receivedMessages.get()[1]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[2]);
+    }
+    if ([receivedMessages.get()[3] hasPrefix:@"pson://www.apple.com/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pagehide persisted", receivedMessages.get()[3]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pageshow persisted", receivedMessages.get()[4]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pageshow persisted", receivedMessages.get()[3]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pagehide persisted", receivedMessages.get()[4]);
+    }
+    if ([receivedMessages.get()[5] hasPrefix:@"pson://www.webkit.org/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[5]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow persisted", receivedMessages.get()[6]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - pageshow persisted", receivedMessages.get()[5]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - pagehide persisted", receivedMessages.get()[6]);
+    }
 }
 
 // Disabling the page cache explicitly is (for some reason) not available on iOS.
@@ -2307,12 +2431,27 @@
 
     EXPECT_EQ(7u, [receivedMessages count]);
     EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - load", receivedMessages.get()[0]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[1]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[2]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - unload", receivedMessages.get()[3]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - load", receivedMessages.get()[4]);
-    EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[5]);
-    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[6]);
+    if ([receivedMessages.get()[1] hasPrefix:@"pson://www.webkit.org/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[1]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[2]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[1]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[2]);
+    }
+    if ([receivedMessages.get()[3] hasPrefix:@"pson://www.apple.com/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - unload", receivedMessages.get()[3]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - load", receivedMessages.get()[4]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - load", receivedMessages.get()[3]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - unload", receivedMessages.get()[4]);
+    }
+    if ([receivedMessages.get()[5] hasPrefix:@"pson://www.webkit.org/main.html"]) {
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[5]);
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[6]);
+    } else {
+        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html - load", receivedMessages.get()[5]);
+        EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html - unload", receivedMessages.get()[6]);
+    }
 }
 
 TEST(ProcessSwap, WebInspector)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to