diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 0cd1ce8e29b..fe76d134677 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,5 +1,7 @@ -## NEXT +## 3.17.0 +* Adds a change listener for the `canGoBack` property. See + `WebKitWebViewController.setOnCanGoBackChange`. * Updates minimum supported SDK version to Flutter 3.22/Dart 3.4. ## 3.16.3 diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart index ae254ef52fe..dd0e91e2705 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart @@ -160,6 +160,14 @@ class WebKitWebViewController extends PlatformWebViewController { }, ); + _webView.addObserver( + _webView, + keyPath: 'canGoBack', + options: { + NSKeyValueObservingOptions.newValue, + }, + ); + final WeakReference weakThis = WeakReference(this); _uiDelegate = _webKitParams.webKitProxy.createUIDelegate( @@ -299,6 +307,12 @@ class WebKitWebViewController extends PlatformWebViewController { final NSUrl? url = change[NSKeyValueChangeKey.newValue] as NSUrl?; urlChangeCallback(UrlChange(url: await url?.getAbsoluteString())); } + case 'canGoBack': + if (controller._onCanGoBackChangeCallback != null) { + final bool canGoBack = + change[NSKeyValueChangeKey.newValue]! as bool; + controller._onCanGoBackChangeCallback!(canGoBack); + } } }; }), @@ -315,6 +329,7 @@ class WebKitWebViewController extends PlatformWebViewController { bool _zoomEnabled = true; WebKitNavigationDelegate? _currentNavigationDelegate; + void Function(bool)? _onCanGoBackChangeCallback; void Function(JavaScriptConsoleMessage)? _onConsoleMessageCallback; void Function(PlatformWebViewPermissionRequest)? _onPermissionRequestCallback; @@ -602,6 +617,12 @@ class WebKitWebViewController extends PlatformWebViewController { .addUserScript(userScript); } + /// Sets the listener for canGoBack changes. + Future setOnCanGoBackChange( + void Function(bool) onCanGoBackChangeCallback) async { + _onCanGoBackChangeCallback = onCanGoBackChangeCallback; + } + /// Sets a callback that notifies the host application of any log messages /// written to the JavaScript console. /// diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 735efa3f86e..58d02d65805 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 3.16.3 +version: 3.17.0 environment: sdk: ^3.5.0 diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart index 4e1208641e8..5fcac5fc406 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart @@ -1550,6 +1550,53 @@ window.addEventListener("error", function(e) { }); }); + test('setOnCanGoBackChange', () async { + final MockWKWebViewIOS mockWebView = MockWKWebViewIOS(); + + late final void Function( + String keyPath, + NSObject object, + Map change, + ) webViewObserveValue; + + final WebKitWebViewController controller = createControllerWithMocks( + createMockWebView: ( + _, { + void Function( + String keyPath, + NSObject object, + Map change, + )? observeValue, + }) { + webViewObserveValue = observeValue!; + return mockWebView; + }, + ); + + verify( + mockWebView.addObserver( + mockWebView, + keyPath: 'canGoBack', + options: { + NSKeyValueObservingOptions.newValue, + }, + ), + ); + + late final bool callbackCanGoBack; + + await controller.setOnCanGoBackChange( + (bool canGoBack) => callbackCanGoBack = canGoBack); + + webViewObserveValue( + 'canGoBack', + mockWebView, + {NSKeyValueChangeKey.newValue: true}, + ); + + expect(callbackCanGoBack, true); + }); + test('setOnScrollPositionChange', () async { final WebKitWebViewController controller = createControllerWithMocks();