diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md index 8d8a839c714d..ec021594fad9 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 c7fbd63958fd..96cbbf8f7e36 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 @@ const String kTransparentBackgroundPage = ''' '''; +const String kLogExamplePage = ''' + + + +Load file or HTML string example + + + +

Local demo page

+

+ This page is used to test the forwarding of console logs to Dart. +

+ + + +
+ + + + + +
+ + + +'''; + class WebViewExample extends StatefulWidget { const WebViewExample({super.key}); @@ -208,6 +242,7 @@ enum MenuOptions { loadHtmlString, transparentBackground, setCookie, + logExample, } class SampleMenu extends StatelessWidget { @@ -264,6 +299,9 @@ class SampleMenu extends StatelessWidget { case MenuOptions.setCookie: _onSetCookie(); break; + case MenuOptions.logExample: + _onLogExample(); + break; } }, itemBuilder: (BuildContext context) => >[ @@ -320,6 +358,10 @@ class SampleMenu extends StatelessWidget { value: MenuOptions.setCookie, child: Text('Set cookie'), ), + const PopupMenuItem( + value: MenuOptions.logExample, + child: Text('Log example'), + ), ], ); } @@ -463,6 +505,16 @@ class SampleMenu extends StatelessWidget { return indexFile.path; } + + Future _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 b0333cbde514..0b81978d6fcc 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 @@ class WebViewController { 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 setOnConsoleMessage( + void Function(JavaScriptConsoleMessage message) onConsoleMessage) { + return platform.setOnConsoleMessage(onConsoleMessage); + } + /// Gets the value used for the HTTP `User-Agent:` request header. Future 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 3e85cc389ac0..37dde9dd3125 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 @@ library webview_flutter; 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 b5349c4ac0b8..87227908af3f 100644 --- a/packages/webview_flutter/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter 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 @@ flutter: 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 ba184c5bfb47..695a781738e2 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 @@ void main() { 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 @@ void main() { final WebViewController webViewController = WebViewController.fromPlatform( mockPlatformWebViewController, ); - await expectLater(webViewController.getUserAgent(), completion(userAgent)); }); }