Skip to content
Permalink
Browse files
Expose APINavigationAction.shouldPerformDownload() on WKNavigationAction
https://bugs.webkit.org/show_bug.cgi?id=195121
rdar://problem/48450302

Reviewed by Alex Christensen.

Source/WebKit:

* UIProcess/API/Cocoa/WKNavigationAction.mm:
(-[WKNavigationAction _shouldPerformDownload]):
* UIProcess/API/Cocoa/WKNavigationActionPrivate.h:

Tools:

Add API tests for -WKNavigationAction._shouldPerformDownload in various
configurations where the 'download' attribute is absent, blank, or populated
with a filename, and where the anchor element is same-origin or cross-origin
(meaning the 'download' attribute shouldn't be honored).

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/NavigationAction.mm: Added.
(-[NavigationActionTestDelegate init]):
(-[NavigationActionTestDelegate navigationAction]):
(-[NavigationActionTestDelegate waitForNavigationActionCallback]):
(-[NavigationActionTestDelegate waitForDidFinishNavigation]):
(-[NavigationActionTestDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[NavigationActionTestDelegate webView:didFinishNavigation:]):
(TEST):


Canonical link: https://commits.webkit.org/209518@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242236 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
davidquesada committed Feb 28, 2019
1 parent 60767e6 commit 9d7e03530c74c71d71124dee07b66d4d7c8adcc3
Showing 6 changed files with 226 additions and 0 deletions.
@@ -1,3 +1,15 @@
2019-02-28 David Quesada <david_quesada@apple.com>

Expose APINavigationAction.shouldPerformDownload() on WKNavigationAction
https://bugs.webkit.org/show_bug.cgi?id=195121
rdar://problem/48450302

Reviewed by Alex Christensen.

* UIProcess/API/Cocoa/WKNavigationAction.mm:
(-[WKNavigationAction _shouldPerformDownload]):
* UIProcess/API/Cocoa/WKNavigationActionPrivate.h:

2019-02-28 Antoine Quint <graouts@apple.com>

Disable Web Animations in Safari Technology Preview
@@ -187,6 +187,11 @@ - (BOOL)_shouldOpenAppLinks
return _navigationAction->shouldOpenAppLinks();
}

- (BOOL)_shouldPerformDownload
{
return _navigationAction->shouldPerformDownload();
}

- (BOOL)_shouldOpenExternalURLs
{
return [self _shouldOpenExternalSchemes];
@@ -47,6 +47,7 @@ typedef NS_ENUM(NSInteger, WKSyntheticClickType) {
@property (nonatomic, readonly) BOOL _canHandleRequest;
@property (nonatomic, readonly) BOOL _shouldOpenExternalSchemes WK_API_AVAILABLE(macosx(10.11), ios(9.0));
@property (nonatomic, readonly) BOOL _shouldOpenAppLinks WK_API_AVAILABLE(macosx(10.11), ios(9.0));
@property (nonatomic, readonly) BOOL _shouldPerformDownload WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));

@property (nonatomic, readonly) BOOL _shouldOpenExternalURLs WK_API_DEPRECATED("use _shouldOpenExternalSchemes and _shouldOpenAppLinks", macosx(10.11, 10.11), ios(9.0, 9.0));

@@ -1,3 +1,26 @@
2019-02-28 David Quesada <david_quesada@apple.com>

Expose APINavigationAction.shouldPerformDownload() on WKNavigationAction
https://bugs.webkit.org/show_bug.cgi?id=195121
rdar://problem/48450302

Reviewed by Alex Christensen.

Add API tests for -WKNavigationAction._shouldPerformDownload in various
configurations where the 'download' attribute is absent, blank, or populated
with a filename, and where the anchor element is same-origin or cross-origin
(meaning the 'download' attribute shouldn't be honored).

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/NavigationAction.mm: Added.
(-[NavigationActionTestDelegate init]):
(-[NavigationActionTestDelegate navigationAction]):
(-[NavigationActionTestDelegate waitForNavigationActionCallback]):
(-[NavigationActionTestDelegate waitForDidFinishNavigation]):
(-[NavigationActionTestDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[NavigationActionTestDelegate webView:didFinishNavigation:]):
(TEST):

2019-02-28 Antoine Quint <graouts@apple.com>

Enable the Pointer Events runtime flag by default
@@ -340,6 +340,7 @@
5E4B1D2E1D404C6100053621 /* WKScrollViewDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegate.mm */; };
631EFFF61E7B5E8D00D2EBB8 /* Geolocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 631EFFF51E7B5E8D00D2EBB8 /* Geolocation.mm */; };
634910E01E9D3FF300880309 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 634910DF1E9D3FF300880309 /* CoreLocation.framework */; };
6351992822275C6A00890AD3 /* NavigationAction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6351992722275C6A00890AD3 /* NavigationAction.mm */; };
6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */; };
6356FB221EC4E0BA0044BF18 /* VisibleContentRect.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */; };
636353A71E98665D0009F8AF /* GeolocationGetCurrentPositionResult.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */; };
@@ -1728,6 +1729,7 @@
5E4B1D2C1D404C6100053621 /* WKScrollViewDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKScrollViewDelegate.mm; path = ../ios/WKScrollViewDelegate.mm; sourceTree = "<group>"; };
631EFFF51E7B5E8D00D2EBB8 /* Geolocation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Geolocation.mm; sourceTree = "<group>"; };
634910DF1E9D3FF300880309 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
6351992722275C6A00890AD3 /* NavigationAction.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigationAction.mm; sourceTree = "<group>"; };
6354F4D01F7C3AB500D89DF3 /* ApplicationManifestParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationManifestParser.cpp; sourceTree = "<group>"; };
6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = VisibleContentRect.mm; sourceTree = "<group>"; };
636353A61E9861940009F8AF /* GeolocationGetCurrentPositionResult.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = GeolocationGetCurrentPositionResult.html; sourceTree = "<group>"; };
@@ -2544,6 +2546,7 @@
5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */,
51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */,
1ABC3DED1899BE6D004F0626 /* Navigation.mm */,
6351992722275C6A00890AD3 /* NavigationAction.mm */,
5C8BC798218CF3E900813886 /* NetworkProcess.mm */,
5CAE4637201937CD0051610F /* NetworkProcessCrashNonPersistentDataStore.mm */,
CD2D0D19213465560018C784 /* NowPlaying.mm */,
@@ -4150,6 +4153,7 @@
7C83E0B61D0A64B300FEBCF3 /* ModalAlertsSPI.cpp in Sources */,
7CCE7F011A411AE600447C4C /* MouseMoveAfterCrash.cpp in Sources */,
7CCE7F241A411AF600447C4C /* Navigation.mm in Sources */,
6351992822275C6A00890AD3 /* NavigationAction.mm in Sources */,
5C0BF8951DD599CD00B00328 /* NavigatorLanguage.mm in Sources */,
5C8BC799218CF44700813886 /* NetworkProcess.mm in Sources */,
5CAE463820193B6A0051610F /* NetworkProcessCrashNonPersistentDataStore.mm in Sources */,
@@ -0,0 +1,181 @@
/*
* Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"

#import "PlatformUtilities.h"
#import "Test.h"
#import "TestWKWebView.h"
#import <WebKit/WKNavigationActionPrivate.h>
#import <wtf/RetainPtr.h>

#if WK_API_ENABLED

@interface NavigationActionTestDelegate : NSObject <WKNavigationDelegate>

@property (nonatomic, readonly) WKNavigationAction *navigationAction;
@property (nonatomic) WKNavigationActionPolicy navigationPolicy;

@end

@implementation NavigationActionTestDelegate {
RetainPtr<WKNavigationAction> _navigationAction;
bool _hasReceivedNavigationCallback;
bool _hasFinishedNavigation;
}

- (instancetype)init
{
if (!(self = [super init]))
return nil;

_navigationPolicy = WKNavigationActionPolicyAllow;

return self;
}

- (WKNavigationAction *)navigationAction
{
return _navigationAction.get();
}

- (void)waitForNavigationActionCallback
{
_navigationAction = nullptr;
_hasReceivedNavigationCallback = false;
TestWebKitAPI::Util::run(&_hasReceivedNavigationCallback);
}

- (void)waitForDidFinishNavigation
{
_hasFinishedNavigation = false;
TestWebKitAPI::Util::run(&_hasFinishedNavigation);
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
decisionHandler(_navigationPolicy);
_navigationAction = navigationAction;
_hasReceivedNavigationCallback = true;
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
_hasFinishedNavigation = true;
}

@end

TEST(WKNavigationAction, ShouldPerformDownload_NoDownloadAttribute)
{
auto navigationDelegate = adoptNS([[NavigationActionTestDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
[webView setNavigationDelegate:navigationDelegate.get()];

auto baseURL = retainPtr([NSURL URLWithString:@"https://example.com/index.html"]);
[webView loadHTMLString:@"<a id='link' href='file.txt'>Click Me!</a>" baseURL:baseURL.get()];
[navigationDelegate waitForDidFinishNavigation];

[webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
navigationDelegate.get().navigationPolicy = WKNavigationActionPolicyCancel;
[navigationDelegate waitForNavigationActionCallback];

EXPECT_NOT_NULL(navigationDelegate.get().navigationAction);
EXPECT_FALSE(navigationDelegate.get().navigationAction._shouldPerformDownload);
}

TEST(WKNavigationAction, ShouldPerformDownload_BlankDownloadAttribute_SameOrigin)
{
auto navigationDelegate = adoptNS([[NavigationActionTestDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
[webView setNavigationDelegate:navigationDelegate.get()];

auto baseURL = retainPtr([NSURL URLWithString:@"https://example.com/index.html"]);
[webView loadHTMLString:@"<a id='link' href='file.txt' download>Click Me!</a>" baseURL:baseURL.get()];
[navigationDelegate waitForDidFinishNavigation];

[webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
navigationDelegate.get().navigationPolicy = WKNavigationActionPolicyCancel;
[navigationDelegate waitForNavigationActionCallback];

EXPECT_NOT_NULL(navigationDelegate.get().navigationAction);
EXPECT_TRUE(navigationDelegate.get().navigationAction._shouldPerformDownload);
}

TEST(WKNavigationAction, ShouldPerformDownload_BlankDownloadAttribute_CrossOrigin)
{
auto navigationDelegate = adoptNS([[NavigationActionTestDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
[webView setNavigationDelegate:navigationDelegate.get()];

auto baseURL = retainPtr([NSURL URLWithString:@"https://example.com/index.html"]);
[webView loadHTMLString:@"<a id='link' href='https://not-example-dot-com.com/file.txt' download>Click Me!</a>" baseURL:baseURL.get()];
[navigationDelegate waitForDidFinishNavigation];

[webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
navigationDelegate.get().navigationPolicy = WKNavigationActionPolicyCancel;
[navigationDelegate waitForNavigationActionCallback];

EXPECT_NOT_NULL(navigationDelegate.get().navigationAction);
EXPECT_FALSE(navigationDelegate.get().navigationAction._shouldPerformDownload);
}

TEST(WKNavigationAction, ShouldPerformDownload_DownloadAttribute_SameOrigin)
{
auto navigationDelegate = adoptNS([[NavigationActionTestDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
[webView setNavigationDelegate:navigationDelegate.get()];

auto baseURL = retainPtr([NSURL URLWithString:@"https://example.com/index.html"]);
[webView loadHTMLString:@"<a id='link' href='file.txt' download='file2.txt'>Click Me!</a>" baseURL:baseURL.get()];
[navigationDelegate waitForDidFinishNavigation];

[webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
navigationDelegate.get().navigationPolicy = WKNavigationActionPolicyCancel;
[navigationDelegate waitForNavigationActionCallback];

EXPECT_NOT_NULL(navigationDelegate.get().navigationAction);
EXPECT_TRUE(navigationDelegate.get().navigationAction._shouldPerformDownload);
}

TEST(WKNavigationAction, ShouldPerformDownload_DownloadAttribute_CrossOrigin)
{
auto navigationDelegate = adoptNS([[NavigationActionTestDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
[webView setNavigationDelegate:navigationDelegate.get()];

auto baseURL = retainPtr([NSURL URLWithString:@"https://example.com/index.html"]);
[webView loadHTMLString:@"<a id='link' href='https://not-example-dot-com.com/file.txt' download='file2.txt'>Click Me!</a>" baseURL:baseURL.get()];
[navigationDelegate waitForDidFinishNavigation];

[webView evaluateJavaScript:@"document.getElementById('link').click();" completionHandler:nil];
navigationDelegate.get().navigationPolicy = WKNavigationActionPolicyCancel;
[navigationDelegate waitForNavigationActionCallback];

EXPECT_NOT_NULL(navigationDelegate.get().navigationAction);
EXPECT_FALSE(navigationDelegate.get().navigationAction._shouldPerformDownload);
}

#endif // WK_API_ENABLED

0 comments on commit 9d7e035

Please sign in to comment.