Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add WebView "blockedURLs" property #11842

Merged
merged 3 commits into from Aug 21, 2020

Conversation

jquick-axway
Copy link
Contributor

JIRA:
https://jira.appcelerator.org/browse/TIMOB-28030

Summary:

  • Deprecated WebView "blacklistedURLs" property in favor of new "blockedURLs" property.
  • Deprecated WebView "blacklisturl" event in favor of new "blockedurl" event.

New API Test:

  1. Build and run the below on Android.
  2. Tap on the "www.apple.com" link.
  3. Verify a dialog is displayed stating "www.apple.com" was blocked.
  4. Tap on the "www.google.com" link.
  5. Verify a dialog is displayed stating "www.google.com" was blocked.
  6. Tap on the "www.axway.com" link.
  7. Verify that the Axway website was loaded. (This requires an Internet connection.)
  8. Repeat steps 1-7 on iOS.
var htmlText =
		'<!DOCTYPE html>\n' +
		'<html>\n' +
		'	<head>\n' +
		'		<meta name="viewport" content="width=device-width, initial-scale=1.0">\n' +
		'	</head>\n' +
		'	<body>\n' +
		'		<p>WebView "blockedURLs" Test</p>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.axway.com">www.axway.com</a>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.apple.com">www.apple.com</a>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.google.com">www.google.com</a>\n' +
		'	</body>\n' +
		'</html>\n';

var window = Ti.UI.createWindow();
var webView = Ti.UI.createWebView({
	html: htmlText,
	blockedURLs: ["www.apple.com", "www.google.com"],
});
webView.addEventListener("blockedurl", function(e) {
	alert("Blocked URL:\n" + e.url);
});
window.add(webView);
window.addEventListener("androidback", function() {
	if (webView.canGoBack()) {
		webView.goBack();
	} else {
		window.close();
	}
});
window.open();

Deprecated API Test:

  1. Build and run the below on Android.
  2. Tap on the "www.apple.com" link.
  3. Verify that a deprecation warning gets logged. (iOS will only log it once.)
  4. Verify a dialog is displayed stating "www.apple.com" was blocked.
  5. Tap on the "www.google.com" link.
  6. Verify a dialog is displayed stating "www.google.com" was blocked.
  7. Tap on the "www.axway.com" link.
  8. Verify that the Axway website was loaded. (This requires an Internet connection.)
  9. Repeat steps 1-8 on iOS.
var htmlText =
		'<!DOCTYPE html>\n' +
		'<html>\n' +
		'	<head>\n' +
		'		<meta name="viewport" content="width=device-width, initial-scale=1.0">\n' +
		'	</head>\n' +
		'	<body>\n' +
		'		<p>WebView "blockedURLs" Test</p>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.axway.com">www.axway.com</a>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.apple.com">www.apple.com</a>\n' +
		'		<br/>\n' +
		'		<br/>\n' +
		'		<a href="https://www.google.com">www.google.com</a>\n' +
		'	</body>\n' +
		'</html>\n';

var window = Ti.UI.createWindow();
var webView = Ti.UI.createWebView({
	html: htmlText,
	blacklistedURLs: ["www.apple.com", "www.google.com"],
});
webView.addEventListener("blacklisturl", function(e) {
	alert("Blocked URL:\n" + e.url);
});
window.add(webView);
window.addEventListener("androidback", function() {
	if (webView.canGoBack()) {
		webView.goBack();
	} else {
		window.close();
	}
});
window.open();

- Deprecated WebView "blacklistedURLs" property in favor of new "blockedURLs" property.
- Deprecated WebView "blacklisturl" event in favor of new "blockedurl" event.

Fixes TIMOB-28030
@build
Copy link
Contributor

build commented Jul 24, 2020

Messages
📖 ✊ The commits in this PR match our conventions! Feel free to Rebase and Merge this PR when ready.
📖

✅ All tests are passing
Nice one! All 4640 tests are passing.
(There are 470 skipped tests not included in that total)

Generated by 🚫 dangerJS against c24c2df

@@ -501,6 +502,47 @@ describe('Titanium.UI.WebView', function () {
win.open();
});

