Diff
Modified: trunk/Source/WebCore/ChangeLog (224757 => 224758)
--- trunk/Source/WebCore/ChangeLog 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/ChangeLog 2017-11-13 18:32:00 UTC (rev 224758)
@@ -1,3 +1,26 @@
+2017-11-13 Alex Christensen <[email protected]>
+
+ Make DocumentLoader::willSendRequest asynchronous
+ https://bugs.webkit.org/show_bug.cgi?id=179549
+
+ Reviewed by Tim Horton.
+
+ No change in behavior, except now redirects will wait for PolicyChecker::checkNavigationPolicy's completion handler.
+ Before, they would just continue in DocumentLoader::redirectReceived hoping the client had responded to
+ decidePolicyForNavigationAction synchronously or that the client would have been ok with continuing.
+
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::redirectReceived):
+ (WebCore::DocumentLoader::willSendRequest):
+ (WebCore::DocumentLoader::startLoadingMainResource):
+ * loader/DocumentLoader.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadURL):
+ (WebCore::FrameLoader::loadWithDocumentLoader):
+ * loader/PolicyChecker.cpp:
+ (WebCore::PolicyChecker::checkNavigationPolicy):
+ * loader/PolicyChecker.h:
+
2017-11-13 Wenson Hsieh <[email protected]>
[Attachment Support] Implement SPI for clients to request data for a given attachment
Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (224757 => 224758)
--- trunk/Source/WebCore/loader/DocumentLoader.cpp 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp 2017-11-13 18:32:00 UTC (rev 224758)
@@ -470,11 +470,10 @@
void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
{
ASSERT_UNUSED(resource, &resource == m_mainResource);
- willSendRequest(request, redirectResponse);
- completionHandler(WTFMove(request));
+ willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler));
}
-void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
+void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
{
// Note that there are no asserts here as there are for the other callbacks. This is due to the
// fact that this "callback" is sent when starting every load, and the state of callback
@@ -485,7 +484,7 @@
bool didReceiveRedirectResponse = !redirectResponse.isNull();
if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url(), didReceiveRedirectResponse)) {
cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
- return;
+ return completionHandler(WTFMove(newRequest));
}
ASSERT(timing().fetchStart());
@@ -496,12 +495,12 @@
if (!redirectingOrigin.get().canDisplay(newRequest.url())) {
FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string());
cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
- return;
+ return completionHandler(WTFMove(newRequest));
}
if (!portAllowed(newRequest.url())) {
FrameLoader::reportBlockedPortFailed(m_frame, newRequest.url().string());
cancelMainResourceLoad(frameLoader()->blockedError(newRequest));
- return;
+ return completionHandler(WTFMove(newRequest));
}
timing().addRedirect(redirectResponse.url(), newRequest.url());
}
@@ -530,17 +529,17 @@
if (&topFrame != m_frame) {
if (!m_frame->loader().mixedContentChecker().canDisplayInsecureContent(m_frame->document()->securityOrigin(), MixedContentChecker::ContentType::Active, newRequest.url(), MixedContentChecker::AlwaysDisplayInNonStrictMode::Yes)) {
cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
- return;
+ return completionHandler(WTFMove(newRequest));
}
if (!frameLoader()->mixedContentChecker().canDisplayInsecureContent(topFrame.document()->securityOrigin(), MixedContentChecker::ContentType::Active, newRequest.url())) {
cancelMainResourceLoad(frameLoader()->cancelledError(newRequest));
- return;
+ return completionHandler(WTFMove(newRequest));
}
}
#if ENABLE(CONTENT_FILTERING)
if (m_contentFilter && !m_contentFilter->continueAfterWillSendRequest(newRequest, redirectResponse))
- return;
+ return completionHandler(WTFMove(newRequest));
#endif
setRequest(newRequest);
@@ -561,12 +560,13 @@
// listener tells us to. In practice that means the navigation policy needs to be decided
// synchronously for these redirect cases.
if (!didReceiveRedirectResponse)
- return;
+ return completionHandler(WTFMove(newRequest));
ASSERT(!m_waitingForNavigationPolicy);
m_waitingForNavigationPolicy = true;
- frameLoader()->policyChecker().checkNavigationPolicy(newRequest, didReceiveRedirectResponse, [this, protectedThis = makeRef(*this)] (const ResourceRequest& request, FormState*, bool shouldContinue) {
+ frameLoader()->policyChecker().checkNavigationPolicy(ResourceRequest(newRequest), didReceiveRedirectResponse, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, FormState*, bool shouldContinue) mutable {
continueAfterNavigationPolicy(request, shouldContinue);
+ completionHandler(WTFMove(request));
});
}
@@ -1453,87 +1453,87 @@
ASSERT(timing().startTime());
ASSERT(timing().fetchStart());
- Ref<DocumentLoader> protectedThis(*this); // willSendRequest() may deallocate the provisional loader (which may be us) if it cancels the load.
- willSendRequest(m_request, ResourceResponse());
+ willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = makeRef(*this)] (ResourceRequest&& request) {
+ m_request = request;
- // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
- if (!m_frame || m_request.isNull()) {
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Load canceled after willSendRequest (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false);
- return;
- }
+ // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
+ if (!m_frame || m_request.isNull()) {
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Load canceled after willSendRequest (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false);
+ return;
+ }
- m_applicationCacheHost->maybeLoadMainResource(m_request, m_substituteData);
+ m_applicationCacheHost->maybeLoadMainResource(m_request, m_substituteData);
- if (m_substituteData.isValid() && m_frame->page()) {
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Returning cached main resource (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
- m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
- frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, m_request);
- frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
- handleSubstituteDataLoadSoon();
- return;
- }
+ if (m_substituteData.isValid() && m_frame->page()) {
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Returning cached main resource (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+ m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
+ frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, m_request);
+ frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
+ handleSubstituteDataLoadSoon();
+ return;
+ }
- ResourceRequest request(m_request);
- request.setRequester(ResourceRequest::Requester::Main);
- // If this is a reload the cache layer might have made the previous request conditional. DocumentLoader can't handle 304 responses itself.
- request.makeUnconditional();
+ request.setRequester(ResourceRequest::Requester::Main);
+ // If this is a reload the cache layer might have made the previous request conditional. DocumentLoader can't handle 304 responses itself.
+ request.makeUnconditional();
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Starting load (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Starting load (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
- static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(SendCallbacks, SniffContent, BufferData, StoredCredentialsPolicy::Use, ClientCredentialPolicy::MayAskClientForCredentials, FetchOptions::Credentials::Include, SkipSecurityCheck, FetchOptions::Mode::NoCors, IncludeCertificateInfo, ContentSecurityPolicyImposition::SkipPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching);
- CachedResourceRequest mainResourceRequest(ResourceRequest(request), mainResourceLoadOptions);
- if (!m_frame->isMainFrame() && m_frame->document()) {
- // If we are loading the main resource of a subframe, use the cache partition of the main document.
- mainResourceRequest.setDomainForCachePartition(*m_frame->document());
- } else {
- auto origin = SecurityOrigin::create(request.url());
- origin->setStorageBlockingPolicy(frameLoader()->frame().settings().storageBlockingPolicy());
- mainResourceRequest.setDomainForCachePartition(origin->domainForCachePartition());
- }
- m_mainResource = m_cachedResourceLoader->requestMainResource(WTFMove(mainResourceRequest)).valueOr(nullptr);
+ static NeverDestroyed<ResourceLoaderOptions> mainResourceLoadOptions(SendCallbacks, SniffContent, BufferData, StoredCredentialsPolicy::Use, ClientCredentialPolicy::MayAskClientForCredentials, FetchOptions::Credentials::Include, SkipSecurityCheck, FetchOptions::Mode::NoCors, IncludeCertificateInfo, ContentSecurityPolicyImposition::SkipPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching);
+ CachedResourceRequest mainResourceRequest(ResourceRequest(request), mainResourceLoadOptions);
+ if (!m_frame->isMainFrame() && m_frame->document()) {
+ // If we are loading the main resource of a subframe, use the cache partition of the main document.
+ mainResourceRequest.setDomainForCachePartition(*m_frame->document());
+ } else {
+ auto origin = SecurityOrigin::create(request.url());
+ origin->setStorageBlockingPolicy(frameLoader()->frame().settings().storageBlockingPolicy());
+ mainResourceRequest.setDomainForCachePartition(origin->domainForCachePartition());
+ }
+ m_mainResource = m_cachedResourceLoader->requestMainResource(WTFMove(mainResourceRequest)).valueOr(nullptr);
#if ENABLE(CONTENT_EXTENSIONS)
- if (m_mainResource && m_mainResource->errorOccurred() && m_frame->page() && m_mainResource->resourceError().domain() == ContentExtensions::WebKitContentBlockerDomain) {
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Blocked by content blocker error (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
- cancelMainResourceLoad(frameLoader()->blockedByContentBlockerError(m_request));
- return;
- }
+ if (m_mainResource && m_mainResource->errorOccurred() && m_frame->page() && m_mainResource->resourceError().domain() == ContentExtensions::WebKitContentBlockerDomain) {
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Blocked by content blocker error (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+ cancelMainResourceLoad(frameLoader()->blockedByContentBlockerError(m_request));
+ return;
+ }
#endif
- if (!m_mainResource) {
- if (!m_request.url().isValid()) {
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, URL is invalid (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
- cancelMainResourceLoad(frameLoader()->client().cannotShowURLError(m_request));
+ if (!m_mainResource) {
+ if (!m_request.url().isValid()) {
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, URL is invalid (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+ cancelMainResourceLoad(frameLoader()->client().cannotShowURLError(m_request));
+ return;
+ }
+
+ RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, returning empty document (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+
+ setRequest(ResourceRequest());
+ // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
+ // is now in a state where starting an empty load will be inconsistent. Replace it with
+ // a new ApplicationCacheHost.
+ m_applicationCacheHost = std::make_unique<ApplicationCacheHost>(*this);
+ maybeLoadEmpty();
return;
}
- RELEASE_LOG_IF_ALLOWED("startLoadingMainResource: Unable to load main resource, returning empty document (frame = %p, main = %d)", m_frame, m_frame->isMainFrame());
+ if (!mainResourceLoader()) {
+ m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
+ frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, request);
+ frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
+ }
- setRequest(ResourceRequest());
- // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
- // is now in a state where starting an empty load will be inconsistent. Replace it with
- // a new ApplicationCacheHost.
- m_applicationCacheHost = std::make_unique<ApplicationCacheHost>(*this);
- maybeLoadEmpty();
- return;
- }
+ becomeMainResourceClient();
- if (!mainResourceLoader()) {
- m_identifierForLoadWithoutResourceLoader = m_frame->page()->progress().createUniqueIdentifier();
- frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, this, request);
- frameLoader()->notifier().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
- }
-
- becomeMainResourceClient();
-
- // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
- if (mainResourceLoader())
- request = mainResourceLoader()->originalRequest();
- // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
- // the fragment identifier, so add that back in.
- if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
- request.setURL(m_request.url());
- setRequest(request);
+ // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
+ if (mainResourceLoader())
+ request = mainResourceLoader()->originalRequest();
+ // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
+ // the fragment identifier, so add that back in.
+ if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
+ request.setURL(m_request.url());
+ setRequest(request);
+ });
}
void DocumentLoader::cancelPolicyCheckIfNeeded()
Modified: trunk/Source/WebCore/loader/DocumentLoader.h (224757 => 224758)
--- trunk/Source/WebCore/loader/DocumentLoader.h 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/loader/DocumentLoader.h 2017-11-13 18:32:00 UTC (rev 224758)
@@ -324,7 +324,7 @@
void clearArchiveResources();
#endif
- void willSendRequest(ResourceRequest&, const ResourceResponse&);
+ void willSendRequest(ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&);
void finishedLoading();
void mainReceivedError(const ResourceError&);
WEBCORE_EXPORT void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) override;
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (224757 => 224758)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2017-11-13 18:32:00 UTC (rev 224758)
@@ -1312,7 +1312,7 @@
oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
policyChecker().stopCheck();
policyChecker().setLoadType(newLoadType);
- policyChecker().checkNavigationPolicy(request, false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this] (const ResourceRequest& request, FormState*, bool shouldContinue) {
+ policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this] (const ResourceRequest& request, FormState*, bool shouldContinue) {
continueFragmentScrollAfterNavigationPolicy(request, shouldContinue);
});
return;
@@ -1472,7 +1472,7 @@
oldDocumentLoader->setTriggeringAction(action);
oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
policyChecker().stopCheck();
- policyChecker().checkNavigationPolicy(loader->request(), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this] (const ResourceRequest& request, FormState*, bool shouldContinue) {
+ policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this] (const ResourceRequest& request, FormState*, bool shouldContinue) {
continueFragmentScrollAfterNavigationPolicy(request, shouldContinue);
});
return;
@@ -1499,7 +1499,7 @@
}
}
- policyChecker().checkNavigationPolicy(loader->request(), false /* didReceiveRedirectResponse */, loader, formState, [this, allowNavigationToInvalidURL] (const ResourceRequest& request, FormState* formState, bool shouldContinue) {
+ policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, formState, [this, allowNavigationToInvalidURL] (const ResourceRequest& request, FormState* formState, bool shouldContinue) {
continueLoadAfterNavigationPolicy(request, formState, shouldContinue, allowNavigationToInvalidURL);
});
}
Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (224757 => 224758)
--- trunk/Source/WebCore/loader/PolicyChecker.cpp 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp 2017-11-13 18:32:00 UTC (rev 224758)
@@ -76,12 +76,12 @@
{
}
-void PolicyChecker::checkNavigationPolicy(const ResourceRequest& newRequest, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&& function)
+void PolicyChecker::checkNavigationPolicy(ResourceRequest&& newRequest, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&& function)
{
- checkNavigationPolicy(newRequest, didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), nullptr, WTFMove(function));
+ checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), nullptr, WTFMove(function));
}
-void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, bool didReceiveRedirectResponse, DocumentLoader* loader, FormState* formState, NavigationPolicyDecisionFunction&& function)
+void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, DocumentLoader* loader, FormState* formState, NavigationPolicyDecisionFunction&& function)
{
NavigationAction action = ""
if (action.isEmpty()) {
@@ -92,8 +92,8 @@
// Don't ask more than once for the same request or if we are loading an empty URL.
// This avoids confusion on the part of the client.
if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
- function(request, nullptr, true);
- loader->setLastCheckedRequest(ResourceRequest(request));
+ function(ResourceRequest(request), nullptr, true);
+ loader->setLastCheckedRequest(WTFMove(request));
return;
}
@@ -107,7 +107,7 @@
#endif
if (isBackForwardLoadType(m_loadType))
m_loadType = FrameLoadType::Reload;
- function(request, nullptr, shouldContinue);
+ function(WTFMove(request), nullptr, shouldContinue);
return;
}
@@ -117,7 +117,7 @@
// reveal that the frame was blocked. This way, it looks like any other cross-origin page load.
m_frame.ownerElement()->dispatchEvent(Event::create(eventNames().loadEvent, false, false));
}
- function(request, nullptr, false);
+ function(WTFMove(request), nullptr, false);
return;
}
@@ -126,7 +126,7 @@
#if USE(QUICK_LOOK)
// Always allow QuickLook-generated URLs based on the protocol scheme.
if (!request.isNull() && isQuickLookPreviewURL(request.url()))
- return function(request, formState, true);
+ return function(WTFMove(request), formState, true);
#endif
#if ENABLE(CONTENT_FILTERING)
@@ -157,7 +157,7 @@
handleUnimplementablePolicy(m_frame.loader().client().cannotShowURLError(request));
return function({ }, nullptr, false);
}
- return function(request, formState.get(), true);
+ return function(WTFMove(request), formState.get(), true);
}
ASSERT_NOT_REACHED();
});
Modified: trunk/Source/WebCore/loader/PolicyChecker.h (224757 => 224758)
--- trunk/Source/WebCore/loader/PolicyChecker.h 2017-11-13 17:40:31 UTC (rev 224757)
+++ trunk/Source/WebCore/loader/PolicyChecker.h 2017-11-13 18:32:00 UTC (rev 224758)
@@ -51,7 +51,7 @@
class ResourceResponse;
using NewWindowPolicyDecisionFunction = WTF::CompletionHandler<void(const ResourceRequest&, FormState*, const String& frameName, const NavigationAction&, bool shouldContinue)>;
-using NavigationPolicyDecisionFunction = WTF::CompletionHandler<void(const ResourceRequest&, FormState*, bool shouldContinue)>;
+using NavigationPolicyDecisionFunction = WTF::CompletionHandler<void(ResourceRequest&&, FormState*, bool shouldContinue)>;
class PolicyChecker {
WTF_MAKE_NONCOPYABLE(PolicyChecker);
@@ -59,8 +59,8 @@
public:
explicit PolicyChecker(Frame&);
- void checkNavigationPolicy(const ResourceRequest&, bool didReceiveRedirectResponse, DocumentLoader*, FormState*, NavigationPolicyDecisionFunction&&);
- void checkNavigationPolicy(const ResourceRequest&, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&&);
+ void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, DocumentLoader*, FormState*, NavigationPolicyDecisionFunction&&);
+ void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&&);
void checkNewWindowPolicy(NavigationAction&&, const ResourceRequest&, FormState*, const String& frameName, NewWindowPolicyDecisionFunction&&);
void stopCheck();