From 1598ccd896653cbe40b7401fb0eafd890e784b39 Mon Sep 17 00:00:00 2001
From: Maurits van Beusekom <maurits@vnbskm.nl>
Date: Thu, 7 Sep 2023 17:36:04 +0200
Subject: [PATCH] [webview_flutter_platform_interface] Adds option to override
 console log (#4701)

Adds an option to the `webview_flutter_platform_interface` to register a JavaScript console callback. This will allow developers to receive JavaScript console messages in a Dart callback.

This PR contains the `webview_flutter_platform_interface` changes from PR #4541.

Related issue: 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].*
---
 .../CHANGELOG.md                              |  5 ++++
 .../lib/src/platform_webview_controller.dart  |  9 +++++++
 .../src/types/javascript_console_message.dart | 23 ++++++++++++++++++
 .../lib/src/types/javascript_log_level.dart   | 24 +++++++++++++++++++
 .../lib/src/types/types.dart                  |  2 ++
 .../pubspec.yaml                              |  2 +-
 .../platform_webview_controller_test.dart     | 14 +++++++++++
 ...latform_webview_controller_test.mocks.dart |  4 +++-
 .../test/webview_platform_test.mocks.dart     |  4 +++-
 9 files changed, 84 insertions(+), 3 deletions(-)
 create mode 100644 packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_console_message.dart
 create mode 100644 packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_log_level.dart

diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md
index 34fb7f60e7..2748ea394c 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.6.0
+
+* Adds support to register a callback to intercept messages that are written to
+  the JavaScript console. See `PlatformWebViewController.setOnConsoleMessage`.
+
 ## 2.5.1
 
 * Adds pub topics to package metadata.
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart
index a2ae88771f..806d2a7a6b 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart
+++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart
@@ -277,6 +277,15 @@ abstract class PlatformWebViewController extends PlatformInterface {
       'getUserAgent is not implemented on the current platform',
     );
   }
+
+  /// Sets a callback that notifies the host application of any console messages
+  /// written to the JavaScript console.
+  Future<void> setOnConsoleMessage(
+      void Function(JavaScriptConsoleMessage consoleMessage) onConsoleMessage) {
+    throw UnimplementedError(
+      'setOnConsoleMessage is not implemented on the current platform',
+    );
+  }
 }
 
 /// Describes the parameters necessary for registering a JavaScript channel.
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_console_message.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_console_message.dart
new file mode 100644
index 0000000000..3509e685f4
--- /dev/null
+++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_console_message.dart
@@ -0,0 +1,23 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+import 'javascript_log_level.dart';
+
+/// Represents a console message written to the JavaScript console.
+@immutable
+class JavaScriptConsoleMessage {
+  /// Creates a [JavaScriptConsoleMessage].
+  const JavaScriptConsoleMessage({
+    required this.level,
+    required this.message,
+  });
+
+  /// The severity of a JavaScript log message.
+  final JavaScriptLogLevel level;
+
+  /// The message written to the console.
+  final String message;
+}
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_log_level.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_log_level.dart
new file mode 100644
index 0000000000..b7319c9082
--- /dev/null
+++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/javascript_log_level.dart
@@ -0,0 +1,24 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/// Represents the severity of a JavaScript log message.
+enum JavaScriptLogLevel {
+  /// Indicates an error message was logged via an "error" event of the
+  /// `console.error` method.
+  error,
+
+  /// Indicates a warning message was logged using the `console.warning`
+  /// method.
+  warning,
+
+  /// Indicates a debug message was logged using the `console.debug` method.
+  debug,
+
+  /// Indicates an informational message was logged using the `console.info`
+  /// method.
+  info,
+
+  /// Indicates a log message was logged using the `console.log` method.
+  log,
+}
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart
index e980aece3a..c6cbe6967a 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart
+++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 export 'http_response_error.dart';
+export 'javascript_console_message.dart';
+export 'javascript_log_level.dart';
 export 'javascript_message.dart';
 export 'javascript_mode.dart';
 export 'load_request_params.dart';
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml
index afdd78d31f..71e85f32de 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/webview_flutt
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview_flutter%22
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 2.5.1
+version: 2.6.0
 
 environment:
   sdk: ">=2.19.0 <4.0.0"
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.dart
index 64725a7fa1..ba83cc1199 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.dart
+++ b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.dart
@@ -400,6 +400,20 @@ void main() {
       throwsUnimplementedError,
     );
   });
+
+  test(
+      'Default implementation of setOnConsoleMessage should throw unimplemented error',
+      () {
+    final PlatformWebViewController controller =
+        ExtendsPlatformWebViewController(
+            const PlatformWebViewControllerCreationParams());
+
+    expect(
+      () =>
+          controller.setOnConsoleMessage((JavaScriptConsoleMessage message) {}),
+      throwsUnimplementedError,
+    );
+  });
 }
 
 class MockWebViewPlatformWithMixin extends MockWebViewPlatform
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart
index 1268858978..3ab612ee8c 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart
@@ -1,7 +1,9 @@
-// Mocks generated by Mockito 5.4.0 from annotations
+// Mocks generated by Mockito 5.4.1 from annotations
 // in webview_flutter_platform_interface/test/platform_webview_controller_test.dart.
 // Do not manually edit this file.
 
+// @dart=2.19
+
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'dart:async' as _i4;
 
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/webview_platform_test.mocks.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/webview_platform_test.mocks.dart
index e9ff0bd9f2..7b6d661a4c 100644
--- a/packages/webview_flutter/webview_flutter_platform_interface/test/webview_platform_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_platform_interface/test/webview_platform_test.mocks.dart
@@ -1,7 +1,9 @@
-// Mocks generated by Mockito 5.4.0 from annotations
+// Mocks generated by Mockito 5.4.1 from annotations
 // in webview_flutter_platform_interface/test/webview_platform_test.dart.
 // Do not manually edit this file.
 
+// @dart=2.19
+
 // ignore_for_file: no_leading_underscores_for_library_prefixes
 import 'package:mockito/mockito.dart' as _i1;
 import 'package:webview_flutter_platform_interface/src/platform_navigation_delegate.dart'