[webview_flutter] Adds app facing implementation to override console log (#4705)
Adds the app facing implementation for registering a JavaScript console callback. This will allow developers to receive JavaScript console messages in a Dart callback.
This PR contains the `webview_flutter` specific changes from PR #4541.
Fixes flutter/flutter#32908
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md
index 8d8a839..ec02159 100644
--- a/packages/webview_flutter/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 4.4.0
+
+* Adds support to register a callback to receive JavaScript console messages. See `WebViewController.setConsoleLogCallback`.
+
## 4.3.0
* Adds support to retrieve the user agent. See `WebViewController.getUserAgent`.
diff --git a/packages/webview_flutter/webview_flutter/example/lib/main.dart b/packages/webview_flutter/webview_flutter/example/lib/main.dart
index c7fbd63..96cbbf8 100644
--- a/packages/webview_flutter/webview_flutter/example/lib/main.dart
+++ b/packages/webview_flutter/webview_flutter/example/lib/main.dart
@@ -76,6 +76,40 @@
</html>
''';
+const String kLogExamplePage = '''
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Load file or HTML string example</title>
+</head>
+<body onload="console.log('Logging that the page is loading.')">
+
+<h1>Local demo page</h1>
+<p>
+ This page is used to test the forwarding of console logs to Dart.
+</p>
+
+<style>
+ .btn-group button {
+ padding: 24px; 24px;
+ display: block;
+ width: 25%;
+ margin: 5px 0px 0px 0px;
+ }
+</style>
+
+<div class="btn-group">
+ <button onclick="console.error('This is an error message.')">Error</button>
+ <button onclick="console.warn('This is a warning message.')">Warning</button>
+ <button onclick="console.info('This is a info message.')">Info</button>
+ <button onclick="console.debug('This is a debug message.')">Debug</button>
+ <button onclick="console.log('This is a log message.')">Log</button>
+</div>
+
+</body>
+</html>
+''';
+
class WebViewExample extends StatefulWidget {
const WebViewExample({super.key});
@@ -208,6 +242,7 @@
loadHtmlString,
transparentBackground,
setCookie,
+ logExample,
}
class SampleMenu extends StatelessWidget {
@@ -264,6 +299,9 @@
case MenuOptions.setCookie:
_onSetCookie();
break;
+ case MenuOptions.logExample:
+ _onLogExample();
+ break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
@@ -320,6 +358,10 @@
value: MenuOptions.setCookie,
child: Text('Set cookie'),
),
+ const PopupMenuItem<MenuOptions>(
+ value: MenuOptions.logExample,
+ child: Text('Log example'),
+ ),
],
);
}
@@ -463,6 +505,16 @@
return indexFile.path;
}
+
+ Future<void> _onLogExample() {
+ webViewController
+ .setOnConsoleMessage((JavaScriptConsoleMessage consoleMessage) {
+ debugPrint(
+ '== JS == ${consoleMessage.level.name}: ${consoleMessage.message}');
+ });
+
+ return webViewController.loadHtmlString(kLogExamplePage);
+ }
}
class NavigationControls extends StatelessWidget {
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart b/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart
index b0333cb..0b81978 100644
--- a/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart
+++ b/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart
@@ -354,6 +354,22 @@
return platform.setUserAgent(userAgent);
}
+ /// Sets a callback that notifies the host application on any log messages
+ /// written to the JavaScript console.
+ ///
+ /// Platforms may not preserve all the log level information so clients should
+ /// not rely on a 1:1 mapping between the JavaScript calls.
+ ///
+ /// On iOS setting this callback will inject a custom [WKUserScript] which
+ /// overrides the default implementation of `console.debug`, `console.error`,
+ /// `console.info`, `console.log` and `console.warning` methods. The iOS
+ /// WebKit framework unfortunately doesn't provide a built-in method to
+ /// forward console messages.
+ Future<void> setOnConsoleMessage(
+ void Function(JavaScriptConsoleMessage message) onConsoleMessage) {
+ return platform.setOnConsoleMessage(onConsoleMessage);
+ }
+
/// Gets the value used for the HTTP `User-Agent:` request header.
Future<String?> getUserAgent() {
return platform.getUserAgent();
diff --git a/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
index 3e85cc3..37dde9d 100644
--- a/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
+++ b/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
@@ -6,6 +6,7 @@
export 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'
show
+ JavaScriptConsoleMessage,
JavaScriptMessage,
JavaScriptMode,
LoadRequestMethod,
diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml
index b5349c4..8722790 100644
--- a/packages/webview_flutter/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin that provides a WebView widget on Android and iOS.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
-version: 4.3.0
+version: 4.4.0
environment:
sdk: ">=2.19.0 <4.0.0"
@@ -19,9 +19,9 @@
dependencies:
flutter:
sdk: flutter
- webview_flutter_android: ^3.0.0
+ webview_flutter_android: ^3.12.0
webview_flutter_platform_interface: ^2.6.0
- webview_flutter_wkwebview: ^3.0.0
+ webview_flutter_wkwebview: ^3.9.0
dev_dependencies:
build_runner: ^2.1.5
diff --git a/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart b/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart
index ba184c5..695a781 100644
--- a/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart
+++ b/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart
@@ -388,6 +388,21 @@
expect(permissionRequestCallbackCalled, isTrue);
});
+ test('setConsoleLogCallback', () async {
+ final MockPlatformWebViewController mockPlatformWebViewController =
+ MockPlatformWebViewController();
+
+ final WebViewController webViewController = WebViewController.fromPlatform(
+ mockPlatformWebViewController,
+ );
+
+ void onConsoleMessage(JavaScriptConsoleMessage message) {}
+
+ await webViewController.setOnConsoleMessage(onConsoleMessage);
+
+ verify(mockPlatformWebViewController.setOnConsoleMessage(onConsoleMessage));
+ });
+
test('getUserAgent', () async {
final MockPlatformWebViewController mockPlatformWebViewController =
MockPlatformWebViewController();
@@ -401,7 +416,6 @@
final WebViewController webViewController = WebViewController.fromPlatform(
mockPlatformWebViewController,
);
-
await expectLater(webViewController.getUserAgent(), completion(userAgent));
});
}