From 4b7a63fac480b92f6fcc754fea8c5c82430c3974 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Fri, 22 Oct 2021 17:09:43 +0200 Subject: [PATCH 1/6] Add methods to load HTML and Flutter assets. Adds methods to the webview_flutter_platform_interface to support loading content from Flutter asset defined in the pubspec.yaml of directly from HTML string. --- .../CHANGELOG.md | 4 ++ .../webview_method_channel.dart | 18 ++++++ .../webview_platform_controller.dart | 23 ++++++++ .../pubspec.yaml | 2 +- .../webview_method_channel_test.dart | 55 +++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 04641f97dc79..287915d0f0ac 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 + +* Added `loadFlutterAsset` and `loadHtml` interface methods. + ## 1.2.0 * Added `runJavascript` and `runJavascriptReturningResult` interface methods to supersede `evaluateJavascript`. diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index 9610038eec82..d52c8bb4959c 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -79,6 +79,24 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { ); } + @override + Future loadFlutterAsset(String assetName) async { + assert(assetName != null); + return _channel.invokeMethod('loadFlutterAsset', assetName); + } + + @override + Future loadHtml( + String html, { + String? baseUrl, + }) async { + assert(html != null); + return _channel.invokeMethod('loadHtml', { + 'html': html, + 'baseUrl': baseUrl, + }); + } + @override Future loadUrl( String url, diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart index b42da4326079..7d9b5f9ddb5c 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart @@ -23,6 +23,29 @@ abstract class WebViewPlatformController { /// The `handler` parameter must not be null. WebViewPlatformController(WebViewPlatformCallbacksHandler handler); + /// Loads the Flutter asset specified in the pubspec.yaml file. + /// + /// Throws an ArgumentError if [assetName] is not part of the specified assets + /// in the pubspec.yaml file. + Future loadFlutterAsset( + String assetName, + ) { + throw UnimplementedError( + "WebView loadFlutterAsset is not implemented on the current platform"); + } + + /// Loads the supplied HTML. + /// + /// The [baseUrl] parameter is used when resolving relative URLs within the + /// HTML string. + Future loadHtml( + String html, { + String? baseUrl, + }) { + throw UnimplementedError( + "WebView loadHtml is not implemented on the current platform"); + } + /// Loads the specified URL. /// /// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index 994c3dcdebdf..508af0ef0862 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/plugins/tree/master/packages/webview_flut 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: 1.2.0 +version: 1.3.0 environment: sdk: ">=2.12.0 <3.0.0" diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 85f184f9f715..94b70bbf4bf4 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -55,6 +55,61 @@ void main() { log.clear(); }); + test('loadFlutterAsset', () async { + await webViewPlatform.loadFlutterAsset( + 'folder/asset.html', + ); + + expect( + log, + [ + isMethodCall( + 'loadFlutterAsset', + arguments: 'folder/asset.html', + ), + ], + ); + }); + + test('loadHtml without base URL', () async { + await webViewPlatform.loadHtml( + 'Test HTML string', + ); + + expect( + log, + [ + isMethodCall( + 'loadHtml', + arguments: { + 'html': 'Test HTML string', + 'baseUrl': null, + }, + ), + ], + ); + }); + + test('loadHtml without base URL', () async { + await webViewPlatform.loadHtml( + 'Test HTML string', + baseUrl: 'https://flutter.dev', + ); + + expect( + log, + [ + isMethodCall( + 'loadHtml', + arguments: { + 'html': 'Test HTML string', + 'baseUrl': 'https://flutter.dev', + }, + ), + ], + ); + }); + test('loadUrl with headers', () async { await webViewPlatform.loadUrl( 'https://test.url', From 31510088d14221eb56d921f9656c2718248938e1 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 27 Oct 2021 17:09:51 +0200 Subject: [PATCH 2/6] Renamed loadHtml to loadHtmlString --- .../src/method_channel/webview_method_channel.dart | 4 ++-- .../webview_platform_controller.dart | 6 +++--- .../method_channel/webview_method_channel_test.dart | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index d52c8bb4959c..a01ee377be49 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -86,12 +86,12 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { } @override - Future loadHtml( + Future loadHtmlString( String html, { String? baseUrl, }) async { assert(html != null); - return _channel.invokeMethod('loadHtml', { + return _channel.invokeMethod('loadHtmlString', { 'html': html, 'baseUrl': baseUrl, }); diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart index 7d9b5f9ddb5c..36d181bac090 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart @@ -34,16 +34,16 @@ abstract class WebViewPlatformController { "WebView loadFlutterAsset is not implemented on the current platform"); } - /// Loads the supplied HTML. + /// Loads the supplied HTML string. /// /// The [baseUrl] parameter is used when resolving relative URLs within the /// HTML string. - Future loadHtml( + Future loadHtmlString( String html, { String? baseUrl, }) { throw UnimplementedError( - "WebView loadHtml is not implemented on the current platform"); + "WebView loadHtmlString is not implemented on the current platform"); } /// Loads the specified URL. diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 94b70bbf4bf4..f20477e8610e 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -71,8 +71,8 @@ void main() { ); }); - test('loadHtml without base URL', () async { - await webViewPlatform.loadHtml( + test('loadHtmlString without base URL', () async { + await webViewPlatform.loadHtmlString( 'Test HTML string', ); @@ -80,7 +80,7 @@ void main() { log, [ isMethodCall( - 'loadHtml', + 'loadHtmlString', arguments: { 'html': 'Test HTML string', 'baseUrl': null, @@ -90,8 +90,8 @@ void main() { ); }); - test('loadHtml without base URL', () async { - await webViewPlatform.loadHtml( + test('loadHtmlString without base URL', () async { + await webViewPlatform.loadHtmlString( 'Test HTML string', baseUrl: 'https://flutter.dev', ); @@ -100,7 +100,7 @@ void main() { log, [ isMethodCall( - 'loadHtml', + 'loadHtmlString', arguments: { 'html': 'Test HTML string', 'baseUrl': 'https://flutter.dev', From 0f28905eeb7ae9b161b3f05d6c5242386ffd3b26 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 27 Oct 2021 18:06:02 +0200 Subject: [PATCH 3/6] Support loading arbitrary files instead of only Flutter assets --- .../src/method_channel/webview_method_channel.dart | 6 +++--- .../webview_platform_controller.dart | 13 ++++++++----- .../method_channel/webview_method_channel_test.dart | 10 +++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index a01ee377be49..3c8948f46c31 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -80,9 +80,9 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { } @override - Future loadFlutterAsset(String assetName) async { - assert(assetName != null); - return _channel.invokeMethod('loadFlutterAsset', assetName); + Future loadFile(String absoluteFilePath) async { + assert(absoluteFilePath != null); + return _channel.invokeMethod('loadFile', absoluteFilePath); } @override diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart index 36d181bac090..bd4653266c3f 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart @@ -23,12 +23,15 @@ abstract class WebViewPlatformController { /// The `handler` parameter must not be null. WebViewPlatformController(WebViewPlatformCallbacksHandler handler); - /// Loads the Flutter asset specified in the pubspec.yaml file. + /// Loads the file located on the specified [absoluteFilePath]. /// - /// Throws an ArgumentError if [assetName] is not part of the specified assets - /// in the pubspec.yaml file. - Future loadFlutterAsset( - String assetName, + /// The [absoluteFilePath] parameter should contain the absolute path to the + /// file as it is stored on the device. For example: + /// `/Users/username/Documents/www/index.html`. + /// + /// Throws an ArgumentError if the [absoluteFilePath] does not exist. + Future loadFile( + String absoluteFilePath, ) { throw UnimplementedError( "WebView loadFlutterAsset is not implemented on the current platform"); diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index f20477e8610e..9d98d33e68a1 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -55,17 +55,17 @@ void main() { log.clear(); }); - test('loadFlutterAsset', () async { - await webViewPlatform.loadFlutterAsset( - 'folder/asset.html', + test('loadFile', () async { + await webViewPlatform.loadFile( + '/folder/asset.html', ); expect( log, [ isMethodCall( - 'loadFlutterAsset', - arguments: 'folder/asset.html', + 'loadFile', + arguments: '/folder/asset.html', ), ], ); From 7a0c69a1d71d0b6a482616727647da1c7b0b4368 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 27 Oct 2021 18:52:39 +0200 Subject: [PATCH 4/6] Update changelog description --- .../webview_flutter_platform_interface/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 287915d0f0ac..b4ac267b780f 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.3.0 -* Added `loadFlutterAsset` and `loadHtml` interface methods. +* Added `loadFile` and `loadHtml` interface methods. ## 1.2.0 From b2efaa8826d2050251ef854a7b8053c1cdada7bf Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 4 Nov 2021 15:03:05 +0100 Subject: [PATCH 5/6] Fix formatting --- .../ios/Classes/FlutterWebView.m | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m index 79bcbc5b80ea..35c46fdcee29 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m @@ -74,26 +74,26 @@ - (instancetype)initWithFrame:(CGRect)frame binaryMessenger:(NSObject*)messenger { if (self = [super init]) { _viewId = viewId; - + NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId]; _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; _javaScriptChannelNames = [[NSMutableSet alloc] init]; - + WKUserContentController* userContentController = [[WKUserContentController alloc] init]; if ([args[@"javascriptChannelNames"] isKindOfClass:[NSArray class]]) { NSArray* javaScriptChannelNames = args[@"javascriptChannelNames"]; [_javaScriptChannelNames addObjectsFromArray:javaScriptChannelNames]; [self registerJavaScriptChannels:_javaScriptChannelNames controller:userContentController]; } - + NSDictionary* settings = args[@"settings"]; - + WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init]; [self applyConfigurationSettings:settings toConfiguration:configuration]; configuration.userContentController = userContentController; [self updateAutoMediaPlaybackPolicy:args[@"autoMediaPlaybackPolicy"] inConfiguration:configuration]; - + _webView = [[FLTWKWebView alloc] initWithFrame:frame configuration:configuration]; _navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel]; _webView.UIDelegate = self; @@ -102,18 +102,18 @@ - (instancetype)initWithFrame:(CGRect)frame [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { [weakSelf onMethodCall:call result:result]; }]; - + if (@available(iOS 11.0, *)) { _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; if (@available(iOS 13.0, *)) { _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO; } } - + [self applySettings:settings]; // TODO(amirh): return an error if apply settings failed once it's possible to do so. // https://github.com/flutter/flutter/issues/36228 - + NSString* initialUrl = args[@"initialUrl"]; if ([initialUrl isKindOfClass:[NSString class]]) { [self loadUrl:initialUrl]; @@ -188,9 +188,9 @@ - (void)onUpdateSettings:(FlutterMethodCall*)call result:(FlutterResult)result { - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { if (![self loadRequest:[call arguments]]) { result([FlutterError - errorWithCode:@"loadUrl_failed" - message:@"Failed parsing the URL" - details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]); + errorWithCode:@"loadUrl_failed" + message:@"Failed parsing the URL" + details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]); } else { result(nil); } @@ -236,16 +236,16 @@ - (void)onEvaluateJavaScript:(FlutterMethodCall*)call result:(FlutterResult)resu } [_webView evaluateJavaScript:jsString completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { - if (error) { - result([FlutterError - errorWithCode:@"evaluateJavaScript_failed" - message:@"Failed evaluating JavaScript" - details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", - jsString, error]]); - } else { - result([NSString stringWithFormat:@"%@", evaluateResult]); - } - }]; + if (error) { + result([FlutterError + errorWithCode:@"evaluateJavaScript_failed" + message:@"Failed evaluating JavaScript" + details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", + jsString, error]]); + } else { + result([NSString stringWithFormat:@"%@", evaluateResult]); + } + }]; } - (void)onRunJavaScript:(FlutterMethodCall*)call @@ -259,27 +259,27 @@ - (void)onRunJavaScript:(FlutterMethodCall*)call return; } [_webView - evaluateJavaScript:jsString - completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { - if (error) { - // WebKit will throw an error (WKErrorJavaScriptResultTypeIsUnsupported) when the - // type of the evaluated value is unsupported. This also goes for - // `null` and `undefined` on iOS 14+, for example when running a void function. - // For ease of use this specific error is ignored when no return value is expected. - BOOL sendError = sendReturnValue || error.code != WKErrorJavaScriptResultTypeIsUnsupported; - result( + evaluateJavaScript:jsString + completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { + if (error) { + // WebKit will throw an error (WKErrorJavaScriptResultTypeIsUnsupported) when the + // type of the evaluated value is unsupported. This also goes for + // `null` and `undefined` on iOS 14+, for example when running a void function. + // For ease of use this specific error is ignored when no return value is expected. + BOOL sendError = sendReturnValue || error.code != WKErrorJavaScriptResultTypeIsUnsupported; + result( sendError - ? [FlutterError - errorWithCode:(sendReturnValue ? @"runJavascriptReturningResult_failed" - : @"runJavascript_failed") - message:@"Failed running JavaScript" - details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", - jsString, error]] - : nil); - return; - } - result(sendReturnValue ? [NSString stringWithFormat:@"%@", evaluateResult] : nil); - }]; + ? [FlutterError + errorWithCode:(sendReturnValue ? @"runJavascriptReturningResult_failed" + : @"runJavascript_failed") + message:@"Failed running JavaScript" + details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", + jsString, error]] + : nil); + return; + } + result(sendReturnValue ? [NSString stringWithFormat:@"%@", evaluateResult] : nil); + }]; } - (void)onAddJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResult)result { @@ -298,12 +298,12 @@ - (void)onRemoveJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResul for (NSString* channelName in _javaScriptChannelNames) { [_webView.configuration.userContentController removeScriptMessageHandlerForName:channelName]; } - + NSArray* channelNamesToRemove = [call arguments]; for (NSString* channelName in channelNamesToRemove) { [_javaScriptChannelNames removeObject:channelName]; } - + [self registerJavaScriptChannels:_javaScriptChannelNames controller:_webView.configuration.userContentController]; result(nil); @@ -317,8 +317,8 @@ - (void)clearCache:(FlutterResult)result { [dataStore removeDataOfTypes:cacheDataTypes modifiedSince:dateFrom completionHandler:^{ - result(nil); - }]; + result(nil); + }]; } else { // support for iOS8 tracked in https://github.com/flutter/flutter/issues/27624. NSLog(@"Clearing cache is not supported for Flutter WebViews prior to iOS 9."); @@ -334,18 +334,18 @@ - (void)onScrollTo:(FlutterMethodCall*)call result:(FlutterResult)result { NSDictionary* arguments = [call arguments]; int x = [arguments[@"x"] intValue]; int y = [arguments[@"y"] intValue]; - + _webView.scrollView.contentOffset = CGPointMake(x, y); result(nil); } - (void)onScrollBy:(FlutterMethodCall*)call result:(FlutterResult)result { CGPoint contentOffset = _webView.scrollView.contentOffset; - + NSDictionary* arguments = [call arguments]; int x = [arguments[@"x"] intValue] + contentOffset.x; int y = [arguments[@"y"] intValue] + contentOffset.y; - + _webView.scrollView.contentOffset = CGPointMake(x, y); result(nil); } @@ -382,7 +382,7 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"gestureNavigationEnabled"]) { NSNumber* allowsBackForwardNavigationGestures = settings[key]; _webView.allowsBackForwardNavigationGestures = - [allowsBackForwardNavigationGestures boolValue]; + [allowsBackForwardNavigationGestures boolValue]; } else if ([key isEqualToString:@"userAgent"]) { NSString* userAgent = settings[key]; [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; @@ -397,7 +397,7 @@ - (NSString*)applySettings:(NSDictionary*)settings { return nil; } return [NSString stringWithFormat:@"webview_flutter: unknown setting keys: {%@}", - [unknownKeys componentsJoinedByString:@", "]]; + [unknownKeys componentsJoinedByString:@", "]]; } - (void)applyConfigurationSettings:(NSDictionary*)settings @@ -462,7 +462,7 @@ - (bool)loadRequest:(NSDictionary*)request { if (!request) { return false; } - + NSString* url = request[@"url"]; if ([url isKindOfClass:[NSString class]]) { id headers = request[@"headers"]; @@ -472,7 +472,7 @@ - (bool)loadRequest:(NSDictionary*)request { return [self loadUrl:url]; } } - + return false; } @@ -495,15 +495,15 @@ - (void)registerJavaScriptChannels:(NSSet*)channelNames controller:(WKUserContentController*)userContentController { for (NSString* channelName in channelNames) { FLTJavaScriptChannel* channel = - [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel - javaScriptChannelName:channelName]; + [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel + javaScriptChannelName:channelName]; [userContentController addScriptMessageHandler:channel name:channelName]; NSString* wrapperSource = [NSString - stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName]; + stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName]; WKUserScript* wrapperScript = - [[WKUserScript alloc] initWithSource:wrapperSource - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:NO]; + [[WKUserScript alloc] initWithSource:wrapperSource + injectionTime:WKUserScriptInjectionTimeAtDocumentStart + forMainFrameOnly:NO]; [userContentController addUserScript:wrapperScript]; } } @@ -519,13 +519,13 @@ - (void)updateUserAgent:(NSString*)userAgent { #pragma mark WKUIDelegate - (WKWebView*)webView:(WKWebView*)webView - createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration - forNavigationAction:(WKNavigationAction*)navigationAction - windowFeatures:(WKWindowFeatures*)windowFeatures { +createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration + forNavigationAction:(WKNavigationAction*)navigationAction + windowFeatures:(WKWindowFeatures*)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [webView loadRequest:navigationAction.request]; } - + return nil; } From 0f70b117df2479170cbe5c2cac9cab388a8bef66 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 4 Nov 2021 15:11:08 +0100 Subject: [PATCH 6/6] Fix formatting --- .../ios/Classes/FlutterWebView.m | 127 +++++++++--------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m index 35c46fdcee29..5e12f8acb2ea 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m @@ -74,26 +74,26 @@ - (instancetype)initWithFrame:(CGRect)frame binaryMessenger:(NSObject*)messenger { if (self = [super init]) { _viewId = viewId; - + NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId]; _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; _javaScriptChannelNames = [[NSMutableSet alloc] init]; - + WKUserContentController* userContentController = [[WKUserContentController alloc] init]; if ([args[@"javascriptChannelNames"] isKindOfClass:[NSArray class]]) { NSArray* javaScriptChannelNames = args[@"javascriptChannelNames"]; [_javaScriptChannelNames addObjectsFromArray:javaScriptChannelNames]; [self registerJavaScriptChannels:_javaScriptChannelNames controller:userContentController]; } - + NSDictionary* settings = args[@"settings"]; - + WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init]; [self applyConfigurationSettings:settings toConfiguration:configuration]; configuration.userContentController = userContentController; [self updateAutoMediaPlaybackPolicy:args[@"autoMediaPlaybackPolicy"] inConfiguration:configuration]; - + _webView = [[FLTWKWebView alloc] initWithFrame:frame configuration:configuration]; _navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel]; _webView.UIDelegate = self; @@ -102,18 +102,18 @@ - (instancetype)initWithFrame:(CGRect)frame [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { [weakSelf onMethodCall:call result:result]; }]; - + if (@available(iOS 11.0, *)) { _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; if (@available(iOS 13.0, *)) { _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO; } } - + [self applySettings:settings]; // TODO(amirh): return an error if apply settings failed once it's possible to do so. // https://github.com/flutter/flutter/issues/36228 - + NSString* initialUrl = args[@"initialUrl"]; if ([initialUrl isKindOfClass:[NSString class]]) { [self loadUrl:initialUrl]; @@ -188,9 +188,9 @@ - (void)onUpdateSettings:(FlutterMethodCall*)call result:(FlutterResult)result { - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { if (![self loadRequest:[call arguments]]) { result([FlutterError - errorWithCode:@"loadUrl_failed" - message:@"Failed parsing the URL" - details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]); + errorWithCode:@"loadUrl_failed" + message:@"Failed parsing the URL" + details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]); } else { result(nil); } @@ -236,16 +236,16 @@ - (void)onEvaluateJavaScript:(FlutterMethodCall*)call result:(FlutterResult)resu } [_webView evaluateJavaScript:jsString completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { - if (error) { - result([FlutterError - errorWithCode:@"evaluateJavaScript_failed" - message:@"Failed evaluating JavaScript" - details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", - jsString, error]]); - } else { - result([NSString stringWithFormat:@"%@", evaluateResult]); - } - }]; + if (error) { + result([FlutterError + errorWithCode:@"evaluateJavaScript_failed" + message:@"Failed evaluating JavaScript" + details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", + jsString, error]]); + } else { + result([NSString stringWithFormat:@"%@", evaluateResult]); + } + }]; } - (void)onRunJavaScript:(FlutterMethodCall*)call @@ -259,27 +259,28 @@ - (void)onRunJavaScript:(FlutterMethodCall*)call return; } [_webView - evaluateJavaScript:jsString - completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { - if (error) { - // WebKit will throw an error (WKErrorJavaScriptResultTypeIsUnsupported) when the - // type of the evaluated value is unsupported. This also goes for - // `null` and `undefined` on iOS 14+, for example when running a void function. - // For ease of use this specific error is ignored when no return value is expected. - BOOL sendError = sendReturnValue || error.code != WKErrorJavaScriptResultTypeIsUnsupported; - result( - sendError - ? [FlutterError - errorWithCode:(sendReturnValue ? @"runJavascriptReturningResult_failed" - : @"runJavascript_failed") - message:@"Failed running JavaScript" - details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@", - jsString, error]] - : nil); - return; - } - result(sendReturnValue ? [NSString stringWithFormat:@"%@", evaluateResult] : nil); - }]; + evaluateJavaScript:jsString + completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) { + if (error) { + // WebKit will throw an error (WKErrorJavaScriptResultTypeIsUnsupported) when the + // type of the evaluated value is unsupported. This also goes for + // `null` and `undefined` on iOS 14+, for example when running a void function. + // For ease of use this specific error is ignored when no return value is expected. + BOOL sendError = + sendReturnValue || error.code != WKErrorJavaScriptResultTypeIsUnsupported; + result(sendError + ? [FlutterError + errorWithCode:(sendReturnValue ? @"runJavascriptReturningResult_failed" + : @"runJavascript_failed") + message:@"Failed running JavaScript" + details:[NSString + stringWithFormat:@"JavaScript string was: '%@'\n%@", + jsString, error]] + : nil); + return; + } + result(sendReturnValue ? [NSString stringWithFormat:@"%@", evaluateResult] : nil); + }]; } - (void)onAddJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResult)result { @@ -298,12 +299,12 @@ - (void)onRemoveJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResul for (NSString* channelName in _javaScriptChannelNames) { [_webView.configuration.userContentController removeScriptMessageHandlerForName:channelName]; } - + NSArray* channelNamesToRemove = [call arguments]; for (NSString* channelName in channelNamesToRemove) { [_javaScriptChannelNames removeObject:channelName]; } - + [self registerJavaScriptChannels:_javaScriptChannelNames controller:_webView.configuration.userContentController]; result(nil); @@ -317,8 +318,8 @@ - (void)clearCache:(FlutterResult)result { [dataStore removeDataOfTypes:cacheDataTypes modifiedSince:dateFrom completionHandler:^{ - result(nil); - }]; + result(nil); + }]; } else { // support for iOS8 tracked in https://github.com/flutter/flutter/issues/27624. NSLog(@"Clearing cache is not supported for Flutter WebViews prior to iOS 9."); @@ -334,18 +335,18 @@ - (void)onScrollTo:(FlutterMethodCall*)call result:(FlutterResult)result { NSDictionary* arguments = [call arguments]; int x = [arguments[@"x"] intValue]; int y = [arguments[@"y"] intValue]; - + _webView.scrollView.contentOffset = CGPointMake(x, y); result(nil); } - (void)onScrollBy:(FlutterMethodCall*)call result:(FlutterResult)result { CGPoint contentOffset = _webView.scrollView.contentOffset; - + NSDictionary* arguments = [call arguments]; int x = [arguments[@"x"] intValue] + contentOffset.x; int y = [arguments[@"y"] intValue] + contentOffset.y; - + _webView.scrollView.contentOffset = CGPointMake(x, y); result(nil); } @@ -382,7 +383,7 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"gestureNavigationEnabled"]) { NSNumber* allowsBackForwardNavigationGestures = settings[key]; _webView.allowsBackForwardNavigationGestures = - [allowsBackForwardNavigationGestures boolValue]; + [allowsBackForwardNavigationGestures boolValue]; } else if ([key isEqualToString:@"userAgent"]) { NSString* userAgent = settings[key]; [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; @@ -397,7 +398,7 @@ - (NSString*)applySettings:(NSDictionary*)settings { return nil; } return [NSString stringWithFormat:@"webview_flutter: unknown setting keys: {%@}", - [unknownKeys componentsJoinedByString:@", "]]; + [unknownKeys componentsJoinedByString:@", "]]; } - (void)applyConfigurationSettings:(NSDictionary*)settings @@ -462,7 +463,7 @@ - (bool)loadRequest:(NSDictionary*)request { if (!request) { return false; } - + NSString* url = request[@"url"]; if ([url isKindOfClass:[NSString class]]) { id headers = request[@"headers"]; @@ -472,7 +473,7 @@ - (bool)loadRequest:(NSDictionary*)request { return [self loadUrl:url]; } } - + return false; } @@ -495,15 +496,15 @@ - (void)registerJavaScriptChannels:(NSSet*)channelNames controller:(WKUserContentController*)userContentController { for (NSString* channelName in channelNames) { FLTJavaScriptChannel* channel = - [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel - javaScriptChannelName:channelName]; + [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel + javaScriptChannelName:channelName]; [userContentController addScriptMessageHandler:channel name:channelName]; NSString* wrapperSource = [NSString - stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName]; + stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName]; WKUserScript* wrapperScript = - [[WKUserScript alloc] initWithSource:wrapperSource - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:NO]; + [[WKUserScript alloc] initWithSource:wrapperSource + injectionTime:WKUserScriptInjectionTimeAtDocumentStart + forMainFrameOnly:NO]; [userContentController addUserScript:wrapperScript]; } } @@ -519,13 +520,13 @@ - (void)updateUserAgent:(NSString*)userAgent { #pragma mark WKUIDelegate - (WKWebView*)webView:(WKWebView*)webView -createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration - forNavigationAction:(WKNavigationAction*)navigationAction - windowFeatures:(WKWindowFeatures*)windowFeatures { + createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration + forNavigationAction:(WKNavigationAction*)navigationAction + windowFeatures:(WKWindowFeatures*)windowFeatures { if (!navigationAction.targetFrame.isMainFrame) { [webView loadRequest:navigationAction.request]; } - + return nil; }