From c94f270e18e95745e7961c030e5148b09f82d344 Mon Sep 17 00:00:00 2001 From: Ben Bieker Date: Wed, 4 Dec 2019 11:21:58 +0100 Subject: [PATCH 1/3] [webview_flutter] add gesture navigation for iOS This introduces a boolean for the allowsBackForwardNavigationGestures setting of the WKWebView in iOS. It has no effect on Android. --- packages/webview_flutter/CHANGELOG.md | 4 +++ .../webviewflutter/FlutterWebView.java | 2 ++ .../webview_flutter/example/lib/main.dart | 1 + .../test_driver/webview_flutter_e2e.dart | 26 +++++++++++++++++++ .../ios/Classes/FlutterWebView.m | 4 +++ .../lib/platform_interface.dart | 8 +++++- .../lib/src/webview_method_channel.dart | 2 ++ .../webview_flutter/lib/webview_flutter.dart | 10 +++++++ packages/webview_flutter/pubspec.yaml | 2 +- .../test/webview_flutter_test.dart | 6 ++++- 10 files changed, 62 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 5230a2b0f7c7..f3dcd4253846 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.19 + +* Add setting for iOS to allow gesture based navigation. + ## 0.3.18+1 * Be explicit that keyboard is not ready for production in README.md. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 83a7ed6340f8..36ecf1fd445e 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -275,6 +275,8 @@ private void applySettings(Map settings) { case "userAgent": updateUserAgent((String) settings.get(key)); break; + case "allowsBackForwardNavigationGestures": + break; default: throw new IllegalArgumentException("Unknown WebView setting: " + key); } diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 20520d1532a4..b37c73de9e11 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -74,6 +74,7 @@ class _WebViewExampleState extends State { onPageFinished: (String url) { print('Page finished loading: $url'); }, + allowsBackForwardNavigationGestures: true, ); }), floatingActionButton: favoriteButton(), diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 373e65c6cbdd..314944df5775 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -652,6 +652,32 @@ void main() { expect(currentUrl, 'https://www.google.com/'); }); }); + + testWidgets('launches with allowsBackForwardNavigationGestures on iOS', + (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: SizedBox( + width: 400, + height: 300, + child: WebView( + key: GlobalKey(), + initialUrl: 'https://flutter.dev/', + allowsBackForwardNavigationGestures: true, + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + ), + ), + ), + ); + final WebViewController controller = await controllerCompleter.future; + final String currentUrl = await controller.currentUrl(); + expect(currentUrl, 'https://flutter.dev/'); + }); } // JavaScript booleans evaluate to different string values on Android and iOS. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 60fa24052038..412587848f92 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -260,6 +260,10 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"userAgent"]) { NSString* userAgent = settings[key]; [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; + } else if ([key isEqualToString:@"allowsBackForwardNavigationGestures"]) { + NSNumber* allowsBackForwardNavigationGestures = settings[key]; + _webView.allowsBackForwardNavigationGestures = + [allowsBackForwardNavigationGestures boolValue]; } else { [unknownKeys addObject:key]; } diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index a3af47a5c714..a847cf98614a 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -232,6 +232,7 @@ class WebSettings { this.hasNavigationDelegate, this.debuggingEnabled, @required this.userAgent, + this.allowsBackForwardNavigationGestures, }) : assert(userAgent != null); /// The JavaScript execution mode to be used by the webview. @@ -255,9 +256,14 @@ class WebSettings { /// See also [WebView.userAgent]. final WebSetting userAgent; + /// Whether to allow swipe based navigation in iOS. + /// + /// See also: [WebView.allowsBackForwardNavigationGestures] + final bool allowsBackForwardNavigationGestures; + @override String toString() { - return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent,)'; + return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent, allowsBackForwardNavigationGestures: $allowsBackForwardNavigationGestures)'; } } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index ad5a81e98ef5..c299b7a3bdbb 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -137,6 +137,8 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); + _addIfNonNull('allowsBackForwardNavigationGestures', + settings.allowsBackForwardNavigationGestures); _addSettingIfPresent('userAgent', settings.userAgent); return map; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index a57e2e13bdba..17a35ab5cb73 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -151,6 +151,7 @@ class WebView extends StatefulWidget { this.userAgent, this.initialMediaPlaybackPolicy = AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + this.allowsBackForwardNavigationGestures, }) : assert(javascriptMode != null), assert(initialMediaPlaybackPolicy != null), super(key: key); @@ -311,6 +312,13 @@ class WebView extends StatefulWidget { /// The default policy is [AutoMediaPlaybackPolicy.require_user_action_for_all_media_types]. final AutoMediaPlaybackPolicy initialMediaPlaybackPolicy; + /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations. + /// + /// This only works on iOS. + /// + /// By default `allowsBackForwardNavigationGestures` is false. + final bool allowsBackForwardNavigationGestures; + @override State createState() => _WebViewState(); } @@ -384,6 +392,8 @@ WebSettings _webSettingsFromWidget(WebView widget) { hasNavigationDelegate: widget.navigationDelegate != null, debuggingEnabled: widget.debuggingEnabled, userAgent: WebSetting.of(widget.userAgent), + allowsBackForwardNavigationGestures: + widget.allowsBackForwardNavigationGestures, ); } diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 8983f05d2b41..5979ec709f1e 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.18+1 +version: 0.3.19 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 1772df3fa815..3b9566b11172 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -822,6 +822,7 @@ void main() { await tester.pumpWidget( const WebView( initialUrl: 'https://youtube.com', + allowsBackForwardNavigationGestures: true, ), ); @@ -837,6 +838,7 @@ void main() { hasNavigationDelegate: false, debuggingEnabled: false, userAgent: WebSetting.of(null), + allowsBackForwardNavigationGestures: true, ), // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals @@ -1193,7 +1195,9 @@ class MatchesWebSettings extends Matcher { _webSettings.hasNavigationDelegate == webSettings.hasNavigationDelegate && _webSettings.debuggingEnabled == webSettings.debuggingEnabled && - _webSettings.userAgent == webSettings.userAgent; + _webSettings.userAgent == webSettings.userAgent && + _webSettings.allowsBackForwardNavigationGestures == + webSettings.allowsBackForwardNavigationGestures; } } From db3091aba6c8f72967ca08e8cefc253d4a28ca82 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Thu, 12 Dec 2019 13:59:25 -0800 Subject: [PATCH 2/3] Rename to gestureNavigationEnabled --- .../webviewflutter/FlutterWebView.java | 4 ++-- .../webview_flutter/example/lib/main.dart | 2 +- .../test_driver/webview_flutter_e2e.dart | 4 ++-- .../ios/Classes/FlutterWebView.m | 8 ++++---- .../lib/platform_interface.dart | 8 ++++---- .../lib/src/webview_method_channel.dart | 3 +-- .../webview_flutter/lib/webview_flutter.dart | 19 +++++++++---------- .../test/webview_flutter_test.dart | 9 ++++----- 8 files changed, 27 insertions(+), 30 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 36ecf1fd445e..0e5a5609dd93 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -272,11 +272,11 @@ private void applySettings(Map settings) { webView.setWebContentsDebuggingEnabled(debuggingEnabled); break; + case "gestureNavigationEnabled": + break; case "userAgent": updateUserAgent((String) settings.get(key)); break; - case "allowsBackForwardNavigationGestures": - break; default: throw new IllegalArgumentException("Unknown WebView setting: " + key); } diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index b37c73de9e11..59c87a25dedf 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -74,7 +74,7 @@ class _WebViewExampleState extends State { onPageFinished: (String url) { print('Page finished loading: $url'); }, - allowsBackForwardNavigationGestures: true, + gestureNavigationEnabled: true, ); }), floatingActionButton: favoriteButton(), diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 314944df5775..9bb72596add7 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -653,7 +653,7 @@ void main() { }); }); - testWidgets('launches with allowsBackForwardNavigationGestures on iOS', + testWidgets('launches with gestureNavigationEnabled on iOS', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -666,7 +666,7 @@ void main() { child: WebView( key: GlobalKey(), initialUrl: 'https://flutter.dev/', - allowsBackForwardNavigationGestures: true, + gestureNavigationEnabled: true, onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 412587848f92..cfcfdaf5d21c 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -257,13 +257,13 @@ - (NSString*)applySettings:(NSDictionary*)settings { _navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue]; } else if ([key isEqualToString:@"debuggingEnabled"]) { // no-op debugging is always enabled on iOS. - } else if ([key isEqualToString:@"userAgent"]) { - NSString* userAgent = settings[key]; - [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; - } else if ([key isEqualToString:@"allowsBackForwardNavigationGestures"]) { + } else if ([key isEqualToString:@"gestureNavigationEnabled"]) { NSNumber* allowsBackForwardNavigationGestures = settings[key]; _webView.allowsBackForwardNavigationGestures = [allowsBackForwardNavigationGestures boolValue]; + } else if ([key isEqualToString:@"userAgent"]) { + NSString* userAgent = settings[key]; + [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; } else { [unknownKeys addObject:key]; } diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index a847cf98614a..aaf63c24f08a 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -231,8 +231,8 @@ class WebSettings { this.javascriptMode, this.hasNavigationDelegate, this.debuggingEnabled, + this.gestureNavigationEnabled, @required this.userAgent, - this.allowsBackForwardNavigationGestures, }) : assert(userAgent != null); /// The JavaScript execution mode to be used by the webview. @@ -258,12 +258,12 @@ class WebSettings { /// Whether to allow swipe based navigation in iOS. /// - /// See also: [WebView.allowsBackForwardNavigationGestures] - final bool allowsBackForwardNavigationGestures; + /// See also: [WebView.gestureNavigationEnabled] + final bool gestureNavigationEnabled; @override String toString() { - return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent, allowsBackForwardNavigationGestures: $allowsBackForwardNavigationGestures)'; + return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, userAgent: $userAgent)'; } } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index c299b7a3bdbb..15ef402eb804 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -137,8 +137,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); - _addIfNonNull('allowsBackForwardNavigationGestures', - settings.allowsBackForwardNavigationGestures); + _addIfNonNull('gestureNavigationEnabled', settings.gestureNavigationEnabled); _addSettingIfPresent('userAgent', settings.userAgent); return map; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 17a35ab5cb73..a91a9ac827ae 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -148,10 +148,10 @@ class WebView extends StatefulWidget { this.onPageStarted, this.onPageFinished, this.debuggingEnabled = false, + this.gestureNavigationEnabled = false, this.userAgent, this.initialMediaPlaybackPolicy = AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, - this.allowsBackForwardNavigationGestures, }) : assert(javascriptMode != null), assert(initialMediaPlaybackPolicy != null), super(key: key); @@ -291,6 +291,13 @@ class WebView extends StatefulWidget { final bool debuggingEnabled; /// The value used for the HTTP User-Agent: request header. + /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations. + /// + /// This only works on iOS. + /// + /// By default `gestureNavigationEnabled` is false. + final bool gestureNavigationEnabled; + /// /// When null the platform's webview default is used for the User-Agent header. /// @@ -312,13 +319,6 @@ class WebView extends StatefulWidget { /// The default policy is [AutoMediaPlaybackPolicy.require_user_action_for_all_media_types]. final AutoMediaPlaybackPolicy initialMediaPlaybackPolicy; - /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations. - /// - /// This only works on iOS. - /// - /// By default `allowsBackForwardNavigationGestures` is false. - final bool allowsBackForwardNavigationGestures; - @override State createState() => _WebViewState(); } @@ -391,9 +391,8 @@ WebSettings _webSettingsFromWidget(WebView widget) { javascriptMode: widget.javascriptMode, hasNavigationDelegate: widget.navigationDelegate != null, debuggingEnabled: widget.debuggingEnabled, + gestureNavigationEnabled: widget.gestureNavigationEnabled, userAgent: WebSetting.of(widget.userAgent), - allowsBackForwardNavigationGestures: - widget.allowsBackForwardNavigationGestures, ); } diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 3b9566b11172..25875442543d 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -822,7 +822,7 @@ void main() { await tester.pumpWidget( const WebView( initialUrl: 'https://youtube.com', - allowsBackForwardNavigationGestures: true, + gestureNavigationEnabled: true, ), ); @@ -838,7 +838,7 @@ void main() { hasNavigationDelegate: false, debuggingEnabled: false, userAgent: WebSetting.of(null), - allowsBackForwardNavigationGestures: true, + gestureNavigationEnabled: true, ), // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals @@ -1195,9 +1195,8 @@ class MatchesWebSettings extends Matcher { _webSettings.hasNavigationDelegate == webSettings.hasNavigationDelegate && _webSettings.debuggingEnabled == webSettings.debuggingEnabled && - _webSettings.userAgent == webSettings.userAgent && - _webSettings.allowsBackForwardNavigationGestures == - webSettings.allowsBackForwardNavigationGestures; + _webSettings.gestureNavigationEnabled == webSettings.gestureNavigationEnabled && + _webSettings.userAgent == webSettings.userAgent; } } From 22057fe8a63d6caf0036326b0cf93c549cad96e4 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Thu, 12 Dec 2019 14:07:22 -0800 Subject: [PATCH 3/3] reformat --- packages/webview_flutter/lib/src/webview_method_channel.dart | 3 ++- packages/webview_flutter/test/webview_flutter_test.dart | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index 15ef402eb804..03d392ef5f8b 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -137,7 +137,8 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); - _addIfNonNull('gestureNavigationEnabled', settings.gestureNavigationEnabled); + _addIfNonNull( + 'gestureNavigationEnabled', settings.gestureNavigationEnabled); _addSettingIfPresent('userAgent', settings.userAgent); return map; } diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 25875442543d..10c7bbb460e0 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -1195,7 +1195,8 @@ class MatchesWebSettings extends Matcher { _webSettings.hasNavigationDelegate == webSettings.hasNavigationDelegate && _webSettings.debuggingEnabled == webSettings.debuggingEnabled && - _webSettings.gestureNavigationEnabled == webSettings.gestureNavigationEnabled && + _webSettings.gestureNavigationEnabled == + webSettings.gestureNavigationEnabled && _webSettings.userAgent == webSettings.userAgent; } }