Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .fvmrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"flutter": "3.29.0",
"flutter": "3.32.8",
"flavors": {}
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Add this to your `pubspec.yaml`:

```yaml
dependencies:
adblocker_webview: ^1.0.0
adblocker_webview: ^2.1.0
```

### Basic Usage
Expand Down Expand Up @@ -130,7 +130,7 @@ AdBlockerWebview(

## Migration Guide

### Migrating from 1.2.0 to 2.0.0-beta
### Migrating from 1.2.0 to 2.0.0

#### Breaking Changes

Expand Down Expand Up @@ -206,7 +206,7 @@ AdBlockerWebview(
1. Update the package version in `pubspec.yaml`:
```yaml
dependencies:
adblocker_webview: ^2.0.0-beta
adblocker_webview: ^2.0.0
```

2. Replace controller initialization with singleton pattern
Expand Down
52 changes: 26 additions & 26 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ packages:
path: ".."
relative: true
source: path
version: "2.0.0"
version: "2.1.0"
async:
dependency: transitive
description:
name: async
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.dev"
source: hosted
version: "2.12.0"
version: "2.13.0"
boolean_selector:
dependency: transitive
description:
Expand Down Expand Up @@ -76,10 +76,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.3.3"
flutter:
dependency: "direct main"
description: flutter
Expand All @@ -102,26 +102,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
url: "https://pub.dev"
source: hosted
version: "10.0.8"
version: "11.0.1"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.9"
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
lints:
dependency: transitive
description:
Expand Down Expand Up @@ -219,58 +219,58 @@ packages:
dependency: transitive
description:
name: test_api
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
version: "0.7.6"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.0"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
url: "https://pub.dev"
source: hosted
version: "14.3.1"
version: "15.0.0"
webview_flutter:
dependency: transitive
description:
name: webview_flutter
sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba
url: "https://pub.dev"
source: hosted
version: "4.10.0"
version: "4.13.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: "3d535126f7244871542b2f0b0fcf94629c9a14883250461f9abe1a6644c1c379"
sha256: "9a25f6b4313978ba1c2cda03a242eea17848174912cfb4d2d8ee84a556f248e3"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
version: "4.10.1"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.14.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb
sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f
url: "https://pub.dev"
source: hosted
version: "3.16.3"
version: "3.23.0"
sdks:
dart: ">=3.7.0 <4.0.0"
dart: ">=3.8.1 <4.0.0"
flutter: ">=3.29.0"
108 changes: 67 additions & 41 deletions lib/src/adblocker_webview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import 'package:adblocker_webview/src/adblocker_webview_controller.dart';
import 'package:adblocker_webview/src/block_resource_loading.dart';
import 'package:adblocker_webview/src/elem_hide.dart';
import 'package:adblocker_webview/src/logger.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';

/// A webview implementation of in Flutter that blocks most of the ads that
/// appear inside of the webpages.
Expand Down Expand Up @@ -84,7 +87,25 @@ class _AdBlockerWebviewState extends State<AdBlockerWebview> {
..clear()
..addAll(widget.adBlockerWebviewController.bannedResourceRules);

_webViewController = WebViewController();
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
);
} else {
params = const PlatformWebViewControllerCreationParams();
}

_webViewController = WebViewController.fromPlatformCreationParams(params);
// ···
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

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

The comment '// ···' is unclear and doesn't provide meaningful information about the code that follows. Replace with a descriptive comment explaining the platform-specific configuration setup.

Suggested change
// ···
// Perform Android-specific WebView configuration: enable debugging and require user gesture for media playback.

Copilot uses AI. Check for mistakes.
if (_webViewController.platform is AndroidWebViewController) {
unawaited(AndroidWebViewController.enableDebugging(kDebugMode));
unawaited(
(_webViewController.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(true),
);
}

await Future.wait([
_webViewController.setOnConsoleMessage((message) {
debugLog('[FLUTTER_WEBVIEW_LOG]: ${message.message}');
Expand Down Expand Up @@ -128,49 +149,54 @@ class _AdBlockerWebviewState extends State<AdBlockerWebview> {
}

void _setNavigationDelegate() {
_webViewController.setNavigationDelegate(
NavigationDelegate(
onNavigationRequest: (request) {
final shouldBlock = widget.adBlockerWebviewController
.shouldBlockResource(request.url);
if (shouldBlock) {
debugLog('Blocking resource: ${request.url}');
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
onPageStarted: (url) async {
if (widget.shouldBlockAds) {
// Inject resource blocking script as early as possible
unawaited(
_webViewController.runJavaScript(
getResourceLoadingBlockerScript(_urlsToBlock),
),
);
}
widget.onLoadStart?.call(url);
},
onPageFinished: (url) {
if (widget.shouldBlockAds) {
// Apply element hiding after page load
final cssRules =
widget.adBlockerWebviewController.getCssRulesForWebsite(url);
unawaited(
_webViewController.runJavaScript(generateHidingScript(cssRules)),
);
}

widget.onLoadFinished?.call(url);
},
onProgress: (progress) => widget.onProgress?.call(progress),
onHttpError:
(error) => widget.onLoadError?.call(
error.request?.uri.toString(),
error.response?.statusCode ?? -1,
final navigationDelegate = NavigationDelegate(
onNavigationRequest: (request) {
final shouldBlock = widget.adBlockerWebviewController
.shouldBlockResource(request.url);
if (shouldBlock) {
debugLog('Blocking resource: ${request.url}');
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
onPageStarted: (url) async {
if (widget.shouldBlockAds) {
// Inject resource blocking script as early as possible
unawaited(
_webViewController.runJavaScript(
getResourceLoadingBlockerScript(_urlsToBlock),
),
onUrlChange: (change) => widget.onUrlChanged?.call(change.url),
);
}
widget.onLoadStart?.call(url);
},
onPageFinished: (url) {
if (widget.shouldBlockAds) {
// Apply element hiding after page load
final cssRules = widget.adBlockerWebviewController
.getCssRulesForWebsite(url);
unawaited(
_webViewController.runJavaScript(generateHidingScript(cssRules)),
);
}

widget.onLoadFinished?.call(url);
},
onProgress: (progress) => widget.onProgress?.call(progress),
onHttpError: (error) => widget.onLoadError?.call(
error.request?.uri.toString(),
error.response?.statusCode ?? -1,
),
onUrlChange: (change) => widget.onUrlChanged?.call(change.url),
);
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
final WebKitNavigationDelegate webKitDelegate =
navigationDelegate.platform as WebKitNavigationDelegate;
} else if (WebViewPlatform.instance is AndroidWebViewPlatform) {
final AndroidNavigationDelegate androidDelegate =
navigationDelegate.platform as AndroidNavigationDelegate;
}
Comment on lines +192 to +198
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

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

The platform-specific navigation delegates are created but never used. Either utilize these delegates for platform-specific configuration or remove the unused variable assignments.

Suggested change
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
final WebKitNavigationDelegate webKitDelegate =
navigationDelegate.platform as WebKitNavigationDelegate;
} else if (WebViewPlatform.instance is AndroidWebViewPlatform) {
final AndroidNavigationDelegate androidDelegate =
navigationDelegate.platform as AndroidNavigationDelegate;
}
// Platform-specific navigation delegates can be configured here if needed.

Copilot uses AI. Check for mistakes.
_webViewController.setNavigationDelegate(navigationDelegate);
}

String _getUserAgent() {
Expand Down
4 changes: 4 additions & 0 deletions lib/src/adblocker_webview_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ abstract interface class AdBlockerWebviewController
/// Reloads the current page
Future<void> reload();

/// Stops loading the current page
Future<void> stopLoading();

/// Runs the given script
Future<void> runScript(String script);

}
11 changes: 11 additions & 0 deletions lib/src/adblocker_webview_controller_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'dart:collection';

import 'package:adblocker_webview/adblocker_webview.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';

///Implementation for [AdBlockerWebviewController]
class AdBlockerWebviewControllerImpl implements AdBlockerWebviewController {
Expand All @@ -21,6 +23,7 @@ class AdBlockerWebviewControllerImpl implements AdBlockerWebviewController {
..clear()
..addAll(_adBlockManager.getAllResourceRules())
..addAll(additionalResourceRules);

}

@override
Expand Down Expand Up @@ -120,6 +123,14 @@ class AdBlockerWebviewControllerImpl implements AdBlockerWebviewController {
return _webViewController!.reload();
}

@override
Future<void> stopLoading() async {
if (_webViewController == null) {
return;
}
return _webViewController!.runJavaScript('window.stop();');
}

@override
Future<void> runScript(String script) async {
if (_webViewController == null) {
Expand Down
8 changes: 5 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: adblocker_webview
description: A webview for flutter with adblocking capability. It's currently based on Flutter InAppWebview Plugin.
repository: https://github.com/islamdidarmd/flutter_adblocker_webview
issue_tracker: https://github.com/islamdidarmd/flutter_adblocker_webview/issues
version: 2.0.0
version: 2.1.0
homepage: https://github.com/islamdidarmd/flutter_adblocker_webview

environment:
sdk: ^3.7.0
sdk: ^3.8.1

workspace:
- packages/adblocker_core
Expand All @@ -16,7 +16,9 @@ dependencies:
adblocker_manager: ^1.0.0
flutter:
sdk: flutter
webview_flutter: ^4.10.0
webview_flutter: ^4.13.0
webview_flutter_android: ^4.10.1
webview_flutter_wkwebview: ^3.23.0

dev_dependencies:
flutter_test:
Expand Down
Loading