<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[244161] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/244161">244161</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2019-04-10 15:56:35 -0700 (Wed, 10 Apr 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add SPI WKNavigationResponse._downloadAttribute
https://bugs.webkit.org/show_bug.cgi?id=196755
<rdar://49587365>

Patch by Alex Christensen <achristensen@webkit.org> on 2019-04-10
Reviewed by Brady Eidson.

Source/WebCore:

Covered by an API test that validates the attribute is correctly sent through the FrameLoader to the API.
When a user clicks on a link with a download attribute, the download attribute should be used as the suggested filename sometimes.
The application needs this information after it has received the response in order to make fully informed decisions about downloads.
In order to get this attribute to the decidePolicyForNavigationResponse, we need to store the attribute on the DocumentLoader
from the FrameLoadRequest then send it from the DocumentLoader when the response is received.

* loader/DocumentLoader.h:
(WebCore::DocumentLoader::setDownloadAttribute):
(WebCore::DocumentLoader::downloadAttribute const):
* loader/EmptyFrameLoaderClient.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::checkContentPolicy):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadWithNavigationAction):
(WebCore::FrameLoader::loadPostRequest):
* loader/FrameLoader.h:
(WebCore::FrameLoader::loadWithNavigationAction):
* loader/FrameLoaderClient.h:

Source/WebKit:

* UIProcess/API/APINavigationResponse.h:
* UIProcess/API/Cocoa/WKNavigationResponse.mm:
(-[WKNavigationResponse _downloadAttribute]):
* UIProcess/API/Cocoa/WKNavigationResponsePrivate.h:
* UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::decidePolicyForResponse):
* UIProcess/ProvisionalPageProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::decidePolicyForResponse):
(WebKit::WebPageProxy::decidePolicyForResponseShared):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:

Source/WebKitLegacy/mac:

* WebCoreSupport/WebFrameLoaderClient.h:
* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::dispatchDecidePolicyForResponse):

Source/WebKitLegacy/win:

