Diff
Modified: trunk/Source/WebKit/ChangeLog (222713 => 222714)
--- trunk/Source/WebKit/ChangeLog 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/ChangeLog 2017-10-02 17:09:30 UTC (rev 222714)
@@ -1,5 +1,42 @@
2017-10-02 Alex Christensen <[email protected]>
+ REGRESSION(r214201): WebProcess hangs during policy decisions
+ https://bugs.webkit.org/show_bug.cgi?id=177590
+ <rdar://problem/33362929>
+
+ Reviewed by Andy Estes.
+
+ This is like r222431 but for trunk instead of a branch.
+ It includes the same regression API test so I don't make the same mistake again.
+
+ * UIProcess/API/C/WKPage.cpp:
+ (WKPageSetPageNavigationClient):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::receivedPolicyDecision):
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ (WebKit::WebPageProxy::decidePolicyForResponseSync):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
+ (WebKit::WebFrameLoaderClient::applyToDocumentLoader):
+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+ * WebProcess/WebPage/WebDocumentLoader.cpp:
+ (WebKit::WebDocumentLoader::setNavigationID):
+ * WebProcess/WebPage/WebFrame.cpp:
+ (WebKit::WebFrame::setUpPolicyListener):
+ (WebKit::WebFrame::invalidatePolicyListener):
+ (WebKit::WebFrame::didReceivePolicyDecision):
+ * WebProcess/WebPage/WebFrame.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::didReceivePolicyDecision):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+2017-10-02 Alex Christensen <[email protected]>
+
Remove unnecessary copy of SessionID in WebPageProxy
https://bugs.webkit.org/show_bug.cgi?id=177702
Modified: trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp (222713 => 222714)
--- trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -2142,19 +2142,15 @@
private:
void decidePolicyForNavigationAction(WebPageProxy& page, Ref<API::NavigationAction>&& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) final
{
- if (!m_client.decidePolicyForNavigationAction) {
- listener->use({ });
+ if (!m_client.decidePolicyForNavigationAction)
return;
- }
m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(navigationAction.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
}
void decidePolicyForNavigationResponse(WebPageProxy& page, API::NavigationResponse& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
{
- if (!m_client.decidePolicyForNavigationResponse) {
- listener->use({ });
+ if (!m_client.decidePolicyForNavigationResponse)
return;
- }
m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(&navigationResponse), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
}
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (222713 => 222714)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -2279,7 +2279,8 @@
DownloadID downloadID = { };
if (action == PolicyAction::Download) {
// Create a download proxy.
- auto* download = m_process->processPool().createDownloadProxy(m_decidePolicyForResponseRequest, this);
+ const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
+ DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest, this);
if (navigation) {
download->setWasUserInitiated(navigation->wasUserInitiated());
download->setRedirectChain(navigation->takeRedirectChain());
@@ -2287,28 +2288,28 @@
downloadID = download->downloadID();
handleDownloadRequest(download);
- m_decidePolicyForResponseRequest = { };
}
// If we received a policy decision while in decidePolicyForResponse the decision will
// be sent back to the web process by decidePolicyForResponse.
- if (m_responsePolicyReply) {
- m_responsePolicyReply->send(action, downloadID);
- ASSERT(!m_newNavigationID);
- m_responsePolicyReply = nullptr;
+ if (m_inDecidePolicyForResponseSync) {
+ m_syncMimeTypePolicyActionIsValid = true;
+ m_syncMimeTypePolicyAction = action;
+ m_syncMimeTypePolicyDownloadID = downloadID;
return;
}
// If we received a policy decision while in decidePolicyForNavigationAction the decision will
// be sent back to the web process by decidePolicyForNavigationAction.
- if (m_navigationActionPolicyReply) {
- m_navigationActionPolicyReply->send(m_newNavigationID, action, downloadID, websitePolicies);
- m_newNavigationID = 0;
- m_navigationActionPolicyReply = nullptr;
+ if (m_inDecidePolicyForNavigationAction) {
+ m_syncNavigationActionPolicyActionIsValid = true;
+ m_syncNavigationActionPolicyAction = action;
+ m_syncNavigationActionPolicyDownloadID = downloadID;
+ m_syncNavigationActionPolicyWebsitePolicies = websitePolicies;
return;
}
- m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
+ m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID, websitePolicies), m_pageID);
}
void WebPageProxy::setUserAgent(const String& userAgent)
@@ -3660,7 +3661,7 @@
m_frameSetLargestFrame = value ? m_mainFrame : 0;
}
-void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, ResourceRequest&& request, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&& reply)
+void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, ResourceRequest&& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, WebCore::PolicyAction& policyAction, DownloadID& downloadID, WebsitePolicies& websitePolicies)
{
PageClientProtector protector(m_pageClient);
@@ -3675,11 +3676,10 @@
MESSAGE_CHECK_URL(request.url());
MESSAGE_CHECK_URL(originalRequest.url());
- m_newNavigationID = 0;
Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
if (!navigationID) {
auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
- m_newNavigationID = navigation->navigationID();
+ newNavigationID = navigation->navigationID();
navigation->setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
listener->setNavigation(WTFMove(navigation));
} else {
@@ -3690,16 +3690,19 @@
#if ENABLE(CONTENT_FILTERING)
if (frame->didHandleContentFilterUnblockNavigation(request)) {
- reply->send(m_newNavigationID, PolicyAction::Ignore, { }, { });
- m_newNavigationID = 0;
+ receivedPolicyAction = true;
+ policyAction = PolicyAction::Ignore;
return;
}
#endif
+ ASSERT(!m_inDecidePolicyForNavigationAction);
+
+ m_inDecidePolicyForNavigationAction = true;
+ m_syncNavigationActionPolicyActionIsValid = false;
#if ENABLE(DOWNLOAD_ATTRIBUTE)
m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull();
#endif
- m_navigationActionPolicyReply = WTFMove(reply);
WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
@@ -3721,6 +3724,15 @@
m_policyClient->decidePolicyForNavigationAction(*this, frame, WTFMove(navigationActionData), originatingFrame, originalRequest, WTFMove(request), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
+ m_inDecidePolicyForNavigationAction = false;
+
+ // Check if we received a policy decision already. If we did, we can just pass it back.
+ receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
+ if (m_syncNavigationActionPolicyActionIsValid) {
+ policyAction = m_syncNavigationActionPolicyAction;
+ downloadID = m_syncNavigationActionPolicyDownloadID;
+ websitePolicies = m_syncNavigationActionPolicyWebsitePolicies;
+ }
}
void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, NavigationActionData&& navigationActionData, ResourceRequest&& request, const String& frameName, uint64_t listenerID, const UserData& userData)
@@ -3768,14 +3780,27 @@
m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
}
-void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&& reply)
+void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, WebCore::PolicyAction& policyAction, DownloadID& downloadID)
{
PageClientProtector protector(m_pageClient);
- m_decidePolicyForResponseRequest = request;
- m_responsePolicyReply = WTFMove(reply);
+ ASSERT(!m_inDecidePolicyForResponseSync);
+ m_inDecidePolicyForResponseSync = true;
+ m_decidePolicyForResponseRequest = &request;
+ m_syncMimeTypePolicyActionIsValid = false;
+
decidePolicyForResponse(frameID, frameSecurityOrigin, navigationID, response, request, canShowMIMEType, listenerID, userData);
+
+ m_inDecidePolicyForResponseSync = false;
+ m_decidePolicyForResponseRequest = nullptr;
+
+ // Check if we received a policy decision already. If we did, we can just pass it back.
+ receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
+ if (m_syncMimeTypePolicyActionIsValid) {
+ policyAction = m_syncMimeTypePolicyAction;
+ downloadID = m_syncMimeTypePolicyDownloadID;
+ }
}
void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (222713 => 222714)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2017-10-02 17:09:30 UTC (rev 222714)
@@ -1282,10 +1282,10 @@
void didDestroyNavigation(uint64_t navigationID);
- void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&&);
+ void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, uint64_t& newNavigationID, WebCore::PolicyAction&, DownloadID&, WebsitePolicies&);
void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, NavigationActionData&&, WebCore::ResourceRequest&&, const String& frameName, uint64_t listenerID, const UserData&);
void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
- void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&&);
+ void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, WebCore::PolicyAction&, DownloadID&);
void unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError&, const UserData&);
void willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData&);
@@ -1799,10 +1799,16 @@
bool m_isInPrintingMode { false };
bool m_isPerformingDOMPrintOperation { false };
- RefPtr<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply> m_navigationActionPolicyReply;
- uint64_t m_newNavigationID { 0 };
- RefPtr<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply> m_responsePolicyReply;
- WebCore::ResourceRequest m_decidePolicyForResponseRequest;
+ bool m_inDecidePolicyForResponseSync { false };
+ const WebCore::ResourceRequest* m_decidePolicyForResponseRequest { nullptr };
+ bool m_syncMimeTypePolicyActionIsValid { false };
+ WebCore::PolicyAction m_syncMimeTypePolicyAction { WebCore::PolicyAction::Use };
+ DownloadID m_syncMimeTypePolicyDownloadID { 0 };
+ bool m_inDecidePolicyForNavigationAction { false };
+ bool m_syncNavigationActionPolicyActionIsValid { false };
+ WebCore::PolicyAction m_syncNavigationActionPolicyAction { WebCore::PolicyAction::Use };
+ DownloadID m_syncNavigationActionPolicyDownloadID { 0 };
+ WebsitePolicies m_syncNavigationActionPolicyWebsitePolicies;
bool m_shouldSuppressAppLinksInNextNavigationPolicyDecision { false };
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (222713 => 222714)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2017-10-02 17:09:30 UTC (rev 222714)
@@ -98,8 +98,8 @@
#endif
# Policy messages
- DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (enum WebCore::PolicyAction policyAction, WebKit::DownloadID downloadID) Delayed
- DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t newNavigationID, enum WebCore::PolicyAction policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies) Delayed
+ DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction, enum WebCore::PolicyAction policyAction, WebKit::DownloadID downloadID)
+ DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction, uint64_t newNavigationID, enum WebCore::PolicyAction policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies)
DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData)
UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::UserData userData)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -699,7 +699,8 @@
bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
- uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
+ uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
+ bool receivedPolicyAction;
PolicyAction policyAction;
DownloadID downloadID;
@@ -706,13 +707,14 @@
Ref<WebFrame> protect(*m_frame);
WebCore::Frame* coreFrame = m_frame->coreFrame();
auto navigationID = static_cast<WebDocumentLoader&>(*coreFrame->loader().provisionalDocumentLoader()).navigationID();
- if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(policyAction, downloadID), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
- m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { });
+ if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
+ m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { }, { });
return;
}
// We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
- m_frame->didReceivePolicyDecision(listenerID, policyAction, 0, downloadID);
+ if (receivedPolicyAction)
+ m_frame->didReceivePolicyDecision(listenerID, policyAction, 0, downloadID, { });
}
void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, FormState* formState, const String& frameName, FramePolicyFunction&& function)
@@ -734,7 +736,7 @@
return;
}
- uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
+ uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
NavigationActionData navigationActionData;
navigationActionData.navigationType = action->navigationType();
@@ -751,6 +753,52 @@
webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationActionData, request, frameName, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
}
+void WebFrameLoaderClient::applyToDocumentLoader(const WebsitePolicies& websitePolicies)
+{
+ if (!m_frame)
+ return;
+ auto* coreFrame = m_frame->coreFrame();
+ if (!coreFrame)
+ return;
+ WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
+ if (!documentLoader)
+ documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().provisionalDocumentLoader());
+ if (!documentLoader)
+ documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
+ if (!documentLoader)
+ return;
+
+ // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
+ if (documentLoader->userContentExtensionsEnabled())
+ documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);
+
+ OptionSet<AutoplayQuirk> quirks;
+ auto allowedQuirks = websitePolicies.allowedAutoplayQuirks;
+
+ if (allowedQuirks.contains(WebsiteAutoplayQuirk::InheritedUserGestures))
+ quirks |= AutoplayQuirk::InheritedUserGestures;
+
+ if (allowedQuirks.contains(WebsiteAutoplayQuirk::SynthesizedPauseEvents))
+ quirks |= AutoplayQuirk::SynthesizedPauseEvents;
+
+ documentLoader->setAllowedAutoplayQuirks(quirks);
+
+ switch (websitePolicies.autoplayPolicy) {
+ case WebsiteAutoplayPolicy::Default:
+ documentLoader->setAutoplayPolicy(AutoplayPolicy::Default);
+ break;
+ case WebsiteAutoplayPolicy::Allow:
+ documentLoader->setAutoplayPolicy(AutoplayPolicy::Allow);
+ break;
+ case WebsiteAutoplayPolicy::AllowWithoutSound:
+ documentLoader->setAutoplayPolicy(AutoplayPolicy::AllowWithoutSound);
+ break;
+ case WebsiteAutoplayPolicy::Deny:
+ documentLoader->setAutoplayPolicy(AutoplayPolicy::Deny);
+ break;
+ }
+}
+
void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, FormState* formState, FramePolicyFunction&& function)
{
WebPage* webPage = m_frame->page();
@@ -776,7 +824,8 @@
return;
}
- uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
+ uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::Yes);
+ bool receivedPolicyAction;
uint64_t newNavigationID;
PolicyAction policyAction;
DownloadID downloadID;
@@ -817,8 +866,8 @@
// Notify the UIProcess.
Ref<WebFrame> protect(*m_frame);
WebsitePolicies websitePolicies;
- if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingFrame && originatingFrame->page() ? originatingFrame->page()->pageID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(newNavigationID, policyAction, downloadID, websitePolicies))) {
- m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { });
+ if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingFrame && originatingFrame->page() ? originatingFrame->page()->pageID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID, websitePolicies))) {
+ m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { }, { });
return;
}
@@ -828,34 +877,9 @@
if (documentLoader->userContentExtensionsEnabled())
documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);
- OptionSet<AutoplayQuirk> quirks;
- auto allowedQuirks = websitePolicies.allowedAutoplayQuirks;
-
- if (allowedQuirks.contains(WebsiteAutoplayQuirk::InheritedUserGestures))
- quirks |= AutoplayQuirk::InheritedUserGestures;
-
- if (allowedQuirks.contains(WebsiteAutoplayQuirk::SynthesizedPauseEvents))
- quirks |= AutoplayQuirk::SynthesizedPauseEvents;
-
- documentLoader->setAllowedAutoplayQuirks(quirks);
-
- switch (websitePolicies.autoplayPolicy) {
- case WebsiteAutoplayPolicy::Default:
- documentLoader->setAutoplayPolicy(AutoplayPolicy::Default);
- break;
- case WebsiteAutoplayPolicy::Allow:
- documentLoader->setAutoplayPolicy(AutoplayPolicy::Allow);
- break;
- case WebsiteAutoplayPolicy::AllowWithoutSound:
- documentLoader->setAutoplayPolicy(AutoplayPolicy::AllowWithoutSound);
- break;
- case WebsiteAutoplayPolicy::Deny:
- documentLoader->setAutoplayPolicy(AutoplayPolicy::Deny);
- break;
- }
-
// We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
- m_frame->didReceivePolicyDecision(listenerID, policyAction, newNavigationID, downloadID);
+ if (receivedPolicyAction)
+ m_frame->didReceivePolicyDecision(listenerID, policyAction, newNavigationID, downloadID, websitePolicies);
}
void WebFrameLoaderClient::cancelPolicyCheck()
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h 2017-10-02 17:09:30 UTC (rev 222714)
@@ -35,6 +35,7 @@
class PluginView;
class WebFrame;
+struct WebsitePolicies;
class WebFrameLoaderClient final : public WebCore::FrameLoaderClient {
public:
@@ -48,6 +49,8 @@
void setUseIconLoadingClient(bool useIconLoadingClient) { m_useIconLoadingClient = useIconLoadingClient; }
+ void applyToDocumentLoader(const WebsitePolicies&);
+
private:
void frameLoaderDestroyed() final;
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebDocumentLoader.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -51,7 +51,7 @@
void WebDocumentLoader::setNavigationID(uint64_t navigationID)
{
ASSERT(navigationID);
- ASSERT(!m_navigationID);
+ ASSERT(!m_navigationID || m_navigationID == navigationID);
m_navigationID = navigationID;
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFrame.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -209,7 +209,7 @@
m_coreFrame = 0;
}
-uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction&& policyFunction)
+uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction&& policyFunction, ForNavigationAction forNavigationAction)
{
// FIXME: <rdar://5634381> We need to support multiple active policy listeners.
@@ -217,6 +217,7 @@
m_policyListenerID = generateListenerID();
m_policyFunction = WTFMove(policyFunction);
+ m_policyFunctionForNavigationAction = forNavigationAction;
return m_policyListenerID;
}
@@ -244,12 +245,13 @@
m_policyListenerID = 0;
if (auto function = std::exchange(m_policyFunction, nullptr))
function(PolicyAction::Ignore);
+ m_policyFunctionForNavigationAction = ForNavigationAction::No;
for (auto& function : m_willSubmitFormCompletionHandlers.values())
function();
m_willSubmitFormCompletionHandlers.clear();
}
-void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID)
+void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID, const WebsitePolicies& websitePolicies)
{
if (!m_coreFrame)
return;
@@ -264,9 +266,13 @@
return;
FramePolicyFunction function = WTFMove(m_policyFunction);
+ bool forNavigationAction = m_policyFunctionForNavigationAction == ForNavigationAction::Yes;
invalidatePolicyListener();
+ if (forNavigationAction && m_frameLoaderClient)
+ m_frameLoaderClient->applyToDocumentLoader(websitePolicies);
+
m_policyDownloadID = downloadID;
if (navigationID) {
if (WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(m_coreFrame->loader().policyDocumentLoader()))
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h 2017-10-02 17:09:30 UTC (rev 222714)
@@ -64,6 +64,7 @@
class InjectedBundleScriptWorld;
class WebPage;
struct FrameInfoData;
+struct WebsitePolicies;
class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame> {
public:
@@ -82,9 +83,10 @@
FrameInfoData info() const;
uint64_t frameID() const { return m_frameID; }
- uint64_t setUpPolicyListener(WebCore::FramePolicyFunction&&);
+ enum class ForNavigationAction { No, Yes };
+ uint64_t setUpPolicyListener(WebCore::FramePolicyFunction&&, ForNavigationAction);
void invalidatePolicyListener();
- void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, DownloadID);
+ void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, DownloadID, const WebsitePolicies&);
uint64_t setUpWillSubmitFormListener(WTF::Function<void(void)>&&);
void continueWillSubmitForm(uint64_t);
@@ -177,6 +179,7 @@
uint64_t m_policyListenerID { 0 };
WebCore::FramePolicyFunction m_policyFunction;
+ ForNavigationAction m_policyFunctionForNavigationAction { ForNavigationAction::No };
HashMap<uint64_t, WTF::Function<void(void)>> m_willSubmitFormCompletionHandlers;
DownloadID m_policyDownloadID { 0 };
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2017-10-02 17:09:30 UTC (rev 222714)
@@ -2733,12 +2733,12 @@
m_page->setSessionID(sessionID);
}
-void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, PolicyAction policyAction, uint64_t navigationID, const DownloadID& downloadID)
+void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, PolicyAction policyAction, uint64_t navigationID, const DownloadID& downloadID, WebsitePolicies&& websitePolicies)
{
WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
return;
- frame->didReceivePolicyDecision(listenerID, policyAction, navigationID, downloadID);
+ frame->didReceivePolicyDecision(listenerID, policyAction, navigationID, downloadID, websitePolicies);
}
void WebPage::continueWillSubmitForm(uint64_t frameID, uint64_t listenerID)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2017-10-02 17:09:30 UTC (rev 222714)
@@ -1138,7 +1138,7 @@
void platformPreferencesDidChange(const WebPreferencesStore&);
void updatePreferences(const WebPreferencesStore&);
- void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, const DownloadID&);
+ void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, const DownloadID&, WebsitePolicies&&);
void continueWillSubmitForm(uint64_t frameID, uint64_t listenerID);
void setUserAgent(const String&);
void setCustomTextEncodingName(const String&);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (222713 => 222714)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2017-10-02 17:09:30 UTC (rev 222714)
@@ -151,7 +151,7 @@
DidRemoveBackForwardItem(uint64_t backForwardItemID)
UpdateWebsitePolicies(struct WebKit::WebsitePolicies websitePolicies)
- DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, enum WebCore::PolicyAction policyAction, uint64_t navigationID, WebKit::DownloadID downloadID)
+ DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, enum WebCore::PolicyAction policyAction, uint64_t navigationID, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies)
ContinueWillSubmitForm(uint64_t frameID, uint64_t listenerID)
ClearSelection()
Modified: trunk/Tools/ChangeLog (222713 => 222714)
--- trunk/Tools/ChangeLog 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Tools/ChangeLog 2017-10-02 17:09:30 UTC (rev 222714)
@@ -1,3 +1,19 @@
+2017-10-02 Alex Christensen <[email protected]>
+
+ REGRESSION(r214201): WebProcess hangs during policy decisions
+ https://bugs.webkit.org/show_bug.cgi?id=177590
+ <rdar://problem/33362929>
+
+ Reviewed by Andy Estes.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/_javascript_DuringNavigation.mm: Added.
+ (-[JSNavigationDelegate webView:didFinishNavigation:]):
+ (-[JSNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+ (-[JSNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
+ (-[JSNavigationDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
+ (TEST):
+
2017-10-02 Jonathan Bedard <[email protected]>
Log stack-trace for run-webkit-tests when interrupted
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (222713 => 222714)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-10-02 17:09:08 UTC (rev 222713)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-10-02 17:09:30 UTC (rev 222714)
@@ -229,6 +229,7 @@
5C2936931D5BF70D00DEAB1E /* CookieAcceptPolicy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */; };
5C2936961D5C00ED00DEAB1E /* CookieMessage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C2936941D5BFD1900DEAB1E /* CookieMessage.html */; };
5C4A84951F7EEFFC00ACFC54 /* Configuration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C4A84941F7EEFD400ACFC54 /* Configuration.mm */; };
+ 5C69BDD51F82A7EF000F4F4B /* _javascript_DuringNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */; };
5C6E65441D5CEFD400F7862E /* URLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E65411D5CEF8500F7862E /* URLParser.cpp */; };
5C726D6F1D3EE06E00C5E1A1 /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C726D6E1D3EE06800C5E1A1 /* InstanceMethodSwizzler.mm */; };
5C7964101EB0278D0075D74C /* EventModifiers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C79640F1EB0269B0075D74C /* EventModifiers.cpp */; };
@@ -1345,6 +1346,7 @@
5C2936941D5BFD1900DEAB1E /* CookieMessage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CookieMessage.html; sourceTree = "<group>"; };
5C4A84941F7EEFD400ACFC54 /* Configuration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Configuration.mm; sourceTree = "<group>"; };
5C5E633D1D0B67940085A025 /* UniqueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UniqueRef.cpp; sourceTree = "<group>"; };
+ 5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _javascript_DuringNavigation.mm; sourceTree = "<group>"; };
5C6E65411D5CEF8500F7862E /* URLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLParser.cpp; sourceTree = "<group>"; };
5C726D6D1D3EE06800C5E1A1 /* InstanceMethodSwizzler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InstanceMethodSwizzler.h; path = cocoa/InstanceMethodSwizzler.h; sourceTree = "<group>"; };
5C726D6E1D3EE06800C5E1A1 /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InstanceMethodSwizzler.mm; path = cocoa/InstanceMethodSwizzler.mm; sourceTree = "<group>"; };
@@ -1994,6 +1996,7 @@
57599E201F07191700A3FB8C /* IndexedDBStructuredCloneBackwardCompatibility.mm */,
5198A23F1EA7E595008910B7 /* InitialWarmedProcessUsed.mm */,
2DB0232E1E4E871800707123 /* InteractionDeadlockAfterCrash.mm */,
+ 5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */,
C25CCA051E51380B0026CB8A /* LineBreaking.mm */,
37D36ED61AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm */,
A125478D1DB18B9400358564 /* LoadDataWithNilMIMEType.mm */,
@@ -3315,6 +3318,7 @@
7A909A821D877480007E10F8 /* IntRect.cpp in Sources */,
7A909A831D877480007E10F8 /* IntSize.cpp in Sources */,
5C0BF8931DD599BD00B00328 /* IsNavigationActionTrusted.mm in Sources */,
+ 5C69BDD51F82A7EF000F4F4B /* _javascript_DuringNavigation.mm in Sources */,
7CCE7EAD1A411A3400447C4C /* _javascript_Test.cpp in Sources */,
7CCE7EA51A411A0800447C4C /* _javascript_TestMac.mm in Sources */,
7CCE7EC41A411A7E00447C4C /* JSWrapperForNodeInWebFrame.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_javascript_DuringNavigation.mm (0 => 222714)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_javascript_DuringNavigation.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_javascript_DuringNavigation.mm 2017-10-02 17:09:30 UTC (rev 222714)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 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"
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import <WebKit/WKWebView.h>
+#import <wtf/RetainPtr.h>
+
+#if WK_API_ENABLED
+
+static bool navigationComplete;
+static size_t alerts;
+static bool receivedBothAlerts;
+static RetainPtr<NSURL> firstURL;
+static RetainPtr<NSURL> secondURL;
+
+@interface JSNavigationDelegate : NSObject <WKNavigationDelegate, WKUIDelegate>
+@end
+
+@implementation JSNavigationDelegate
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
+{
+ navigationComplete = true;
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+ if ([navigationAction.request.URL.absoluteString isEqualToString:[secondURL absoluteString]]) {
+ [webView evaluateJavaScript:@"alert(document.location);" completionHandler:^(id, NSError *) {
+ decisionHandler(WKNavigationActionPolicyAllow);
+ }];
+ } else
+ decisionHandler(WKNavigationActionPolicyAllow);
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
+{
+ if ([navigationResponse.response.URL.absoluteString isEqualToString:[secondURL absoluteString]]) {
+ [webView evaluateJavaScript:@"alert(document.location);" completionHandler:^(id, NSError *) {
+ decisionHandler(WKNavigationResponsePolicyAllow);
+ }];
+ } else
+ decisionHandler(WKNavigationResponsePolicyAllow);
+}
+
+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
+{
+ EXPECT_STREQ(message.UTF8String, [[firstURL absoluteString] UTF8String]);
+ if (++alerts == 2)
+ receivedBothAlerts = true;
+ completionHandler();
+}
+
+@end
+
+TEST(WebKit, _javascript_DuringNavigation)
+{
+ firstURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ secondURL = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+ auto webView = adoptNS([[WKWebView alloc] init]);
+ auto delegate = adoptNS([[JSNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:delegate.get()];
+ [webView setUIDelegate:delegate.get()];
+
+ [webView loadRequest:[NSURLRequest requestWithURL:firstURL.get()]];
+ TestWebKitAPI::Util::run(&navigationComplete);
+
+ [webView loadRequest:[NSURLRequest requestWithURL:secondURL.get()]];
+ TestWebKitAPI::Util::run(&receivedBothAlerts);
+}
+
+#endif