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
Conversation
- Deprecated WebView "blacklistedURLs" property in favor of new "blockedURLs" property. - Deprecated WebView "blacklisturl" event in favor of new "blockedurl" event. Fixes TIMOB-28030
@@ -501,6 +502,47 @@ describe('Titanium.UI.WebView', function () { | |||
win.open(); | |||
}); | |||
|
|||
it.ios('blockedurl', function (finish) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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!
There was a problem hiding this 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!
// 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; |
There was a problem hiding this comment.
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;`
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explaining. Approved!
for (id blacklistedURL in blacklistedURLs) { | ||
ENSURE_TYPE(blacklistedURL, NSString); | ||
ENSURE_TYPE(blacklistedURLs, NSArray); | ||
for (id nextURL in blacklistedURLs) { | ||
ENSURE_TYPE(nextURL, NSString); | ||
} | ||
|
||
_blacklistedURLs = blacklistedURLs; |
There was a problem hiding this comment.
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.
There was a problem hiding this 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?
On iOS, it logs a deprecation warning every time you get/set the "blacklistedURLs" property. Yes, it's inconsistent, but I didn't think it was worth reworking the Android code to make it behave more like iOS. |
JIRA:
https://jira.appcelerator.org/browse/TIMOB-28030
Summary:
WebView
"blacklistedURLs" property in favor of new "blockedURLs" property.WebView
"blacklisturl" event in favor of new "blockedurl" event.New API Test:
Deprecated API Test: