diff --git a/CHANGELOG.md b/CHANGELOG.md index 43aec0b9..695460d9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 6.0.0-beta.13 + +- Added `ContentBlockerActionType.BLOCK_COOKIES` and `ContentBlockerActionType.IGNORE_PREVIOUS_RULES` for iOS and macOS platforms +- Updated `ContentBlockerTrigger.urlFilterIsCaseSensitive` for Android +- Fixed Android `ContentBlockerActionType.CSS_DISPLAY_NONE` usage + ## 6.0.0-beta.12 - Removed `willSuppressErrorPage` WebView Android setting in favor of `disableDefaultErrorPage`. diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java index 40ed27a7..5df041a1 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java @@ -8,6 +8,7 @@ import android.webkit.WebResourceResponse; import androidx.annotation.Nullable; import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.InAppWebView; +import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS; import com.pichillilorenzo.flutter_inappwebview.Util; import java.io.ByteArrayInputStream; @@ -150,9 +151,9 @@ public class ContentBlockerHandler { final String cssSelector = action.getSelector(); final String jsScript = "(function(d) { " + " function hide () { " + - " if (!d.getElementById('css-display-none-style')) { " + + " if (!d.getElementById('" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "-css-display-none-style')) { " + " var c = d.createElement('style'); " + - " c.id = 'css-display-none-style'; " + + " c.id = '" + JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME + "-css-display-none-style'; " + " c.innerHTML = '" + cssSelector + " { display: none !important; }'; " + " d.body.appendChild(c); " + " }" + @@ -165,7 +166,7 @@ public class ContentBlockerHandler { "})(document);"; final Handler handler = new Handler(webView.getWebViewLooper()); - handler.post(new Runnable() { + handler.postDelayed(new Runnable() { @Override public void run() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -174,7 +175,7 @@ public class ContentBlockerHandler { webView.loadUrl("javascript:" + jsScript); } } - }); + }, 800); break; case MAKE_HTTPS: diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java index 8310ede1..f47ea7b5 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerTrigger.java @@ -25,11 +25,12 @@ public class ContentBlockerTrigger { public ContentBlockerTrigger(@NonNull String urlFilter, @Nullable Boolean urlFilterIsCaseSensitive, @Nullable List resourceType, @Nullable List ifDomain, @Nullable List unlessDomain, @Nullable List loadType, @Nullable List ifTopUrl, @Nullable List unlessTopUrl) { + this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive != null ? urlFilterIsCaseSensitive : false; + this.urlFilter = urlFilter; - this.urlFilterPatternCompiled = Pattern.compile(this.urlFilter); + this.urlFilterPatternCompiled = Pattern.compile(this.urlFilter, this.urlFilterIsCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE); this.resourceType = resourceType != null ? resourceType : this.resourceType; - this.urlFilterIsCaseSensitive = urlFilterIsCaseSensitive != null ? urlFilterIsCaseSensitive : false; this.ifDomain = ifDomain != null ? ifDomain : this.ifDomain; this.unlessDomain = unlessDomain != null ? unlessDomain : this.unlessDomain; if ((!(this.ifDomain.isEmpty() || this.unlessDomain.isEmpty()) != false)) diff --git a/lib/src/content_blocker.dart b/lib/src/content_blocker.dart index ae88732e..f4f34be0 100755 --- a/lib/src/content_blocker.dart +++ b/lib/src/content_blocker.dart @@ -49,14 +49,17 @@ class ContentBlockerTrigger { ///- MacOS List ifFrameUrl; - ///A Boolean value. The default value is `false`. + ///A Boolean value indicating if the URL matching should be case-sensitive. + ///The default value is `false`. /// ///**Supported Platforms/Implementations**: + ///- Android native WebView ///- iOS ///- MacOS bool urlFilterIsCaseSensitive; - ///A list of [ContentBlockerTriggerResourceType] representing the resource types (how the browser intends to use the resource) that the rule should match. + ///A list of [ContentBlockerTriggerResourceType] representing the resource types + ///(how the browser intends to use the resource) that the rule should match. ///If not specified, the rule matches all resource types. /// ///**Supported Platforms/Implementations**: @@ -66,7 +69,8 @@ class ContentBlockerTrigger { List resourceType; ///A list of strings matched to a URL's domain; limits action to a list of specific domains. - ///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.unlessDomain]. + ///Values must be lowercase ASCII, or punycode for non-ASCII. + ///Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.unlessDomain]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView @@ -75,7 +79,8 @@ class ContentBlockerTrigger { List ifDomain; ///A list of strings matched to a URL's domain; acts on any site except domains in a provided list. - ///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.ifDomain]. + ///Values must be lowercase ASCII, or punycode for non-ASCII. + ///Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.ifDomain]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView @@ -83,7 +88,8 @@ class ContentBlockerTrigger { ///- MacOS List unlessDomain; - ///A list of [ContentBlockerTriggerLoadType] that can include one of two mutually exclusive values. If not specified, the rule matches all load types. + ///A list of [ContentBlockerTriggerLoadType] that can include one of two mutually exclusive values. + ///If not specified, the rule matches all load types. /// ///**Supported Platforms/Implementations**: ///- Android native WebView diff --git a/lib/src/types/content_blocker_action_type.dart b/lib/src/types/content_blocker_action_type.dart index dfbce79e..606c151a 100644 --- a/lib/src/types/content_blocker_action_type.dart +++ b/lib/src/types/content_blocker_action_type.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; import '../content_blocker.dart'; @@ -9,18 +10,55 @@ part 'content_blocker_action_type.g.dart'; class ContentBlockerActionType_ { // ignore: unused_field final String _value; + const ContentBlockerActionType_._internal(this._value); ///Stops loading of the resource. If the resource was cached, the cache is ignored. + @EnumSupportedPlatforms(platforms: [ + EnumAndroidPlatform(value: 'block'), + EnumIOSPlatform(value: 'block'), + EnumMacOSPlatform(value: 'block') + ]) static const BLOCK = const ContentBlockerActionType_._internal('block'); - ///Hides elements of the page based on a CSS selector. A selector field contains the selector list. Any matching element has its display property set to none, which hides it. + ///Hides elements of the page based on a CSS selector. + ///A selector field contains the selector list. + ///Any matching element has its display property set to none, which hides it. /// ///**NOTE**: on Android, JavaScript must be enabled. + @EnumSupportedPlatforms(platforms: [ + EnumAndroidPlatform(value: 'css-display-none'), + EnumIOSPlatform(value: 'css-display-none'), + EnumMacOSPlatform(value: 'css-display-none') + ]) static const CSS_DISPLAY_NONE = const ContentBlockerActionType_._internal('css-display-none'); - ///Changes a URL from http to https. URLs with a specified (nondefault) port and links using other protocols are unaffected. + ///Changes a URL from http to https. + ///URLs with a specified (nondefault) port and links using other protocols are unaffected. + @EnumSupportedPlatforms(platforms: [ + EnumAndroidPlatform(value: 'make-https'), + EnumIOSPlatform(value: 'make-https'), + EnumMacOSPlatform(value: 'make-https') + ]) static const MAKE_HTTPS = const ContentBlockerActionType_._internal('make-https'); + + ///Strips cookies from the header before sending it to the server. + ///This only blocks cookies otherwise acceptable to WebView's privacy policy. + ///Combining with [IGNORE_PREVIOUS_RULES] doesn't override the browser’s privacy settings. + @EnumSupportedPlatforms(platforms: [ + EnumIOSPlatform(value: 'block-cookies'), + EnumMacOSPlatform(value: 'block-cookies') + ]) + static const BLOCK_COOKIES = + const ContentBlockerActionType_._internal('block-cookies'); + + ///Ignores previously triggered actions. + @EnumSupportedPlatforms(platforms: [ + EnumIOSPlatform(value: 'ignore-previous-rules'), + EnumMacOSPlatform(value: 'ignore-previous-rules') + ]) + static const IGNORE_PREVIOUS_RULES = + const ContentBlockerActionType_._internal('ignore-previous-rules'); } diff --git a/lib/src/types/content_blocker_action_type.g.dart b/lib/src/types/content_blocker_action_type.g.dart index 45b202ec..bcd89be2 100644 --- a/lib/src/types/content_blocker_action_type.g.dart +++ b/lib/src/types/content_blocker_action_type.g.dart @@ -17,23 +17,119 @@ class ContentBlockerActionType { ContentBlockerActionType._internal(value, nativeValue()); ///Stops loading of the resource. If the resource was cached, the cache is ignored. - static const BLOCK = ContentBlockerActionType._internal('block', 'block'); + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + static final BLOCK = + ContentBlockerActionType._internalMultiPlatform('block', () { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return 'block'; + case TargetPlatform.iOS: + return 'block'; + case TargetPlatform.macOS: + return 'block'; + default: + break; + } + return null; + }); - ///Hides elements of the page based on a CSS selector. A selector field contains the selector list. Any matching element has its display property set to none, which hides it. + ///Hides elements of the page based on a CSS selector. + ///A selector field contains the selector list. + ///Any matching element has its display property set to none, which hides it. /// ///**NOTE**: on Android, JavaScript must be enabled. - static const CSS_DISPLAY_NONE = ContentBlockerActionType._internal( - 'css-display-none', 'css-display-none'); + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + static final CSS_DISPLAY_NONE = + ContentBlockerActionType._internalMultiPlatform('css-display-none', () { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return 'css-display-none'; + case TargetPlatform.iOS: + return 'css-display-none'; + case TargetPlatform.macOS: + return 'css-display-none'; + default: + break; + } + return null; + }); - ///Changes a URL from http to https. URLs with a specified (nondefault) port and links using other protocols are unaffected. - static const MAKE_HTTPS = - ContentBlockerActionType._internal('make-https', 'make-https'); + ///Changes a URL from http to https. + ///URLs with a specified (nondefault) port and links using other protocols are unaffected. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + static final MAKE_HTTPS = + ContentBlockerActionType._internalMultiPlatform('make-https', () { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return 'make-https'; + case TargetPlatform.iOS: + return 'make-https'; + case TargetPlatform.macOS: + return 'make-https'; + default: + break; + } + return null; + }); + + ///Strips cookies from the header before sending it to the server. + ///This only blocks cookies otherwise acceptable to WebView's privacy policy. + ///Combining with [IGNORE_PREVIOUS_RULES] doesn't override the browser’s privacy settings. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + ///- MacOS + static final BLOCK_COOKIES = + ContentBlockerActionType._internalMultiPlatform('block-cookies', () { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + return 'block-cookies'; + case TargetPlatform.macOS: + return 'block-cookies'; + default: + break; + } + return null; + }); + + ///Ignores previously triggered actions. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + ///- MacOS + static final IGNORE_PREVIOUS_RULES = + ContentBlockerActionType._internalMultiPlatform('ignore-previous-rules', + () { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + return 'ignore-previous-rules'; + case TargetPlatform.macOS: + return 'ignore-previous-rules'; + default: + break; + } + return null; + }); ///Set of all values of [ContentBlockerActionType]. static final Set values = [ ContentBlockerActionType.BLOCK, ContentBlockerActionType.CSS_DISPLAY_NONE, ContentBlockerActionType.MAKE_HTTPS, + ContentBlockerActionType.BLOCK_COOKIES, + ContentBlockerActionType.IGNORE_PREVIOUS_RULES, ].toSet(); ///Gets a possible [ContentBlockerActionType] instance from [String] value. diff --git a/pubspec.yaml b/pubspec.yaml index 5678ea76..6e760d4a 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_inappwebview description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window. -version: 6.0.0-beta.12 +version: 6.0.0-beta.13 homepage: https://inappwebview.dev/ repository: https://github.com/pichillilorenzo/flutter_inappwebview issue_tracker: https://github.com/pichillilorenzo/flutter_inappwebview/issues