diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md index f599889c0d5e..50660d08fc1f 100644 --- a/packages/webview_flutter/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.2.0 +* Add `loadData` call. + ## 2.1.2 * Fix typos in the README. diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview.dart b/packages/webview_flutter/webview_flutter/lib/src/webview.dart index 7699cc46c5d3..d2339b08d89e 100644 --- a/packages/webview_flutter/webview_flutter/lib/src/webview.dart +++ b/packages/webview_flutter/webview_flutter/lib/src/webview.dart @@ -495,6 +495,31 @@ class WebViewController { return _webViewPlatformController.loadUrl(url, headers); } + /// Loads the specified content data into the WebView. + /// + /// [baseUrl] is the apparent URL which the page was loaded at, used to resolve + /// relative paths. + /// + /// The [data] string will be interpreted as as string of the encoding specified by [encoding]. + /// + /// Throws an ArgumentError if [baseUrl] is not a valid URL string. + Future loadData( + String baseUrl, + String data, + String mimeType, + String encoding, + ) async { + assert(baseUrl != null); + assert(data != null); + _validateUrlString(baseUrl); + return _webViewPlatformController.loadData( + baseUrl, + data, + mimeType, + encoding, + ); + } + /// Accessor to the current URL that the WebView is displaying. /// /// If [WebView.initialUrl] was never specified, returns `null`. diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml index dabfe0d0d14a..563645d256c1 100644 --- a/packages/webview_flutter/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 2.1.2 +version: 2.2.0 environment: sdk: ">=2.14.0 <3.0.0" @@ -29,3 +29,8 @@ dev_dependencies: flutter_test: sdk: flutter pedantic: ^1.10.0 + +# TODO: This is only for testing, remove it when it should be merged! +dependency_overrides: + webview_flutter_platform_interface: + path: ../webview_flutter_platform_interface diff --git a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart index f7d09266a64b..1475cf5bcfdc 100644 --- a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart @@ -129,6 +129,28 @@ void main() { expect(await controller!.currentUrl(), equals('https://flutter.io')); }); + testWidgets('Load data', (WidgetTester tester) async { + WebViewController? controller; + await tester.pumpWidget( + WebView( + onWebViewCreated: (WebViewController webViewController) { + controller = webViewController; + }, + ), + ); + + expect(controller, isNotNull); + + await controller!.loadData( + 'https://flutter.io', + 'test!', + 'text/html', + 'UTF-8', + ); + + expect(await controller!.currentUrl(), 'https://flutter.io'); + }); + testWidgets("Can't go back before loading a page", (WidgetTester tester) async { WebViewController? controller; @@ -966,6 +988,10 @@ class FakePlatformWebView { final Map request = call.arguments; _loadUrl(request['url']); return Future.sync(() {}); + case 'loadData': + final Map request = call.arguments; + _loadUrl(request['baseUrl']); + return Future.sync(() {}); case 'updateSettings': if (call.arguments['jsMode'] != null) { javascriptMode = JavascriptMode.values[call.arguments['jsMode']]; diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 176028f2b11c..125c710a9104 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.3.0 +* Add `loadData` call. + ## 2.2.0 * Implemented new `runJavascript` and `runJavascriptReturningResult` methods in platform interface. diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index ed14107220b8..dfcc69c5b693 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -223,6 +223,9 @@ public void onMethodCall(MethodCall methodCall, Result result) { case "loadUrl": loadUrl(methodCall, result); break; + case "loadData": + loadData(methodCall, result); + break; case "updateSettings": updateSettings(methodCall, result); break; @@ -292,6 +295,18 @@ private void loadUrl(MethodCall methodCall, Result result) { result.success(null); } + @SuppressWarnings("unchecked") + private void loadData(MethodCall methodCall, Result result) { + Map request = (Map) methodCall.arguments; + String baseUrl = (String) request.get("baseUrl"); + String data = (String) request.get("data"); + String mimeType = (String) request.get("mimeType"); + String encoding = (String) request.get("encoding"); + webView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, ""); + result.success(null); + } + + private void canGoBack(Result result) { result.success(webView.canGoBack()); } diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index ac208a09ebc0..667668089872 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_android description: A Flutter plugin that provides a WebView widget on Android. repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 2.2.0 +version: 2.3.0 environment: sdk: ">=2.14.0 <3.0.0" diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 04641f97dc79..5fa41b0a4efa 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.3.0 +* Add `loadData` call. + ## 1.2.0 * Added `runJavascript` and `runJavascriptReturningResult` interface methods to supersede `evaluateJavascript`. @@ -8,4 +11,4 @@ ## 1.0.0 -* Extracted platform interface from `webview_flutter`. \ No newline at end of file +* Extracted platform interface from `webview_flutter`. 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..b02054b9fcdb 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 @@ -91,6 +91,21 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { }); } + @override + Future loadData( + String baseUrl, + String data, + String mimeType, + String encoding, + ) async { + return _channel.invokeMethod('loadData', { + 'baseUrl': baseUrl, + 'data': data, + 'mimeType': mimeType, + 'encoding': encoding, + }); + } + @override Future currentUrl() => _channel.invokeMethod('currentUrl'); 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..9b69a296d7b7 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 @@ -39,6 +39,16 @@ abstract class WebViewPlatformController { "WebView loadUrl is not implemented on the current platform"); } + Future loadData( + String baseUrl, + String data, + String mimeType, + String encoding, + ) { + throw UnimplementedError( + "WebView loadData is not implemented on the current platform"); + } + /// Updates the webview settings. /// /// Any non null field in `settings` will be set as the new setting value. diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index 994c3dcdebdf..2426b0d61c4e 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" @@ -19,4 +19,4 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.0.0 - pedantic: ^1.10.0 \ No newline at end of file + pedantic: ^1.10.0 diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 4db6dbfd2864..33e8b0b1f8a6 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.3.0 +* Add `loadData` call. + ## 2.2.0 * Implemented new `runJavascript` and `runJavascriptReturningResult` methods in platform interface. 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 5e12f8acb2ea..fa98c94ab5b7 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m @@ -137,6 +137,8 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onUpdateSettings:call result:result]; } else if ([[call method] isEqualToString:@"loadUrl"]) { [self onLoadUrl:call result:result]; + } else if ([[call method] isEqualToString:@"loadData"]) { + [self onLoadData:call result:result]; } else if ([[call method] isEqualToString:@"canGoBack"]) { [self onCanGoBack:call result:result]; } else if ([[call method] isEqualToString:@"canGoForward"]) { @@ -196,6 +198,17 @@ - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { } } +- (void)onLoadData:(FlutterMethodCall*)call result:(FlutterResult)result { + if (![self loadData:[call arguments]]) { + result([FlutterError + errorWithCode:@"loadData_failed" + message:@"Failed parsing the data" + details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]); + } else { + result(nil); + } +} + - (void)onCanGoBack:(FlutterMethodCall*)call result:(FlutterResult)result { BOOL canGoBack = [_webView canGoBack]; result(@(canGoBack)); @@ -492,6 +505,20 @@ - (bool)loadUrl:(NSString*)url withHeaders:(NSDictionary*) return true; } +- (bool)loadData:(NSDictionary*)request { + if (!request) { + return false; + } + + NSString* data = request[@"data"]; + NSString* baseUrl = request[@"baseUrl"]; + NSString* mimeType = request[@"mimeType"]; + NSString* encoding = request[@"encoding"]; + NSData* nsData = [data dataUsingEncoding:NSUTF8StringEncoding]; + NSURL* nsUrl = [NSURL URLWithString:baseUrl]; + return [_webView loadData:nsData MIMEType:mimeType characterEncodingName:encoding baseURL:nsUrl]; +} + - (void)registerJavaScriptChannels:(NSSet*)channelNames controller:(WKUserContentController*)userContentController { for (NSString* channelName in channelNames) { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 5176adb9749c..888c5699cf4f 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 2.2.0 +version: 2.3.0 environment: sdk: ">=2.14.0 <3.0.0" @@ -25,4 +25,4 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter - pedantic: ^1.10.0 \ No newline at end of file + pedantic: ^1.10.0