Commit 0e30767c authored by Lorenzo Pichilli's avatar Lorenzo Pichilli

code refactoring, added InAppBrowserManager and ChromeSafariBrowserManager...

code refactoring, added InAppBrowserManager and ChromeSafariBrowserManager classes on native code, updated webview options class names
parent 4d752ee9
...@@ -81,7 +81,7 @@ See the online [API Reference](https://pub.dartlang.org/documentation/flutter_in ...@@ -81,7 +81,7 @@ See the online [API Reference](https://pub.dartlang.org/documentation/flutter_in
The API showed in this `README.md` file shows only a part of the documentation that conforms to the master branch only. The API showed in this `README.md` file shows only a part of the documentation that conforms to the master branch only.
So, here you could have methods, options, and events that aren't published yet. So, here you could have methods, options, and events that aren't published yet.
If you need a specific version, change the **GitHub branch** to your version or use the **online API Reference** (recommended). If you need a specific version, change the **GitHub branch** to your version or use the **online API Reference** (recommended).
### Load a file inside `assets` folder ### Load a file inside `assets` folder
...@@ -530,8 +530,7 @@ class MyInAppBrowser extends InAppBrowser { ...@@ -530,8 +530,7 @@ class MyInAppBrowser extends InAppBrowser {
@override @override
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async { Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n"); print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n");
this.webViewController.loadUrl(url: shouldOverrideUrlLoadingRequest.url); return ShouldOverrideUrlLoadingAction.ALLOW;
return ShouldOverrideUrlLoadingAction.CANCEL;
} }
@override @override
......
...@@ -5,7 +5,6 @@ import android.content.Intent; ...@@ -5,7 +5,6 @@ import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsIntent; import androidx.browser.customtabs.CustomTabsIntent;
...@@ -14,16 +13,21 @@ import androidx.browser.customtabs.CustomTabsSession; ...@@ -14,16 +13,21 @@ import androidx.browser.customtabs.CustomTabsSession;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.R; import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ChromeCustomTabsActivity extends Activity { import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class ChromeCustomTabsActivity extends Activity implements MethodChannel.MethodCallHandler {
protected static final String LOG_TAG = "CustomTabsActivity"; protected static final String LOG_TAG = "CustomTabsActivity";
String uuid; public MethodChannel channel;
CustomTabsIntent.Builder builder; public String uuid;
ChromeCustomTabsOptions options; private CustomTabsIntent.Builder builder;
private ChromeCustomTabsOptions options;
private CustomTabActivityHelper customTabActivityHelper; private CustomTabActivityHelper customTabActivityHelper;
private CustomTabsSession customTabsSession; private CustomTabsSession customTabsSession;
private final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100; private final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
...@@ -39,13 +43,15 @@ public class ChromeCustomTabsActivity extends Activity { ...@@ -39,13 +43,15 @@ public class ChromeCustomTabsActivity extends Activity {
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
assert b != null; assert b != null;
uuid = b.getString("uuid"); uuid = b.getString("uuid");
channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid);
channel.setMethodCallHandler(this);
final String url = b.getString("url"); final String url = b.getString("url");
options = new ChromeCustomTabsOptions(); options = new ChromeCustomTabsOptions();
options.parse((HashMap<String, Object>) b.getSerializable("options")); options.parse((HashMap<String, Object>) b.getSerializable("options"));
InAppWebViewFlutterPlugin.inAppBrowser.chromeCustomTabsActivities.put(uuid, this);
final ChromeCustomTabsActivity chromeCustomTabsActivity = this; final ChromeCustomTabsActivity chromeCustomTabsActivity = this;
customTabActivityHelper = new CustomTabActivityHelper(); customTabActivityHelper = new CustomTabActivityHelper();
...@@ -68,7 +74,7 @@ public class ChromeCustomTabsActivity extends Activity { ...@@ -68,7 +74,7 @@ public class ChromeCustomTabsActivity extends Activity {
finish(); finish();
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", uuid); obj.put("uuid", uuid);
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserClosed", obj); channel.invokeMethod("onChromeSafariBrowserClosed", obj);
} }
}); });
...@@ -79,14 +85,14 @@ public class ChromeCustomTabsActivity extends Activity { ...@@ -79,14 +85,14 @@ public class ChromeCustomTabsActivity extends Activity {
onChromeSafariBrowserOpened = true; onChromeSafariBrowserOpened = true;
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", uuid); obj.put("uuid", uuid);
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserOpened", obj); channel.invokeMethod("onChromeSafariBrowserOpened", obj);
} }
if (navigationEvent == NAVIGATION_FINISHED && !onChromeSafariBrowserCompletedInitialLoad) { if (navigationEvent == NAVIGATION_FINISHED && !onChromeSafariBrowserCompletedInitialLoad) {
onChromeSafariBrowserCompletedInitialLoad = true; onChromeSafariBrowserCompletedInitialLoad = true;
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", uuid); obj.put("uuid", uuid);
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", obj); channel.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", obj);
} }
} }
...@@ -113,6 +119,14 @@ public class ChromeCustomTabsActivity extends Activity { ...@@ -113,6 +119,14 @@ public class ChromeCustomTabsActivity extends Activity {
}); });
} }
@Override
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
switch (call.method) {
default:
result.notImplemented();
}
}
private void prepareCustomTabs(CustomTabsIntent customTabsIntent) { private void prepareCustomTabs(CustomTabsIntent customTabsIntent) {
if (options.addDefaultShareMenuItem) if (options.addDefaultShareMenuItem)
builder.addDefaultShareMenuItem(); builder.addDefaultShareMenuItem();
...@@ -155,7 +169,7 @@ public class ChromeCustomTabsActivity extends Activity { ...@@ -155,7 +169,7 @@ public class ChromeCustomTabsActivity extends Activity {
finish(); finish();
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", uuid); obj.put("uuid", uuid);
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserClosed", obj); InAppWebViewFlutterPlugin.inAppBrowserManager.channel.invokeMethod("onChromeSafariBrowserClosed", obj);
} }
} }
......
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ChromeCustomTabsActivity;
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CustomTabActivityHelper;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "ChromeBrowserManager";
public ChromeSafariBrowserManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_chromesafaribrowser");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
final Activity activity = Shared.activity;
final String uuid = (String) call.argument("uuid");
switch (call.method) {
case "open":
{
String url = (String) call.argument("url");
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
String uuidFallback = (String) call.argument("uuidFallback");
Map<String, String> headersFallback = (Map<String, String>) call.argument("headersFallback");
HashMap<String, Object> optionsFallback = (HashMap<String, Object>) call.argument("optionsFallback");
open(activity, uuid, url, options, uuidFallback, headersFallback, optionsFallback, result);
}
break;
default:
result.notImplemented();
}
}
public void open(Activity activity, String uuid, String url, HashMap<String, Object> options, String uuidFallback, Map<String, String> headersFallback, HashMap<String, Object> optionsFallback, MethodChannel.Result result) {
Intent intent = null;
Bundle extras = new Bundle();
extras.putString("fromActivity", activity.getClass().getName());
extras.putString("url", url);
extras.putBoolean("isData", false);
extras.putString("uuid", uuid);
extras.putSerializable("options", options);
extras.putSerializable("headers", (Serializable) headersFallback);
if (CustomTabActivityHelper.isAvailable(activity)) {
intent = new Intent(activity, ChromeCustomTabsActivity.class);
}
// check for webview fallback
else if (!CustomTabActivityHelper.isAvailable(activity) && !uuidFallback.isEmpty()) {
Log.d(LOG_TAG, "WebView fallback declared.");
// overwrite with extras fallback parameters
extras.putString("uuid", uuidFallback);
if (optionsFallback != null)
extras.putSerializable("options", optionsFallback);
else
extras.putSerializable("options", (new InAppBrowserOptions()).getHashMap());
intent = new Intent(activity, InAppBrowserActivity.class);
}
if (intent != null) {
intent.putExtras(extras);
activity.startActivity(intent);
result.success(true);
return;
}
result.error(LOG_TAG, "No WebView fallback declared.", null);
}
public void dispose() {
channel.setMethodCallHandler(null);
}
}
...@@ -38,6 +38,9 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { ...@@ -38,6 +38,9 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
public final MethodChannel channel; public final MethodChannel channel;
public FlutterWebView(BinaryMessenger messenger, final Context context, int id, HashMap<String, Object> params, View containerView) { public FlutterWebView(BinaryMessenger messenger, final Context context, int id, HashMap<String, Object> params, View containerView) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy(); DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
displayListenerProxy.onPreWebViewInitialization(displayManager); displayListenerProxy.onPreWebViewInitialization(displayManager);
...@@ -70,9 +73,6 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { ...@@ -70,9 +73,6 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
webView.prepare(); webView.prepare();
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
if (initialFile != null) { if (initialFile != null) {
try { try {
initialUrl = Util.getUrlAsset(initialFile); initialUrl = Util.getUrlAsset(initialFile);
......
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Parcelable;
import android.provider.Browser;
import android.net.Uri;
import android.os.Bundle;
import android.webkit.MimeTypeMap;
import android.util.Log;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.Result;
/**
* InAppBrowserManager
*/
public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "InAppBrowserManager";
public InAppBrowserManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappbrowser");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(final MethodCall call, final Result result) {
final Activity activity = Shared.activity;
final String uuid = (String) call.argument("uuid");
switch (call.method) {
case "openUrl":
{
String url = (String) call.argument("url");
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
Map<String, String> headers = (Map<String, String>) call.argument("headers");
openUrl(activity, uuid, url, options, headers);
}
result.success(true);
break;
case "openFile":
{
String url = (String) call.argument("url");
try {
url = Util.getUrlAsset(url);
} catch (IOException e) {
e.printStackTrace();
result.error(LOG_TAG, url + " asset file cannot be found!", e);
return;
}
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
Map<String, String> headers = (Map<String, String>) call.argument("headers");
openUrl(activity, uuid, url, options, headers);
}
result.success(true);
break;
case "openData":
{
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
String data = (String) call.argument("data");
String mimeType = (String) call.argument("mimeType");
String encoding = (String) call.argument("encoding");
String baseUrl = (String) call.argument("baseUrl");
String historyUrl = (String) call.argument("historyUrl");
openData(activity, uuid, options, data, mimeType, encoding, baseUrl, historyUrl);
}
result.success(true);
break;
case "openWithSystemBrowser":
{
String url = (String) call.argument("url");
openWithSystemBrowser(activity, url, result);
}
break;
default:
result.notImplemented();
}
}
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
/**
* Display a new browser with the specified URL.
*
* @param url the url to load.
* @param result
* @return "" if ok, or error message.
*/
public void openWithSystemBrowser(Activity activity, String url, Result result) {
try {
Intent intent;
intent = new Intent(Intent.ACTION_VIEW);
// Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
// Adding the MIME type to http: URLs causes them to not be handled by the downloader.
Uri uri = Uri.parse(url);
if ("file".equals(uri.getScheme())) {
intent.setDataAndType(uri, getMimeType(url));
} else {
intent.setData(uri);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
// CB-10795: Avoid circular loops by preventing it from opening in the current app
this.openExternalExcludeCurrentApp(activity, intent);
result.success(true);
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) {
Log.d(LOG_TAG, url + " cannot be opened: " + e.toString());
result.error(LOG_TAG, url + " cannot be opened!", null);
}
}
/**
* Opens the intent, providing a chooser that excludes the current app to avoid
* circular loops.
*/
public void openExternalExcludeCurrentApp(Activity activity, Intent intent) {
String currentPackage = activity.getPackageName();
boolean hasCurrentPackage = false;
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
ArrayList<Intent> targetIntents = new ArrayList<Intent>();
for (ResolveInfo ri : activities) {
if (!currentPackage.equals(ri.activityInfo.packageName)) {
Intent targetIntent = (Intent) intent.clone();
targetIntent.setPackage(ri.activityInfo.packageName);
targetIntents.add(targetIntent);
} else {
hasCurrentPackage = true;
}
}
// If the current app package isn't a target for this URL, then use
// the normal launch behavior
if (!hasCurrentPackage || targetIntents.size() == 0) {
activity.startActivity(intent);
}
// If there's only one possible intent, launch it directly
else if (targetIntents.size() == 1) {
activity.startActivity(targetIntents.get(0));
}
// Otherwise, show a custom chooser without the current app listed
else if (targetIntents.size() > 0) {
Intent chooser = Intent.createChooser(targetIntents.remove(targetIntents.size() - 1), null);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
activity.startActivity(chooser);
}
}
public void openUrl(Activity activity, String uuid, String url, HashMap<String, Object> options, Map<String, String> headers) {
Bundle extras = new Bundle();
extras.putString("fromActivity", activity.getClass().getName());
extras.putString("url", url);
extras.putBoolean("isData", false);
extras.putString("uuid", uuid);
extras.putSerializable("options", options);
extras.putSerializable("headers", (Serializable) headers);
startInAppBrowserActivity(activity, extras);
}
public void openData(Activity activity, String uuid, HashMap<String, Object> options, String data, String mimeType, String encoding, String baseUrl, String historyUrl) {
Bundle extras = new Bundle();
extras.putBoolean("isData", true);
extras.putString("uuid", uuid);
extras.putSerializable("options", options);
extras.putString("data", data);
extras.putString("mimeType", mimeType);
extras.putString("encoding", encoding);
extras.putString("baseUrl", baseUrl);
extras.putString("historyUrl", historyUrl);
startInAppBrowserActivity(activity, extras);
}
public void startInAppBrowserActivity(Activity activity, Bundle extras) {
Intent intent = new Intent(activity, InAppBrowserActivity.class);
if (extras != null)
intent.putExtras(extras);
activity.startActivity(intent);
}
public void dispose() {
channel.setMethodCallHandler(null);
}
}
package com.pichillilorenzo.flutter_inappwebview.InAppWebView; package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
...@@ -21,13 +19,8 @@ import android.webkit.WebBackForwardList; ...@@ -21,13 +19,8 @@ import android.webkit.WebBackForwardList;
import android.webkit.WebHistoryItem; import android.webkit.WebHistoryItem;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebStorage; import android.webkit.WebStorage;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlocker; import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlocker;
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerAction; import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerAction;
...@@ -37,7 +30,6 @@ import com.pichillilorenzo.flutter_inappwebview.FlutterWebView; ...@@ -37,7 +30,6 @@ import com.pichillilorenzo.flutter_inappwebview.FlutterWebView;
import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity; import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface; import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared; import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util; import com.pichillilorenzo.flutter_inappwebview.Util;
...@@ -50,7 +42,6 @@ import java.util.Map; ...@@ -50,7 +42,6 @@ import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.fromValue; import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.fromValue;
...@@ -61,6 +52,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -61,6 +52,7 @@ final public class InAppWebView extends InputAwareWebView {
public InAppBrowserActivity inAppBrowserActivity; public InAppBrowserActivity inAppBrowserActivity;
public FlutterWebView flutterWebView; public FlutterWebView flutterWebView;
public MethodChannel channel;
public int id; public int id;
public InAppWebViewClient inAppWebViewClient; public InAppWebViewClient inAppWebViewClient;
public InAppWebViewChromeClient inAppWebViewChromeClient; public InAppWebViewChromeClient inAppWebViewChromeClient;
...@@ -123,7 +115,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -123,7 +115,7 @@ final public class InAppWebView extends InputAwareWebView {
static final String interceptAjaxRequestsJS = "(function(ajax) {" + static final String interceptAjaxRequestsJS = "(function(ajax) {" +
" var send = ajax.prototype.send;" + " var send = ajax.prototype.send;" +
" var open = ajax.prototype.open;" + " var openUrl = ajax.prototype.openUrl;" +
" var setRequestHeader = ajax.prototype.setRequestHeader;" + " var setRequestHeader = ajax.prototype.setRequestHeader;" +
" ajax.prototype._flutter_inappwebview_url = null;" + " ajax.prototype._flutter_inappwebview_url = null;" +
" ajax.prototype._flutter_inappwebview_method = null;" + " ajax.prototype._flutter_inappwebview_method = null;" +
...@@ -156,7 +148,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -156,7 +148,7 @@ final public class InAppWebView extends InputAwareWebView {
" }" + " }" +
" callback(null);" + " callback(null);" +
" };" + " };" +
" ajax.prototype.open = function(method, url, isAsync, user, password) {" + " ajax.prototype.openUrl = function(method, url, isAsync, user, password) {" +
" isAsync = (isAsync != null) ? isAsync : true;" + " isAsync = (isAsync != null) ? isAsync : true;" +
" this._flutter_inappwebview_url = url;" + " this._flutter_inappwebview_url = url;" +
" this._flutter_inappwebview_method = method;" + " this._flutter_inappwebview_method = method;" +
...@@ -164,7 +156,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -164,7 +156,7 @@ final public class InAppWebView extends InputAwareWebView {
" this._flutter_inappwebview_user = user;" + " this._flutter_inappwebview_user = user;" +
" this._flutter_inappwebview_password = password;" + " this._flutter_inappwebview_password = password;" +
" this._flutter_inappwebview_request_headers = {};" + " this._flutter_inappwebview_request_headers = {};" +
" open.call(this, method, url, isAsync, user, password);" + " openUrl.call(this, method, url, isAsync, user, password);" +
" };" + " };" +
" ajax.prototype.setRequestHeader = function(header, value) {" + " ajax.prototype.setRequestHeader = function(header, value) {" +
" this._flutter_inappwebview_request_headers[header] = value;" + " this._flutter_inappwebview_request_headers[header] = value;" +
...@@ -319,7 +311,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -319,7 +311,7 @@ final public class InAppWebView extends InputAwareWebView {
" };" + " };" +
" if ((self._flutter_inappwebview_method != result.method && result.method != null) || (self._flutter_inappwebview_url != result.url && result.url != null)) {" + " if ((self._flutter_inappwebview_method != result.method && result.method != null) || (self._flutter_inappwebview_url != result.url && result.url != null)) {" +
" self.abort();" + " self.abort();" +
" self.open(result.method, result.url, result.isAsync, result.user, result.password);" + " self.openUrl(result.method, result.url, result.isAsync, result.user, result.password);" +
" return;" + " return;" +
" }" + " }" +
" }" + " }" +
...@@ -532,6 +524,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -532,6 +524,7 @@ final public class InAppWebView extends InputAwareWebView {
this.inAppBrowserActivity = (InAppBrowserActivity) obj; this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView) else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj; this.flutterWebView = (FlutterWebView) obj;
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
this.id = id; this.id = id;
this.options = options; this.options = options;
} }
...@@ -689,7 +682,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -689,7 +682,7 @@ final public class InAppWebView extends InputAwareWebView {
obj.put("activeMatchOrdinal", activeMatchOrdinal); obj.put("activeMatchOrdinal", activeMatchOrdinal);
obj.put("numberOfMatches", numberOfMatches); obj.put("numberOfMatches", numberOfMatches);
obj.put("isDoneCounting", isDoneCounting); obj.put("isDoneCounting", isDoneCounting);
getChannel().invokeMethod("onFindResultReceived", obj); channel.invokeMethod("onFindResultReceived", obj);
} }
}); });
...@@ -1264,11 +1257,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -1264,11 +1257,7 @@ final public class InAppWebView extends InputAwareWebView {
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("x", x); obj.put("x", x);
obj.put("y", y); obj.put("y", y);
getChannel().invokeMethod("onScrollChanged", obj); channel.invokeMethod("onScrollChanged", obj);
}
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
} }
public void startSafeBrowsing(final MethodChannel.Result result) { public void startSafeBrowsing(final MethodChannel.Result result) {
...@@ -1304,7 +1293,7 @@ final public class InAppWebView extends InputAwareWebView { ...@@ -1304,7 +1293,7 @@ final public class InAppWebView extends InputAwareWebView {
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("url", url); obj.put("url", url);
getChannel().invokeMethod("onDownloadStart", obj); channel.invokeMethod("onDownloadStart", obj);
} }
} }
......
...@@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview.InAppWebView; ...@@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
...@@ -33,7 +32,6 @@ import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity; ...@@ -33,7 +32,6 @@ import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.R; import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared; import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -52,6 +50,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -52,6 +50,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
protected static final String LOG_TAG = "IABWebChromeClient"; protected static final String LOG_TAG = "IABWebChromeClient";
private FlutterWebView flutterWebView; private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity; private InAppBrowserActivity inAppBrowserActivity;
public MethodChannel channel;
private ValueCallback<Uri> mUploadMessage; private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1; private final static int FILECHOOSER_RESULTCODE = 1;
...@@ -65,6 +64,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -65,6 +64,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
this.inAppBrowserActivity = (InAppBrowserActivity) obj; this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView) else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj; this.flutterWebView = (FlutterWebView) obj;
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
if (Shared.registrar != null) if (Shared.registrar != null)
Shared.registrar.addActivityResultListener(this); Shared.registrar.addActivityResultListener(this);
...@@ -121,7 +121,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -121,7 +121,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("message", message); obj.put("message", message);
getChannel().invokeMethod("onJsAlert", obj, new MethodChannel.Result() { channel.invokeMethod("onJsAlert", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
String responseMessage = null; String responseMessage = null;
...@@ -204,7 +204,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -204,7 +204,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("message", message); obj.put("message", message);
getChannel().invokeMethod("onJsConfirm", obj, new MethodChannel.Result() { channel.invokeMethod("onJsConfirm", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
String responseMessage = null; String responseMessage = null;
...@@ -301,7 +301,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -301,7 +301,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
obj.put("message", message); obj.put("message", message);
obj.put("defaultValue", defaultValue); obj.put("defaultValue", defaultValue);
getChannel().invokeMethod("onJsPrompt", obj, new MethodChannel.Result() { channel.invokeMethod("onJsPrompt", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
String responseMessage = null; String responseMessage = null;
...@@ -433,7 +433,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -433,7 +433,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
super.onPageStarted(v, url, favicon); super.onPageStarted(v, url, favicon);
obj.put("url", url); obj.put("url", url);
getChannel().invokeMethod("onCreateWindow", obj); channel.invokeMethod("onCreateWindow", obj);
// stop webview loading // stop webview loading
v.stopLoading(); v.stopLoading();
...@@ -449,7 +449,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -449,7 +449,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
} }
obj.put("url", data); obj.put("url", data);
getChannel().invokeMethod("onCreateWindow", obj); channel.invokeMethod("onCreateWindow", obj);
return false; return false;
} }
...@@ -459,7 +459,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -459,7 +459,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("origin", origin); obj.put("origin", origin);
getChannel().invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() { channel.invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object o) { public void success(Object o) {
Map<String, Object> response = (Map<String, Object>) o; Map<String, Object> response = (Map<String, Object>) o;
...@@ -486,7 +486,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -486,7 +486,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
getChannel().invokeMethod("onGeolocationPermissionsHidePrompt", obj); channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj);
} }
@Override @Override
...@@ -496,7 +496,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -496,7 +496,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("message", consoleMessage.message()); obj.put("message", consoleMessage.message());
obj.put("messageLevel", consoleMessage.messageLevel().ordinal()); obj.put("messageLevel", consoleMessage.messageLevel().ordinal());
getChannel().invokeMethod("onConsoleMessage", obj); channel.invokeMethod("onConsoleMessage", obj);
return true; return true;
} }
...@@ -518,7 +518,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -518,7 +518,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("progress", progress); obj.put("progress", progress);
getChannel().invokeMethod("onProgressChanged", obj); channel.invokeMethod("onProgressChanged", obj);
super.onProgressChanged(view, progress); super.onProgressChanged(view, progress);
} }
...@@ -608,7 +608,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -608,7 +608,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("origin", request.getOrigin().toString()); obj.put("origin", request.getOrigin().toString());
obj.put("resources", Arrays.asList(request.getResources())); obj.put("resources", Arrays.asList(request.getResources()));
getChannel().invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() { channel.invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -646,8 +646,4 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR ...@@ -646,8 +646,4 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}); });
} }
} }
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
}
} }
...@@ -17,7 +17,6 @@ import android.webkit.SslErrorHandler; ...@@ -17,7 +17,6 @@ import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import android.webkit.WebResourceRequest; import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse; import android.webkit.WebResourceResponse;
import android.webkit.WebStorage;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
...@@ -53,6 +52,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -53,6 +52,7 @@ public class InAppWebViewClient extends WebViewClient {
protected static final String LOG_TAG = "IABWebViewClient"; protected static final String LOG_TAG = "IABWebViewClient";
private FlutterWebView flutterWebView; private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity; private InAppBrowserActivity inAppBrowserActivity;
public MethodChannel channel;
private static int previousAuthRequestFailureCount = 0; private static int previousAuthRequestFailureCount = 0;
private static List<Credential> credentialsProposed = null; private static List<Credential> credentialsProposed = null;
...@@ -62,6 +62,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -62,6 +62,7 @@ public class InAppWebViewClient extends WebViewClient {
this.inAppBrowserActivity = (InAppBrowserActivity) obj; this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView) else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj; this.flutterWebView = (FlutterWebView) obj;
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
} }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @TargetApi(Build.VERSION_CODES.LOLLIPOP)
...@@ -125,7 +126,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -125,7 +126,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("androidHasGesture", hasGesture); obj.put("androidHasGesture", hasGesture);
obj.put("androidIsRedirect", isRedirect); obj.put("androidIsRedirect", isRedirect);
obj.put("iosWKNavigationType", null); obj.put("iosWKNavigationType", null);
getChannel().invokeMethod("shouldOverrideUrlLoading", obj, new MethodChannel.Result() { channel.invokeMethod("shouldOverrideUrlLoading", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -199,7 +200,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -199,7 +200,7 @@ public class InAppWebViewClient extends WebViewClient {
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("url", url); obj.put("url", url);
getChannel().invokeMethod("onLoadStart", obj); channel.invokeMethod("onLoadStart", obj);
} }
...@@ -212,7 +213,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -212,7 +213,7 @@ public class InAppWebViewClient extends WebViewClient {
previousAuthRequestFailureCount = 0; previousAuthRequestFailureCount = 0;
credentialsProposed = null; credentialsProposed = null;
// CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage // CB-10395 InAppBrowserManager's WebView not storing cookies reliable to local device storage
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush(); CookieManager.getInstance().flush();
} else { } else {
...@@ -235,7 +236,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -235,7 +236,7 @@ public class InAppWebViewClient extends WebViewClient {
if (inAppBrowserActivity != null) if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("url", url); obj.put("url", url);
getChannel().invokeMethod("onLoadStop", obj); channel.invokeMethod("onLoadStop", obj);
} }
@Override @Override
...@@ -245,7 +246,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -245,7 +246,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("uuid", inAppBrowserActivity.uuid); obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("url", url); obj.put("url", url);
obj.put("androidIsReload", isReload); obj.put("androidIsReload", isReload);
getChannel().invokeMethod("onUpdateVisitedHistory", obj); channel.invokeMethod("onUpdateVisitedHistory", obj);
super.doUpdateVisitedHistory(view, url, isReload); super.doUpdateVisitedHistory(view, url, isReload);
} }
...@@ -264,7 +265,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -264,7 +265,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("url", failingUrl); obj.put("url", failingUrl);
obj.put("code", errorCode); obj.put("code", errorCode);
obj.put("message", description); obj.put("message", description);
getChannel().invokeMethod("onLoadError", obj); channel.invokeMethod("onLoadError", obj);
} }
@RequiresApi(api = Build.VERSION_CODES.M) @RequiresApi(api = Build.VERSION_CODES.M)
...@@ -278,7 +279,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -278,7 +279,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("url", request.getUrl().toString()); obj.put("url", request.getUrl().toString());
obj.put("statusCode", errorResponse.getStatusCode()); obj.put("statusCode", errorResponse.getStatusCode());
obj.put("description", errorResponse.getReasonPhrase()); obj.put("description", errorResponse.getReasonPhrase());
getChannel().invokeMethod("onLoadHttpError", obj); channel.invokeMethod("onLoadHttpError", obj);
} }
} }
...@@ -316,7 +317,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -316,7 +317,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("port", port); obj.put("port", port);
obj.put("previousFailureCount", previousAuthRequestFailureCount); obj.put("previousFailureCount", previousAuthRequestFailureCount);
getChannel().invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() { channel.invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -461,7 +462,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -461,7 +462,7 @@ public class InAppWebViewClient extends WebViewClient {
Log.d(LOG_TAG, obj.toString()); Log.d(LOG_TAG, obj.toString());
getChannel().invokeMethod("onReceivedServerTrustAuthRequest", obj, new MethodChannel.Result() { channel.invokeMethod("onReceivedServerTrustAuthRequest", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -520,7 +521,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -520,7 +521,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("realm", realm); obj.put("realm", realm);
obj.put("port", request.getPort()); obj.put("port", request.getPort());
getChannel().invokeMethod("onReceivedClientCertRequest", obj, new MethodChannel.Result() { channel.invokeMethod("onReceivedClientCertRequest", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -579,7 +580,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -579,7 +580,7 @@ public class InAppWebViewClient extends WebViewClient {
obj.put("url", request.getUrl().toString()); obj.put("url", request.getUrl().toString());
obj.put("threatType", threatType); obj.put("threatType", threatType);
getChannel().invokeMethod("onSafeBrowsingHit", obj, new MethodChannel.Result() { channel.invokeMethod("onSafeBrowsingHit", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object response) { public void success(Object response) {
if (response != null) { if (response != null) {
...@@ -652,7 +653,7 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -652,7 +653,7 @@ public class InAppWebViewClient extends WebViewClient {
Util.WaitFlutterResult flutterResult; Util.WaitFlutterResult flutterResult;
try { try {
flutterResult = Util.invokeMethodAndWait(getChannel(), "onLoadResourceCustomScheme", obj); flutterResult = Util.invokeMethodAndWait(channel, "onLoadResourceCustomScheme", obj);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
Log.e(LOG_TAG, e.getMessage()); Log.e(LOG_TAG, e.getMessage());
...@@ -701,9 +702,4 @@ public class InAppWebViewClient extends WebViewClient { ...@@ -701,9 +702,4 @@ public class InAppWebViewClient extends WebViewClient {
public void onUnhandledKeyEvent(WebView view, KeyEvent event) { public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
} }
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
}
} }
...@@ -4,7 +4,6 @@ import android.app.Activity; ...@@ -4,7 +4,6 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityAware;
...@@ -19,7 +18,8 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { ...@@ -19,7 +18,8 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
protected static final String LOG_TAG = "InAppWebViewFlutterPL"; protected static final String LOG_TAG = "InAppWebViewFlutterPL";
public static InAppBrowser inAppBrowser; public static InAppBrowserManager inAppBrowserManager;
public static ChromeSafariBrowserManager chromeSafariBrowserManager;
public static InAppWebViewStatic inAppWebViewStatic; public static InAppWebViewStatic inAppWebViewStatic;
public static MyCookieManager myCookieManager; public static MyCookieManager myCookieManager;
public static CredentialDatabaseHandler credentialDatabaseHandler; public static CredentialDatabaseHandler credentialDatabaseHandler;
...@@ -46,8 +46,10 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { ...@@ -46,8 +46,10 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) { private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
Shared.applicationContext = applicationContext; Shared.applicationContext = applicationContext;
Shared.activity = activity; Shared.activity = activity;
Shared.messenger = messenger;
inAppBrowser = new InAppBrowser(messenger); inAppBrowserManager = new InAppBrowserManager(messenger);
chromeSafariBrowserManager = new ChromeSafariBrowserManager(messenger);
platformViewRegistry.registerViewFactory( platformViewRegistry.registerViewFactory(
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView)); "com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView));
...@@ -61,9 +63,13 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { ...@@ -61,9 +63,13 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
@Override @Override
public void onDetachedFromEngine(FlutterPluginBinding binding) { public void onDetachedFromEngine(FlutterPluginBinding binding) {
if (inAppBrowser != null) { if (inAppBrowserManager != null) {
inAppBrowser.dispose(); inAppBrowserManager.dispose();
inAppBrowser = null; inAppBrowserManager = null;
}
if (chromeSafariBrowserManager != null) {
chromeSafariBrowserManager.dispose();
chromeSafariBrowserManager = null;
} }
if (myCookieManager != null) { if (myCookieManager != null) {
myCookieManager.dispose(); myCookieManager.dispose();
......
...@@ -9,13 +9,7 @@ import android.webkit.ValueCallback; ...@@ -9,13 +9,7 @@ import android.webkit.ValueCallback;
import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView; import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
...@@ -25,6 +19,7 @@ public class JavaScriptBridgeInterface { ...@@ -25,6 +19,7 @@ public class JavaScriptBridgeInterface {
public static final String name = "flutter_inappwebview"; public static final String name = "flutter_inappwebview";
private FlutterWebView flutterWebView; private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity; private InAppBrowserActivity inAppBrowserActivity;
public MethodChannel channel;
// https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js // https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js
public static final String promisePolyfillJS = "if (window.Promise == null) {" + public static final String promisePolyfillJS = "if (window.Promise == null) {" +
...@@ -254,6 +249,7 @@ public class JavaScriptBridgeInterface { ...@@ -254,6 +249,7 @@ public class JavaScriptBridgeInterface {
this.inAppBrowserActivity = (InAppBrowserActivity) obj; this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView) else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj; this.flutterWebView = (FlutterWebView) obj;
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
} }
@JavascriptInterface @JavascriptInterface
...@@ -277,7 +273,7 @@ public class JavaScriptBridgeInterface { ...@@ -277,7 +273,7 @@ public class JavaScriptBridgeInterface {
webView.printCurrentPage(); webView.printCurrentPage();
} }
getChannel().invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() { channel.invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() {
@Override @Override
public void success(Object json) { public void success(Object json) {
if (webView == null) { if (webView == null) {
...@@ -305,8 +301,4 @@ public class JavaScriptBridgeInterface { ...@@ -305,8 +301,4 @@ public class JavaScriptBridgeInterface {
} }
}); });
} }
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
}
} }
...@@ -5,11 +5,13 @@ import android.content.Context; ...@@ -5,11 +5,13 @@ import android.content.Context;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
public class Shared { public class Shared {
public static Context applicationContext; public static Context applicationContext;
public static PluginRegistry.Registrar registrar; public static PluginRegistry.Registrar registrar;
public static BinaryMessenger messenger;
public static FlutterPlugin.FlutterAssets flutterAssets; public static FlutterPlugin.FlutterAssets flutterAssets;
public static ActivityPluginBinding activityPluginBinding; public static ActivityPluginBinding activityPluginBinding;
public static Activity activity; public static Activity activity;
......
...@@ -196,10 +196,9 @@ ...@@ -196,10 +196,9 @@
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
English,
en, en,
Base, Base,
); );
......
...@@ -38,9 +38,8 @@ class MyInAppBrowser extends InAppBrowser { ...@@ -38,9 +38,8 @@ class MyInAppBrowser extends InAppBrowser {
@override @override
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async { Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n"); print("\n\nOverride ${shouldOverrideUrlLoadingRequest.url}\n\n");
this.webViewController.loadUrl(url: shouldOverrideUrlLoadingRequest.url); return ShouldOverrideUrlLoadingAction.ALLOW;
return ShouldOverrideUrlLoadingAction.CANCEL;
} }
@override @override
...@@ -87,14 +86,15 @@ class _InAppBrowserExampleScreenState extends State<InAppBrowserExampleScreen> { ...@@ -87,14 +86,15 @@ class _InAppBrowserExampleScreenState extends State<InAppBrowserExampleScreen> {
drawer: myDrawer(context: context), drawer: myDrawer(context: context),
body: Center( body: Center(
child: RaisedButton( child: RaisedButton(
onPressed: () { onPressed: () async {
widget.browser.openFile( await widget.browser.openFile(
assetFilePath: "assets/index.html", assetFilePath: "assets/index.html",
options: InAppBrowserClassOptions( options: InAppBrowserClassOptions(
inAppWebViewWidgetOptions: InAppWebViewWidgetOptions( inAppWebViewWidgetOptions: InAppWebViewWidgetOptions(
crossPlatform: InAppWebViewOptions( crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true, debuggingEnabled: true,
useOnLoadResource: true, useShouldOverrideUrlLoading: true,
useOnLoadResource: true,
)))); ))));
}, },
child: Text("Open Webview Browser")), child: Text("Open Webview Browser")),
......
...@@ -59,6 +59,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> { ...@@ -59,6 +59,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
), ),
onWebViewCreated: (InAppWebViewController controller) { onWebViewCreated: (InAppWebViewController controller) {
webView = controller; webView = controller;
print("onWebViewCreated");
}, },
onLoadStart: (InAppWebViewController controller, String url) { onLoadStart: (InAppWebViewController controller, String url) {
print("onLoadStart $url"); print("onLoadStart $url");
...@@ -71,6 +72,29 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> { ...@@ -71,6 +72,29 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
setState(() { setState(() {
this.url = url; this.url = url;
}); });
/*var origins = await WebStorageManager.instance().android.getOrigins();
for (var origin in origins) {
print(origin);
print(await WebStorageManager.instance().android.getQuotaForOrigin(origin: origin.origin));
print(await WebStorageManager.instance().android.getUsageForOrigin(origin: origin.origin));
}
await WebStorageManager.instance().android.deleteAllData();
print("\n\nDELETED\n\n");
origins = await WebStorageManager.instance().android.getOrigins();
for (var origin in origins) {
print(origin);
await WebStorageManager.instance().android.deleteOrigin(origin: origin.origin);
}*/
/*var records = await WebStorageManager.instance().ios.fetchDataRecords(dataTypes: IOSWKWebsiteDataType.ALL);
for(var record in records) {
print(record);
}
await WebStorageManager.instance().ios.removeDataModifiedSince(dataTypes: IOSWKWebsiteDataType.ALL, date: DateTime(0));
print("\n\nDELETED\n\n");
records = await WebStorageManager.instance().ios.fetchDataRecords(dataTypes: IOSWKWebsiteDataType.ALL);
for(var record in records) {
print(record);
}*/
}, },
onProgressChanged: (InAppWebViewController controller, int progress) { onProgressChanged: (InAppWebViewController controller, int progress) {
setState(() { setState(() {
......
//
// ChromeSafariBrowserManager.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 18/12/2019.
//
import Flutter
import UIKit
import WebKit
import Foundation
import AVFoundation
import SafariServices
public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
static var registrar: FlutterPluginRegistrar?
static var channel: FlutterMethodChannel?
var tmpWindow: UIWindow?
private var previousStatusBarStyle = -1
public static func register(with registrar: FlutterPluginRegistrar) {
}
init(registrar: FlutterPluginRegistrar) {
super.init()
ChromeSafariBrowserManager.registrar = registrar
ChromeSafariBrowserManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(self, channel: ChromeSafariBrowserManager.channel!)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? NSDictionary
let uuid: String = arguments!["uuid"] as! String
switch call.method {
case "open":
let url = arguments!["url"] as! String
let options = arguments!["options"] as! [String: Any?]
let uuidFallback: String = arguments!["uuidFallback"] as! String
let headersFallback = arguments!["headersFallback"] as! [String: String]
let optionsFallback = arguments!["optionsFallback"] as! [String: Any?]
open(uuid: uuid, url: url, options: options, uuidFallback: uuidFallback, headersFallback: headersFallback, optionsFallback: optionsFallback, result: result)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
public func open(uuid: String, url: String, options: [String: Any?], uuidFallback: String?, headersFallback: [String: String], optionsFallback: [String: Any?], result: @escaping FlutterResult) {
let absoluteUrl = URL(string: url)!.absoluteURL
if self.previousStatusBarStyle == -1 {
self.previousStatusBarStyle = UIApplication.shared.statusBarStyle.rawValue
}
if !(self.tmpWindow != nil) {
let frame: CGRect = UIScreen.main.bounds
self.tmpWindow = UIWindow(frame: frame)
}
let tmpController = UIViewController()
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
self.tmpWindow!.rootViewController = tmpController
self.tmpWindow!.windowLevel = UIWindow.Level(baseWindowLevel!.rawValue + 1.0)
self.tmpWindow!.makeKeyAndVisible()
if #available(iOS 9.0, *) {
let safariOptions = SafariBrowserOptions()
let _ = safariOptions.parse(options: options)
let safari: SafariViewController
if #available(iOS 11.0, *) {
let config = SFSafariViewController.Configuration()
config.entersReaderIfAvailable = safariOptions.entersReaderIfAvailable
config.barCollapsingEnabled = safariOptions.barCollapsingEnabled
safari = SafariViewController(url: absoluteUrl, configuration: config)
} else {
// Fallback on earlier versions
safari = SafariViewController(url: absoluteUrl)
}
safari.uuid = uuid
safari.prepareMethodChannel()
safari.delegate = safari
safari.tmpWindow = tmpWindow
safari.safariOptions = safariOptions
tmpController.present(safari, animated: true) {
result(true)
}
return
}
else {
if uuidFallback == nil {
print("No WebView fallback declared.")
result(true)
return
}
SwiftFlutterPlugin.instance!.inAppBrowserManager!.openUrl(uuid: uuidFallback!, url: url, options: optionsFallback, headers: headersFallback)
}
}
}
...@@ -19,14 +19,14 @@ class CustomeSchemeHandler : NSObject, WKURLSchemeHandler { ...@@ -19,14 +19,14 @@ class CustomeSchemeHandler : NSObject, WKURLSchemeHandler {
if let url = urlSchemeTask.request.url, let scheme = url.scheme { if let url = urlSchemeTask.request.url, let scheme = url.scheme {
inAppWebView.onLoadResourceCustomScheme(scheme: scheme, url: url.absoluteString, result: {(result) -> Void in inAppWebView.onLoadResourceCustomScheme(scheme: scheme, url: url.absoluteString, result: {(result) -> Void in
if result is FlutterError { if result is FlutterError {
print((result as! FlutterError).message) print((result as! FlutterError).message ?? "")
} }
else if (result as? NSObject) == FlutterMethodNotImplemented {} else if (result as? NSObject) == FlutterMethodNotImplemented {}
else { else {
let json: [String: Any] let json: [String: Any]
if let r = result { if let r = result {
json = r as! [String: Any] json = r as! [String: Any]
let urlResponse = URLResponse(url: url, mimeType: json["content-type"] as! String, expectedContentLength: -1, textEncodingName: json["content-encoding"] as! String) let urlResponse = URLResponse(url: url, mimeType: (json["content-type"] as! String), expectedContentLength: -1, textEncodingName: (json["content-encoding"] as! String))
let data = json["data"] as! FlutterStandardTypedData let data = json["data"] as! FlutterStandardTypedData
if (self.schemeHandlers[urlSchemeTask.hash] != nil) { if (self.schemeHandlers[urlSchemeTask.hash] != nil) {
urlSchemeTask.didReceive(urlResponse) urlSchemeTask.didReceive(urlResponse)
......
...@@ -25,20 +25,20 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -25,20 +25,20 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
myView = UIView(frame: frame) myView = UIView(frame: frame)
let channelName = "com.pichillilorenzo/flutter_inappwebview_" + String(viewId) let channelName = "com.pichillilorenzo/flutter_inappwebview_" + String(viewId)
self.channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger()) channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
self.channel?.setMethodCallHandler(LeakAvoider(delegate: self).handle) channel!.setMethodCallHandler(LeakAvoider(delegate: self).handle)
let initialUrl = (args["initialUrl"] as? String)! let initialUrl = args["initialUrl"] as? String
let initialFile = args["initialFile"] as? String let initialFile = args["initialFile"] as? String
let initialData = args["initialData"] as? [String: String] let initialData = args["initialData"] as? [String: String]
let initialHeaders = (args["initialHeaders"] as? [String: String])! let initialHeaders = args["initialHeaders"] as? [String: String]
let initialOptions = (args["initialOptions"] as? [String: Any])! let initialOptions = args["initialOptions"] as! [String: Any?]
let options = InAppWebViewOptions() let options = InAppWebViewOptions()
options.parse(options: initialOptions) let _ = options.parse(options: initialOptions)
let preWebviewConfiguration = InAppWebView.preWKWebViewConfiguration(options: options) let preWebviewConfiguration = InAppWebView.preWKWebViewConfiguration(options: options)
webView = InAppWebView(frame: myView!.bounds, configuration: preWebviewConfiguration, IABController: nil, channel: self.channel) webView = InAppWebView(frame: myView!.bounds, configuration: preWebviewConfiguration, IABController: nil, channel: channel!)
webView!.autoresizingMask = [.flexibleWidth, .flexibleHeight] webView!.autoresizingMask = [.flexibleWidth, .flexibleHeight]
myView!.addSubview(webView!) myView!.addSubview(webView!)
...@@ -76,7 +76,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -76,7 +76,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
deinit { deinit {
print("FlutterWebViewController - dealloc") print("FlutterWebViewController - dealloc")
self.channel?.setMethodCallHandler(nil) channel?.setMethodCallHandler(nil)
webView!.dispose() webView!.dispose()
webView = nil webView = nil
myView = nil myView = nil
...@@ -86,7 +86,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -86,7 +86,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
return myView! return myView!
} }
public func load(initialUrl: String, initialFile: String?, initialData: [String: String]?, initialHeaders: [String: String]) { public func load(initialUrl: String?, initialFile: String?, initialData: [String: String]?, initialHeaders: [String: String]?) {
if initialFile != nil { if initialFile != nil {
do { do {
try webView!.loadFile(url: initialFile!, headers: initialHeaders) try webView!.loadFile(url: initialFile!, headers: initialHeaders)
...@@ -98,14 +98,14 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -98,14 +98,14 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
} }
if initialData != nil { if initialData != nil {
let data = (initialData!["data"] as? String)! let data = initialData!["data"]!
let mimeType = (initialData!["mimeType"] as? String)! let mimeType = initialData!["mimeType"]!
let encoding = (initialData!["encoding"] as? String)! let encoding = initialData!["encoding"]!
let baseUrl = (initialData!["baseUrl"] as? String)! let baseUrl = initialData!["baseUrl"]!
webView!.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl) webView!.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
} }
else { else {
webView!.loadUrl(url: URL(string: initialUrl)!, headers: initialHeaders) webView!.loadUrl(url: URL(string: initialUrl!)!, headers: initialHeaders)
} }
} }
...@@ -263,7 +263,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -263,7 +263,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
if webView != nil { if webView != nil {
let inAppWebViewOptions = InAppWebViewOptions() let inAppWebViewOptions = InAppWebViewOptions()
let inAppWebViewOptionsMap = arguments!["options"] as! [String: Any] let inAppWebViewOptionsMap = arguments!["options"] as! [String: Any]
inAppWebViewOptions.parse(options: inAppWebViewOptionsMap) let _ = inAppWebViewOptions.parse(options: inAppWebViewOptionsMap)
webView!.setOptions(newOptions: inAppWebViewOptions, newOptionsMap: inAppWebViewOptionsMap) webView!.setOptions(newOptions: inAppWebViewOptions, newOptionsMap: inAppWebViewOptionsMap)
} }
result(true) result(true)
...@@ -277,8 +277,13 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -277,8 +277,13 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
case "findAllAsync": case "findAllAsync":
if webView != nil { if webView != nil {
let find = arguments!["find"] as! String let find = arguments!["find"] as! String
webView!.findAllAsync(find: find, completionHandler: nil) webView!.findAllAsync(find: find, completionHandler: {(value, error) in
if error != nil {
result(FlutterError(code: "FlutterWebViewController", message: error?.localizedDescription, details: nil))
return
}
result(true) result(true)
})
} else { } else {
result(false) result(false)
} }
...@@ -347,13 +352,12 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor ...@@ -347,13 +352,12 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
case "printCurrentPage": case "printCurrentPage":
if webView != nil { if webView != nil {
webView!.printCurrentPage(printCompletionHandler: {(completed, error) in webView!.printCurrentPage(printCompletionHandler: {(completed, error) in
if !completed, let e = error { if !completed, let _ = error {
result(false) result(false)
return return
} }
result(true) result(true)
}) })
} else { } else {
result(false) result(false)
} }
......
//
// InAppBrowserManager.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 18/12/2019.
//
import Flutter
import UIKit
import WebKit
import Foundation
import AVFoundation
let WEBVIEW_STORYBOARD = "WebView"
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
public class InAppBrowserManager: NSObject, FlutterPlugin {
static var registrar: FlutterPluginRegistrar?
static var channel: FlutterMethodChannel?
var tmpWindow: UIWindow?
private var previousStatusBarStyle = -1
public static func register(with registrar: FlutterPluginRegistrar) {
}
init(registrar: FlutterPluginRegistrar) {
super.init()
InAppBrowserManager.registrar = registrar
InAppBrowserManager.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
registrar.addMethodCallDelegate(self, channel: InAppBrowserManager.channel!)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? NSDictionary
let uuid: String = arguments!["uuid"] as! String
switch call.method {
case "openUrl":
let url = arguments!["url"] as! String
let options = arguments!["options"] as! [String: Any?]
let headers = arguments!["headers"] as! [String: String]
openUrl(uuid: uuid, url: url, options: options, headers: headers)
result(true)
break
case "openFile":
var url = arguments!["url"] as! String
let key = InAppBrowserManager.registrar!.lookupKey(forAsset: url)
let assetURL = Bundle.main.url(forResource: key, withExtension: nil)
if assetURL == nil {
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url + " asset file cannot be found!", details: nil))
return
} else {
url = assetURL!.absoluteString
}
let options = arguments!["options"] as! [String: Any?]
let headers = arguments!["headers"] as! [String: String]
openUrl(uuid: uuid, url: url, options: options, headers: headers)
result(true)
break
case "openData":
let options = arguments!["options"] as! [String: Any?]
let data = arguments!["data"] as! String
let mimeType = arguments!["mimeType"] as! String
let encoding = arguments!["encoding"] as! String
let baseUrl = arguments!["baseUrl"] as! String
openData(uuid: uuid, options: options, data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
result(true)
break
case "openWithSystemBrowser":
let url = arguments!["url"] as! String
openWithSystemBrowser(url: url, result: result)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
public func prepareInAppBrowserWebViewController(options: [String: Any?]) -> InAppBrowserWebViewController {
if self.previousStatusBarStyle == -1 {
self.previousStatusBarStyle = UIApplication.shared.statusBarStyle.rawValue
}
if !(self.tmpWindow != nil) {
let frame: CGRect = UIScreen.main.bounds
self.tmpWindow = UIWindow(frame: frame)
}
let tmpController = UIViewController()
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
self.tmpWindow!.rootViewController = tmpController
self.tmpWindow!.windowLevel = UIWindow.Level(baseWindowLevel!.rawValue + 1.0)
self.tmpWindow!.makeKeyAndVisible()
let browserOptions = InAppBrowserOptions()
let _ = browserOptions.parse(options: options)
let webViewOptions = InAppWebViewOptions()
let _ = webViewOptions.parse(options: options)
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppWebViewFlutterPlugin.self))
let webViewController = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID) as! InAppBrowserWebViewController
webViewController.browserOptions = browserOptions
webViewController.webViewOptions = webViewOptions
webViewController.isHidden = browserOptions.hidden
webViewController.previousStatusBarStyle = previousStatusBarStyle
return webViewController
}
public func openUrl(uuid: String, url: String, options: [String: Any?], headers: [String: String]) {
let absoluteUrl = URL(string: url)!.absoluteURL
let webViewController = prepareInAppBrowserWebViewController(options: options)
webViewController.uuid = uuid
webViewController.prepareMethodChannel()
webViewController.tmpWindow = tmpWindow
webViewController.initURL = absoluteUrl
webViewController.initHeaders = headers
if webViewController.isHidden {
webViewController.view.isHidden = true
tmpWindow!.rootViewController!.present(webViewController, animated: false, completion: {() -> Void in
})
webViewController.presentingViewController?.dismiss(animated: false, completion: {() -> Void in
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
})
}
else {
tmpWindow!.rootViewController!.present(webViewController, animated: true, completion: {() -> Void in
})
}
}
public func openData(uuid: String, options: [String: Any?], data: String, mimeType: String, encoding: String, baseUrl: String) {
let webViewController = prepareInAppBrowserWebViewController(options: options)
webViewController.uuid = uuid
webViewController.tmpWindow = tmpWindow
webViewController.initData = data
webViewController.initMimeType = mimeType
webViewController.initEncoding = encoding
webViewController.initBaseUrl = baseUrl
if webViewController.isHidden {
webViewController.view.isHidden = true
tmpWindow!.rootViewController!.present(webViewController, animated: false, completion: {() -> Void in
webViewController.webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
})
webViewController.presentingViewController?.dismiss(animated: false, completion: {() -> Void in
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
})
}
else {
tmpWindow!.rootViewController!.present(webViewController, animated: true, completion: {() -> Void in
webViewController.webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
})
}
}
public func openWithSystemBrowser(url: String, result: @escaping FlutterResult) {
let absoluteUrl = URL(string: url)!.absoluteURL
if !UIApplication.shared.canOpenURL(absoluteUrl) {
result(FlutterError(code: "InAppBrowserManager", message: url + " cannot be opened!", details: nil))
return
}
else {
if #available(iOS 10.0, *) {
UIApplication.shared.open(absoluteUrl, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
} else {
UIApplication.shared.openURL(absoluteUrl)
}
}
result(true)
}
}
// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToUIApplicationOpenExternalURLOptionsKeyDictionary(_ input: [String: Any]) -> [UIApplication.OpenExternalURLOptionsKey: Any] {
return Dictionary(uniqueKeysWithValues: input.map { key, value in (UIApplication.OpenExternalURLOptionsKey(rawValue: key), value)})
}
This diff is collapsed.
...@@ -14,7 +14,7 @@ public class Options: NSObject { ...@@ -14,7 +14,7 @@ public class Options: NSObject {
super.init() super.init()
} }
func parse(options: [String: Any]) -> Options { func parse(options: [String: Any?]) -> Options {
for (key, value) in options { for (key, value) in options {
if self.responds(to: Selector(key)) { if self.responds(to: Selector(key)) {
self.setValue(value, forKey: key) self.setValue(value, forKey: key)
...@@ -23,8 +23,8 @@ public class Options: NSObject { ...@@ -23,8 +23,8 @@ public class Options: NSObject {
return self return self
} }
func getHashMap() -> [String: Any] { func getHashMap() -> [String: Any?] {
var options: [String: Any] = [:] var options: [String: Any?] = [:]
var counts = UInt32(); var counts = UInt32();
let properties = class_copyPropertyList(object_getClass(self), &counts); let properties = class_copyPropertyList(object_getClass(self), &counts);
for i in 0..<counts { for i in 0..<counts {
......
...@@ -9,16 +9,34 @@ import Foundation ...@@ -9,16 +9,34 @@ import Foundation
import SafariServices import SafariServices
@available(iOS 9.0, *) @available(iOS 9.0, *)
class SafariViewController: SFSafariViewController, SFSafariViewControllerDelegate { public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafariViewControllerDelegate {
weak var statusDelegate: SwiftFlutterPlugin? var channel: FlutterMethodChannel?
var tmpWindow: UIWindow? var tmpWindow: UIWindow?
var safariOptions: SafariBrowserOptions? var safariOptions: SafariBrowserOptions?
var uuid: String = "" var uuid: String = ""
override func viewWillAppear(_ animated: Bool) { public static func register(with registrar: FlutterPluginRegistrar) {
}
deinit {
print("SafariViewController - dealloc")
}
public func prepareMethodChannel() {
channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
SwiftFlutterPlugin.instance!.registrar!.addMethodCallDelegate(self, channel: channel!)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
}
public override func viewWillAppear(_ animated: Bool) {
prepareSafariBrowser() prepareSafariBrowser()
super.viewWillAppear(animated) super.viewWillAppear(animated)
onChromeSafariBrowserOpened()
} }
func prepareSafariBrowser() { func prepareSafariBrowser() {
...@@ -45,50 +63,64 @@ class SafariViewController: SFSafariViewController, SFSafariViewControllerDelega ...@@ -45,50 +63,64 @@ class SafariViewController: SFSafariViewController, SFSafariViewControllerDelega
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0) self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
UIApplication.shared.delegate?.window??.makeKeyAndVisible() UIApplication.shared.delegate?.window??.makeKeyAndVisible()
self.onChromeSafariBrowserClosed()
if (self.statusDelegate != nil) { self.dispose()
self.statusDelegate?.safariExit(uuid: self.uuid)
}
}) })
} }
func safariViewControllerDidFinish(_ controller: SFSafariViewController) { public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
close() close()
} }
func safariViewController(_ controller: SFSafariViewController, public func safariViewController(_ controller: SFSafariViewController,
didCompleteInitialLoad didLoadSuccessfully: Bool) { didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully { if didLoadSuccessfully {
statusDelegate?.onChromeSafariBrowserCompletedInitialLoad(uuid: self.uuid) onChromeSafariBrowserCompletedInitialLoad()
} }
else { else {
print("Cant load successfully the 'SafariViewController'.") print("Cant load successfully the 'SafariViewController'.")
} }
} }
func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] { public func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] {
// print("activityItemsFor") // print("activityItemsFor")
// print(URL) // print(URL)
// print(title) // print(title)
return [] return []
} }
func safariViewController(_ controller: SFSafariViewController, excludedActivityTypesFor URL: URL, title: String?) -> [UIActivity.ActivityType] { public func safariViewController(_ controller: SFSafariViewController, excludedActivityTypesFor URL: URL, title: String?) -> [UIActivity.ActivityType] {
// print("excludedActivityTypesFor") // print("excludedActivityTypesFor")
// print(URL) // print(URL)
// print(title) // print(title)
return [] return []
} }
func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) { public func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
// print("initialLoadDidRedirectTo") // print("initialLoadDidRedirectTo")
// print(URL) // print(URL)
} }
public func onChromeSafariBrowserOpened() {
channel!.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
}
public func onChromeSafariBrowserCompletedInitialLoad() {
channel!.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
}
public func onChromeSafariBrowserClosed() {
channel!.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
}
public func dispose() {
delegate = nil
channel!.setMethodCallHandler(nil)
}
// Helper function to convert hex color string to UIColor // Helper function to convert hex color string to UIColor
// Assumes input like "#00FF00" (#RRGGBB). // Assumes input like "#00FF00" (#RRGGBB).
// Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string // Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
func color(fromHexString: String, alpha:CGFloat? = 1.0) -> UIColor { func color(fromHexString: String, alpha:CGFloat? = 1.0) -> UIColor {
// Convert hex string to an integer // Convert hex string to an integer
......
This diff is collapsed.
...@@ -24,7 +24,6 @@ library flutter_inappwebview; ...@@ -24,7 +24,6 @@ library flutter_inappwebview;
export 'src/types.dart'; export 'src/types.dart';
export 'src/in_app_webview.dart'; export 'src/in_app_webview.dart';
export 'src/in_app_browser.dart'; export 'src/in_app_browser.dart';
export 'src/channel_manager.dart';
export 'src/cookie_manager.dart'; export 'src/cookie_manager.dart';
export 'src/chrome_safari_browser.dart'; export 'src/chrome_safari_browser.dart';
export 'src/chrome_safari_browser.dart'; export 'src/chrome_safari_browser.dart';
......
import 'dart:async';
import 'dart:collection';
import 'package:flutter/services.dart';
import 'types.dart' show ListenerCallback;
class ChannelManager {
static const MethodChannel channel =
const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
static bool initialized = false;
static final listeners = HashMap<String, ListenerCallback>();
static Future<dynamic> _handleMethod(MethodCall call) async {
String uuid = call.arguments["uuid"];
return await listeners[uuid](call);
}
static void addListener(String key, ListenerCallback callback) {
if (!initialized) init();
listeners.putIfAbsent(key, () => callback);
}
static void init() {
channel.setMethodCallHandler(_handleMethod);
initialized = true;
}
}
...@@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart'; ...@@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'types.dart'; import 'types.dart';
import 'channel_manager.dart';
import 'in_app_browser.dart'; import 'in_app_browser.dart';
///ChromeSafariBrowser class. ///ChromeSafariBrowser class.
...@@ -18,12 +17,16 @@ class ChromeSafariBrowser { ...@@ -18,12 +17,16 @@ class ChromeSafariBrowser {
String uuid; String uuid;
InAppBrowser browserFallback; InAppBrowser browserFallback;
bool _isOpened = false; bool _isOpened = false;
MethodChannel _channel;
static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser');
///Initialize the [ChromeSafariBrowser] instance with an [InAppBrowser] fallback instance or `null`. ///Initialize the [ChromeSafariBrowser] instance with an [InAppBrowser] fallback instance or `null`.
ChromeSafariBrowser({bFallback}) { ChromeSafariBrowser({bFallback}) {
uuid = uuidGenerator.v4(); uuid = uuidGenerator.v4();
browserFallback = bFallback; browserFallback = bFallback;
ChannelManager.addListener(uuid, handleMethod); this._channel =
MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser_$uuid');
this._channel.setMethodCallHandler(handleMethod);
_isOpened = false; _isOpened = false;
} }
...@@ -94,15 +97,13 @@ class ChromeSafariBrowser { ...@@ -94,15 +97,13 @@ class ChromeSafariBrowser {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); args.putIfAbsent('uuid', () => uuid);
args.putIfAbsent('uuidFallback',
() => (browserFallback != null) ? browserFallback.uuid : '');
args.putIfAbsent('url', () => url); args.putIfAbsent('url', () => url);
args.putIfAbsent('headers', () => headersFallback);
args.putIfAbsent('options', () => optionsMap); args.putIfAbsent('options', () => optionsMap);
args.putIfAbsent('uuidFallback',
() => (browserFallback != null) ? browserFallback.uuid : '');
args.putIfAbsent('headersFallback', () => headersFallback);
args.putIfAbsent('optionsFallback', () => optionsFallbackMap); args.putIfAbsent('optionsFallback', () => optionsFallbackMap);
args.putIfAbsent('isData', () => false); await _sharedChannel.invokeMethod('open', args);
args.putIfAbsent('useChromeSafariBrowser', () => true);
await ChannelManager.channel.invokeMethod('open', args);
this._isOpened = true; this._isOpened = true;
} }
......
...@@ -7,7 +7,6 @@ import 'package:flutter/services.dart'; ...@@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
import 'webview_options.dart'; import 'webview_options.dart';
import 'types.dart'; import 'types.dart';
import 'channel_manager.dart';
import 'in_app_webview.dart' show InAppWebViewController; import 'in_app_webview.dart' show InAppWebViewController;
///InAppBrowser class. [webViewController] can be used to access the [InAppWebView] API. ///InAppBrowser class. [webViewController] can be used to access the [InAppWebView] API.
...@@ -18,6 +17,8 @@ class InAppBrowser { ...@@ -18,6 +17,8 @@ class InAppBrowser {
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap = Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
HashMap<String, JavaScriptHandlerCallback>(); HashMap<String, JavaScriptHandlerCallback>();
bool _isOpened = false; bool _isOpened = false;
MethodChannel _channel;
static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
/// WebView Controller that can be used to access the [InAppWebView] API. /// WebView Controller that can be used to access the [InAppWebView] API.
InAppWebViewController webViewController; InAppWebViewController webViewController;
...@@ -25,10 +26,12 @@ class InAppBrowser { ...@@ -25,10 +26,12 @@ class InAppBrowser {
/// ///
InAppBrowser() { InAppBrowser() {
uuid = uuidGenerator.v4(); uuid = uuidGenerator.v4();
ChannelManager.addListener(uuid, handleMethod); this._channel =
MethodChannel('com.pichillilorenzo/flutter_inappbrowser_$uuid');
this._channel.setMethodCallHandler(handleMethod);
_isOpened = false; _isOpened = false;
webViewController = new InAppWebViewController.fromInAppBrowser( webViewController = new InAppWebViewController.fromInAppBrowser(
uuid, ChannelManager.channel, this); uuid, this._channel, this);
} }
Future<dynamic> handleMethod(MethodCall call) async { Future<dynamic> handleMethod(MethodCall call) async {
...@@ -53,8 +56,8 @@ class InAppBrowser { ...@@ -53,8 +56,8 @@ class InAppBrowser {
///[headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value. ///[headers]: The additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
/// ///
///[options]: Options for the [InAppBrowser]. ///[options]: Options for the [InAppBrowser].
Future<void> open( Future<void> openUrl(
{String url = "about:blank", {@required String url,
Map<String, String> headers = const {}, Map<String, String> headers = const {},
InAppBrowserClassOptions options}) async { InAppBrowserClassOptions options}) async {
assert(url != null && url.isNotEmpty); assert(url != null && url.isNotEmpty);
...@@ -83,14 +86,10 @@ class InAppBrowser { ...@@ -83,14 +86,10 @@ class InAppBrowser {
args.putIfAbsent('url', () => url); args.putIfAbsent('url', () => url);
args.putIfAbsent('headers', () => headers); args.putIfAbsent('headers', () => headers);
args.putIfAbsent('options', () => optionsMap); args.putIfAbsent('options', () => optionsMap);
args.putIfAbsent('openWithSystemBrowser', () => false); await _sharedChannel.invokeMethod('openUrl', args);
args.putIfAbsent('isLocalFile', () => false);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('useChromeSafariBrowser', () => false);
await ChannelManager.channel.invokeMethod('open', args);
} }
///Opens the given [assetFilePath] file in a new [InAppBrowser] instance. The other arguments are the same of [InAppBrowser.open]. ///Opens the given [assetFilePath] file in a new [InAppBrowser] instance. The other arguments are the same of [InAppBrowser.openUrl].
/// ///
///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! ///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!
/// ///
...@@ -153,11 +152,7 @@ class InAppBrowser { ...@@ -153,11 +152,7 @@ class InAppBrowser {
args.putIfAbsent('url', () => assetFilePath); args.putIfAbsent('url', () => assetFilePath);
args.putIfAbsent('headers', () => headers); args.putIfAbsent('headers', () => headers);
args.putIfAbsent('options', () => optionsMap); args.putIfAbsent('options', () => optionsMap);
args.putIfAbsent('openWithSystemBrowser', () => false); await _sharedChannel.invokeMethod('openFile', args);
args.putIfAbsent('isLocalFile', () => true);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('useChromeSafariBrowser', () => false);
await ChannelManager.channel.invokeMethod('open', args);
} }
///Opens a new [InAppBrowser] instance with [data] as a content, using [baseUrl] as the base URL for it. ///Opens a new [InAppBrowser] instance with [data] as a content, using [baseUrl] as the base URL for it.
...@@ -203,26 +198,16 @@ class InAppBrowser { ...@@ -203,26 +198,16 @@ class InAppBrowser {
args.putIfAbsent('mimeType', () => mimeType); args.putIfAbsent('mimeType', () => mimeType);
args.putIfAbsent('encoding', () => encoding); args.putIfAbsent('encoding', () => encoding);
args.putIfAbsent('baseUrl', () => baseUrl); args.putIfAbsent('baseUrl', () => baseUrl);
args.putIfAbsent('openWithSystemBrowser', () => false); args.putIfAbsent('historyUrl', () => androidHistoryUrl);
args.putIfAbsent('isLocalFile', () => false); await _sharedChannel.invokeMethod('openData', args);
args.putIfAbsent('isData', () => true);
args.putIfAbsent('useChromeSafariBrowser', () => false);
await ChannelManager.channel.invokeMethod('open', args);
} }
///This is a static method that opens an [url] in the system browser. You wont be able to use the [InAppBrowser] methods here! ///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<void> openWithSystemBrowser({@required String url}) async { static Future<void> openWithSystemBrowser({@required String url}) async {
assert(url != null && url.isNotEmpty); assert(url != null && url.isNotEmpty);
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => "");
args.putIfAbsent('url', () => url); args.putIfAbsent('url', () => url);
args.putIfAbsent('headers', () => {}); return await _sharedChannel.invokeMethod('openWithSystemBrowser', args);
args.putIfAbsent('isLocalFile', () => false);
args.putIfAbsent('isData', () => false);
args.putIfAbsent('openWithSystemBrowser', () => true);
args.putIfAbsent('useChromeSafariBrowser', () => false);
args.putIfAbsent('options', () => {});
return await ChannelManager.channel.invokeMethod('open', args);
} }
///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible. ///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible.
...@@ -230,31 +215,28 @@ class InAppBrowser { ...@@ -230,31 +215,28 @@ class InAppBrowser {
this.throwIsNotOpened(); this.throwIsNotOpened();
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); args.putIfAbsent('uuid', () => uuid);
await ChannelManager.channel.invokeMethod('show', args); await _channel.invokeMethod('show', args);
} }
///Hides the [InAppBrowser] window. Calling this has no effect if the [InAppBrowser] was already hidden. ///Hides the [InAppBrowser] window. Calling this has no effect if the [InAppBrowser] was already hidden.
Future<void> hide() async { Future<void> hide() async {
this.throwIsNotOpened(); this.throwIsNotOpened();
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); await _channel.invokeMethod('hide', args);
await ChannelManager.channel.invokeMethod('hide', args);
} }
///Closes the [InAppBrowser] window. ///Closes the [InAppBrowser] window.
Future<void> close() async { Future<void> close() async {
this.throwIsNotOpened(); this.throwIsNotOpened();
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); await _channel.invokeMethod('close', args);
await ChannelManager.channel.invokeMethod('close', args);
} }
///Check if the Web View of the [InAppBrowser] instance is hidden. ///Check if the Web View of the [InAppBrowser] instance is hidden.
Future<bool> isHidden() async { Future<bool> isHidden() async {
this.throwIsNotOpened(); this.throwIsNotOpened();
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); return await _channel.invokeMethod('isHidden', args);
return await ChannelManager.channel.invokeMethod('isHidden', args);
} }
///Sets the [InAppBrowser] options with the new [options] and evaluates them. ///Sets the [InAppBrowser] options with the new [options] and evaluates them.
...@@ -280,23 +262,19 @@ class InAppBrowser { ...@@ -280,23 +262,19 @@ class InAppBrowser {
} }
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid);
args.putIfAbsent('options', () => optionsMap); args.putIfAbsent('options', () => optionsMap);
args.putIfAbsent('optionsType', () => "InAppBrowserOptions"); await _channel.invokeMethod('setOptions', args);
await ChannelManager.channel.invokeMethod('setOptions', args);
} }
///Gets the current [InAppBrowser] options as a `Map`. Returns `null` if the options are not setted yet. ///Gets the current [InAppBrowser] options as a `Map`. Returns `null` if the options are not setted yet.
Future<InAppBrowserClassOptions> getOptions() async { Future<InAppBrowserClassOptions> getOptions() async {
this.throwIsNotOpened(); this.throwIsNotOpened();
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid);
args.putIfAbsent('optionsType', () => "InAppBrowserOptions");
InAppBrowserClassOptions inAppBrowserClassOptions = InAppBrowserClassOptions inAppBrowserClassOptions =
InAppBrowserClassOptions(); InAppBrowserClassOptions();
Map<dynamic, dynamic> options = Map<dynamic, dynamic> options =
await ChannelManager.channel.invokeMethod('getOptions', args); await _channel.invokeMethod('getOptions', args);
if (options != null) { if (options != null) {
options = options.cast<String, dynamic>(); options = options.cast<String, dynamic>();
inAppBrowserClassOptions.crossPlatform = inAppBrowserClassOptions.crossPlatform =
......
...@@ -9,8 +9,6 @@ import 'webview_options.dart'; ...@@ -9,8 +9,6 @@ import 'webview_options.dart';
var uuidGenerator = new Uuid(); var uuidGenerator = new Uuid();
typedef Future<dynamic> ListenerCallback(MethodCall call);
///This type represents a callback, added with [addJavaScriptHandler], that listens to post messages sent from JavaScript. ///This type represents a callback, added with [addJavaScriptHandler], that listens to post messages sent from JavaScript.
/// ///
///The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)). ///The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment