diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 36dc43fd0337..4733afdb7239 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.21+1 + +* static html and baseUrl support. + ## 0.3.21 * Enable programmatic scrolling using Android's WebView.scrollTo & iOS WKWebView.scrollView.contentOffset. 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 f9659d9873f4..e38df3ffc293 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 @@ -28,6 +28,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { private final MethodChannel methodChannel; private final FlutterWebViewClient flutterWebViewClient; private final Handler platformThreadHandler; + private String baseUrl; @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") @@ -65,7 +66,15 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { String userAgent = (String) params.get("userAgent"); updateUserAgent(userAgent); } - if (params.containsKey("initialUrl")) { + if (params.containsKey("html")) { + String html = (String) params.get("html"); + if (params.containsKey("baseUrl")) { + baseUrl = (String) params.get("baseUrl"); + webView.loadDataWithBaseURL(baseUrl, html, "text/html", "UTF-8", null); + } else { + webView.loadData(html, "text/html", "UTF-8"); + } + } else if (params.containsKey("initialUrl")) { String url = (String) params.get("initialUrl"); webView.loadUrl(url); } @@ -122,6 +131,9 @@ public void onMethodCall(MethodCall methodCall, Result result) { case "loadUrl": loadUrl(methodCall, result); break; + case "loadHtml": + loadHtml(methodCall, result); + break; case "updateSettings": updateSettings(methodCall, result); break; @@ -187,6 +199,20 @@ private void loadUrl(MethodCall methodCall, Result result) { result.success(null); } + @SuppressWarnings("unchecked") + private void loadHtml(MethodCall methodCall, Result result) { + Map request = (Map) methodCall.arguments; + String html = (String) request.get("html"); + if (html != null) { + if (baseUrl != null) { + webView.loadDataWithBaseURL(baseUrl, html, "text/html", "UTF-8", null); + } else { + webView.loadData(html, "text/html", "UTF-8"); + } + } + result.success(null); + } + private void canGoBack(Result result) { result.success(webView.canGoBack()); } diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 969e010913f3..ed9c5cc8b32d 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -111,14 +111,27 @@ - (instancetype)initWithFrame:(CGRect)frame // 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]; + NSString* html = args[@"html"]; + if ([html isKindOfClass:[NSString class]]) { + NSString* baseURLString = args[@"baseUrl"]; + if ([baseURLString isKindOfClass:[NSString class]]) { + baseURL = [NSURL URLWithString:baseURLString]; + [_webView loadHTMLString:html baseURL:baseURL]; + } else { + [_webView loadHTMLString:html baseURL:nil]; + } + } else { + NSString* initialUrl = args[@"initialUrl"]; + if ([initialUrl isKindOfClass:[NSString class]]) { + [self loadUrl:initialUrl]; + } } } return self; } +NSURL* baseURL = nil; + - (UIView*)view { return _webView; } @@ -128,6 +141,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:@"loadHtml"]) { + [self onLoadHtml:call result:result]; } else if ([[call method] isEqualToString:@"canGoBack"]) { [self onCanGoBack:call result:result]; } else if ([[call method] isEqualToString:@"canGoForward"]) { @@ -183,6 +198,18 @@ - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { } } +- (void)onLoadHtml:(FlutterMethodCall*)call result:(FlutterResult)result { + NSString* html = [call arguments][@"html"]; + if ([html isKindOfClass:[NSString class]]) { + if (baseURL != nil) { + [_webView loadHTMLString:html baseURL:baseURL]; + } else { + [_webView loadHTMLString:html baseURL:nil]; + } + } + result(nil); +} + - (void)onCanGoBack:(FlutterMethodCall*)call result:(FlutterResult)result { BOOL canGoBack = [_webView canGoBack]; result([NSNumber numberWithBool:canGoBack]); diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index 238d25b9c677..11205bb552c1 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -175,6 +175,14 @@ abstract class WebViewPlatformController { "WebView loadUrl is not implemented on the current platform"); } + /// Loads the specified html. + /// + /// `html` must not be null. + Future loadHtml(String html) { + throw UnimplementedError( + "WebView loadHtml 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. @@ -420,6 +428,8 @@ class CreationParams { /// The `autoMediaPlaybackPolicy` parameter must not be null. CreationParams({ this.initialUrl, + this.html, + this.baseUrl, this.webSettings, this.javascriptChannelNames, this.userAgent, @@ -432,6 +442,12 @@ class CreationParams { /// When null the webview will be created without loading any page. final String initialUrl; + /// The initial baseUrl to load in the webview. It will work with html only. + final String baseUrl; + + /// The initial html to load in the webview. This will be preferred over initialUrl if it exists. + final String html; + /// The initial [WebSettings] for the new webview. /// /// This can later be updated with [WebViewPlatformController.updateSettings]. diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index a75dee3c172b..e06f8475ce6b 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -79,6 +79,13 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { }); } + @override + Future loadHtml(String html) async { + return _channel.invokeMethod('loadHtml', { + 'html': html, + }); + } + @override Future currentUrl() => _channel.invokeMethod('currentUrl'); @@ -190,12 +197,20 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { /// [AndroidWebViewBuilder] and [CupertinoWebViewBuilder]. static Map creationParamsToMap( CreationParams creationParams) { - return { + var creationParamMap = { 'initialUrl': creationParams.initialUrl, 'settings': _webSettingsToMap(creationParams.webSettings), 'javascriptChannelNames': creationParams.javascriptChannelNames.toList(), 'userAgent': creationParams.userAgent, 'autoMediaPlaybackPolicy': creationParams.autoMediaPlaybackPolicy.index, }; + + if (creationParams.html != null) { + creationParamMap['html'] = creationParams.html; + } + if (creationParams.baseUrl != null) { + creationParamMap['baseUrl'] = creationParams.baseUrl; + } + return creationParamMap; } } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 2635b0446fa2..f8e64e28ac84 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -144,6 +144,8 @@ class WebView extends StatefulWidget { Key key, this.onWebViewCreated, this.initialUrl, + this.html, + this.baseUrl, this.javascriptMode = JavascriptMode.disabled, this.javascriptChannels, this.navigationDelegate, @@ -210,6 +212,12 @@ class WebView extends StatefulWidget { /// The initial URL to load. final String initialUrl; + /// The initial baseURL to load. + final String baseUrl; + + /// The initial static html to load. + final String html; + /// Whether Javascript execution is enabled. final JavascriptMode javascriptMode; @@ -389,6 +397,8 @@ class _WebViewState extends State { CreationParams _creationParamsfromWidget(WebView widget) { return CreationParams( initialUrl: widget.initialUrl, + html: widget.html, + baseUrl: widget.baseUrl, webSettings: _webSettingsFromWidget(widget), javascriptChannelNames: _extractChannelNames(widget.javascriptChannels), userAgent: widget.userAgent, @@ -548,6 +558,15 @@ class WebViewController { return _webViewPlatformController.loadUrl(url, headers); } + /// Loads the specified html. + /// + /// `html` must not be null. + /// + Future loadHtml(String html) async { + assert(html != null); + return _webViewPlatformController.loadHtml(html); + } + /// Accessor to the current URL that the WebView is displaying. /// /// If [WebView.initialUrl] was never specified, returns `null`. diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 26e4fbc26edc..6b4779dc8680 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.21 +version: 0.3.21+1 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: