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 603f9cf4be3..03a85132f69 100644 --- a/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart +++ b/packages/webview_flutter/webview_flutter/lib/src/webview_controller.dart @@ -405,6 +405,16 @@ class WebViewController { ) { return platform.setOnScrollPositionChange(onScrollPositionChange); } + + /// Define whether the vertical scrollbar should be drawn or not. The default value is true. + Future verticalScrollBarEnabled(bool enabled) { + return platform.verticalScrollBarEnabled(enabled); + } + + /// Define whether the horizontal scrollbar should be drawn or not. The default value is true. + Future horizontalScrollBarEnabled(bool enabled) { + return platform.horizontalScrollBarEnabled(enabled); + } } /// Permissions request when web content requests access to protected resources. diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml index 837800d7fee..1e90c37be23 100644 --- a/packages/webview_flutter/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter/pubspec.yaml @@ -21,9 +21,12 @@ flutter: dependencies: flutter: sdk: flutter - webview_flutter_android: ^4.0.0 - webview_flutter_platform_interface: ^2.10.0 - webview_flutter_wkwebview: ^3.15.0 + webview_flutter_android: + path: ../webview_flutter_android + webview_flutter_platform_interface: + path: ../webview_flutter_platform_interface + webview_flutter_wkwebview: + path: ../webview_flutter_wkwebview 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 6cae01a4941..49351a119c7 100644 --- a/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter/test/webview_controller_test.dart @@ -281,6 +281,30 @@ void main() { verify(mockPlatformWebViewController.scrollBy(2, 3)); }); + test('verticalScrollBarEnabled', () async { + final MockPlatformWebViewController mockPlatformWebViewController = + MockPlatformWebViewController(); + + final WebViewController webViewController = WebViewController.fromPlatform( + mockPlatformWebViewController, + ); + + await webViewController.verticalScrollBarEnabled(false); + verify(mockPlatformWebViewController.verticalScrollBarEnabled(false)); + }); + + test('horizontalScrollBarEnabled', () async { + final MockPlatformWebViewController mockPlatformWebViewController = + MockPlatformWebViewController(); + + final WebViewController webViewController = WebViewController.fromPlatform( + mockPlatformWebViewController, + ); + + await webViewController.horizontalScrollBarEnabled(false); + verify(mockPlatformWebViewController.horizontalScrollBarEnabled(false)); + }); + test('getScrollPosition', () async { final MockPlatformWebViewController mockPlatformWebViewController = MockPlatformWebViewController(); diff --git a/packages/webview_flutter/webview_flutter/test/webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter/test/webview_controller_test.mocks.dart index 981e7386ac0..7bef6d0efe2 100644 --- a/packages/webview_flutter/webview_flutter/test/webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter/test/webview_controller_test.mocks.dart @@ -313,6 +313,28 @@ class MockPlatformWebViewController extends _i1.Mock returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override + _i5.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future<_i3.Offset> getScrollPosition() => (super.noSuchMethod( Invocation.method( diff --git a/packages/webview_flutter/webview_flutter/test/webview_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter/test/webview_widget_test.mocks.dart index ec6bd85e095..3e8471b4a78 100644 --- a/packages/webview_flutter/webview_flutter/test/webview_widget_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter/test/webview_widget_test.mocks.dart @@ -331,6 +331,28 @@ class MockPlatformWebViewController extends _i1.Mock returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override + _i7.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + + @override + _i7.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i7.Future.value(), + returnValueForMissingStub: _i7.Future.value(), + ) as _i7.Future); + @override _i7.Future<_i3.Offset> getScrollPosition() => (super.noSuchMethod( Invocation.method( diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt index f2808272548..bb9f68a24fb 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt @@ -1387,6 +1387,12 @@ abstract class PigeonApiWebView( /** Sets the background color for this view. */ abstract fun setBackgroundColor(pigeon_instance: android.webkit.WebView, color: Long) + /** Define whether the vertical scrollbar should be drawn or not. The default value is true. */ + abstract fun verticalScrollBarEnabled(pigeon_instance: android.webkit.WebView, enabled: Boolean) + + /** Define whether the horizontal scrollbar should be drawn or not. The default value is true. */ + abstract fun horizontalScrollBarEnabled(pigeon_instance: android.webkit.WebView, enabled: Boolean) + /** Destroys the internal state of this WebView. */ abstract fun destroy(pigeon_instance: android.webkit.WebView) @@ -1924,6 +1930,54 @@ abstract class PigeonApiWebView( channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebView.verticalScrollBarEnabled", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.webkit.WebView + val enabledArg = args[1] as Boolean + val wrapped: List = + try { + api.verticalScrollBarEnabled(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebView.horizontalScrollBarEnabled", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.webkit.WebView + val enabledArg = args[1] as Boolean + val wrapped: List = + try { + api.horizontalScrollBarEnabled(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewProxyApi.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewProxyApi.java index 7f976905526..7164fd2d682 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewProxyApi.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewProxyApi.java @@ -271,6 +271,16 @@ public void setBackgroundColor(@NonNull WebView pigeon_instance, long color) { pigeon_instance.setBackgroundColor((int) color); } + @Override + public void verticalScrollBarEnabled(@NonNull WebView pigeon_instance, boolean enabled) { + pigeon_instance.setVerticalScrollBarEnabled(enabled); + } + + @Override + public void horizontalScrollBarEnabled(@NonNull WebView pigeon_instance, boolean enabled) { + pigeon_instance.setHorizontalScrollBarEnabled(enabled); + } + @NonNull @Override public ProxyApiRegistrar getPigeonRegistrar() { diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart index fc7174a27d0..b95003ef6f6 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart @@ -2170,6 +2170,62 @@ class WebView extends View { } } + /// Define whether the vertical scrollbar should be drawn or not. The default value is true. + Future verticalScrollBarEnabled(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecWebView; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebView.verticalScrollBarEnabled'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enabled]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Define whether the horizontal scrollbar should be drawn or not. The default value is true. + Future horizontalScrollBarEnabled(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecWebView; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebView.horizontalScrollBarEnabled'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enabled]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + /// Destroys the internal state of this WebView. Future destroy() async { final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart index c250a87d36a..a5a36a07305 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart @@ -712,6 +712,14 @@ class AndroidWebViewController extends PlatformWebViewController { _onJavaScriptPrompt = onJavaScriptTextInputDialog; return _webChromeClient.setSynchronousReturnValueForOnJsPrompt(true); } + + @override + Future verticalScrollBarEnabled(bool enabled) => + _webView.verticalScrollBarEnabled(enabled); + + @override + Future horizontalScrollBarEnabled(bool enabled) => + _webView.horizontalScrollBarEnabled(enabled); } /// Android implementation of [PlatformWebViewPermissionRequest]. diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 4ff9b6166a6..ed75d555191 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -20,7 +20,8 @@ flutter: dependencies: flutter: sdk: flutter - webview_flutter_platform_interface: ^2.10.0 + webview_flutter_platform_interface: + path: ../webview_flutter_platform_interface dev_dependencies: build_runner: ^2.1.4 diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart index 6879c33253e..3cea924df86 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart @@ -1401,6 +1401,28 @@ void main() { verify(mockWebView.scrollBy(4, 2)).called(1); }); + test('verticalScrollBarEnabled', () async { + final MockWebView mockWebView = MockWebView(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + ); + + await controller.verticalScrollBarEnabled(false); + + verify(mockWebView.verticalScrollBarEnabled(false)).called(1); + }); + + test('horizontalScrollBarEnabled', () async { + final MockWebView mockWebView = MockWebView(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + ); + + await controller.horizontalScrollBarEnabled(false); + + verify(mockWebView.horizontalScrollBarEnabled(false)).called(1); + }); + test('getScrollPosition', () async { final MockWebView mockWebView = MockWebView(); final AndroidWebViewController controller = createControllerWithMocks( diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart index d0254f2bd80..04df59a0065 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart @@ -911,6 +911,28 @@ class MockAndroidWebViewController extends _i1.Mock returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + + @override + _i8.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); } /// A class which mocks [AndroidWebViewProxy]. @@ -2977,6 +2999,28 @@ class MockWebView extends _i1.Mock implements _i2.WebView { returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override + _i8.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + @override _i8.Future destroy() => (super.noSuchMethod( Invocation.method( diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart index 303f54d46f6..80c2843e40d 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart @@ -615,4 +615,26 @@ class MockAndroidWebViewController extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + + @override + _i5.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); } 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 2aaabb519cc..6a04c8607f8 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 @@ -229,6 +229,18 @@ abstract class PlatformWebViewController extends PlatformInterface { 'scrollBy is not implemented on the current platform'); } + /// Define whether the vertical scrollbar should be drawn or not. The default value is true. + Future verticalScrollBarEnabled(bool enabled) { + throw UnimplementedError( + 'verticalScrollBarEnabled is not implemented on the current platform'); + } + + /// Define whether the horizontal scrollbar should be drawn or not. The default value is true. + Future horizontalScrollBarEnabled(bool enabled) { + throw UnimplementedError( + 'horizontalScrollBarEnabled is not implemented on the current platform'); + } + /// Return the current scroll position of this view. /// /// Scroll position is measured from the top left. 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 db3cf1dd5d6..ae458d7b994 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 @@ -311,6 +311,30 @@ void main() { ); }); + test('Default implementation of verticalScrollBarEnabled should throw unimplemented error', + () { + final PlatformWebViewController controller = + ExtendsPlatformWebViewController( + const PlatformWebViewControllerCreationParams()); + + expect( + () => controller.verticalScrollBarEnabled(false), + throwsUnimplementedError, + ); + }); + + test('Default implementation of horizontalScrollBarEnabled should throw unimplemented error', + () { + final PlatformWebViewController controller = + ExtendsPlatformWebViewController( + const PlatformWebViewControllerCreationParams()); + + expect( + () => controller.horizontalScrollBarEnabled(false), + throwsUnimplementedError, + ); + }); + test( 'Default implementation of getScrollPosition should throw unimplemented error', () { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m index 0ceb9214dde..783fc8c6112 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFGeneratedWebKitApis.m @@ -1183,6 +1183,62 @@ void SetUpFWFUIScrollViewHostApiWithSuffix(id binaryMess [channel setMessageHandler:nil]; } } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.verticalScrollBarEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FWFUIScrollViewHostApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (verticalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:error:)], + @"FWFWKPreferencesHostApi api (%@) doesn't respond to " + @"@selector(verticalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSInteger arg_identifier = [GetNullableObjectAtIndex(args, 0) integerValue]; + BOOL arg_enabled = [GetNullableObjectAtIndex(args, 1) boolValue]; + FlutterError *error; + [api verticalScrollBarEnabledForScrollViewWithIdentifier:arg_identifier + isEnabled:arg_enabled + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.webview_flutter_wkwebview." + @"UIScrollViewHostApi.horizontalScrollBarEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FWFUIScrollViewHostApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector + (horizontalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:error:)], + @"FWFWKPreferencesHostApi api (%@) doesn't respond to " + @"@selector(horizontalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSInteger arg_identifier = [GetNullableObjectAtIndex(args, 0) integerValue]; + BOOL arg_enabled = [GetNullableObjectAtIndex(args, 1) boolValue]; + FlutterError *error; + [api horizontalScrollBarEnabledForScrollViewWithIdentifier:arg_identifier + isEnabled:arg_enabled + error:&error]; + callback(wrapResult(nil, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } { FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] initWithName:[NSString stringWithFormat:@"%@%@", diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m index b57ba2a539a..33b0fe7a145 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/FWFScrollViewHostApi.m @@ -65,6 +65,22 @@ - (void)scrollByForScrollViewWithIdentifier:(NSInteger)identifier #endif } +- (void)verticalScrollBarEnabledForScrollViewWithIdentifier:(NSInteger)identifier + isEnabled:(BOOL)enabled + error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS + [[self scrollViewForIdentifier:identifier] setShowsVerticalScrollIndicator:enabled]; +#endif +} + +- (void)horizontalScrollBarEnabledForScrollViewWithIdentifier:(NSInteger)identifier + isEnabled:(BOOL)enabled + error:(FlutterError *_Nullable *_Nonnull)error { +#if TARGET_OS_IOS + [[self scrollViewForIdentifier:identifier] setShowsHorizontalScrollIndicator:enabled]; +#endif +} + - (void)setContentOffsetForScrollViewWithIdentifier:(NSInteger)identifier toX:(double)x y:(double)y diff --git a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h index dd5fdf97bbc..6d68c6c5bf3 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/darwin/webview_flutter_wkwebview/Sources/webview_flutter_wkwebview/include/webview_flutter_wkwebview/FWFGeneratedWebKitApis.h @@ -645,6 +645,12 @@ NSObject *FWFUIScrollViewHostApiGetCodec(void); x:(double)x y:(double)y error:(FlutterError *_Nullable *_Nonnull)error; +- (void)verticalScrollBarEnabledForScrollViewWithIdentifier:(NSInteger)identifier + isEnabled:(BOOL)enabled + error:(FlutterError *_Nullable *_Nonnull)error; +- (void)horizontalScrollBarEnabledForScrollViewWithIdentifier:(NSInteger)identifier + isEnabled:(BOOL)enabled + error:(FlutterError *_Nullable *_Nonnull)error; - (void)setContentOffsetForScrollViewWithIdentifier:(NSInteger)identifier toX:(double)x y:(double)y diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart index bd0ac2c0294..38e4cb187cf 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart @@ -1128,6 +1128,54 @@ class UIScrollViewHostApi { } } + Future verticalScrollBarEnabled(int identifier, bool enabled) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.verticalScrollBarEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, enabled]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + Future horizontalScrollBarEnabled(int identifier, bool enabled) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.horizontalScrollBarEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([identifier, enabled]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + Future setContentOffset(int identifier, double x, double y) async { final String __pigeon_channelName = 'dev.flutter.pigeon.webview_flutter_wkwebview.UIScrollViewHostApi.setContentOffset$__pigeon_messageChannelSuffix'; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart index fe5a0a3343b..a331792dd37 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit.dart @@ -68,6 +68,16 @@ class UIScrollView extends UIViewBase { return _scrollViewApi.scrollByForInstances(this, offset); } + /// Define whether the vertical scrollbar should be drawn or not. The default value is true. + Future verticalScrollBarEnabled(bool enabled) { + return _scrollViewApi.verticalScrollBarEnabledForInstances(this, enabled); + } + + /// Define whether the horizontal scrollbar should be drawn or not. The default value is true. + Future horizontalScrollBarEnabled(bool enabled) { + return _scrollViewApi.horizontalScrollBarEnabledForInstances(this, enabled); + } + /// Set point at which the origin of the content view is offset from the origin of the scroll view. /// /// The default value is `Point(0.0, 0.0)`. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit_api_impls.dart index 6f15f7d6a9a..97f562c86c7 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/ui_kit/ui_kit_api_impls.dart @@ -64,6 +64,28 @@ class UIScrollViewHostApiImpl extends UIScrollViewHostApi { ); } + /// Calls [verticalScrollBarEnabled] with the ids of the provided object instances. + Future verticalScrollBarEnabledForInstances( + UIView instance, + bool enabled, + ) async { + return verticalScrollBarEnabled( + instanceManager.getIdentifier(instance)!, + enabled, + ); + } + + /// Calls [horizontalScrollBarEnabled] with the ids of the provided object instances. + Future horizontalScrollBarEnabledForInstances( + UIView instance, + bool enabled, + ) async { + return horizontalScrollBarEnabled( + instanceManager.getIdentifier(instance)!, + enabled, + ); + } + /// Calls [setContentOffset] with the ids of the provided object instances. Future setContentOffsetForInstances( UIScrollView instance, 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..c93f66587fc 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 @@ -517,6 +517,28 @@ class WebKitWebViewController extends PlatformWebViewController { } } + @override + Future verticalScrollBarEnabled(bool enabled) { + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + return webView.scrollView.verticalScrollBarEnabled(enabled); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('verticalScrollBarEnabled is not implemented on macOS'); + } + } + + @override + Future horizontalScrollBarEnabled(bool enabled) { + final WKWebView webView = _webView; + if (webView is WKWebViewIOS) { + return webView.scrollView.horizontalScrollBarEnabled(enabled); + } else { + // TODO(stuartmorgan): Investigate doing this via JS instead. + throw UnimplementedError('horizontalScrollBarEnabled is not implemented on macOS'); + } + } + @override Future getScrollPosition() async { final WKWebView webView = _webView; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart index a7d2fbd488d..c62a0dd2a83 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart @@ -480,6 +480,12 @@ abstract class UIScrollViewHostApi { @ObjCSelector('scrollByForScrollViewWithIdentifier:x:y:') void scrollBy(int identifier, double x, double y); + @ObjCSelector('verticalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:') + void verticalScrollBarEnabled(int identifier, bool enabled); + + @ObjCSelector('horizontalScrollBarEnabledForScrollViewWithIdentifier:isEnabled:') + void horizontalScrollBarEnabled(int identifier, bool enabled); + @ObjCSelector('setContentOffsetForScrollViewWithIdentifier:toX:y:') void setContentOffset(int identifier, double x, double y); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 735efa3f86e..cb7796bc487 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -25,7 +25,8 @@ dependencies: flutter: sdk: flutter path: ^1.8.0 - webview_flutter_platform_interface: ^2.10.0 + webview_flutter_platform_interface: + path: ../webview_flutter_platform_interface dev_dependencies: build_runner: ^2.1.5 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..235932953f1 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 @@ -603,6 +603,28 @@ void main() { verify(mockScrollView.scrollBy(const Point(2.0, 4.0))); }); + test('verticalScrollBarEnabled', () async { + final MockUIScrollView mockScrollView = MockUIScrollView(); + + final WebKitWebViewController controller = createControllerWithMocks( + mockScrollView: mockScrollView, + ); + + await controller.verticalScrollBarEnabled(false); + verify(mockScrollView.verticalScrollBarEnabled(false)); + }); + + test('horizontalScrollBarEnabled', () async { + final MockUIScrollView mockScrollView = MockUIScrollView(); + + final WebKitWebViewController controller = createControllerWithMocks( + mockScrollView: mockScrollView, + ); + + await controller.horizontalScrollBarEnabled(false); + verify(mockScrollView.horizontalScrollBarEnabled(false); + }); + test('getScrollPosition', () { final MockUIScrollView mockScrollView = MockUIScrollView(); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart index 0c4924df62d..b2abb40db13 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart @@ -244,6 +244,28 @@ class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override + _i6.Future verticalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #verticalScrollBarEnabled, + [enabled], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future horizontalScrollBarEnabled(bool? enabled) => + (super.noSuchMethod( + Invocation.method( + #horizontalScrollBarEnabled, + [enabled], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + @override _i6.Future setContentOffset(_i3.Point? offset) => (super.noSuchMethod(