* WebCoreSupport/WebFrameLoaderClient.cpp:
(WebFrameLoaderClient::dispatchDecidePolicyForResponse):
* WebCoreSupport/WebFrameLoaderClient.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm:
(-[NavigationResponseTestDelegate navigationResponse]):
(-[NavigationResponseTestDelegate waitForNavigationResponseCallback]):
(-[NavigationResponseTestDelegate waitForNavigationFinishedCallback]):
(-[NavigationResponseTestDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[NavigationResponseTestDelegate webView:didFinishNavigation:]):
(-[NavigationResponseTestDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
(readRequest):
(writeResponse):
(TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentLoaderh">trunk/Source/WebCore/loader/DocumentLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloaderEmptyFrameLoaderClienth">trunk/Source/WebCore/loader/EmptyFrameLoaderClient.h</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoadercpp">trunk/Source/WebCore/loader/FrameLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoaderh">trunk/Source/WebCore/loader/FrameLoader.h</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoaderClienth">trunk/Source/WebCore/loader/FrameLoaderClient.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPIAPINavigationResponseh">trunk/Source/WebKit/UIProcess/API/APINavigationResponse.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoaWKNavigationResponsemm">trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponse.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoaWKNavigationResponsePrivateh">trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponsePrivate.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessProvisionalPageProxycpp">trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessProvisionalPageProxyh">trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxycpp">trunk/Source/WebKit/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxyh">trunk/Source/WebKit/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxymessagesin">trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebCoreSupportWebFrameLoaderClientcpp">trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebCoreSupportWebFrameLoaderClienth">trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h</a></li>
<li><a href="#trunkSourceWebKitLegacymacChangeLog">trunk/Source/WebKitLegacy/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitLegacymacWebCoreSupportWebFrameLoaderClienth">trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h</a></li>
<li><a href="#trunkSourceWebKitLegacymacWebCoreSupportWebFrameLoaderClientmm">trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm</a></li>
<li><a href="#trunkSourceWebKitLegacywinChangeLog">trunk/Source/WebKitLegacy/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitLegacywinWebCoreSupportWebFrameLoaderClientcpp">trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp</a></li>
<li><a href="#trunkSourceWebKitLegacywinWebCoreSupportWebFrameLoaderClienth">trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWKNavigationResponsemm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/ChangeLog      2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2019-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI WKNavigationResponse._downloadAttribute
+        https://bugs.webkit.org/show_bug.cgi?id=196755
+        <rdar://49587365>
+
+        Reviewed by Brady Eidson.
+
+        Covered by an API test that validates the attribute is correctly sent through the FrameLoader to the API.
+        When a user clicks on a link with a download attribute, the download attribute should be used as the suggested filename sometimes.
+        The application needs this information after it has received the response in order to make fully informed decisions about downloads.
+        In order to get this attribute to the decidePolicyForNavigationResponse, we need to store the attribute on the DocumentLoader
+        from the FrameLoadRequest then send it from the DocumentLoader when the response is received.
+
+        * loader/DocumentLoader.h:
+        (WebCore::DocumentLoader::setDownloadAttribute):
+        (WebCore::DocumentLoader::downloadAttribute const):
+        * loader/EmptyFrameLoaderClient.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::checkContentPolicy):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        (WebCore::FrameLoader::loadPostRequest):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::loadWithNavigationAction):
+        * loader/FrameLoaderClient.h:
+
</ins><span class="cx"> 2019-04-10  Youenn Fablet  <youenn@apple.com>
</span><span class="cx"> 
</span><span class="cx">         SWClientConnection should not double hop to fire some events
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentLoader.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentLoader.h     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/loader/DocumentLoader.h        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -356,6 +356,9 @@
</span><span class="cx">     void setAllowsWebArchiveForMainFrame(bool allowsWebArchiveForMainFrame) { m_allowsWebArchiveForMainFrame = allowsWebArchiveForMainFrame; }
</span><span class="cx">     bool allowsWebArchiveForMainFrame() const { return m_allowsWebArchiveForMainFrame; }
</span><span class="cx"> 
</span><ins>+    void setDownloadAttribute(const String& attribute) { m_downloadAttribute = attribute; }
+    const String& downloadAttribute() const { return m_downloadAttribute; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&);
</span><span class="cx"> 
</span><span class="lines">@@ -581,6 +584,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool m_allowsWebArchiveForMainFrame { false };
</span><ins>+    String m_downloadAttribute;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const ResourceRequest& request)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderEmptyFrameLoaderClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/EmptyFrameLoaderClient.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/EmptyFrameLoaderClient.h     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/loader/EmptyFrameLoaderClient.h        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -93,7 +93,7 @@
</span><span class="cx">     Frame* dispatchCreatePage(const NavigationAction&) final { return nullptr; }
</span><span class="cx">     void dispatchShow() final { }
</span><span class="cx"> 
</span><del>-    void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, PolicyCheckIdentifier, FramePolicyFunction&&) final { }
</del><ins>+    void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, PolicyCheckIdentifier, const String&, FramePolicyFunction&&) final { }
</ins><span class="cx">     void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String&, PolicyCheckIdentifier, FramePolicyFunction&&) final;
</span><span class="cx">     void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, const ResourceResponse& redirectResponse, FormState*, PolicyDecisionMode, PolicyCheckIdentifier, FramePolicyFunction&&) final;
</span><span class="cx">     void cancelPolicyCheck() final { }
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.cpp      2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -372,7 +372,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // FIXME: Validate the policy check identifier.
</span><del>-    client().dispatchDecidePolicyForResponse(response, activeDocumentLoader()->request(), identifier, WTFMove(function));
</del><ins>+    client().dispatchDecidePolicyForResponse(response, activeDocumentLoader()->request(), identifier, activeDocumentLoader()->downloadAttribute(), WTFMove(function));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void FrameLoader::changeLocation(FrameLoadRequest&& request)
</span><span class="lines">@@ -1416,7 +1416,7 @@
</span><span class="cx">     if (isSystemPreview)
</span><span class="cx">         request.setSystemPreviewRect(frameLoadRequest.systemPreviewRect());
</span><span class="cx"> #endif
</span><del>-    loadWithNavigationAction(request, WTFMove(action), lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
</del><ins>+    loadWithNavigationAction(request, WTFMove(action), lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, frameLoadRequest.downloadAttribute(), [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
</ins><span class="cx">         if (isRedirect) {
</span><span class="cx">             m_quickRedirectComing = false;
</span><span class="cx">             if (m_provisionalDocumentLoader)
</span><span class="lines">@@ -1492,11 +1492,12 @@
</span><span class="cx">     load(loader.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, CompletionHandler<void()>&& completionHandler)
</del><ins>+void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, const String& downloadAttribute, CompletionHandler<void()>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_LOG_IF_ALLOWED("loadWithNavigationAction: frame load started (frame = %p, main = %d)", &m_frame, m_frame.isMainFrame());
</span><span class="cx"> 
</span><span class="cx">     Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
</span><ins>+    loader->setDownloadAttribute(downloadAttribute);
</ins><span class="cx">     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
</span><span class="cx"> 
</span><span class="cx">     if (lockHistory == LockHistory::Yes && m_documentLoader)
</span><span class="lines">@@ -3016,7 +3017,7 @@
</span><span class="cx">     if (!frameName.isEmpty()) {
</span><span class="cx">         // The search for a target frame is done earlier in the case of form submission.
</span><span class="cx">         if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
</span><del>-            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, WTFMove(completionHandler));
</del><ins>+            targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, WTFMove(completionHandler));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -3029,7 +3030,7 @@
</span><span class="cx"> 
</span><span class="cx">     // must grab this now, since this load may stop the previous load and clear this flag
</span><span class="cx">     bool isRedirect = m_quickRedirectComing;
</span><del>-    loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
</del><ins>+    loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
</ins><span class="cx">         if (isRedirect) {
</span><span class="cx">             m_quickRedirectComing = false;
</span><span class="cx">             if (m_provisionalDocumentLoader)
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.h        2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/loader/FrameLoader.h   2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -381,7 +381,7 @@
</span><span class="cx">     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, CompletionHandler<void()>&& = [] { }); // Calls continueLoadAfterNavigationPolicy
</span><span class="cx">     void load(DocumentLoader&); // Calls loadWithDocumentLoader
</span><span class="cx"> 
</span><del>-    void loadWithNavigationAction(const ResourceRequest&, NavigationAction&&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
</del><ins>+    void loadWithNavigationAction(const ResourceRequest&, NavigationAction&&, LockHistory, FrameLoadType, RefPtr<FormState>&&, AllowNavigationToInvalidURL, const String& downloadAttribute = { }, CompletionHandler<void()>&& = [] { }); // Calls loadWithDocumentLoader
</ins><span class="cx"> 
</span><span class="cx">     void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, CompletionHandler<void()>&&);
</span><span class="cx">     void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, RefPtr<FormState>&&, Optional<AdClickAttribution>&&, CompletionHandler<void()>&&);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoaderClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoaderClient.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoaderClient.h  2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebCore/loader/FrameLoaderClient.h     2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx">     virtual Frame* dispatchCreatePage(const NavigationAction&) = 0;
</span><span class="cx">     virtual void dispatchShow() = 0;
</span><span class="cx"> 
</span><del>-    virtual void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, PolicyCheckIdentifier, FramePolicyFunction&&) = 0;
</del><ins>+    virtual void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, PolicyCheckIdentifier, const String& downloadAttribute, FramePolicyFunction&&) = 0;
</ins><span class="cx">     virtual void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String& frameName, PolicyCheckIdentifier, FramePolicyFunction&&) = 0;
</span><span class="cx">     virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, const ResourceResponse& redirectResponse, FormState*, PolicyDecisionMode, PolicyCheckIdentifier, FramePolicyFunction&&) = 0;
</span><span class="cx">     virtual void cancelPolicyCheck() = 0;
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/ChangeLog       2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2019-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI WKNavigationResponse._downloadAttribute
+        https://bugs.webkit.org/show_bug.cgi?id=196755
+        <rdar://49587365>
+
+        Reviewed by Brady Eidson.
+
+        * UIProcess/API/APINavigationResponse.h:
+        * UIProcess/API/Cocoa/WKNavigationResponse.mm:
+        (-[WKNavigationResponse _downloadAttribute]):
+        * UIProcess/API/Cocoa/WKNavigationResponsePrivate.h:
+        * UIProcess/ProvisionalPageProxy.cpp:
+        (WebKit::ProvisionalPageProxy::decidePolicyForResponse):
+        * UIProcess/ProvisionalPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::decidePolicyForResponse):
+        (WebKit::WebPageProxy::decidePolicyForResponseShared):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+
</ins><span class="cx"> 2019-04-10  Youenn Fablet  <youenn@apple.com>
</span><span class="cx"> 
</span><span class="cx">         SWClientConnection should not double hop to fire some events
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPIAPINavigationResponseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/APINavigationResponse.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/APINavigationResponse.h        2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/API/APINavigationResponse.h   2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -23,8 +23,7 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef APINavigationResponse_h
-#define APINavigationResponse_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><span class="cx"> #include "APIFrameInfo.h"
</span><span class="cx"> #include "APIObject.h"
</span><span class="lines">@@ -37,19 +36,11 @@
</span><span class="cx"> 
</span><span class="cx"> class NavigationResponse final : public ObjectImpl<Object::Type::NavigationResponse> {
</span><span class="cx"> public:
</span><del>-    static Ref<NavigationResponse> create(API::FrameInfo& frame, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, bool canShowMIMEType)
</del><ins>+    template<typename... Args> static Ref<NavigationResponse> create(Args&&... args)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new NavigationResponse(frame, request, response, canShowMIMEType));
</del><ins>+        return adoptRef(*new NavigationResponse(std::forward<Args>(args)...));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    NavigationResponse(API::FrameInfo& frame, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, bool canShowMIMEType)
-        : m_frame(frame)
-        , m_request(request)
-        , m_response(response)
-        , m_canShowMIMEType(canShowMIMEType)
-    {
-    }
-
</del><span class="cx">     FrameInfo& frame() { return m_frame.get(); }
</span><span class="cx"> 
</span><span class="cx">     const WebCore::ResourceRequest& request() const { return m_request; }
</span><span class="lines">@@ -56,15 +47,22 @@
</span><span class="cx">     const WebCore::ResourceResponse& response() const { return m_response; }
</span><span class="cx"> 
</span><span class="cx">     bool canShowMIMEType() const { return m_canShowMIMEType; }
</span><ins>+    const WTF::String& downloadAttribute() const { return m_downloadAttribute; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    NavigationResponse(API::FrameInfo& frame, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, bool canShowMIMEType, const WTF::String& downloadAttribute)
+        : m_frame(frame)
+        , m_request(request)
+        , m_response(response)
+        , m_canShowMIMEType(canShowMIMEType)
+        , m_downloadAttribute(downloadAttribute) { }
+
</ins><span class="cx">     Ref<FrameInfo> m_frame;
</span><span class="cx"> 
</span><span class="cx">     WebCore::ResourceRequest m_request;
</span><span class="cx">     WebCore::ResourceResponse m_response;
</span><span class="cx">     bool m_canShowMIMEType;
</span><ins>+    WTF::String m_downloadAttribute;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace API
</span><del>-
-#endif // APINavigationResponse_h
</del></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoaWKNavigationResponsemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponse.mm (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponse.mm  2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponse.mm     2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -78,4 +78,9 @@
</span><span class="cx">     return _navigationResponse->request().nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSString *)_downloadAttribute
+{
+    return _navigationResponse->downloadAttribute();
+}
+
</ins><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoaWKNavigationResponsePrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponsePrivate.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponsePrivate.h    2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationResponsePrivate.h       2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -29,5 +29,6 @@
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, readonly) WKFrameInfo *_frame;
</span><span class="cx"> @property (nonatomic, readonly) NSURLRequest *_request;
</span><ins>+@property (nonatomic, readonly) NSString *_downloadAttribute WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
</ins><span class="cx"> 
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessProvisionalPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp   2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.cpp      2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -283,9 +283,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ProvisionalPageProxy::decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, WebCore::PolicyCheckIdentifier identifier,
</span><del>-    uint64_t navigationID, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
</del><ins>+    uint64_t navigationID, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData& userData)
</ins><span class="cx"> {
</span><del>-    m_page.decidePolicyForResponseShared(m_process.copyRef(), frameID, frameSecurityOrigin, identifier, navigationID, response, request, canShowMIMEType, listenerID, userData);
</del><ins>+    m_page.decidePolicyForResponseShared(m_process.copyRef(), frameID, frameSecurityOrigin, identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, listenerID, userData);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ProvisionalPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessProvisionalPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/ProvisionalPageProxy.h        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">         uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&, IPC::FormDataReference&& requestBody,
</span><span class="cx">         WebCore::ResourceResponse&& redirectResponse, const UserData&, uint64_t listenerID);
</span><span class="cx">     void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData&, WebCore::PolicyCheckIdentifier, uint64_t navigationID, const WebCore::ResourceResponse&,
</span><del>-        const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
</del><ins>+        const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData&);
</ins><span class="cx">     void didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, URL&&);
</span><span class="cx">     void didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID);
</span><span class="cx">     void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceRequest&&, const UserData&);
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp   2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp      2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -4770,13 +4770,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, PolicyCheckIdentifier identifier,
</span><del>-    uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
</del><ins>+    uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData& userData)
</ins><span class="cx"> {
</span><del>-    decidePolicyForResponseShared(m_process.copyRef(), frameID, frameSecurityOrigin, identifier, navigationID, response, request, canShowMIMEType, listenerID, userData);
</del><ins>+    decidePolicyForResponseShared(m_process.copyRef(), frameID, frameSecurityOrigin, identifier, navigationID, response, request, canShowMIMEType, downloadAttribute, listenerID, userData);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::decidePolicyForResponseShared(Ref<WebProcessProxy>&& process, uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, PolicyCheckIdentifier identifier,
</span><del>-    uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
</del><ins>+    uint64_t navigationID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData& userData)
</ins><span class="cx"> {
</span><span class="cx">     PageClientProtector protector(pageClient());
</span><span class="cx"> 
</span><span class="lines">@@ -4804,7 +4804,7 @@
</span><span class="cx">     if (m_policyClient)
</span><span class="cx">         m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), process->transformHandlesToObjects(userData.object()).get());
</span><span class="cx">     else {
</span><del>-        auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType);
</del><ins>+        auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType, downloadAttribute);
</ins><span class="cx">         m_navigationClient->decidePolicyForNavigationResponse(*this, WTFMove(navigationResponse), WTFMove(listener), process->transformHandlesToObjects(userData.object()).get());
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.h     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1490,7 +1490,7 @@
</span><span class="cx">         uint64_t navigationID, NavigationActionData&&, FrameInfoData&&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&&,
</span><span class="cx">         IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData&, uint64_t listenerID);
</span><span class="cx">     void decidePolicyForResponseShared(Ref<WebProcessProxy>&&, uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, WebCore::PolicyCheckIdentifier,
</span><del>-        uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
</del><ins>+        uint64_t navigationID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData&);
</ins><span class="cx">     void startURLSchemeTaskShared(Ref<WebProcessProxy>&&, URLSchemeTaskParameters&&);
</span><span class="cx">     void loadDataWithNavigationShared(Ref<WebProcessProxy>&&, API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
</span><span class="cx">     void loadRequestWithNavigationShared(Ref<WebProcessProxy>&&, API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& = WTF::nullopt);
</span><span class="lines">@@ -1618,7 +1618,7 @@
</span><span class="cx">     void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData&, WebCore::PolicyCheckIdentifier, NavigationActionData&&,
</span><span class="cx">         WebCore::ResourceRequest&&, const String& frameName, uint64_t listenerID, const UserData&);
</span><span class="cx">     void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData&, WebCore::PolicyCheckIdentifier, uint64_t navigationID,
</span><del>-        const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
</del><ins>+        const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, const String& downloadAttribute, uint64_t listenerID, const UserData&);
</ins><span class="cx">     void unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError&, const UserData&);
</span><span class="cx">     void beginSafeBrowsingCheck(const URL&, bool, WebFramePolicyListenerProxy&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in   2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in      2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Policy messages
</span><del>-    DecidePolicyForResponse(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData)
</del><ins>+    DecidePolicyForResponse(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, String downloadAttribute, uint64_t listenerID, WebKit::UserData userData)
</ins><span class="cx">     DecidePolicyForNavigationActionAsync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, IPC::FormDataReference requestBody, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData, uint64_t listenerID)
</span><span class="cx">     DecidePolicyForNavigationActionSync(uint64_t frameID, bool isMainFrame, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::PolicyCheckIdentifier policyCheckIdentifier, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, IPC::FormDataReference requestBody, WebCore::ResourceResponse redirectResponse, WebKit::UserData userData) -> (WebCore::PolicyCheckIdentifier policyCheckIdentifier, enum:uint8_t WebCore::PolicyAction policyAction, uint64_t newNavigationID, WebKit::DownloadID downloadID, Optional<WebKit::WebsitePoliciesData> websitePolicies) Synchronous
</span><span class="cx">     DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::PolicyCheckIdentifier policyCheckIdentifier, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData)
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebCoreSupportWebFrameLoaderClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp   2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp      2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -763,7 +763,7 @@
</span><span class="cx">     webPage->show();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, FramePolicyFunction&& function)
</del><ins>+void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, const String& downloadAttribute, FramePolicyFunction&& function)
</ins><span class="cx"> {
</span><span class="cx">     WebPage* webPage = m_frame ? m_frame->page() : nullptr;
</span><span class="cx">     if (!webPage) {
</span><span class="lines">@@ -794,7 +794,7 @@
</span><span class="cx">     Ref<WebFrame> protector(*m_frame);
</span><span class="cx">     uint64_t listenerID = m_frame->setUpPolicyListener(identifier, WTFMove(function), WebFrame::ForNavigationAction::No);
</span><span class="cx">     if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), identifier, navigationID, response, request,
</span><del>-        canShowResponse, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))))
</del><ins>+        canShowResponse, downloadAttribute, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))))
</ins><span class="cx">         m_frame->didReceivePolicyDecision(listenerID, identifier, PolicyAction::Ignore, 0, { }, { });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebCoreSupportWebFrameLoaderClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -123,7 +123,7 @@
</span><span class="cx">     WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&) final;
</span><span class="cx">     void dispatchShow() final;
</span><span class="cx">     
</span><del>-    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</del><ins>+    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, const String&, WebCore::FramePolicyFunction&&) final;
</ins><span class="cx">     void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const String& frameName, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</span><span class="cx">     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</span><span class="cx">     void cancelPolicyCheck() final;
</span></span></pre></div>
<a id="trunkSourceWebKitLegacymacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/mac/ChangeLog  2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog     2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2019-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI WKNavigationResponse._downloadAttribute
+        https://bugs.webkit.org/show_bug.cgi?id=196755
+        <rdar://49587365>
+
+        Reviewed by Brady Eidson.
+
+        * WebCoreSupport/WebFrameLoaderClient.h:
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+
</ins><span class="cx"> 2019-04-10  Antoine Quint  <graouts@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Enable Pointer Events on watchOS
</span></span></pre></div>
<a id="trunkSourceWebKitLegacymacWebCoreSupportWebFrameLoaderClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h      2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h 2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -126,7 +126,7 @@
</span><span class="cx">     WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&) final;
</span><span class="cx">     void dispatchShow() final;
</span><span class="cx"> 
</span><del>-    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</del><ins>+    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, const String&,  WebCore::FramePolicyFunction&&) final;
</ins><span class="cx">     void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const WTF::String& frameName, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</span><span class="cx">     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) final;
</span><span class="cx">     void cancelPolicyCheck() final;
</span></span></pre></div>
<a id="trunkSourceWebKitLegacymacWebCoreSupportWebFrameLoaderClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm     2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm        2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -866,7 +866,7 @@
</span><span class="cx">     [[webView _UIDelegateForwarder] webViewShow:webView];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, FramePolicyFunction&& function)
</del><ins>+void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, const String&, FramePolicyFunction&& function)
</ins><span class="cx"> {
</span><span class="cx">     WebView *webView = getWebView(m_webFrame.get());
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitLegacywinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/win/ChangeLog (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/win/ChangeLog  2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/win/ChangeLog     2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2019-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI WKNavigationResponse._downloadAttribute
+        https://bugs.webkit.org/show_bug.cgi?id=196755
+        <rdar://49587365>
+
+        Reviewed by Brady Eidson.
+
+        * WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+        * WebCoreSupport/WebFrameLoaderClient.h:
+
</ins><span class="cx"> 2019-04-05  Commit Queue  <commit-queue@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r243833.
</span></span></pre></div>
<a id="trunkSourceWebKitLegacywinWebCoreSupportWebFrameLoaderClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp    2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp       2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -529,7 +529,7 @@
</span><span class="cx">         ui->webViewShow(webView);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, FramePolicyFunction&& function)
</del><ins>+void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, const String&, FramePolicyFunction&& function)
</ins><span class="cx"> {
</span><span class="cx">     WebView* webView = m_webFrame->webView();
</span><span class="cx">     Frame* coreFrame = core(m_webFrame);
</span></span></pre></div>
<a id="trunkSourceWebKitLegacywinWebCoreSupportWebFrameLoaderClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h      2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h 2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -100,7 +100,7 @@
</span><span class="cx">     void dispatchDidFinishLoad() override;
</span><span class="cx">     void dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone>) override;
</span><span class="cx"> 
</span><del>-    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) override;
</del><ins>+    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::PolicyCheckIdentifier, const String&, WebCore::FramePolicyFunction&&) override;
</ins><span class="cx">     void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const WTF::String& frameName, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) override;
</span><span class="cx">     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&) override;
</span><span class="cx">     void cancelPolicyCheck() override;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Tools/ChangeLog       2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2019-04-10  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI WKNavigationResponse._downloadAttribute
+        https://bugs.webkit.org/show_bug.cgi?id=196755
+        <rdar://49587365>
+
+        Reviewed by Brady Eidson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm:
+        (-[NavigationResponseTestDelegate navigationResponse]):
+        (-[NavigationResponseTestDelegate waitForNavigationResponseCallback]):
+        (-[NavigationResponseTestDelegate waitForNavigationFinishedCallback]):
+        (-[NavigationResponseTestDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
+        (-[NavigationResponseTestDelegate webView:didFinishNavigation:]):
+        (-[NavigationResponseTestDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
+        (readRequest):
+        (writeResponse):
+        (TEST):
+
</ins><span class="cx"> 2019-04-10  Tim Horton  <timothy_horton@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Add modern API for overriding the page's specified viewport configuration
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWKNavigationResponsemm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm (244160 => 244161)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm      2019-04-10 22:55:01 UTC (rev 244160)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm 2019-04-10 22:56:35 UTC (rev 244161)
</span><span class="lines">@@ -25,7 +25,10 @@
</span><span class="cx"> 
</span><span class="cx"> #import "config.h"
</span><span class="cx"> 
</span><ins>+#import "TCPServer.h"
+#import "Test.h"
</ins><span class="cx"> #import "Utilities.h"
</span><ins>+#import <WebKit/WKNavigationResponsePrivate.h>
</ins><span class="cx"> #import <WebKit/WKProcessPoolPrivate.h>
</span><span class="cx"> #import <WebKit/WebKit.h>
</span><span class="cx"> #import <wtf/RetainPtr.h>
</span><span class="lines">@@ -142,3 +145,103 @@
</span><span class="cx">     [webView loadRequest:[NSURLRequest requestWithURL:testURL]];
</span><span class="cx">     TestWebKitAPI::Util::run(&isDone);
</span><span class="cx"> }
</span><ins>+
+@interface NavigationResponseTestDelegate : NSObject <WKNavigationDelegate>
+
+@property (nonatomic, readonly) WKNavigationResponse *navigationResponse;
+@property (nonatomic) WKNavigationResponsePolicy navigationPolicy;
+
+@end
+
+@implementation NavigationResponseTestDelegate {
+    RetainPtr<WKNavigationResponse> _navigationResponse;
+    bool _hasReceivedResponseCallback;
+    bool _hasReceivedNavigationFinishedCallback;
+}
+
+- (WKNavigationResponse *)navigationResponse
+{
+    return _navigationResponse.get();
+}
+
+- (void)waitForNavigationResponseCallback
+{
+    _hasReceivedResponseCallback = false;
+    TestWebKitAPI::Util::run(&_hasReceivedResponseCallback);
+}
+
+- (void)waitForNavigationFinishedCallback
+{
+    _hasReceivedNavigationFinishedCallback = false;
+    TestWebKitAPI::Util::run(&_hasReceivedNavigationFinishedCallback);
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+    decisionHandler(WKNavigationActionPolicyAllow);
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
+{
+    _hasReceivedNavigationFinishedCallback = true;
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
+{
+    decisionHandler(WKNavigationResponsePolicyAllow);
+    _navigationResponse = navigationResponse;
+    _hasReceivedResponseCallback = true;
+}
+
+@end
+
+static void readRequest(int socket)
+{
+    char readBuffer[1000];
+    auto bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
+    EXPECT_GT(bytesRead, 0);
+    EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
+}
+
+static void writeResponse(int socket, NSString *response)
+{
+    const char* bytes = response.UTF8String;
+    auto bytesWritten = ::write(socket, bytes, strlen(bytes));
+    EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(bytes));
+}
+
+TEST(WebKit, WKNavigationResponseDownloadAttribute)
+{
+    TestWebKitAPI::TCPServer server([](int socket) {
+        readRequest(socket);
+        NSString *body = @"<a id='link' href='/fromHref.txt' download='fromDownloadAttribute.txt'>Click Me!</a>";
+        unsigned bodyLength = body.length;
+        writeResponse(socket, [NSString stringWithFormat:
+            @"HTTP/1.1 200 OK\r\n"
+            "Content-Length: %d\r\n\r\n"
+            "%@",
+            bodyLength,
+            body
+        ]);
+        readRequest(socket);
+        writeResponse(socket,
+            @"HTTP/1.1 200 OK\r\n"
+            "Content-Length: 6\r\n"
+            "Content-Disposition: attachment; filename=fromHeader.txt;\r\n\r\n"
+            "Hello!"
+        );
+    });
+    auto delegate = adoptNS([NavigationResponseTestDelegate new]);
+    auto webView = adoptNS([WKWebView new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
+    [delegate waitForNavigationFinishedCallback];
+
+    [webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
+    [delegate waitForNavigationResponseCallback];
+    
+    WKNavigationResponse *response = [delegate navigationResponse];
+    EXPECT_STREQ(response.response.suggestedFilename.UTF8String, "fromHeader.txt");
+    EXPECT_STREQ(response._downloadAttribute.UTF8String, "fromDownloadAttribute.txt");
+}
</ins></span></pre>
</div>
</div>

</body>
</html>