Diff
Modified: trunk/Source/WebCore/ChangeLog (230050 => 230051)
--- trunk/Source/WebCore/ChangeLog 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebCore/ChangeLog 2018-03-28 21:21:43 UTC (rev 230051)
@@ -1,5 +1,33 @@
2018-03-28 Chris Dumez <cdu...@apple.com>
+ Do process swap when opening a cross-origin URL via window.open(url, '_blank', 'noopener')
+ https://bugs.webkit.org/show_bug.cgi?id=183962
+ <rdar://problem/38817833>
+
+ Reviewed by Brady Eidson.
+
+ Pass extra bits of information to the UIProcess via NavigationAction:
+ - Is it a cross origin navigation caused by window.open()
+ - Does the navigated frame have an opener
+
+ This information is useful to determine on UIProcess side if we want
+ to swap WebProcess.
+
+ * loader/FrameLoadRequest.h:
+ (WebCore::FrameLoadRequest::setIsCrossOriginWindowOpenNavigation):
+ (WebCore::FrameLoadRequest::isCrossOriginWindowOpenNavigation const):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadURL):
+ * loader/NavigationAction.h:
+ (WebCore::NavigationAction::setIsCrossOriginWindowOpenNavigation):
+ (WebCore::NavigationAction::isCrossOriginWindowOpenNavigation const):
+ (WebCore::NavigationAction::setOpener):
+ (WebCore::NavigationAction::opener const):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::createWindow):
+
+2018-03-28 Chris Dumez <cdu...@apple.com>
+
Thread safety issue in IDBFactory' shouldThrowSecurityException()
https://bugs.webkit.org/show_bug.cgi?id=184064
Modified: trunk/Source/WebCore/loader/FrameLoadRequest.h (230050 => 230051)
--- trunk/Source/WebCore/loader/FrameLoadRequest.h 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebCore/loader/FrameLoadRequest.h 2018-03-28 21:21:43 UTC (rev 230051)
@@ -84,6 +84,9 @@
InitiatedByMainFrame initiatedByMainFrame() const { return m_initiatedByMainFrame; }
+ void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
+ bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
+
private:
Ref<Document> m_requester;
Ref<SecurityOrigin> m_requesterSecurityOrigin;
@@ -102,6 +105,7 @@
ShouldOpenExternalURLsPolicy m_shouldOpenExternalURLsPolicy { ShouldOpenExternalURLsPolicy::ShouldNotAllow };
AtomicString m_downloadAttribute;
InitiatedByMainFrame m_initiatedByMainFrame { InitiatedByMainFrame::Unknown };
+ bool m_isCrossOriginWindowOpenNavigation { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (230050 => 230051)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -1306,6 +1306,13 @@
return;
NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
+ action.setIsCrossOriginWindowOpenNavigation(frameLoadRequest.isCrossOriginWindowOpenNavigation());
+ if (auto* opener = this->opener()) {
+ auto pageID = opener->loader().client().pageID();
+ auto frameID = opener->loader().client().frameID();
+ if (pageID && frameID)
+ action.setOpener(std::make_pair(*pageID, *frameID));
+ }
if (!targetFrame && !frameName.isEmpty()) {
action = "" frameLoadRequest));
Modified: trunk/Source/WebCore/loader/NavigationAction.h (230050 => 230051)
--- trunk/Source/WebCore/loader/NavigationAction.h 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebCore/loader/NavigationAction.h 2018-03-28 21:21:43 UTC (rev 230051)
@@ -72,6 +72,12 @@
const AtomicString& downloadAttribute() const { return m_downloadAttribute; }
+ void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
+ bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
+
+ void setOpener(std::optional<std::pair<uint64_t, uint64_t>>&& opener) { m_opener = WTFMove(opener); }
+ const std::optional<std::pair<uint64_t, uint64_t>>& opener() const { return m_opener; }
+
private:
RefPtr<Document> m_sourceDocument;
ResourceRequest m_resourceRequest;
@@ -81,6 +87,8 @@
RefPtr<Event> m_event;
RefPtr<UserGestureToken> m_userGestureToken { UserGestureIndicator::currentUserGesture() };
AtomicString m_downloadAttribute;
+ bool m_isCrossOriginWindowOpenNavigation { false };
+ std::optional<std::pair<uint64_t /* pageID */, uint64_t /* frameID */>> m_opener;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (230050 => 230051)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -2279,6 +2279,8 @@
if (created) {
ResourceRequest resourceRequest { completedURL, referrer, UseProtocolCachePolicy };
FrameLoadRequest frameLoadRequest { *activeWindow.document(), activeWindow.document()->securityOrigin(), resourceRequest, ASCIILiteral("_self"), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, activeDocument->shouldOpenExternalURLsPolicyToPropagate(), initiatedByMainFrame };
+ if (openerFrame.document() && !protocolHostAndPortAreEqual(openerFrame.document()->url(), frameLoadRequest.resourceRequest().url()))
+ frameLoadRequest.setIsCrossOriginWindowOpenNavigation(true);
newFrame->loader().changeLocation(WTFMove(frameLoadRequest));
#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
Modified: trunk/Source/WebKit/ChangeLog (230050 => 230051)
--- trunk/Source/WebKit/ChangeLog 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/ChangeLog 2018-03-28 21:21:43 UTC (rev 230051)
@@ -1,3 +1,34 @@
+2018-03-28 Chris Dumez <cdu...@apple.com>
+
+ Do process swap when opening a cross-origin URL via window.open(url, '_blank', 'noopener')
+ https://bugs.webkit.org/show_bug.cgi?id=183962
+ <rdar://problem/38817833>
+
+ Reviewed by Brady Eidson.
+
+ Swap WebProcess on for the initial navigation in a new Window that was opened
+ via window.open(), when the new URL is cross-origin compared to the opener's
+ origin. For now, we only swap process if 'noopener' property is set when calling
+ window.open(). This is because we do not support the remote DOMWindows yet.
+
+ * Shared/NavigationActionData.cpp:
+ (WebKit::NavigationActionData::encode const):
+ (WebKit::NavigationActionData::decode):
+ * Shared/NavigationActionData.h:
+ * UIProcess/API/APINavigation.h:
+ (API::Navigation::setIsCrossOriginWindowOpenNavigation):
+ (API::Navigation::isCrossOriginWindowOpenNavigation const):
+ (API::Navigation::setOpener):
+ (API::Navigation::opener const):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::receivedPolicyDecision):
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::processForNavigation):
+ * UIProcess/WebProcessPool.h:
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+
2018-03-28 Per Arne Vollan <pvol...@apple.com>
Adopt WEBPROCESS_WINDOWSERVER_BLOCKING compiler guard in WebProcess.
Modified: trunk/Source/WebKit/Shared/NavigationActionData.cpp (230050 => 230051)
--- trunk/Source/WebKit/Shared/NavigationActionData.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/Shared/NavigationActionData.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -47,6 +47,8 @@
encoder << downloadAttribute;
encoder << clickLocationInRootViewCoordinates;
encoder << isRedirect;
+ encoder << isCrossOriginWindowOpenNavigation;
+ encoder << opener;
}
std::optional<NavigationActionData> NavigationActionData::decode(IPC::Decoder& decoder)
@@ -95,7 +97,17 @@
if (!isRedirect)
return std::nullopt;
- return {{ WTFMove(navigationType), WTFMove(modifiers), WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier), WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates), WTFMove(*isRedirect) }};
+ std::optional<bool> isCrossOriginWindowOpenNavigation;
+ decoder >> isCrossOriginWindowOpenNavigation;
+ if (!isCrossOriginWindowOpenNavigation)
+ return std::nullopt;
+
+ std::optional<std::optional<std::pair<uint64_t, uint64_t>>> opener;
+ decoder >> opener;
+ if (!opener)
+ return std::nullopt;
+
+ return {{ WTFMove(navigationType), WTFMove(modifiers), WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier), WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates), WTFMove(*isRedirect), *isCrossOriginWindowOpenNavigation, WTFMove(*opener) }};
}
} // namespace WebKit
Modified: trunk/Source/WebKit/Shared/NavigationActionData.h (230050 => 230051)
--- trunk/Source/WebKit/Shared/NavigationActionData.h 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/Shared/NavigationActionData.h 2018-03-28 21:21:43 UTC (rev 230051)
@@ -50,6 +50,8 @@
WTF::String downloadAttribute;
WebCore::FloatPoint clickLocationInRootViewCoordinates;
bool isRedirect { false };
+ bool isCrossOriginWindowOpenNavigation { false };
+ std::optional<std::pair<uint64_t, uint64_t>> opener;
};
}
Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (230050 => 230051)
--- trunk/Source/WebKit/UIProcess/API/APINavigation.h 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h 2018-03-28 21:21:43 UTC (rev 230051)
@@ -31,7 +31,7 @@
namespace WebCore {
enum class FrameLoadType;
-};
+}
namespace WebKit {
class WebBackForwardListItem;
@@ -75,6 +75,12 @@
void setShouldForceDownload(bool value) { m_shouldForceDownload = value; }
bool shouldForceDownload() const { return m_shouldForceDownload; }
+ void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
+ bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
+
+ void setOpener(const std::optional<std::pair<uint64_t, uint64_t>>& opener) { m_opener = opener; }
+ const std::optional<std::pair<uint64_t, uint64_t>>& opener() const { return m_opener; }
+
#if !LOG_DISABLED
WTF::String loggingURL() const;
#endif
@@ -92,6 +98,8 @@
RefPtr<WebKit::WebBackForwardListItem> m_backForwardListItem;
std::optional<WebCore::FrameLoadType> m_backForwardFrameLoadType;
+ bool m_isCrossOriginWindowOpenNavigation { false };
+ std::optional<std::pair<uint64_t, uint64_t>> m_opener;
};
} // namespace API
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (230050 => 230051)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -2351,11 +2351,10 @@
ASSERT(activePolicyListener->listenerID() == listenerID);
if (action == PolicyAction::Use && navigation) {
- auto proposedProcess = process().processPool().processForNavigation(*this, navigation->request().url());
+ auto proposedProcess = process().processPool().processForNavigation(*this, *navigation, action);
if (proposedProcess.ptr() != &process()) {
LOG(Loading, "Switching to new process for navigation %" PRIu64 " to url '%s' (WebBackForwardListItem %p)", navigation->navigationID(), navigation->loggingURL().utf8().data(), navigation->backForwardListItem());
- action = ""
RunLoop::main().dispatch([this, protectedThis = makeRef(*this), navigation = makeRef(*navigation), proposedProcess = WTFMove(proposedProcess)]() mutable {
continueNavigationInNewProcess(navigation.get(), WTFMove(proposedProcess));
});
@@ -3809,20 +3808,15 @@
uint64_t newNavigationID { 0 };
Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID, PolicyListenerType::NavigationAction);
- if (!navigationID) {
- auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
- newNavigationID = navigation->navigationID();
- navigation->setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
- navigation->setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
- listener->setNavigation(WTFMove(navigation));
- } else {
- auto& navigation = m_navigationState->navigation(navigationID);
- newNavigationID = navigationID;
- navigation.setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
- navigation.setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
- listener->setNavigation(navigation);
- }
+ Ref<API::Navigation> navigation = navigationID ? makeRef(m_navigationState->navigation(navigationID)) : m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
+ newNavigationID = navigation->navigationID();
+ navigation->setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
+ navigation->setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
+ navigation->setIsCrossOriginWindowOpenNavigation(navigationActionData.isCrossOriginWindowOpenNavigation);
+ navigation->setOpener(navigationActionData.opener);
+ listener->setNavigation(WTFMove(navigation));
+
#if ENABLE(CONTENT_FILTERING)
if (frame->didHandleContentFilterUnblockNavigation(request))
return receivedPolicyDecision(PolicyAction::Ignore, *frame, listenerID, &m_navigationState->navigation(newNavigationID), { });
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (230050 => 230051)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -1965,15 +1965,26 @@
}
#endif
-Ref<WebProcessProxy> WebProcessPool::processForNavigation(WebPageProxy& page, const URL& targetURL)
+Ref<WebProcessProxy> WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, PolicyAction& action)
{
if (!m_configuration->processSwapsOnNavigation())
return page.process();
+ // FIXME: We should support process swap when a window has an opener.
+ if (navigation.opener())
+ return page.process();
+
+ if (navigation.isCrossOriginWindowOpenNavigation()) {
+ action = ""
+ return createNewWebProcess(page.websiteDataStore());
+ }
+
+ auto targetURL = navigation.request().url();
auto url = "" { ParsedURLString, page.pageLoadState().url() };
- if (protocolHostAndPortAreEqual(url, targetURL) || url.isBlankURL())
+ if (!url.isValid() || url.isBlankURL() || protocolHostAndPortAreEqual(url, targetURL))
return page.process();
+ action = ""
return createNewWebProcess(page.websiteDataStore());
}
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (230050 => 230051)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2018-03-28 21:21:43 UTC (rev 230051)
@@ -445,7 +445,7 @@
BackgroundWebProcessToken backgroundWebProcessToken() const { return BackgroundWebProcessToken(m_backgroundWebProcessCounter.count()); }
#endif
- Ref<WebProcessProxy> processForNavigation(WebPageProxy&, const WebCore::URL&);
+ Ref<WebProcessProxy> processForNavigation(WebPageProxy&, const API::Navigation&, WebCore::PolicyAction&);
private:
void platformInitialize();
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (230050 => 230051)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2018-03-28 21:21:43 UTC (rev 230051)
@@ -861,6 +861,8 @@
navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
navigationActionData.isRedirect = didReceiveRedirectResponse;
+ navigationActionData.isCrossOriginWindowOpenNavigation = navigationAction.isCrossOriginWindowOpenNavigation();
+ navigationActionData.opener = navigationAction.opener();
WebCore::Frame* coreFrame = m_frame->coreFrame();
if (!coreFrame)
Modified: trunk/Tools/ChangeLog (230050 => 230051)
--- trunk/Tools/ChangeLog 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Tools/ChangeLog 2018-03-28 21:21:43 UTC (rev 230051)
@@ -1,3 +1,17 @@
+2018-03-28 Chris Dumez <cdu...@apple.com>
+
+ Do process swap when opening a cross-origin URL via window.open(url, '_blank', 'noopener')
+ https://bugs.webkit.org/show_bug.cgi?id=183962
+ <rdar://problem/38817833>
+
+ Reviewed by Brady Eidson.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+ (-[PSONUIDelegate initWithNavigationDelegate:]):
+ (-[PSONUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
+
2018-03-28 Carlos Eduardo Ramalho <cadubent...@gmail.com>
Add Carlos Eduardo Ramalho as contributor
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (230050 => 230051)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-03-28 21:17:14 UTC (rev 230050)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-03-28 21:21:43 UTC (rev 230051)
@@ -30,6 +30,7 @@
#import <WebKit/WKNavigationDelegate.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
+#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKURLSchemeHandler.h>
#import <WebKit/WKURLSchemeTaskPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
@@ -40,6 +41,7 @@
#import <WebKit/_WKExperimentalFeature.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
+#import <WebKit/_WKWebsitePolicies.h>
#import <wtf/Deque.h>
#import <wtf/HashMap.h>
#import <wtf/RetainPtr.h>
@@ -50,6 +52,7 @@
#if WK_API_ENABLED
static bool done;
+static bool didCreateWebView;
static int numberOfDecidePolicyCalls;
static RetainPtr<NSMutableArray> receivedMessages = adoptNS([@[] mutableCopy]);
@@ -83,6 +86,35 @@
@end
+static RetainPtr<WKWebView> createdWebView;
+
+@interface PSONUIDelegate : NSObject <WKUIDelegatePrivate>
+- (instancetype)initWithNavigationDelegate:(PSONNavigationDelegate *)navigationDelegate;
+@end
+
+@implementation PSONUIDelegate {
+ RetainPtr<PSONNavigationDelegate> _navigationDelegate;
+}
+
+- (instancetype)initWithNavigationDelegate:(PSONNavigationDelegate *)navigationDelegate
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _navigationDelegate = navigationDelegate;
+ return self;
+}
+
+- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
+{
+ createdWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);
+ [createdWebView setNavigationDelegate:_navigationDelegate.get()];
+ didCreateWebView = true;
+ return createdWebView.get();
+}
+
+@end
+
@interface PSONScheme : NSObject <WKURLSchemeHandler> {
const char* _bytes;
}
@@ -140,6 +172,35 @@
</head>
)PSONRESOURCE";
+static const char* windowOpenCrossOriginNoOpenerTestBytes = R"PSONRESOURCE(
+<script>
+window._onload_ = function() {
+ window.open("pson2://host/main2.html", "_blank", "noopener");
+}
+</script>
+)PSONRESOURCE";
+
+static const char* windowOpenCrossOriginWithOpenerTestBytes = R"PSONRESOURCE(
+<script>
+window._onload_ = function() {
+ window.open("pson2://host/main2.html");
+}
+</script>
+)PSONRESOURCE";
+
+static const char* windowOpenSameOriginNoOpenerTestBytes = R"PSONRESOURCE(
+<script>
+window._onload_ = function() {
+ if (!opener)
+ window.open("pson1://host/main2.html", "_blank", "noopener");
+}
+</script>
+)PSONRESOURCE";
+
+static const char* dummyBytes = R"PSONRESOURCE(
+<body>TEST</body>
+)PSONRESOURCE";
+
TEST(ProcessSwap, Basic)
{
auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
@@ -253,4 +314,126 @@
EXPECT_FALSE(pid1 == pid3);
}
+TEST(ProcessSwap, CrossOriginWindowOpenNoOpener)
+{
+ 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()];
+ RetainPtr<PSONScheme> handler1 = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenCrossOriginNoOpenerTestBytes]);
+ RetainPtr<PSONScheme> handler2 = adoptNS([[PSONScheme alloc] initWithBytes:dummyBytes]);
+ [webViewConfiguration setURLSchemeHandler:handler1.get() forURLScheme:@"PSON1"];
+ [webViewConfiguration setURLSchemeHandler:handler2.get() forURLScheme:@"PSON2"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+ auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ numberOfDecidePolicyCalls = 0;
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main1.html"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ TestWebKitAPI::Util::run(&didCreateWebView);
+ didCreateWebView = false;
+
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_EQ(2, numberOfDecidePolicyCalls);
+
+ auto pid1 = [webView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid1);
+ auto pid2 = [createdWebView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid2);
+
+ EXPECT_NE(pid1, pid2);
+}
+
+TEST(ProcessSwap, CrossOriginWindowOpenWithOpener)
+{
+ 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()];
+ RetainPtr<PSONScheme> handler1 = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenCrossOriginWithOpenerTestBytes]);
+ RetainPtr<PSONScheme> handler2 = adoptNS([[PSONScheme alloc] initWithBytes:dummyBytes]);
+ [webViewConfiguration setURLSchemeHandler:handler1.get() forURLScheme:@"PSON1"];
+ [webViewConfiguration setURLSchemeHandler:handler2.get() forURLScheme:@"PSON2"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+ auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ numberOfDecidePolicyCalls = 0;
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main1.html"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ TestWebKitAPI::Util::run(&didCreateWebView);
+ didCreateWebView = false;
+
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_EQ(2, numberOfDecidePolicyCalls);
+
+ auto pid1 = [webView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid1);
+ auto pid2 = [createdWebView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid2);
+
+ // FIXME: This should eventually be false once we support process swapping when there is an opener.
+ EXPECT_EQ(pid1, pid2);
+}
+
+TEST(ProcessSwap, SamOriginWindowOpenNoOpener)
+{
+ 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()];
+ RetainPtr<PSONScheme> handler = adoptNS([[PSONScheme alloc] initWithBytes:windowOpenSameOriginNoOpenerTestBytes]);
+ [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON1"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+ auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ numberOfDecidePolicyCalls = 0;
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main1.html"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ TestWebKitAPI::Util::run(&didCreateWebView);
+ didCreateWebView = false;
+
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_EQ(2, numberOfDecidePolicyCalls);
+
+ auto pid1 = [webView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid1);
+ auto pid2 = [createdWebView _webProcessIdentifier];
+ EXPECT_TRUE(!!pid2);
+
+ EXPECT_EQ(pid1, pid2);
+}
+
#endif // WK_API_ENABLED