it.ios('blockedurl', function (finish) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be ran on Android too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately no. On Android, we can only "natively" block the links the end-user tapped on. We can't block the URLs that are loaded programmatically. This is something we document.

We can natively detect the URL being navigated to after the HTTP request has been sent by the WebView on Android, but then it's already too late. We may not be able to abort it in time. Especially if a cached HTTP response is received.

Copy link
Collaborator

@ewanharris ewanharris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me, just a comment on an iOS only test. Thanks for doing this @jquick-axway!

Copy link
Contributor

@vijaysingh-axway vijaysingh-axway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jquick-axway iOS changes will work. Code can be updated as per review comment. Thanks!

Comment on lines -1013 to 1057
// Handle blacklisted URL's
// Do not load the URL if it's black-listed.
// DEPRECATED: Should use "blockedURLs" property with a "blockedurl" event listener instead.
NSString *urlCandidate = navigationAction.request.URL.absoluteString;
if (_blacklistedURLs != nil && _blacklistedURLs.count > 0) {
NSString *urlCandidate = navigationAction.request.URL.absoluteString;

for (NSString *blackListedURL in _blacklistedURLs) {
if ([urlCandidate rangeOfString:blackListedURL options:NSCaseInsensitiveSearch].location != NSNotFound) {
for (NSString *blockedURL in _blacklistedURLs) {
if ([urlCandidate rangeOfString:blockedURL options:NSCaseInsensitiveSearch].location != NSNotFound) {
if ([[self proxy] _hasListeners:@"blacklisturl"]) {
[[self proxy] fireEvent:@"blacklisturl"
withObject:@{
@"url" : urlCandidate,
@"message" : @"Webview did not load blacklisted url."
}];
}
decisionHandler(WKNavigationActionPolicyCancel);
[self _cleanupLoadingIndicator];
return;
}
}
}

// Do not load the URL if it's on the block-list.
if (_blockedURLs != nil && _blockedURLs.count > 0) {
for (NSString *blockedURL in _blockedURLs) {
if ([urlCandidate rangeOfString:blockedURL options:NSCaseInsensitiveSearch].location != NSNotFound) {
if ([[self proxy] _hasListeners:@"blockedurl"]) {
[[self proxy] fireEvent:@"blockedurl"
withObject:@{
@"url" : urlCandidate,
@"message" : @"Webview did not load blocked url."
}];
}
decisionHandler(WKNavigationActionPolicyCancel);
[self _cleanupLoadingIndicator];
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be better to merge 'backlisteurl' event related code snippet inside 'blockedurl' . So above code snippet can be replaced by following-
`
// Do not load the URL if it's on the block-list.
if (_blockedURLs != nil && _blockedURLs.count > 0) {
NSString *urlCandidate = navigationAction.request.URL.absoluteString;
for (NSString *blockedURL in _blockedURLs) {
if ([urlCandidate rangeOfString:blockedURL options:NSCaseInsensitiveSearch].location != NSNotFound) {
if ([[self proxy] _hasListeners:@"blacklisturl"]) {
DEPRECATED_REPLACED(@"UI.WebView.blacklisturl", @"9.2.0", @"UI.WebView.blockedurl");

      [[self proxy] fireEvent:@"blacklisturl"
                   withObject:@{
                     @"url" : urlCandidate,
                     @"message" : @"Webview did not load blacklisted url."
                   }];
    }
    if ([[self proxy] _hasListeners:@"blockedurl"]) {
      [[self proxy] fireEvent:@"blockedurl"
                   withObject:@{
                     @"url" : urlCandidate,
                     @"message" : @"Webview did not load blocked url."
                   }];
    }
    decisionHandler(WKNavigationActionPolicyCancel);
    [self _cleanupLoadingIndicator];
    return;`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I separated the 2 on purpose so that we can easily delete the "blacklisted" code in the future.
(Otherwise I wouldn't normally duplicate code like this.)

So, the way it works now is a "blacklisturl" event will only be fired for matches in the blacklistedURLs property... and a "blockedurl" event will only be fired for matches in the blockedURLs property. I purposely treat them separately on both Android and iOS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explaining. Approved!

Comment on lines -250 to 255
for (id blacklistedURL in blacklistedURLs) {
ENSURE_TYPE(blacklistedURL, NSString);
ENSURE_TYPE(blacklistedURLs, NSArray);
for (id nextURL in blacklistedURLs) {
ENSURE_TYPE(nextURL, NSString);
}

_blacklistedURLs = blacklistedURLs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call [self setBlockedURLs_: blacklistedURLs] from here.

Copy link
Contributor

@ssjsamir ssjsamir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FR Passed, tested using the test case mentioned in the description.

Test Environment

MacOS Big Sur: 11.0 Beta 4
Xcode: 12.0 Beta  4
Java Version: 1.8.0_242
Android NDK: 21.3.6528147
Node.js: 12.18.1
""NPM":"5.0.0","CLI":"8.1.0-master.11""
iphone 8 Sim (14.0 Beta)
API29 Pixel XL

@jquick-axway On iOS does the following message [WARN] �� � Ti.UI.WebView.blacklistedURLs DEPRECATED in 9.2.0, in favor of Ti.UI.WebView.blockedURLs only display the first time the app is launched or just it be displayed only once every-time a blocked URL is clicked?

@jquick-axway
Copy link
Contributor Author

@ssjsamir,

On iOS, it logs a deprecation warning every time you get/set the "blacklistedURLs" property.
On Android, it logs a deprecation warning when you tap on a blacklisted link.

Yes, it's inconsistent, but I didn't think it was worth reworking the Android code to make it behave more like iOS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants