diff --git a/.idea/workspace.xml b/.idea/workspace.xml index ca6d2fe0..55989e27 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -14,7 +14,20 @@ - + + + + + + + + + + + + + + @@ -29,7 +42,7 @@ - + @@ -37,8 +50,8 @@ - - + + @@ -57,20 +70,21 @@ - - + + + - + - - + + @@ -78,25 +92,25 @@ - - - - - - - - - - + + + + + - - - - - + + + + + + + + + + @@ -112,13 +126,6 @@ - MethodChannel - WebViewController - HashMap - String code - flutter_inappwebview - _closeServer - _startS _throwIsAlreadyOpened isHidden shouldOverrideUrlLoading @@ -142,6 +149,13 @@ a InApp A [InApp + A `InApp + assets + Ui + postUrl + assert( + sNotEmpty() + loadData activity.getPreferences(0) @@ -183,11 +197,11 @@ - - + + @@ -203,6 +217,19 @@ + + + + + + + + + + + + + @@ -220,19 +247,6 @@ - - - - - - - - - - - - - @@ -401,9 +415,9 @@ - + - + @@ -586,13 +600,6 @@ - - - - - - - @@ -673,26 +680,58 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -705,40 +744,16 @@ - + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CHANGELOG.md b/CHANGELOG.md index 221309be..59f235d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.2 + +- fixed some missing `result.success()` on Android and iOS +- added `postUrl()` method for `InAppWebView` and `InAppBrowser` +- added `loadData()` method for `InAppWebView` and `InAppBrowser` + ## 0.5.1 - updated README.md diff --git a/README.md b/README.md index 73e3ddd0..d5e40cee 100644 --- a/README.md +++ b/README.md @@ -295,7 +295,6 @@ InAppWebView( } ``` - #### Future\ InAppWebViewController.loadUrl Loads the given `url` with optional `headers` specified as a map from name to value. @@ -304,6 +303,24 @@ Loads the given `url` with optional `headers` specified as a map from name to va inAppWebViewController.loadUrl(String url, {Map headers = const {}}); ``` +#### Future\ InAppWebViewController.postUrl + +Loads the given `url` with `postData` using `POST` method into this WebView. + +```dart +inAppWebViewController.postUrl(String url, Uint8List postData); +``` + +#### Future\ InAppWebViewController.loadData + +Loads the given `data` into this WebView, using `baseUrl` as the base URL for the content. +The `mimeType` parameter specifies the format of the data. +The `encoding` parameter specifies the encoding of the data. + +```dart +inAppWebViewController.loadData(String data, {String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank"}); +``` + #### Future\ InAppWebViewController.loadFile Loads the given `assetFilePath` with optional `headers` specified as a map from name to value. diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java index b73b671d..1dd633f3 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/FlutterWebView.java @@ -83,6 +83,25 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { else result.success(false); break; + case "postUrl": + if (webView != null) + webView.postUrl(call.argument("url").toString(), (byte[]) call.argument("postData"), result); + else + result.success(false); + break; + case "loadData": + { + String data = call.argument("data").toString(); + String mimeType = call.argument("mimeType").toString(); + String encoding = call.argument("encoding").toString(); + String baseUrl = call.argument("baseUrl").toString(); + + if (webView != null) + webView.loadData(data, mimeType, encoding, baseUrl, result); + else + result.success(false); + } + break; case "loadFile": if (webView != null) webView.loadFile(call.argument("url").toString(), (Map) call.argument("headers"), result); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java index b63ec76e..febbabf0 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserActivity.java @@ -180,6 +180,22 @@ public class InAppBrowserActivity extends AppCompatActivity { } } + public void postUrl(String url, byte[] postData, MethodChannel.Result result) { + if (webView != null) { + webView.postUrl(url, postData, result); + } else { + result.error(LOG_TAG, "Cannot load url " + url, null); + } + } + + public void loadData(String data, String mimeType, String encoding, String baseUrl, MethodChannel.Result result) { + if (webView != null) { + webView.loadData(data, mimeType, encoding, baseUrl, result); + } else { + result.error(LOG_TAG, "Cannot load data", null); + } + } + public void loadFile(String url, MethodChannel.Result result) { if (webView != null) { webView.loadFile(url, result); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java index fa0ac556..7c08780c 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java @@ -137,8 +137,7 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler { if (openWithSystemBrowser) { Log.d(LOG_TAG, "in system"); openExternal(url, result); - } - else { + } else { //Load the dialer if (url.startsWith(WebView.SCHEME_TEL)) { try { @@ -163,6 +162,18 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler { case "loadUrl": loadUrl(uuid, call.argument("url").toString(), (Map) call.argument("headers"), result); break; + case "postUrl": + postUrl(uuid, call.argument("url").toString(), (byte[]) call.argument("postData"), result); + break; + case "loadData": + { + String data = call.argument("data").toString(); + String mimeType = call.argument("mimeType").toString(); + String encoding = call.argument("encoding").toString(); + String baseUrl = call.argument("baseUrl").toString(); + loadData(uuid, data, mimeType, encoding, baseUrl, result); + } + break; case "loadFile": loadFile(uuid, call.argument("url").toString(), (Map) call.argument("headers"), result); break; @@ -393,6 +404,18 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler { } } + public void postUrl(String uuid, String url, byte[] postData, Result result) { + InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid); + if (inAppBrowserActivity != null) + inAppBrowserActivity.postUrl(url, postData, result); + } + + public void loadData(String uuid, String data, String mimeType, String encoding, String baseUrl, Result result) { + InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid); + if (inAppBrowserActivity != null) + inAppBrowserActivity.loadData(data, mimeType, encoding, baseUrl, result); + } + public void loadFile(String uuid, String url, Map headers, Result result) { InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid); if (inAppBrowserActivity != null) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java index 79fc739d..4b476c50 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebView.java @@ -183,7 +183,9 @@ public class InAppWebView extends WebView { loadUrl(url); } else { result.error(LOG_TAG, "url is empty", null); + return; } + result.success(true); } public void loadUrl(String url, Map headers, MethodChannel.Result result) { @@ -191,7 +193,24 @@ public class InAppWebView extends WebView { loadUrl(url, headers); } else { result.error(LOG_TAG, "url is empty", null); + return; } + result.success(true); + } + + public void postUrl(String url, byte[] postData, MethodChannel.Result result) { + if (!url.isEmpty()) { + postUrl(url, postData); + } else { + result.error(LOG_TAG, "url is empty", null); + return; + } + result.success(true); + } + + public void loadData(String data, String mimeType, String encoding, String baseUrl, MethodChannel.Result result) { + loadDataWithBaseURL(baseUrl, data, mimeType, encoding, null); + result.success(true); } public void loadFile(String url, MethodChannel.Result result) { @@ -206,7 +225,9 @@ public class InAppWebView extends WebView { loadUrl(url); } else { result.error(LOG_TAG, "url is empty", null); + return; } + result.success(true); } public void loadFile(String url, Map headers, MethodChannel.Result result) { @@ -221,7 +242,9 @@ public class InAppWebView extends WebView { loadUrl(url, headers); } else { result.error(LOG_TAG, "url is empty", null); + return; } + result.success(true); } public boolean isLoading() { diff --git a/example/lib/main.dart b/example/lib/main.dart index a306d1ed..c24d8d67 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'dart:convert' show base64; +import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_inappbrowser/flutter_inappbrowser.dart'; @@ -7,9 +7,9 @@ class MyInAppBrowser extends InAppBrowser { @override Future onLoadStart(String url) async { print("\n\nStarted $url\n\n"); - print("\n\n ${await this.isHidden()} \n\n"); - print(await this.webViewController.canGoBack()); - print(await this.webViewController.canGoForward()); +// print("\n\n ${await this.isHidden()} \n\n"); +// print(await this.webViewController.canGoBack()); +// print(await this.webViewController.canGoForward()); } @override @@ -105,7 +105,7 @@ class MyInAppBrowser extends InAppBrowser { @override void onProgressChanged(int progress) { - print("Progress: $progress"); +// print("Progress: $progress"); } @override @@ -117,6 +117,47 @@ class MyInAppBrowser extends InAppBrowser { void shouldOverrideUrlLoading(String url) { print("\n\n override $url\n\n"); this.webViewController.loadUrl(url); + +// var postData = "username=my_username&password=my_password"; +// inAppBrowserFallback.webViewController.postUrl("http://localhost:8080", utf8.encode(postData)); + +// var htmlData = """ +// +// +// +// +// +// +// Document +// +// +// +// +// +// +// +// +// +// +// One of three columns +// +// +// One of three columns +// +// +// One of three columns +// +// +// +// +// +// +// +// """; +// inAppBrowserFallback.webViewController.loadData(htmlData); } @override @@ -231,10 +272,10 @@ class _MyAppState extends State { // }); // await inAppBrowserFallback.open(url: "https://flutter.io/", options: { - "useOnLoadResource": true, + //"useOnLoadResource": true, //"hidden": true, //"toolbarTopFixedTitle": "Fixed title", - //"useShouldOverrideUrlLoading": true + "useShouldOverrideUrlLoading": true //"hideUrlBar": true, //"toolbarTop": false, //"toolbarBottom": false diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift index c2a5ce40..cb1daef3 100644 --- a/ios/Classes/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowserWebViewController.swift @@ -378,6 +378,34 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio webView.load(request) } + func loadData(data: String, mimeType: String, encoding: String, baseUrl: String) { + let url = URL(string: baseUrl)! + currentURL = url + if #available(iOS 9.0, *) { + webView.load(data.data(using: .utf8)!, mimeType: mimeType, characterEncodingName: encoding, baseURL: url) + } else { + webView.loadHTMLString(data, baseURL: url) + } + } + + func postUrl(url: URL, postData: Data, result: @escaping FlutterResult) { + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.httpBody = postData + + let task = URLSession.shared.dataTask(with: request) { (data : Data?, response : URLResponse?, error : Error?) in + var returnString = "" + if data != nil { + returnString = String(data: data!, encoding: .utf8) ?? "" + } + DispatchQueue.main.async(execute: {() -> Void in + self.webView.loadHTMLString(returnString, baseURL: url) + result(true) + }) + } + task.resume() + } + // Load user requested url func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift index cce85a0d..31d9a189 100644 --- a/ios/Classes/SwiftFlutterPlugin.swift +++ b/ios/Classes/SwiftFlutterPlugin.swift @@ -68,6 +68,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { case "loadUrl": self.loadUrl(uuid: uuid, arguments: arguments!, result: result) break + case "loadData": + self.loadData(uuid: uuid, arguments: arguments!, result: result) + break + case "postUrl": + self.postUrl(uuid: uuid, arguments: arguments!, result: result) + break case "loadFile": self.loadFile(uuid: uuid, arguments: arguments!, result: result) break @@ -384,10 +390,34 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { } else { result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil)) + return } result(true) } + public func loadData(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) { + let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController + let data = (arguments["data"] as? String)! + let mimeType = (arguments["mimeType"] as? String)! + let encoding = (arguments["encoding"] as? String)! + let baseUrl = (arguments["baseUrl"] as? String)! + webViewController.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl) + result(true) + } + + public func postUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) { + let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController + if let url = arguments["url"] as? String { + let postData = (arguments["postData"] as? FlutterStandardTypedData)! + let absoluteUrl = URL(string: url)!.absoluteURL + webViewController.postUrl(url: absoluteUrl, postData: postData.data, result: result) + } + else { + result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil)) + return + } + } + public func loadFile(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) { let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController if let url = arguments["url"] as? String { @@ -404,6 +434,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { } else { result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil)) + return } result(true) } @@ -458,6 +489,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { func open(inSystem url: URL, result: @escaping FlutterResult) { if !UIApplication.shared.canOpenURL(url) { result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url.absoluteString + " cannot be opened!", details: nil)) + return } else { if #available(iOS 10.0, *) { diff --git a/lib/flutter_inappbrowser.dart b/lib/flutter_inappbrowser.dart index 115682dc..4b410e60 100644 --- a/lib/flutter_inappbrowser.dart +++ b/lib/flutter_inappbrowser.dart @@ -189,7 +189,7 @@ class InAppBrowser { /// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`. /// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`. Future open({String url = "about:blank", Map headers = const {}, Map options = const {}}) async { - assert(url != null); + assert(url != null && url.isNotEmpty); this._throwIsAlreadyOpened(message: 'Cannot open $url!'); Map args = {}; args.putIfAbsent('uuid', () => uuid); @@ -233,7 +233,7 @@ class InAppBrowser { ///... ///``` Future openFile(String assetFilePath, {Map headers = const {}, Map options = const {}}) async { - assert(assetFilePath != null); + assert(assetFilePath != null && assetFilePath.isNotEmpty); this._throwIsAlreadyOpened(message: 'Cannot open $assetFilePath!'); Map args = {}; args.putIfAbsent('uuid', () => uuid); @@ -249,7 +249,7 @@ class InAppBrowser { ///This is a static method that opens an [url] in the system browser. You wont be able to use the [InAppBrowser] methods here! static Future openWithSystemBrowser(String url) async { - assert(url != null); + assert(url != null && url.isNotEmpty); Map args = {}; args.putIfAbsent('uuid', () => ""); args.putIfAbsent('url', () => url); @@ -441,7 +441,7 @@ class ChromeSafariBrowser { ///- __presentationStyle__: Set the custom modal presentation style when presenting the WebView. The default value is `0 //fullscreen`. See [UIModalPresentationStyle](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle) for all the available styles. ///- __transitionStyle__: Set to the custom transition style when presenting the WebView. The default value is `0 //crossDissolve`. See [UIModalTransitionStyle](https://developer.apple.com/documentation/uikit/uimodaltransitionStyle) for all the available styles. Future open(String url, {Map options = const {}, Map headersFallback = const {}, Map optionsFallback = const {}}) async { - assert(url != null); + assert(url != null && url.isNotEmpty); this._throwIsAlreadyOpened(message: 'Cannot open $url!'); Map args = {}; args.putIfAbsent('uuid', () => uuid); @@ -768,7 +768,7 @@ class InAppWebViewController { ///Loads the given [url] with optional [headers] specified as a map from name to value. Future loadUrl(String url, {Map headers = const {}}) async { - assert(url != null); + assert(url != null && url.isNotEmpty); Map args = {}; if (_inAppBrowserUuid != null) { _inAppBrowser._throwIsNotOpened(message: 'Cannot laod $url!'); @@ -779,6 +779,37 @@ class InAppWebViewController { await _channel.invokeMethod('loadUrl', args); } + ///Loads the given [url] with [postData] using `POST` method into this WebView. + Future postUrl(String url, Uint8List postData) async { + assert(url != null && url.isNotEmpty); + assert(postData != null); + Map args = {}; + if (_inAppBrowserUuid != null) { + _inAppBrowser._throwIsNotOpened(message: 'Cannot laod $url!'); + args.putIfAbsent('uuid', () => _inAppBrowserUuid); + } + args.putIfAbsent('url', () => url); + args.putIfAbsent('postData', () => postData); + await _channel.invokeMethod('postUrl', args); + } + + ///Loads the given [data] into this WebView, using [baseUrl] as the base URL for the content. + ///The [mimeType] parameter specifies the format of the data. + ///The [encoding] parameter specifies the encoding of the data. + Future loadData(String data, {String mimeType = "text/html", String encoding = "utf8", String baseUrl = "about:blank"}) async { + assert(data != null); + Map args = {}; + if (_inAppBrowserUuid != null) { + _inAppBrowser._throwIsNotOpened(); + args.putIfAbsent('uuid', () => _inAppBrowserUuid); + } + args.putIfAbsent('data', () => data); + args.putIfAbsent('mimeType', () => mimeType); + args.putIfAbsent('encoding', () => encoding); + args.putIfAbsent('baseUrl', () => baseUrl); + await _channel.invokeMethod('loadData', args); + } + ///Loads the given [assetFilePath] with optional [headers] specified as a map from name to value. /// ///To be able to load your local files (assets, js, css, etc.), you need to add them in the `assets` section of the `pubspec.yaml` file, otherwise they cannot be found! @@ -809,7 +840,7 @@ class InAppWebViewController { ///... ///``` Future loadFile(String assetFilePath, {Map headers = const {}}) async { - assert(assetFilePath != null); + assert(assetFilePath != null && assetFilePath.isNotEmpty); Map args = {}; if (_inAppBrowserUuid != null) { _inAppBrowser._throwIsNotOpened(message: 'Cannot laod $assetFilePath!'); @@ -1064,8 +1095,6 @@ class InAppLocalhostServer { } } - print(contentType); - request.response.headers.contentType = new ContentType(contentType[0], contentType[1], charset: 'utf-8'); request.response.add(body); request.response.close(); diff --git a/pubspec.yaml b/pubspec.yaml index 404aa960..93d2a649 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_inappbrowser description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser). -version: 0.5.1 +version: 0.5.2 author: Lorenzo Pichilli homepage: https://github.com/pichillilorenzo/flutter_inappbrowser