code refactoring, added InAppBrowserManager and ChromeSafariBrowserManager classes on native code, updated webview options class names
This commit is contained in:
parent
4d752ee9d9
commit
0e30767c15
|
@ -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.
|
||||
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
|
||||
|
||||
|
@ -530,8 +530,7 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
@override
|
||||
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
||||
print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
||||
this.webViewController.loadUrl(url: shouldOverrideUrlLoadingRequest.url);
|
||||
return ShouldOverrideUrlLoadingAction.CANCEL;
|
||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent;
|
|||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.browser.customtabs.CustomTabsCallback;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
|
@ -14,16 +13,21 @@ import androidx.browser.customtabs.CustomTabsSession;
|
|||
|
||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
|
||||
import java.util.HashMap;
|
||||
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";
|
||||
String uuid;
|
||||
CustomTabsIntent.Builder builder;
|
||||
ChromeCustomTabsOptions options;
|
||||
public MethodChannel channel;
|
||||
public String uuid;
|
||||
private CustomTabsIntent.Builder builder;
|
||||
private ChromeCustomTabsOptions options;
|
||||
private CustomTabActivityHelper customTabActivityHelper;
|
||||
private CustomTabsSession customTabsSession;
|
||||
private final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
||||
|
@ -39,13 +43,15 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||
Bundle b = getIntent().getExtras();
|
||||
assert b != null;
|
||||
uuid = b.getString("uuid");
|
||||
|
||||
channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid);
|
||||
channel.setMethodCallHandler(this);
|
||||
|
||||
final String url = b.getString("url");
|
||||
|
||||
options = new ChromeCustomTabsOptions();
|
||||
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
||||
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.chromeCustomTabsActivities.put(uuid, this);
|
||||
|
||||
final ChromeCustomTabsActivity chromeCustomTabsActivity = this;
|
||||
|
||||
customTabActivityHelper = new CustomTabActivityHelper();
|
||||
|
@ -68,7 +74,7 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||
finish();
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserClosed", obj);
|
||||
channel.invokeMethod("onChromeSafariBrowserClosed", obj);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -79,14 +85,14 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||
onChromeSafariBrowserOpened = true;
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserOpened", obj);
|
||||
channel.invokeMethod("onChromeSafariBrowserOpened", obj);
|
||||
}
|
||||
|
||||
if (navigationEvent == NAVIGATION_FINISHED && !onChromeSafariBrowserCompletedInitialLoad) {
|
||||
onChromeSafariBrowserCompletedInitialLoad = true;
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", obj);
|
||||
channel.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
if (options.addDefaultShareMenuItem)
|
||||
builder.addDefaultShareMenuItem();
|
||||
|
@ -155,7 +169,7 @@ public class ChromeCustomTabsActivity extends Activity {
|
|||
finish();
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onChromeSafariBrowserClosed", obj);
|
||||
InAppWebViewFlutterPlugin.inAppBrowserManager.channel.invokeMethod("onChromeSafariBrowserClosed", obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
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 {
|
|||
public final MethodChannel channel;
|
||||
|
||||
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();
|
||||
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
||||
displayListenerProxy.onPreWebViewInitialization(displayManager);
|
||||
|
@ -70,9 +73,6 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
|
|||
|
||||
webView.prepare();
|
||||
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
|
||||
channel.setMethodCallHandler(this);
|
||||
|
||||
if (initialFile != null) {
|
||||
try {
|
||||
initialUrl = Util.getUrlAsset(initialFile);
|
||||
|
|
|
@ -1,868 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* 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.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.Browser;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ChromeCustomTabsActivity;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CustomTabActivityHelper;
|
||||
|
||||
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;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
|
||||
/**
|
||||
* InAppBrowser
|
||||
*/
|
||||
public class InAppBrowser implements MethodChannel.MethodCallHandler {
|
||||
|
||||
public MethodChannel channel;
|
||||
public Map<String, InAppBrowserActivity> webViewActivities = new HashMap<>();
|
||||
public Map<String, ChromeCustomTabsActivity> chromeCustomTabsActivities = new HashMap<>();
|
||||
|
||||
protected static final String LOG_TAG = "IABFlutterPlugin";
|
||||
|
||||
public InAppBrowser(BinaryMessenger messenger) {
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappbrowser");
|
||||
channel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(final MethodCall call, final Result result) {
|
||||
String source;
|
||||
String urlFile;
|
||||
final Activity activity = Shared.activity;
|
||||
final String uuid = (String) call.argument("uuid");
|
||||
|
||||
switch (call.method) {
|
||||
case "open":
|
||||
boolean isData = (boolean) call.argument("isData");
|
||||
if (!isData) {
|
||||
final String url_final = (String) call.argument("url");
|
||||
|
||||
final boolean useChromeSafariBrowser = (boolean) call.argument("useChromeSafariBrowser");
|
||||
|
||||
final Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
||||
|
||||
Log.d(LOG_TAG, "use Chrome Custom Tabs = " + useChromeSafariBrowser);
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (useChromeSafariBrowser) {
|
||||
|
||||
final String uuidFallback = (String) call.argument("uuidFallback");
|
||||
|
||||
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
|
||||
|
||||
final HashMap<String, Object> optionsFallback = (HashMap<String, Object>) call.argument("optionsFallback");
|
||||
|
||||
open(activity, uuid, uuidFallback, url_final, options, headers, true, optionsFallback, result);
|
||||
} else {
|
||||
|
||||
String url = url_final;
|
||||
|
||||
final HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
|
||||
|
||||
final boolean isLocalFile = (boolean) call.argument("isLocalFile");
|
||||
final boolean openWithSystemBrowser = (boolean) call.argument("openWithSystemBrowser");
|
||||
|
||||
if (isLocalFile) {
|
||||
// check if the asset file exists
|
||||
try {
|
||||
url = Util.getUrlAsset(url);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
result.error(LOG_TAG, url + " asset file cannot be found!", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// SYSTEM
|
||||
if (openWithSystemBrowser) {
|
||||
Log.d(LOG_TAG, "in system");
|
||||
openExternal(activity, url, result);
|
||||
} else {
|
||||
//Load the dialer
|
||||
if (url.startsWith(WebView.SCHEME_TEL)) {
|
||||
try {
|
||||
Log.d(LOG_TAG, "loading in dialer");
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse(url));
|
||||
activity.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
// load in InAppBrowser
|
||||
else {
|
||||
Log.d(LOG_TAG, "loading in InAppBrowser");
|
||||
open(activity, uuid, null, url, options, headers, false, null, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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 "getUrl":
|
||||
result.success(getUrl(uuid));
|
||||
break;
|
||||
case "getTitle":
|
||||
result.success(getTitle(uuid));
|
||||
break;
|
||||
case "getProgress":
|
||||
result.success(getProgress(uuid));
|
||||
break;
|
||||
case "loadUrl":
|
||||
loadUrl(uuid, (String) call.argument("url"), (Map<String, String>) call.argument("headers"), result);
|
||||
break;
|
||||
case "postUrl":
|
||||
postUrl(uuid, (String) call.argument("url"), (byte[]) call.argument("postData"), result);
|
||||
break;
|
||||
case "loadData":
|
||||
{
|
||||
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");
|
||||
loadData(uuid, data, mimeType, encoding, baseUrl, historyUrl, result);
|
||||
}
|
||||
break;
|
||||
case "loadFile":
|
||||
loadFile(uuid, (String) call.argument("url"), (Map<String, String>) call.argument("headers"), result);
|
||||
break;
|
||||
case "close":
|
||||
close(activity, uuid, result);
|
||||
break;
|
||||
case "evaluateJavascript":
|
||||
source = (String) call.argument("source");
|
||||
evaluateJavascript(uuid, source, result);
|
||||
break;
|
||||
case "injectJavascriptFileFromUrl":
|
||||
urlFile = (String) call.argument("urlFile");
|
||||
injectJavascriptFileFromUrl(uuid, urlFile);
|
||||
result.success(true);
|
||||
break;
|
||||
case "injectCSSCode":
|
||||
source = (String) call.argument("source");
|
||||
injectCSSCode(uuid, source);
|
||||
result.success(true);
|
||||
break;
|
||||
case "injectCSSFileFromUrl":
|
||||
urlFile = (String) call.argument("urlFile");
|
||||
injectCSSFileFromUrl(uuid, urlFile);
|
||||
result.success(true);
|
||||
break;
|
||||
case "show":
|
||||
show(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "hide":
|
||||
hide(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "reload":
|
||||
reload(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "goBack":
|
||||
goBack(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoBack":
|
||||
result.success(canGoBack(uuid));
|
||||
break;
|
||||
case "goForward":
|
||||
goForward(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoForward":
|
||||
result.success(canGoForward(uuid));
|
||||
break;
|
||||
case "goBackOrForward":
|
||||
goBackOrForward(uuid, (Integer) call.argument("steps"));
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoBackOrForward":
|
||||
result.success(canGoBackOrForward(uuid, (Integer) call.argument("steps")));
|
||||
break;
|
||||
case "stopLoading":
|
||||
stopLoading(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "isLoading":
|
||||
result.success(isLoading(uuid));
|
||||
break;
|
||||
case "isHidden":
|
||||
result.success(isHidden(uuid));
|
||||
break;
|
||||
case "takeScreenshot":
|
||||
result.success(takeScreenshot(uuid));
|
||||
break;
|
||||
case "setOptions":
|
||||
{
|
||||
String optionsType = (String) call.argument("optionsType");
|
||||
switch (optionsType){
|
||||
case "InAppBrowserOptions":
|
||||
InAppBrowserOptions inAppBrowserOptions = new InAppBrowserOptions();
|
||||
HashMap<String, Object> inAppBrowserOptionsMap = (HashMap<String, Object>) call.argument("options");
|
||||
inAppBrowserOptions.parse(inAppBrowserOptionsMap);
|
||||
setOptions(uuid, inAppBrowserOptions, inAppBrowserOptionsMap);
|
||||
break;
|
||||
default:
|
||||
result.error(LOG_TAG, "Options " + optionsType + " not available.", null);
|
||||
}
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getOptions":
|
||||
result.success(getOptions(uuid));
|
||||
break;
|
||||
case "getCopyBackForwardList":
|
||||
result.success(getCopyBackForwardList(uuid));
|
||||
break;
|
||||
case "startSafeBrowsing":
|
||||
startSafeBrowsing(uuid, result);
|
||||
break;
|
||||
case "setSafeBrowsingWhitelist":
|
||||
setSafeBrowsingWhitelist(uuid, (List<String>) call.argument("hosts"), result);
|
||||
break;
|
||||
case "clearCache":
|
||||
clearCache(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "clearSslPreferences":
|
||||
clearSslPreferences(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "clearClientCertPreferences":
|
||||
clearClientCertPreferences(uuid, result);
|
||||
break;
|
||||
case "findAllAsync":
|
||||
String find = (String) call.argument("find");
|
||||
findAllAsync(uuid, find);
|
||||
result.success(true);
|
||||
break;
|
||||
case "findNext":
|
||||
Boolean forward = (Boolean) call.argument("forward");
|
||||
findNext(uuid, forward, result);
|
||||
break;
|
||||
case "clearMatches":
|
||||
clearMatches(uuid, result);
|
||||
break;
|
||||
case "scrollTo":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollTo(uuid, x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "scrollBy":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollBy(uuid, x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "pause":
|
||||
onPause(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "resume":
|
||||
onResume(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "pauseTimers":
|
||||
pauseTimers(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "resumeTimers":
|
||||
resumeTimers(uuid);
|
||||
result.success(true);
|
||||
break;
|
||||
case "printCurrentPage":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
printCurrentPage(uuid);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getContentHeight":
|
||||
result.success(getContentHeight(uuid));
|
||||
break;
|
||||
case "zoomBy":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Float zoomFactor = (Float) call.argument("zoomFactor");
|
||||
zoomBy(uuid, zoomFactor);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getOriginalUrl":
|
||||
result.success(getOriginalUrl(uuid));
|
||||
break;
|
||||
case "getScale":
|
||||
result.success(getScale(uuid));
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void evaluateJavascript(String uuid, String source, final Result result) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.evaluateJavascript(source, result);
|
||||
} else {
|
||||
Log.d(LOG_TAG, "webView is null");
|
||||
}
|
||||
}
|
||||
|
||||
public void injectJavascriptFileFromUrl(String uuid, String urlFile) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectJavascriptFileFromUrl(urlFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectCSSCode(String uuid, String source) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectCSSCode(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectCSSFileFromUrl(String uuid, String urlFile) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
inAppBrowserActivity.injectCSSFileFromUrl(urlFile);
|
||||
}
|
||||
}
|
||||
|
||||
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 openExternal(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 open(Activity activity, String uuid, String uuidFallback, String url, HashMap<String, Object> options, Map<String, String> headers, boolean useChromeSafariBrowser, HashMap<String, Object> optionsFallback, 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) headers);
|
||||
|
||||
if (useChromeSafariBrowser && CustomTabActivityHelper.isAvailable(activity)) {
|
||||
intent = new Intent(activity, ChromeCustomTabsActivity.class);
|
||||
}
|
||||
// check for webview fallback
|
||||
else if (useChromeSafariBrowser && !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());
|
||||
extras.putSerializable("headers", (Serializable) headers);
|
||||
intent = new Intent(activity, InAppBrowserActivity.class);
|
||||
}
|
||||
// native webview
|
||||
else if (!useChromeSafariBrowser) {
|
||||
intent = new Intent(activity, InAppBrowserActivity.class);
|
||||
}
|
||||
else {
|
||||
Log.d(LOG_TAG, "No WebView fallback declared.");
|
||||
}
|
||||
|
||||
if (intent != null) {
|
||||
intent.putExtras(extras);
|
||||
activity.startActivity(intent);
|
||||
result.success(true);
|
||||
return;
|
||||
}
|
||||
|
||||
result.error(LOG_TAG, "No WebView fallback declared.", null);
|
||||
}
|
||||
|
||||
public void openData(Activity activity, String uuid, HashMap<String, Object> options, String data, String mimeType, String encoding, String baseUrl, String historyUrl) {
|
||||
Intent intent = new Intent(activity, InAppBrowserActivity.class);
|
||||
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);
|
||||
|
||||
intent.putExtras(extras);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
public String getUrl(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getUrl();
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTitle(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getWebViewTitle();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getProgress(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getProgress();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void loadUrl(String uuid, String url, Map<String, String> headers, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
if (headers != null)
|
||||
inAppBrowserActivity.loadUrl(url, headers, result);
|
||||
else
|
||||
inAppBrowserActivity.loadUrl(url, result);
|
||||
}
|
||||
}
|
||||
|
||||
public void postUrl(String uuid, String url, byte[] postData, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.postUrl(url, postData, result);
|
||||
}
|
||||
|
||||
public void loadData(String uuid, String data, String mimeType, String encoding, String baseUrl, String historyUrl, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.loadData(data, mimeType, encoding, baseUrl, historyUrl, result);
|
||||
}
|
||||
|
||||
public void loadFile(String uuid, String url, Map<String, String> headers, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
if (headers != null)
|
||||
inAppBrowserActivity.loadFile(url, headers, result);
|
||||
else
|
||||
inAppBrowserActivity.loadFile(url, result);
|
||||
}
|
||||
}
|
||||
|
||||
public void show(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.show();
|
||||
}
|
||||
|
||||
public void hide(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.hide();
|
||||
}
|
||||
|
||||
public void reload(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.reload();
|
||||
}
|
||||
|
||||
public boolean isLoading(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.isLoading();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isHidden(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.isHidden;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void stopLoading(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.stopLoading();
|
||||
}
|
||||
|
||||
public void goBack(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.goBack();
|
||||
}
|
||||
|
||||
public boolean canGoBack(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.canGoBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goForward(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.goForward();
|
||||
}
|
||||
|
||||
public boolean canGoForward(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.canGoForward();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void goBackOrForward(String uuid, int steps) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.goBackOrForward(steps);
|
||||
}
|
||||
|
||||
public boolean canGoBackOrForward(String uuid, int steps) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.canGoBackOrForward(steps);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close(Activity activity, final String uuid, final Result result) {
|
||||
final InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
channel.invokeMethod("onExit", obj);
|
||||
|
||||
// The JS protects against multiple calls, so this should happen only when
|
||||
// close() is called by other native code.
|
||||
if (inAppBrowserActivity == null) {
|
||||
if (result != null) {
|
||||
result.success(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
inAppBrowserActivity.webView.setWebViewClient(new WebViewClient() {
|
||||
// NB: wait for about:blank before dismissing
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
inAppBrowserActivity.close();
|
||||
}
|
||||
});
|
||||
// NB: From SDK 19: "If you call methods on WebView from any thread
|
||||
// other than your app's UI thread, it can cause unexpected results."
|
||||
// http://developer.android.com/guide/webapps/migrating.html#Threads
|
||||
inAppBrowserActivity.webView.loadUrl("about:blank");
|
||||
if (result != null) {
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (result != null) {
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] takeScreenshot(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.takeScreenshot();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setOptions(String uuid, InAppBrowserOptions options, HashMap<String, Object> optionsMap) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.setOptions(options, optionsMap);
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getOptions(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getOptions();
|
||||
return null;
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getCopyBackForwardList(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getCopyBackForwardList();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void startSafeBrowsing(String uuid, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.startSafeBrowsing(result);
|
||||
result.success(false);
|
||||
}
|
||||
|
||||
public void setSafeBrowsingWhitelist(String uuid, List<String> hosts, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.setSafeBrowsingWhitelist(hosts, result);
|
||||
result.success(false);
|
||||
}
|
||||
|
||||
public void clearCache(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.clearCache();
|
||||
}
|
||||
|
||||
public void clearSslPreferences(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.clearSslPreferences();
|
||||
}
|
||||
|
||||
public void clearClientCertPreferences(String uuid, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.clearClientCertPreferences(result);
|
||||
result.success(false);
|
||||
}
|
||||
|
||||
public void findAllAsync(String uuid, String find) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.findAllAsync(find);
|
||||
}
|
||||
|
||||
public void findNext(String uuid, Boolean forward, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.findNext(forward, result);
|
||||
result.success(false);
|
||||
}
|
||||
|
||||
public void clearMatches(String uuid, Result result) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.clearMatches(result);
|
||||
result.success(false);
|
||||
}
|
||||
|
||||
public void scrollTo(String uuid, Integer x, Integer y) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.scrollTo(x, y);
|
||||
}
|
||||
|
||||
public void scrollBy(String uuid, Integer x, Integer y) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.scrollBy(x, y);
|
||||
}
|
||||
|
||||
public void onPause(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.onPauseWebView();
|
||||
}
|
||||
|
||||
public void onResume(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.onResumeWebView();
|
||||
}
|
||||
|
||||
public void pauseTimers(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.pauseTimers();
|
||||
}
|
||||
|
||||
public void resumeTimers(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.resumeTimers();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void printCurrentPage(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.printCurrentPage();
|
||||
}
|
||||
|
||||
public Integer getContentHeight(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getContentHeight();
|
||||
return null;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void zoomBy(String uuid, Float zoomFactor) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
inAppBrowserActivity.zoomBy(zoomFactor);
|
||||
}
|
||||
|
||||
public String getOriginalUrl(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getOriginalUrl();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Float getScale(String uuid) {
|
||||
InAppBrowserActivity inAppBrowserActivity = webViewActivities.get(uuid);
|
||||
if (inAppBrowserActivity != null)
|
||||
return inAppBrowserActivity.getScale();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
for ( InAppBrowserActivity activity : webViewActivities.values()) {
|
||||
activity.dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,11 +6,6 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
@ -25,6 +20,10 @@ import android.webkit.WebViewClient;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.SearchView;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebView;
|
||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebView.InAppWebViewOptions;
|
||||
|
||||
|
@ -34,11 +33,13 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class InAppBrowserActivity extends AppCompatActivity {
|
||||
public class InAppBrowserActivity extends AppCompatActivity implements MethodChannel.MethodCallHandler {
|
||||
|
||||
static final String LOG_TAG = "InAppBrowserActivity";
|
||||
public MethodChannel channel;
|
||||
public String uuid;
|
||||
public InAppWebView webView;
|
||||
public ActionBar actionBar;
|
||||
|
@ -54,13 +55,17 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle b = getIntent().getExtras();
|
||||
uuid = b.getString("uuid");
|
||||
|
||||
channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + uuid);
|
||||
channel.setMethodCallHandler(this);
|
||||
|
||||
setContentView(R.layout.activity_web_view);
|
||||
|
||||
webView = findViewById(R.id.webView);
|
||||
webView.inAppBrowserActivity = this;
|
||||
|
||||
Bundle b = getIntent().getExtras();
|
||||
uuid = b.getString("uuid");
|
||||
fromActivity = b.getString("fromActivity");
|
||||
|
||||
HashMap<String, Object> optionsMap = (HashMap<String, Object>) b.getSerializable("options");
|
||||
|
@ -72,8 +77,6 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
webViewOptions.parse(optionsMap);
|
||||
webView.options = webViewOptions;
|
||||
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.webViewActivities.put(uuid, this);
|
||||
|
||||
actionBar = getSupportActionBar();
|
||||
|
||||
prepareView();
|
||||
|
@ -95,8 +98,238 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("uuid", uuid);
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.channel.invokeMethod("onBrowserCreated", obj);
|
||||
channel.invokeMethod("onBrowserCreated", obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "getUrl":
|
||||
result.success(getUrl());
|
||||
break;
|
||||
case "getTitle":
|
||||
result.success(getWebViewTitle());
|
||||
break;
|
||||
case "getProgress":
|
||||
result.success(getProgress());
|
||||
break;
|
||||
case "loadUrl":
|
||||
{
|
||||
String url = (String) call.argument("url");
|
||||
Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
||||
if (headers != null)
|
||||
loadUrl(url, headers, result);
|
||||
else
|
||||
loadUrl(url, result);
|
||||
}
|
||||
break;
|
||||
case "postUrl":
|
||||
postUrl((String) call.argument("url"), (byte[]) call.argument("postData"), result);
|
||||
break;
|
||||
case "loadData":
|
||||
{
|
||||
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");
|
||||
loadData(data, mimeType, encoding, baseUrl, historyUrl, result);
|
||||
}
|
||||
break;
|
||||
case "loadFile":
|
||||
{
|
||||
String url = (String) call.argument("url");
|
||||
Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
||||
if (headers != null)
|
||||
loadFile(url, headers, result);
|
||||
else
|
||||
loadFile(url, result);
|
||||
}
|
||||
break;
|
||||
case "close":
|
||||
close(result);
|
||||
break;
|
||||
case "evaluateJavascript":
|
||||
{
|
||||
String source = (String) call.argument("source");
|
||||
evaluateJavascript(source, result);
|
||||
}
|
||||
break;
|
||||
case "injectJavascriptFileFromUrl":
|
||||
{
|
||||
String urlFile = (String) call.argument("urlFile");
|
||||
injectJavascriptFileFromUrl(urlFile);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "injectCSSCode":
|
||||
{
|
||||
String source = (String) call.argument("source");
|
||||
injectCSSCode(source);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "injectCSSFileFromUrl":
|
||||
{
|
||||
String urlFile = (String) call.argument("urlFile");
|
||||
injectCSSFileFromUrl(urlFile);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "show":
|
||||
show();
|
||||
result.success(true);
|
||||
break;
|
||||
case "hide":
|
||||
hide();
|
||||
result.success(true);
|
||||
break;
|
||||
case "reload":
|
||||
reload();
|
||||
result.success(true);
|
||||
break;
|
||||
case "goBack":
|
||||
goBack();
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoBack":
|
||||
result.success(canGoBack());
|
||||
break;
|
||||
case "goForward":
|
||||
goForward();
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoForward":
|
||||
result.success(canGoForward());
|
||||
break;
|
||||
case "goBackOrForward":
|
||||
goBackOrForward((Integer) call.argument("steps"));
|
||||
result.success(true);
|
||||
break;
|
||||
case "canGoBackOrForward":
|
||||
result.success(canGoBackOrForward((Integer) call.argument("steps")));
|
||||
break;
|
||||
case "stopLoading":
|
||||
stopLoading();
|
||||
result.success(true);
|
||||
break;
|
||||
case "isLoading":
|
||||
result.success(isLoading());
|
||||
break;
|
||||
case "isHidden":
|
||||
result.success(isHidden);
|
||||
break;
|
||||
case "takeScreenshot":
|
||||
result.success(takeScreenshot());
|
||||
break;
|
||||
case "setOptions":
|
||||
{
|
||||
String optionsType = (String) call.argument("optionsType");
|
||||
switch (optionsType){
|
||||
case "InAppBrowserOptions":
|
||||
InAppBrowserOptions inAppBrowserOptions = new InAppBrowserOptions();
|
||||
HashMap<String, Object> inAppBrowserOptionsMap = (HashMap<String, Object>) call.argument("options");
|
||||
inAppBrowserOptions.parse(inAppBrowserOptionsMap);
|
||||
setOptions(inAppBrowserOptions, inAppBrowserOptionsMap);
|
||||
break;
|
||||
default:
|
||||
result.error(LOG_TAG, "Options " + optionsType + " not available.", null);
|
||||
}
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getOptions":
|
||||
result.success(getOptions());
|
||||
break;
|
||||
case "getCopyBackForwardList":
|
||||
result.success(getCopyBackForwardList());
|
||||
break;
|
||||
case "startSafeBrowsing":
|
||||
startSafeBrowsing(result);
|
||||
break;
|
||||
case "setSafeBrowsingWhitelist":
|
||||
setSafeBrowsingWhitelist((List<String>) call.argument("hosts"), result);
|
||||
break;
|
||||
case "clearCache":
|
||||
clearCache();
|
||||
result.success(true);
|
||||
break;
|
||||
case "clearSslPreferences":
|
||||
clearSslPreferences();
|
||||
result.success(true);
|
||||
break;
|
||||
case "clearClientCertPreferences":
|
||||
clearClientCertPreferences(result);
|
||||
break;
|
||||
case "findAllAsync":
|
||||
String find = (String) call.argument("find");
|
||||
findAllAsync(find);
|
||||
result.success(true);
|
||||
break;
|
||||
case "findNext":
|
||||
Boolean forward = (Boolean) call.argument("forward");
|
||||
findNext(forward, result);
|
||||
break;
|
||||
case "clearMatches":
|
||||
clearMatches(result);
|
||||
break;
|
||||
case "scrollTo":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollTo(x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "scrollBy":
|
||||
{
|
||||
Integer x = (Integer) call.argument("x");
|
||||
Integer y = (Integer) call.argument("y");
|
||||
scrollBy(x, y);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "pause":
|
||||
onPauseWebView();
|
||||
result.success(true);
|
||||
break;
|
||||
case "resume":
|
||||
onResumeWebView();
|
||||
result.success(true);
|
||||
break;
|
||||
case "pauseTimers":
|
||||
pauseTimers();
|
||||
result.success(true);
|
||||
break;
|
||||
case "resumeTimers":
|
||||
resumeTimers();
|
||||
result.success(true);
|
||||
break;
|
||||
case "printCurrentPage":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
printCurrentPage();
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getContentHeight":
|
||||
result.success(getContentHeight());
|
||||
break;
|
||||
case "zoomBy":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Float zoomFactor = (Float) call.argument("zoomFactor");
|
||||
zoomBy(zoomFactor);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "getOriginalUrl":
|
||||
result.success(getOriginalUrl());
|
||||
break;
|
||||
case "getScale":
|
||||
result.success(getScale());
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareView() {
|
||||
|
@ -259,15 +492,37 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
if (canGoBack())
|
||||
goBack();
|
||||
else if (options.closeOnCannotGoBack)
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.close(this, uuid, null);
|
||||
close(null);
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
hide();
|
||||
finish();
|
||||
public void close(final MethodChannel.Result result) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
channel.invokeMethod("onExit", obj);
|
||||
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
// NB: wait for about:blank before dismissing
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
hide();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
// NB: From SDK 19: "If you call methods on WebView from any thread
|
||||
// other than your app's UI thread, it can cause unexpected results."
|
||||
// http://developer.android.com/guide/webapps/migrating.html#Threads
|
||||
webView.loadUrl("about:blank");
|
||||
if (result != null) {
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
|
@ -358,7 +613,7 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
public void closeButtonClicked(MenuItem item) {
|
||||
InAppWebViewFlutterPlugin.inAppBrowser.close(this, uuid, null);
|
||||
close(null);
|
||||
}
|
||||
|
||||
public byte[] takeScreenshot() {
|
||||
|
@ -525,20 +780,6 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
result.success(false);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (webView != null) {
|
||||
webView.setWebChromeClient(new WebChromeClient());
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
webView.dispose();
|
||||
webView.destroy();
|
||||
webView = null;
|
||||
}
|
||||
});
|
||||
webView.loadUrl("about:blank");
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollTo(Integer x, Integer y) {
|
||||
if (webView != null)
|
||||
webView.scrollTo(x, y);
|
||||
|
@ -598,4 +839,25 @@ public class InAppBrowserActivity extends AppCompatActivity {
|
|||
return webView.getUpdatedScale();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
if (webView != null) {
|
||||
webView.setWebChromeClient(new WebChromeClient());
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
webView.dispose();
|
||||
webView.destroy();
|
||||
webView = null;
|
||||
}
|
||||
});
|
||||
webView.loadUrl("about:blank");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
dispose();
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
|
@ -21,13 +19,8 @@ import android.webkit.WebBackForwardList;
|
|||
import android.webkit.WebHistoryItem;
|
||||
import android.webkit.WebSettings;
|
||||
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.appcompat.app.AlertDialog;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlocker;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerAction;
|
||||
|
@ -37,7 +30,6 @@ import com.pichillilorenzo.flutter_inappwebview.FlutterWebView;
|
|||
import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity;
|
||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
|
||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||
|
||||
|
@ -50,7 +42,6 @@ import java.util.Map;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import static com.pichillilorenzo.flutter_inappwebview.InAppWebView.PreferredContentModeOptionType.fromValue;
|
||||
|
@ -61,6 +52,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
|
||||
public InAppBrowserActivity inAppBrowserActivity;
|
||||
public FlutterWebView flutterWebView;
|
||||
public MethodChannel channel;
|
||||
public int id;
|
||||
public InAppWebViewClient inAppWebViewClient;
|
||||
public InAppWebViewChromeClient inAppWebViewChromeClient;
|
||||
|
@ -123,7 +115,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
|
||||
static final String interceptAjaxRequestsJS = "(function(ajax) {" +
|
||||
" var send = ajax.prototype.send;" +
|
||||
" var open = ajax.prototype.open;" +
|
||||
" var openUrl = ajax.prototype.openUrl;" +
|
||||
" var setRequestHeader = ajax.prototype.setRequestHeader;" +
|
||||
" ajax.prototype._flutter_inappwebview_url = null;" +
|
||||
" ajax.prototype._flutter_inappwebview_method = null;" +
|
||||
|
@ -156,7 +148,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
" }" +
|
||||
" 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;" +
|
||||
" this._flutter_inappwebview_url = url;" +
|
||||
" this._flutter_inappwebview_method = method;" +
|
||||
|
@ -164,7 +156,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
" this._flutter_inappwebview_user = user;" +
|
||||
" this._flutter_inappwebview_password = password;" +
|
||||
" 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) {" +
|
||||
" this._flutter_inappwebview_request_headers[header] = value;" +
|
||||
|
@ -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)) {" +
|
||||
" 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;" +
|
||||
" }" +
|
||||
" }" +
|
||||
|
@ -532,6 +524,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||
else if (obj instanceof FlutterWebView)
|
||||
this.flutterWebView = (FlutterWebView) obj;
|
||||
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
|
||||
this.id = id;
|
||||
this.options = options;
|
||||
}
|
||||
|
@ -689,7 +682,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
obj.put("activeMatchOrdinal", activeMatchOrdinal);
|
||||
obj.put("numberOfMatches", numberOfMatches);
|
||||
obj.put("isDoneCounting", isDoneCounting);
|
||||
getChannel().invokeMethod("onFindResultReceived", obj);
|
||||
channel.invokeMethod("onFindResultReceived", obj);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1264,11 +1257,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("x", x);
|
||||
obj.put("y", y);
|
||||
getChannel().invokeMethod("onScrollChanged", obj);
|
||||
}
|
||||
|
||||
private MethodChannel getChannel() {
|
||||
return (inAppBrowserActivity != null) ? InAppWebViewFlutterPlugin.inAppBrowser.channel : flutterWebView.channel;
|
||||
channel.invokeMethod("onScrollChanged", obj);
|
||||
}
|
||||
|
||||
public void startSafeBrowsing(final MethodChannel.Result result) {
|
||||
|
@ -1304,7 +1293,7 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("onDownloadStart", obj);
|
||||
channel.invokeMethod("onDownloadStart", obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.pichillilorenzo.flutter_inappwebview.InAppWebView;
|
|||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -33,7 +32,6 @@ import com.pichillilorenzo.flutter_inappwebview.InAppBrowserActivity;
|
|||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Shared;
|
||||
import com.pichillilorenzo.flutter_inappwebview.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -52,6 +50,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
protected static final String LOG_TAG = "IABWebChromeClient";
|
||||
private FlutterWebView flutterWebView;
|
||||
private InAppBrowserActivity inAppBrowserActivity;
|
||||
public MethodChannel channel;
|
||||
private ValueCallback<Uri> mUploadMessage;
|
||||
private final static int FILECHOOSER_RESULTCODE = 1;
|
||||
|
||||
|
@ -65,6 +64,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||
else if (obj instanceof FlutterWebView)
|
||||
this.flutterWebView = (FlutterWebView) obj;
|
||||
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
|
||||
|
||||
if (Shared.registrar != null)
|
||||
Shared.registrar.addActivityResultListener(this);
|
||||
|
@ -121,7 +121,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("message", message);
|
||||
|
||||
getChannel().invokeMethod("onJsAlert", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onJsAlert", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
String responseMessage = null;
|
||||
|
@ -204,7 +204,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("message", message);
|
||||
|
||||
getChannel().invokeMethod("onJsConfirm", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onJsConfirm", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
String responseMessage = null;
|
||||
|
@ -301,7 +301,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
obj.put("message", message);
|
||||
obj.put("defaultValue", defaultValue);
|
||||
|
||||
getChannel().invokeMethod("onJsPrompt", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onJsPrompt", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
String responseMessage = null;
|
||||
|
@ -433,7 +433,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
super.onPageStarted(v, url, favicon);
|
||||
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("onCreateWindow", obj);
|
||||
channel.invokeMethod("onCreateWindow", obj);
|
||||
|
||||
// stop webview loading
|
||||
v.stopLoading();
|
||||
|
@ -449,7 +449,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
|
||||
obj.put("url", data);
|
||||
getChannel().invokeMethod("onCreateWindow", obj);
|
||||
channel.invokeMethod("onCreateWindow", obj);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -459,7 +459,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("origin", origin);
|
||||
getChannel().invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object o) {
|
||||
Map<String, Object> response = (Map<String, Object>) o;
|
||||
|
@ -486,7 +486,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
Map<String, Object> obj = new HashMap<>();
|
||||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
getChannel().invokeMethod("onGeolocationPermissionsHidePrompt", obj);
|
||||
channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -496,7 +496,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("message", consoleMessage.message());
|
||||
obj.put("messageLevel", consoleMessage.messageLevel().ordinal());
|
||||
getChannel().invokeMethod("onConsoleMessage", obj);
|
||||
channel.invokeMethod("onConsoleMessage", obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -518,7 +518,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("progress", progress);
|
||||
getChannel().invokeMethod("onProgressChanged", obj);
|
||||
channel.invokeMethod("onProgressChanged", obj);
|
||||
|
||||
super.onProgressChanged(view, progress);
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("origin", request.getOrigin().toString());
|
||||
obj.put("resources", Arrays.asList(request.getResources()));
|
||||
getChannel().invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -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;
|
|||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebStorage;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
|
@ -53,6 +52,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
protected static final String LOG_TAG = "IABWebViewClient";
|
||||
private FlutterWebView flutterWebView;
|
||||
private InAppBrowserActivity inAppBrowserActivity;
|
||||
public MethodChannel channel;
|
||||
private static int previousAuthRequestFailureCount = 0;
|
||||
private static List<Credential> credentialsProposed = null;
|
||||
|
||||
|
@ -62,6 +62,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||
else if (obj instanceof FlutterWebView)
|
||||
this.flutterWebView = (FlutterWebView) obj;
|
||||
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
|
@ -125,7 +126,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("androidHasGesture", hasGesture);
|
||||
obj.put("androidIsRedirect", isRedirect);
|
||||
obj.put("iosWKNavigationType", null);
|
||||
getChannel().invokeMethod("shouldOverrideUrlLoading", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("shouldOverrideUrlLoading", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -199,7 +200,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("onLoadStart", obj);
|
||||
channel.invokeMethod("onLoadStart", obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +213,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
previousAuthRequestFailureCount = 0;
|
||||
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) {
|
||||
CookieManager.getInstance().flush();
|
||||
} else {
|
||||
|
@ -235,7 +236,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
if (inAppBrowserActivity != null)
|
||||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
getChannel().invokeMethod("onLoadStop", obj);
|
||||
channel.invokeMethod("onLoadStop", obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -245,7 +246,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("uuid", inAppBrowserActivity.uuid);
|
||||
obj.put("url", url);
|
||||
obj.put("androidIsReload", isReload);
|
||||
getChannel().invokeMethod("onUpdateVisitedHistory", obj);
|
||||
channel.invokeMethod("onUpdateVisitedHistory", obj);
|
||||
|
||||
super.doUpdateVisitedHistory(view, url, isReload);
|
||||
}
|
||||
|
@ -264,7 +265,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("url", failingUrl);
|
||||
obj.put("code", errorCode);
|
||||
obj.put("message", description);
|
||||
getChannel().invokeMethod("onLoadError", obj);
|
||||
channel.invokeMethod("onLoadError", obj);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
|
@ -278,7 +279,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("url", request.getUrl().toString());
|
||||
obj.put("statusCode", errorResponse.getStatusCode());
|
||||
obj.put("description", errorResponse.getReasonPhrase());
|
||||
getChannel().invokeMethod("onLoadHttpError", obj);
|
||||
channel.invokeMethod("onLoadHttpError", obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +317,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("port", port);
|
||||
obj.put("previousFailureCount", previousAuthRequestFailureCount);
|
||||
|
||||
getChannel().invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onReceivedHttpAuthRequest", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -461,7 +462,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
|
||||
Log.d(LOG_TAG, obj.toString());
|
||||
|
||||
getChannel().invokeMethod("onReceivedServerTrustAuthRequest", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onReceivedServerTrustAuthRequest", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -520,7 +521,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("realm", realm);
|
||||
obj.put("port", request.getPort());
|
||||
|
||||
getChannel().invokeMethod("onReceivedClientCertRequest", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onReceivedClientCertRequest", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -579,7 +580,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
obj.put("url", request.getUrl().toString());
|
||||
obj.put("threatType", threatType);
|
||||
|
||||
getChannel().invokeMethod("onSafeBrowsingHit", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onSafeBrowsingHit", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object response) {
|
||||
if (response != null) {
|
||||
|
@ -652,7 +653,7 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
|
||||
Util.WaitFlutterResult flutterResult;
|
||||
try {
|
||||
flutterResult = Util.invokeMethodAndWait(getChannel(), "onLoadResourceCustomScheme", obj);
|
||||
flutterResult = Util.invokeMethodAndWait(channel, "onLoadResourceCustomScheme", obj);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(LOG_TAG, e.getMessage());
|
||||
|
@ -701,9 +702,4 @@ public class InAppWebViewClient extends WebViewClient {
|
|||
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;
|
|||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.webkit.ValueCallback;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||
|
@ -19,7 +18,8 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
|
||||
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 MyCookieManager myCookieManager;
|
||||
public static CredentialDatabaseHandler credentialDatabaseHandler;
|
||||
|
@ -46,8 +46,10 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
|
||||
Shared.applicationContext = applicationContext;
|
||||
Shared.activity = activity;
|
||||
Shared.messenger = messenger;
|
||||
|
||||
inAppBrowser = new InAppBrowser(messenger);
|
||||
inAppBrowserManager = new InAppBrowserManager(messenger);
|
||||
chromeSafariBrowserManager = new ChromeSafariBrowserManager(messenger);
|
||||
|
||||
platformViewRegistry.registerViewFactory(
|
||||
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView));
|
||||
|
@ -61,9 +63,13 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
|
||||
@Override
|
||||
public void onDetachedFromEngine(FlutterPluginBinding binding) {
|
||||
if (inAppBrowser != null) {
|
||||
inAppBrowser.dispose();
|
||||
inAppBrowser = null;
|
||||
if (inAppBrowserManager != null) {
|
||||
inAppBrowserManager.dispose();
|
||||
inAppBrowserManager = null;
|
||||
}
|
||||
if (chromeSafariBrowserManager != null) {
|
||||
chromeSafariBrowserManager.dispose();
|
||||
chromeSafariBrowserManager = null;
|
||||
}
|
||||
if (myCookieManager != null) {
|
||||
myCookieManager.dispose();
|
||||
|
|
|
@ -9,13 +9,7 @@ import android.webkit.ValueCallback;
|
|||
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
@ -25,6 +19,7 @@ public class JavaScriptBridgeInterface {
|
|||
public static final String name = "flutter_inappwebview";
|
||||
private FlutterWebView flutterWebView;
|
||||
private InAppBrowserActivity inAppBrowserActivity;
|
||||
public MethodChannel channel;
|
||||
|
||||
// https://github.com/taylorhakes/promise-polyfill/blob/master/src/index.js
|
||||
public static final String promisePolyfillJS = "if (window.Promise == null) {" +
|
||||
|
@ -254,6 +249,7 @@ public class JavaScriptBridgeInterface {
|
|||
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
|
||||
else if (obj instanceof FlutterWebView)
|
||||
this.flutterWebView = (FlutterWebView) obj;
|
||||
this.channel = (this.inAppBrowserActivity != null) ? this.inAppBrowserActivity.channel : this.flutterWebView.channel;
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
|
@ -277,7 +273,7 @@ public class JavaScriptBridgeInterface {
|
|||
webView.printCurrentPage();
|
||||
}
|
||||
|
||||
getChannel().invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() {
|
||||
channel.invokeMethod("onCallJsHandler", obj, new MethodChannel.Result() {
|
||||
@Override
|
||||
public void success(Object json) {
|
||||
if (webView == null) {
|
||||
|
@ -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;
|
|||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
public class Shared {
|
||||
public static Context applicationContext;
|
||||
public static PluginRegistry.Registrar registrar;
|
||||
public static BinaryMessenger messenger;
|
||||
public static FlutterPlugin.FlutterAssets flutterAssets;
|
||||
public static ActivityPluginBinding activityPluginBinding;
|
||||
public static Activity activity;
|
||||
|
|
|
@ -196,10 +196,9 @@
|
|||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
|
|
|
@ -38,9 +38,8 @@ class MyInAppBrowser extends InAppBrowser {
|
|||
|
||||
@override
|
||||
Future<ShouldOverrideUrlLoadingAction> shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
|
||||
print("\n\n override ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
||||
this.webViewController.loadUrl(url: shouldOverrideUrlLoadingRequest.url);
|
||||
return ShouldOverrideUrlLoadingAction.CANCEL;
|
||||
print("\n\nOverride ${shouldOverrideUrlLoadingRequest.url}\n\n");
|
||||
return ShouldOverrideUrlLoadingAction.ALLOW;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -87,14 +86,15 @@ class _InAppBrowserExampleScreenState extends State<InAppBrowserExampleScreen> {
|
|||
drawer: myDrawer(context: context),
|
||||
body: Center(
|
||||
child: RaisedButton(
|
||||
onPressed: () {
|
||||
widget.browser.openFile(
|
||||
onPressed: () async {
|
||||
await widget.browser.openFile(
|
||||
assetFilePath: "assets/index.html",
|
||||
options: InAppBrowserClassOptions(
|
||||
inAppWebViewWidgetOptions: InAppWebViewWidgetOptions(
|
||||
crossPlatform: InAppWebViewOptions(
|
||||
useShouldOverrideUrlLoading: true,
|
||||
useOnLoadResource: true,
|
||||
debuggingEnabled: true,
|
||||
useShouldOverrideUrlLoading: true,
|
||||
useOnLoadResource: true,
|
||||
))));
|
||||
},
|
||||
child: Text("Open Webview Browser")),
|
||||
|
|
|
@ -59,6 +59,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
),
|
||||
onWebViewCreated: (InAppWebViewController controller) {
|
||||
webView = controller;
|
||||
print("onWebViewCreated");
|
||||
},
|
||||
onLoadStart: (InAppWebViewController controller, String url) {
|
||||
print("onLoadStart $url");
|
||||
|
@ -71,6 +72,29 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
setState(() {
|
||||
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) {
|
||||
setState(() {
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// 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 {
|
|||
if let url = urlSchemeTask.request.url, let scheme = url.scheme {
|
||||
inAppWebView.onLoadResourceCustomScheme(scheme: scheme, url: url.absoluteString, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {}
|
||||
else {
|
||||
let json: [String: Any]
|
||||
if let r = result {
|
||||
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
|
||||
if (self.schemeHandlers[urlSchemeTask.hash] != nil) {
|
||||
urlSchemeTask.didReceive(urlResponse)
|
||||
|
|
|
@ -25,20 +25,20 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
myView = UIView(frame: frame)
|
||||
|
||||
let channelName = "com.pichillilorenzo/flutter_inappwebview_" + String(viewId)
|
||||
self.channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
|
||||
self.channel?.setMethodCallHandler(LeakAvoider(delegate: self).handle)
|
||||
channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
|
||||
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 initialData = args["initialData"] as? [String: String]
|
||||
let initialHeaders = (args["initialHeaders"] as? [String: String])!
|
||||
let initialOptions = (args["initialOptions"] as? [String: Any])!
|
||||
let initialHeaders = args["initialHeaders"] as? [String: String]
|
||||
let initialOptions = args["initialOptions"] as! [String: Any?]
|
||||
|
||||
let options = InAppWebViewOptions()
|
||||
options.parse(options: initialOptions)
|
||||
let _ = options.parse(options: initialOptions)
|
||||
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]
|
||||
myView!.addSubview(webView!)
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
|
||||
deinit {
|
||||
print("FlutterWebViewController - dealloc")
|
||||
self.channel?.setMethodCallHandler(nil)
|
||||
channel?.setMethodCallHandler(nil)
|
||||
webView!.dispose()
|
||||
webView = nil
|
||||
myView = nil
|
||||
|
@ -86,7 +86,7 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
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 {
|
||||
do {
|
||||
try webView!.loadFile(url: initialFile!, headers: initialHeaders)
|
||||
|
@ -98,14 +98,14 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
}
|
||||
|
||||
if initialData != nil {
|
||||
let data = (initialData!["data"] as? String)!
|
||||
let mimeType = (initialData!["mimeType"] as? String)!
|
||||
let encoding = (initialData!["encoding"] as? String)!
|
||||
let baseUrl = (initialData!["baseUrl"] as? String)!
|
||||
let data = initialData!["data"]!
|
||||
let mimeType = initialData!["mimeType"]!
|
||||
let encoding = initialData!["encoding"]!
|
||||
let baseUrl = initialData!["baseUrl"]!
|
||||
webView!.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||
}
|
||||
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
|
|||
if webView != nil {
|
||||
let inAppWebViewOptions = InAppWebViewOptions()
|
||||
let inAppWebViewOptionsMap = arguments!["options"] as! [String: Any]
|
||||
inAppWebViewOptions.parse(options: inAppWebViewOptionsMap)
|
||||
let _ = inAppWebViewOptions.parse(options: inAppWebViewOptionsMap)
|
||||
webView!.setOptions(newOptions: inAppWebViewOptions, newOptionsMap: inAppWebViewOptionsMap)
|
||||
}
|
||||
result(true)
|
||||
|
@ -277,8 +277,13 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
case "findAllAsync":
|
||||
if webView != nil {
|
||||
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)
|
||||
})
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
|
@ -347,13 +352,12 @@ public class FlutterWebViewController: FlutterMethodCallDelegate, FlutterPlatfor
|
|||
case "printCurrentPage":
|
||||
if webView != nil {
|
||||
webView!.printCurrentPage(printCompletionHandler: {(completed, error) in
|
||||
if !completed, let e = error {
|
||||
if !completed, let _ = error {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
//
|
||||
// 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)})
|
||||
}
|
|
@ -14,55 +14,7 @@ import AVFoundation
|
|||
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
|
||||
typealias NewerClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
|
||||
|
||||
//extension WKWebView{
|
||||
//
|
||||
// var keyboardDisplayRequiresUserAction: Bool? {
|
||||
// get {
|
||||
// return self.keyboardDisplayRequiresUserAction
|
||||
// }
|
||||
// set {
|
||||
// self.setKeyboardRequiresUserInteraction(newValue ?? true)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func setKeyboardRequiresUserInteraction( _ value: Bool) {
|
||||
//
|
||||
// guard
|
||||
// let WKContentViewClass: AnyClass = NSClassFromString("WKContentView") else {
|
||||
// print("Cannot find the WKContentView class")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// let olderSelector: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:")
|
||||
// let newerSelector: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:")
|
||||
//
|
||||
// if let method = class_getInstanceMethod(WKContentViewClass, olderSelector) {
|
||||
//
|
||||
// let originalImp: IMP = method_getImplementation(method)
|
||||
// let original: OlderClosureType = unsafeBitCast(originalImp, to: OlderClosureType.self)
|
||||
// let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3) in
|
||||
// original(me, olderSelector, arg0, !value, arg2, arg3)
|
||||
// }
|
||||
// let imp: IMP = imp_implementationWithBlock(block)
|
||||
// method_setImplementation(method, imp)
|
||||
// }
|
||||
//
|
||||
// if let method = class_getInstanceMethod(WKContentViewClass, newerSelector) {
|
||||
//
|
||||
// let originalImp: IMP = method_getImplementation(method)
|
||||
// let original: NewerClosureType = unsafeBitCast(originalImp, to: NewerClosureType.self)
|
||||
// let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
|
||||
// original(me, newerSelector, arg0, !value, arg2, arg3, arg4)
|
||||
// }
|
||||
// let imp: IMP = imp_implementationWithBlock(block)
|
||||
// method_setImplementation(method, imp)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
class InAppWebView_IBWrapper: InAppWebView {
|
||||
public class InAppWebView_IBWrapper: InAppWebView {
|
||||
required init(coder: NSCoder) {
|
||||
let config = WKWebViewConfiguration()
|
||||
super.init(frame: .zero, configuration: config, IABController: nil, channel: nil)
|
||||
|
@ -70,7 +22,7 @@ class InAppWebView_IBWrapper: InAppWebView {
|
|||
}
|
||||
}
|
||||
|
||||
class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, UITextFieldDelegate {
|
||||
public class InAppBrowserWebViewController: UIViewController, FlutterPlugin, UIScrollViewDelegate, WKUIDelegate, UITextFieldDelegate {
|
||||
|
||||
@IBOutlet var containerWebView: UIView!
|
||||
@IBOutlet var closeButton: UIButton!
|
||||
|
@ -90,8 +42,9 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
@IBOutlet var webView_BottomFullScreenConstraint: NSLayoutConstraint!
|
||||
@IBOutlet var webView_TopFullScreenConstraint: NSLayoutConstraint!
|
||||
|
||||
var uuid: String = ""
|
||||
var webView: InAppWebView!
|
||||
weak var navigationDelegate: SwiftFlutterPlugin?
|
||||
var channel: FlutterMethodChannel?
|
||||
var initURL: URL?
|
||||
var tmpWindow: UIWindow?
|
||||
var browserOptions: InAppBrowserOptions?
|
||||
|
@ -102,25 +55,245 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
var initEncoding: String?
|
||||
var initBaseUrl: String?
|
||||
var isHidden = false
|
||||
var uuid: String = ""
|
||||
var WKNavigationMap: [String: [String: Any]] = [:]
|
||||
var startPageTime: Int64 = 0
|
||||
var viewPrepared = false
|
||||
var previousStatusBarStyle = -1
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)!
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
|
||||
}
|
||||
|
||||
public func prepareMethodChannel() {
|
||||
channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
|
||||
SwiftFlutterPlugin.instance!.registrar!.addMethodCallDelegate(self, channel: channel!)
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
let arguments = call.arguments as? NSDictionary
|
||||
|
||||
switch call.method {
|
||||
case "getUrl":
|
||||
result(webView.url?.absoluteString)
|
||||
break
|
||||
case "getTitle":
|
||||
result(webView.title)
|
||||
break
|
||||
case "getProgress":
|
||||
let progress = Int(webView.estimatedProgress * 100)
|
||||
result(progress)
|
||||
break
|
||||
case "loadUrl":
|
||||
let url = arguments!["url"] as! String
|
||||
let headers = arguments!["headers"] as? [String: String]
|
||||
let absoluteUrl = URL(string: url)!.absoluteURL
|
||||
webView.loadUrl(url: absoluteUrl, headers: headers)
|
||||
result(true)
|
||||
break
|
||||
case "loadData":
|
||||
let data = arguments!["data"] as! String
|
||||
let mimeType = arguments!["mimeType"] as! String
|
||||
let encoding = arguments!["encoding"] as! String
|
||||
let baseUrl = arguments!["baseUrl"] as! String
|
||||
webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||
result(true)
|
||||
break
|
||||
case "postUrl":
|
||||
let url = arguments!["url"] as! String
|
||||
let postData = arguments!["postData"] as! FlutterStandardTypedData
|
||||
let absoluteUrl = URL(string: url)!.absoluteURL
|
||||
webView.postUrl(url: absoluteUrl, postData: postData.data, completionHandler: { () -> Void in
|
||||
result(true)
|
||||
})
|
||||
break
|
||||
case "loadFile":
|
||||
let url = arguments!["url"] as! String
|
||||
let headers = arguments!["headers"] as? [String: String]
|
||||
do {
|
||||
try webView.loadFile(url: url, headers: headers)
|
||||
result(true)
|
||||
}
|
||||
catch let error as NSError {
|
||||
dump(error)
|
||||
result(FlutterError(code: "InAppBrowserWebViewController", message: error.localizedDescription, details: nil))
|
||||
}
|
||||
break
|
||||
case "close":
|
||||
close()
|
||||
result(true)
|
||||
break
|
||||
case "show":
|
||||
show()
|
||||
result(true)
|
||||
break
|
||||
case "hide":
|
||||
hide()
|
||||
result(true)
|
||||
break
|
||||
case "reload":
|
||||
webView.reload()
|
||||
result(true)
|
||||
break
|
||||
case "goBack":
|
||||
webView.goBack()
|
||||
result(true)
|
||||
break
|
||||
case "canGoBack":
|
||||
result(webView.canGoBack)
|
||||
break
|
||||
case "goForward":
|
||||
webView.goForward()
|
||||
result(true)
|
||||
break
|
||||
case "canGoForward":
|
||||
result(webView.canGoForward)
|
||||
break
|
||||
case "goBackOrForward":
|
||||
let steps = arguments!["steps"] as! Int
|
||||
webView.goBackOrForward(steps: steps)
|
||||
result(true)
|
||||
break
|
||||
case "canGoBackOrForward":
|
||||
let steps = arguments!["steps"] as! Int
|
||||
result(webView.canGoBackOrForward(steps: steps))
|
||||
break
|
||||
case "isLoading":
|
||||
result(webView.isLoading == true)
|
||||
break
|
||||
case "stopLoading":
|
||||
webView.stopLoading()
|
||||
result(true)
|
||||
break
|
||||
case "isHidden":
|
||||
result(isHidden == true)
|
||||
break
|
||||
case "evaluateJavascript":
|
||||
let source = arguments!["source"] as! String
|
||||
webView.evaluateJavascript(source: source, result: result)
|
||||
break
|
||||
case "injectJavascriptFileFromUrl":
|
||||
let urlFile = arguments!["urlFile"] as! String
|
||||
webView.injectJavascriptFileFromUrl(urlFile: urlFile)
|
||||
result(true)
|
||||
break
|
||||
case "injectCSSCode":
|
||||
let source = arguments!["source"] as! String
|
||||
webView.injectCSSCode(source: source)
|
||||
result(true)
|
||||
break
|
||||
case "injectCSSFileFromUrl":
|
||||
let urlFile = arguments!["urlFile"] as! String
|
||||
webView.injectCSSFileFromUrl(urlFile: urlFile)
|
||||
result(true)
|
||||
break
|
||||
case "takeScreenshot":
|
||||
webView.takeScreenshot(completionHandler: { (screenshot) -> Void in
|
||||
result(screenshot)
|
||||
})
|
||||
break
|
||||
case "setOptions":
|
||||
let inAppBrowserOptions = InAppBrowserOptions()
|
||||
let inAppBrowserOptionsMap = arguments!["options"] as! [String: Any]
|
||||
let _ = inAppBrowserOptions.parse(options: inAppBrowserOptionsMap)
|
||||
self.setOptions(newOptions: inAppBrowserOptions, newOptionsMap: inAppBrowserOptionsMap)
|
||||
result(true)
|
||||
break
|
||||
case "getOptions":
|
||||
result(getOptions())
|
||||
break
|
||||
case "getCopyBackForwardList":
|
||||
result(webView.getCopyBackForwardList())
|
||||
break
|
||||
case "findAllAsync":
|
||||
let find = arguments!["find"] as! String
|
||||
webView.findAllAsync(find: find, completionHandler: {(value, error) in
|
||||
if error != nil {
|
||||
result(FlutterError(code: "InAppBrowserWebViewController", message: error?.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
break
|
||||
case "findNext":
|
||||
let forward = arguments!["forward"] as! Bool
|
||||
webView.findNext(forward: forward, completionHandler: {(value, error) in
|
||||
if error != nil {
|
||||
result(FlutterError(code: "InAppBrowserWebViewController", message: error?.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
break
|
||||
case "clearMatches":
|
||||
webView.clearMatches(completionHandler: {(value, error) in
|
||||
if error != nil {
|
||||
result(FlutterError(code: "InAppBrowserWebViewController", message: error?.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
break
|
||||
case "clearCache":
|
||||
webView.clearCache()
|
||||
result(true)
|
||||
break
|
||||
case "scrollTo":
|
||||
let x = arguments!["x"] as! Int
|
||||
let y = arguments!["y"] as! Int
|
||||
webView.scrollTo(x: x, y: y)
|
||||
result(true)
|
||||
break
|
||||
case "scrollBy":
|
||||
let x = arguments!["x"] as! Int
|
||||
let y = arguments!["y"] as! Int
|
||||
webView.scrollTo(x: x, y: y)
|
||||
result(true)
|
||||
break
|
||||
case "pauseTimers":
|
||||
webView.pauseTimers()
|
||||
result(true)
|
||||
break
|
||||
case "resumeTimers":
|
||||
webView.resumeTimers()
|
||||
result(true)
|
||||
break
|
||||
case "printCurrentPage":
|
||||
webView.printCurrentPage(printCompletionHandler: {(completed, error) in
|
||||
if !completed, let _ = error {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
break
|
||||
case "getContentHeight":
|
||||
result(webView.getContentHeight())
|
||||
break
|
||||
case "reloadFromOrigin":
|
||||
webView.reloadFromOrigin()
|
||||
result(true)
|
||||
break
|
||||
case "getScale":
|
||||
result(webView.getScale())
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
if !viewPrepared {
|
||||
let preWebviewConfiguration = InAppWebView.preWKWebViewConfiguration(options: webViewOptions)
|
||||
self.webView = InAppWebView(frame: .zero, configuration: preWebviewConfiguration, IABController: self, channel: nil)
|
||||
self.webView = InAppWebView(frame: .zero, configuration: preWebviewConfiguration, IABController: self, channel: channel!)
|
||||
self.containerWebView.addSubview(self.webView)
|
||||
prepareConstraints()
|
||||
prepareWebView()
|
||||
|
||||
if #available(iOS 11.0, *) {
|
||||
if let contentBlockers = webView!.options?.contentBlockers, contentBlockers.count > 0 {
|
||||
if let contentBlockers = webView.options?.contentBlockers, contentBlockers.count > 0 {
|
||||
do {
|
||||
let jsonData = try JSONSerialization.data(withJSONObject: contentBlockers, options: [])
|
||||
let blockRules = String(data: jsonData, encoding: String.Encoding.utf8)
|
||||
|
@ -138,7 +311,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
|
||||
self.initLoad(initURL: self.initURL, initData: self.initData, initMimeType: self.initMimeType, initEncoding: self.initEncoding, initBaseUrl: self.initBaseUrl, initHeaders: self.initHeaders)
|
||||
|
||||
self.navigationDelegate?.onBrowserCreated(uuid: self.uuid, webView: self.webView)
|
||||
self.onBrowserCreated()
|
||||
}
|
||||
return
|
||||
} catch {
|
||||
|
@ -149,13 +322,13 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
|
||||
initLoad(initURL: initURL, initData: initData, initMimeType: initMimeType, initEncoding: initEncoding, initBaseUrl: initBaseUrl, initHeaders: initHeaders)
|
||||
|
||||
navigationDelegate?.onBrowserCreated(uuid: uuid, webView: webView)
|
||||
onBrowserCreated()
|
||||
}
|
||||
viewPrepared = true
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
func initLoad(initURL: URL?, initData: String?, initMimeType: String?, initEncoding: String?, initBaseUrl: String?, initHeaders: [String: String]?) {
|
||||
public func initLoad(initURL: URL?, initData: String?, initMimeType: String?, initEncoding: String?, initBaseUrl: String?, initHeaders: [String: String]?) {
|
||||
if self.initData == nil {
|
||||
loadUrl(url: self.initURL!, headers: self.initHeaders)
|
||||
}
|
||||
|
@ -164,7 +337,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
public override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
urlField.delegate = self
|
||||
|
@ -197,39 +370,28 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
print("InAppBrowserWebViewController - dealloc")
|
||||
}
|
||||
|
||||
override func viewWillDisappear (_ animated: Bool) {
|
||||
public override func viewWillDisappear (_ animated: Bool) {
|
||||
dispose()
|
||||
super.viewWillDisappear(animated)
|
||||
webView.dispose()
|
||||
navigationDelegate = nil
|
||||
transitioningDelegate = nil
|
||||
urlField.delegate = nil
|
||||
closeButton.removeTarget(self, action: #selector(self.close), for: .touchUpInside)
|
||||
forwardButton.target = nil
|
||||
forwardButton.target = nil
|
||||
backButton.target = nil
|
||||
reloadButton.target = nil
|
||||
shareButton.target = nil
|
||||
}
|
||||
|
||||
func prepareConstraints () {
|
||||
containerWebView_BottomFullScreenConstraint = NSLayoutConstraint(item: self.containerWebView, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
|
||||
containerWebView_TopFullScreenConstraint = NSLayoutConstraint(item: self.containerWebView, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
|
||||
public func prepareConstraints () {
|
||||
containerWebView_BottomFullScreenConstraint = NSLayoutConstraint(item: self.containerWebView!, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
|
||||
containerWebView_TopFullScreenConstraint = NSLayoutConstraint(item: self.containerWebView!, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
|
||||
|
||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||
let height = NSLayoutConstraint(item: webView, attribute: .height, relatedBy: .equal, toItem: containerWebView, attribute: .height, multiplier: 1, constant: 0)
|
||||
let width = NSLayoutConstraint(item: webView, attribute: .width, relatedBy: .equal, toItem: containerWebView, attribute: .width, multiplier: 1, constant: 0)
|
||||
let leftConstraint = NSLayoutConstraint(item: webView, attribute: .leftMargin, relatedBy: .equal, toItem: containerWebView, attribute: .leftMargin, multiplier: 1, constant: 0)
|
||||
let rightConstraint = NSLayoutConstraint(item: webView, attribute: .rightMargin, relatedBy: .equal, toItem: containerWebView, attribute: .rightMargin, multiplier: 1, constant: 0)
|
||||
let bottomContraint = NSLayoutConstraint(item: webView, attribute: .bottomMargin, relatedBy: .equal, toItem: containerWebView, attribute: .bottomMargin, multiplier: 1, constant: 0)
|
||||
let height = NSLayoutConstraint(item: self.webView!, attribute: .height, relatedBy: .equal, toItem: containerWebView, attribute: .height, multiplier: 1, constant: 0)
|
||||
let width = NSLayoutConstraint(item: self.webView!, attribute: .width, relatedBy: .equal, toItem: containerWebView, attribute: .width, multiplier: 1, constant: 0)
|
||||
let leftConstraint = NSLayoutConstraint(item: self.webView!, attribute: .leftMargin, relatedBy: .equal, toItem: containerWebView, attribute: .leftMargin, multiplier: 1, constant: 0)
|
||||
let rightConstraint = NSLayoutConstraint(item: self.webView!, attribute: .rightMargin, relatedBy: .equal, toItem: containerWebView, attribute: .rightMargin, multiplier: 1, constant: 0)
|
||||
let bottomContraint = NSLayoutConstraint(item: self.webView!, attribute: .bottomMargin, relatedBy: .equal, toItem: containerWebView, attribute: .bottomMargin, multiplier: 1, constant: 0)
|
||||
containerWebView.addConstraints([height, width, leftConstraint, rightConstraint, bottomContraint])
|
||||
|
||||
webView_BottomFullScreenConstraint = NSLayoutConstraint(item: self.webView, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerWebView, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
|
||||
webView_TopFullScreenConstraint = NSLayoutConstraint(item: self.webView, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerWebView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
|
||||
webView_BottomFullScreenConstraint = NSLayoutConstraint(item: webView!, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerWebView, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
|
||||
webView_TopFullScreenConstraint = NSLayoutConstraint(item: webView!, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.containerWebView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1, constant: 0)
|
||||
}
|
||||
|
||||
func prepareWebView() {
|
||||
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
|
||||
|
||||
public func prepareWebView() {
|
||||
self.webView.options = webViewOptions
|
||||
self.webView.prepare()
|
||||
|
||||
|
@ -274,13 +436,13 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: (browserOptions?.transitionStyle)!)!
|
||||
}
|
||||
|
||||
func loadUrl(url: URL, headers: [String: String]?) {
|
||||
public func loadUrl(url: URL, headers: [String: String]?) {
|
||||
webView.loadUrl(url: url, headers: headers)
|
||||
updateUrlTextField(url: (webView.currentURL?.absoluteString)!)
|
||||
}
|
||||
|
||||
// Load user requested url
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
if textField.text != nil && textField.text != "" {
|
||||
let url = textField.text?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
|
||||
|
@ -298,69 +460,91 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
webView.frame = frame
|
||||
}
|
||||
|
||||
@objc func reload () {
|
||||
public func show() {
|
||||
isHidden = false
|
||||
view.isHidden = false
|
||||
|
||||
// Run later to avoid the "took a long time" log message.
|
||||
DispatchQueue.main.async(execute: {() -> Void in
|
||||
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(baseWindowLevel!.rawValue + 1.0)
|
||||
self.tmpWindow?.makeKeyAndVisible()
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
self.tmpWindow?.rootViewController?.present(self, animated: true, completion: nil)
|
||||
})
|
||||
}
|
||||
|
||||
public func hide() {
|
||||
isHidden = true
|
||||
|
||||
// Run later to avoid the "took a long time" log message.
|
||||
DispatchQueue.main.async(execute: {() -> Void in
|
||||
self.presentingViewController?.dismiss(animated: true, completion: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
if self.previousStatusBarStyle != -1 {
|
||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@objc public func reload () {
|
||||
webView.reload()
|
||||
}
|
||||
|
||||
@objc func share () {
|
||||
@objc public func share () {
|
||||
let vc = UIActivityViewController(activityItems: [webView.currentURL ?? ""], applicationActivities: [])
|
||||
present(vc, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func close() {
|
||||
//currentURL = nil
|
||||
|
||||
@objc public func close() {
|
||||
weak var weakSelf = self
|
||||
|
||||
if (weakSelf?.responds(to: #selector(getter: self.presentingViewController)))! {
|
||||
weakSelf?.presentingViewController?.dismiss(animated: true, completion: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
|
||||
})
|
||||
}
|
||||
else {
|
||||
weakSelf?.parent?.dismiss(animated: true, completion: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
|
||||
})
|
||||
}
|
||||
if (self.navigationDelegate != nil) {
|
||||
self.navigationDelegate?.browserExit(uuid: self.uuid)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func goBack() {
|
||||
@objc public func goBack() {
|
||||
if canGoBack() {
|
||||
webView.goBack()
|
||||
updateUrlTextField(url: (webView?.url?.absoluteString)!)
|
||||
}
|
||||
}
|
||||
|
||||
func canGoBack() -> Bool {
|
||||
public func canGoBack() -> Bool {
|
||||
return webView.canGoBack
|
||||
}
|
||||
|
||||
@objc func goForward() {
|
||||
@objc public func goForward() {
|
||||
if canGoForward() {
|
||||
webView.goForward()
|
||||
updateUrlTextField(url: (webView?.url?.absoluteString)!)
|
||||
}
|
||||
}
|
||||
|
||||
func canGoForward() -> Bool {
|
||||
public func canGoForward() -> Bool {
|
||||
return webView.canGoForward
|
||||
}
|
||||
|
||||
@objc func goBackOrForward(steps: Int) {
|
||||
@objc public func goBackOrForward(steps: Int) {
|
||||
webView.goBackOrForward(steps: steps)
|
||||
updateUrlTextField(url: (webView?.url?.absoluteString)!)
|
||||
}
|
||||
|
||||
func canGoBackOrForward(steps: Int) -> Bool {
|
||||
public func canGoBackOrForward(steps: Int) -> Bool {
|
||||
return webView.canGoBackOrForward(steps: steps)
|
||||
}
|
||||
|
||||
func updateUrlTextField(url: String) {
|
||||
public func updateUrlTextField(url: String) {
|
||||
urlField.text = url
|
||||
}
|
||||
|
||||
|
@ -405,18 +589,18 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
return hexInt
|
||||
}
|
||||
|
||||
func setOptions(newOptions: InAppBrowserOptions, newOptionsMap: [String: Any]) {
|
||||
public func setOptions(newOptions: InAppBrowserOptions, newOptionsMap: [String: Any]) {
|
||||
|
||||
let newInAppWebViewOptions = InAppWebViewOptions()
|
||||
newInAppWebViewOptions.parse(options: newOptionsMap)
|
||||
let _ = newInAppWebViewOptions.parse(options: newOptionsMap)
|
||||
self.webView.setOptions(newOptions: newInAppWebViewOptions, newOptionsMap: newOptionsMap)
|
||||
|
||||
if newOptionsMap["hidden"] != nil && browserOptions?.hidden != newOptions.hidden {
|
||||
if newOptions.hidden {
|
||||
self.navigationDelegate?.hide(uuid: self.uuid)
|
||||
hide()
|
||||
}
|
||||
else {
|
||||
self.navigationDelegate?.show(uuid: self.uuid)
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,7 +655,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
self.webViewOptions = newInAppWebViewOptions
|
||||
}
|
||||
|
||||
func getOptions() -> [String: Any]? {
|
||||
public func getOptions() -> [String: Any?]? {
|
||||
if (self.browserOptions == nil || self.webView.getOptions() == nil) {
|
||||
return nil
|
||||
}
|
||||
|
@ -479,5 +663,31 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
|
|||
optionsMap.merge(self.webView.getOptions()!, uniquingKeysWith: { (current, _) in current })
|
||||
return optionsMap
|
||||
}
|
||||
|
||||
|
||||
public func dispose() {
|
||||
webView.dispose()
|
||||
if previousStatusBarStyle != -1 {
|
||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: previousStatusBarStyle)!
|
||||
}
|
||||
transitioningDelegate = nil
|
||||
urlField.delegate = nil
|
||||
closeButton.removeTarget(self, action: #selector(self.close), for: .touchUpInside)
|
||||
forwardButton.target = nil
|
||||
forwardButton.target = nil
|
||||
backButton.target = nil
|
||||
reloadButton.target = nil
|
||||
shareButton.target = nil
|
||||
tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
onExit()
|
||||
channel!.setMethodCallHandler(nil)
|
||||
}
|
||||
|
||||
public func onBrowserCreated() {
|
||||
channel!.invokeMethod("onBrowserCreated", arguments: [])
|
||||
}
|
||||
|
||||
public func onExit() {
|
||||
channel!.invokeMethod("onExit", arguments: [])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -890,7 +890,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
var activateShouldOverrideUrlLoading = false
|
||||
|
||||
init(frame: CGRect, configuration: WKWebViewConfiguration, IABController: InAppBrowserWebViewController?, channel: FlutterMethodChannel?) {
|
||||
|
||||
super.init(frame: frame, configuration: configuration)
|
||||
self.channel = channel
|
||||
self.IABController = IABController
|
||||
|
@ -1403,7 +1402,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
self.options = newOptions
|
||||
}
|
||||
|
||||
func getOptions() -> [String: Any]? {
|
||||
func getOptions() -> [String: Any?]? {
|
||||
if (self.options == nil) {
|
||||
return nil
|
||||
}
|
||||
|
@ -1512,7 +1511,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
|
||||
shouldOverrideUrlLoading(url: url, method: navigationAction.request.httpMethod, headers: navigationAction.request.allHTTPHeaderFields, isForMainFrame: isForMainFrame, navigationType: navigationAction.navigationType, result: { (result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
self.updateUrlTextFieldForIABController(navigationAction: navigationAction)
|
||||
|
@ -1642,7 +1641,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
let port = challenge.protectionSpace.port
|
||||
onReceivedHttpAuthRequest(challenge: challenge, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
completionHandler(.performDefaultHandling, nil)
|
||||
|
@ -1711,7 +1710,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
|
||||
onReceivedServerTrustAuthRequest(challenge: challenge, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
completionHandler(.performDefaultHandling, nil)
|
||||
|
@ -1746,7 +1745,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate {
|
||||
onReceivedClientCertRequest(challenge: challenge, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
completionHandler(.performDefaultHandling, nil)
|
||||
|
@ -1832,7 +1831,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
} else {
|
||||
print("Security Error: " + securityError.description)
|
||||
if #available(iOS 11.3, *) {
|
||||
print(SecCopyErrorMessageString(securityError,nil))
|
||||
print(SecCopyErrorMessageString(securityError,nil) ?? "")
|
||||
}
|
||||
}
|
||||
return identityAndTrust;
|
||||
|
@ -1863,7 +1862,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
|
||||
onJsAlert(message: message, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
self.createAlertDialog(message: message, responseMessage: nil, confirmButtonTitle: nil, completionHandler: completionHandler)
|
||||
|
@ -1921,7 +1920,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
|
||||
onJsConfirm(message: message, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
self.createConfirmDialog(message: message, responseMessage: nil, confirmButtonTitle: nil, cancelButtonTitle: nil, completionHandler: completionHandler)
|
||||
|
@ -1993,7 +1992,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
completionHandler: @escaping (String?) -> Void) {
|
||||
onJsPrompt(message: message, defaultValue: defaultValue, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {
|
||||
self.createPromptDialog(message: message, defaultValue: defaultValue, responseMessage: nil, confirmButtonTitle: nil, cancelButtonTitle: nil, value: nil, completionHandler: completionHandler)
|
||||
|
@ -2069,102 +2068,56 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
}
|
||||
|
||||
public func onLoadStart(url: String) {
|
||||
var arguments: [String: Any] = ["url": url]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onLoadStart", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["url": url]
|
||||
channel?.invokeMethod("onLoadStart", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onLoadStop(url: String) {
|
||||
var arguments: [String: Any] = ["url": url]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onLoadStop", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["url": url]
|
||||
channel?.invokeMethod("onLoadStop", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onLoadError(url: String, error: Error) {
|
||||
var arguments: [String: Any] = ["url": url, "code": error._code, "message": error.localizedDescription]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onLoadError", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["url": url, "code": error._code, "message": error.localizedDescription]
|
||||
channel?.invokeMethod("onLoadError", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onLoadHttpError(url: String, statusCode: Int, description: String) {
|
||||
var arguments: [String: Any] = ["url": url, "statusCode": statusCode, "description": description]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onLoadHttpError", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["url": url, "statusCode": statusCode, "description": description]
|
||||
channel?.invokeMethod("onLoadHttpError", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onProgressChanged(progress: Int) {
|
||||
var arguments: [String: Any] = ["progress": progress]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onProgressChanged", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["progress": progress]
|
||||
channel?.invokeMethod("onProgressChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onFindResultReceived(activeMatchOrdinal: Int, numberOfMatches: Int, isDoneCounting: Bool) {
|
||||
var arguments: [String : Any] = [
|
||||
let arguments: [String : Any] = [
|
||||
"activeMatchOrdinal": activeMatchOrdinal,
|
||||
"numberOfMatches": numberOfMatches,
|
||||
"isDoneCounting": isDoneCounting
|
||||
]
|
||||
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onFindResultReceived", arguments: arguments)
|
||||
}
|
||||
channel?.invokeMethod("onFindResultReceived", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onScrollChanged(x: Int, y: Int) {
|
||||
var arguments: [String: Any] = ["x": x, "y": y]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onScrollChanged", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["x": x, "y": y]
|
||||
channel?.invokeMethod("onScrollChanged", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onDownloadStart(url: String) {
|
||||
var arguments: [String: Any] = ["url": url]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onDownloadStart", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["url": url]
|
||||
channel?.invokeMethod("onDownloadStart", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onLoadResourceCustomScheme(scheme: String, url: String, result: FlutterResult?) {
|
||||
var arguments: [String: Any] = ["scheme": scheme, "url": url]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onLoadResourceCustomScheme", arguments: arguments, result: result)
|
||||
}
|
||||
let arguments: [String: Any] = ["scheme": scheme, "url": url]
|
||||
channel?.invokeMethod("onLoadResourceCustomScheme", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func shouldOverrideUrlLoading(url: URL, method: String?, headers: [String: String]?, isForMainFrame: Bool, navigationType: WKNavigationType, result: FlutterResult?) {
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"url": url.absoluteString,
|
||||
"method": method,
|
||||
"headers": headers,
|
||||
|
@ -2173,43 +2126,28 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
"androidIsRedirect": nil,
|
||||
"iosWKNavigationType": navigationType.rawValue
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("shouldOverrideUrlLoading", arguments: arguments, result: result)
|
||||
}
|
||||
channel?.invokeMethod("shouldOverrideUrlLoading", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onCreateWindow(url: URL, navigationType: WKNavigationType) {
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"url": url.absoluteString,
|
||||
"androidIsDialog": nil,
|
||||
"androidIsUserGesture": nil,
|
||||
"iosWKNavigationType": navigationType.rawValue
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onCreateWindow", arguments: arguments)
|
||||
}
|
||||
channel?.invokeMethod("onCreateWindow", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"host": challenge.protectionSpace.host,
|
||||
"protocol": challenge.protectionSpace.protocol,
|
||||
"realm": challenge.protectionSpace.realm,
|
||||
"port": challenge.protectionSpace.port,
|
||||
"previousFailureCount": challenge.previousFailureCount
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, result: result)
|
||||
}
|
||||
channel?.invokeMethod("onReceivedHttpAuthRequest", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onReceivedServerTrustAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
|
||||
|
@ -2222,7 +2160,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
serverCertificateData = NSData(bytes: data, length: size)
|
||||
}
|
||||
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"host": challenge.protectionSpace.host,
|
||||
"protocol": challenge.protectionSpace.protocol,
|
||||
"realm": challenge.protectionSpace.realm,
|
||||
|
@ -2232,103 +2170,62 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
"error": -1,
|
||||
"message": "",
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, result: result)
|
||||
}
|
||||
channel?.invokeMethod("onReceivedServerTrustAuthRequest", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onReceivedClientCertRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"host": challenge.protectionSpace.host,
|
||||
"protocol": challenge.protectionSpace.protocol,
|
||||
"realm": challenge.protectionSpace.realm,
|
||||
"port": challenge.protectionSpace.port
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onReceivedClientCertRequest", arguments: arguments, result: result)
|
||||
}
|
||||
channel?.invokeMethod("onReceivedClientCertRequest", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onJsAlert(message: String, result: FlutterResult?) {
|
||||
var arguments: [String: Any] = ["message": message]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onJsAlert", arguments: arguments, result: result)
|
||||
}
|
||||
let arguments: [String: Any] = ["message": message]
|
||||
channel?.invokeMethod("onJsAlert", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onJsConfirm(message: String, result: FlutterResult?) {
|
||||
var arguments: [String: Any] = ["message": message]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onJsConfirm", arguments: arguments, result: result)
|
||||
}
|
||||
let arguments: [String: Any] = ["message": message]
|
||||
channel?.invokeMethod("onJsConfirm", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onJsPrompt(message: String, defaultValue: String?, result: FlutterResult?) {
|
||||
var arguments: [String: Any] = ["message": message, "defaultValue": defaultValue as Any]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onJsPrompt", arguments: arguments, result: result)
|
||||
}
|
||||
let arguments: [String: Any] = ["message": message, "defaultValue": defaultValue as Any]
|
||||
channel?.invokeMethod("onJsPrompt", arguments: arguments, result: result)
|
||||
}
|
||||
|
||||
public func onConsoleMessage(message: String, messageLevel: Int) {
|
||||
var arguments: [String: Any] = ["message": message, "messageLevel": messageLevel]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onConsoleMessage", arguments: arguments)
|
||||
}
|
||||
let arguments: [String: Any] = ["message": message, "messageLevel": messageLevel]
|
||||
channel?.invokeMethod("onConsoleMessage", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onUpdateVisitedHistory(url: String) {
|
||||
var arguments: [String: Any?] = [
|
||||
let arguments: [String: Any?] = [
|
||||
"url": url,
|
||||
"androidIsReload": nil
|
||||
]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onUpdateVisitedHistory", arguments: arguments)
|
||||
}
|
||||
channel?.invokeMethod("onUpdateVisitedHistory", arguments: arguments)
|
||||
}
|
||||
|
||||
public func onCallJsHandler(handlerName: String, _callHandlerID: Int64, args: String) {
|
||||
var arguments: [String: Any] = ["handlerName": handlerName, "args": args]
|
||||
if IABController != nil {
|
||||
arguments["uuid"] = IABController!.uuid
|
||||
}
|
||||
|
||||
if let channel = getChannel() {
|
||||
channel.invokeMethod("onCallJsHandler", arguments: arguments, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message)
|
||||
let arguments: [String: Any] = ["handlerName": handlerName, "args": args]
|
||||
channel?.invokeMethod("onCallJsHandler", arguments: arguments, result: {(result) -> Void in
|
||||
if result is FlutterError {
|
||||
print((result as! FlutterError).message ?? "")
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {}
|
||||
else {
|
||||
var json = "null"
|
||||
if let r = result {
|
||||
json = r as! String
|
||||
}
|
||||
else if (result as? NSObject) == FlutterMethodNotImplemented {}
|
||||
else {
|
||||
var json = "null"
|
||||
if let r = result {
|
||||
json = r as! String
|
||||
}
|
||||
self.evaluateJavaScript("if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)](\(json)); delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)];}", completionHandler: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
self.evaluateJavaScript("if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)](\(json)); delete window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)];}", completionHandler: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
|
@ -2377,10 +2274,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
}
|
||||
}
|
||||
|
||||
private func getChannel() -> FlutterMethodChannel? {
|
||||
return (IABController != nil) ? SwiftFlutterPlugin.instance!.channel! : ((channel != nil) ? channel! : nil);
|
||||
}
|
||||
|
||||
public func findAllAsync(find: String?, completionHandler: ((Any?, Error?) -> Void)?) {
|
||||
let startSearch = "wkwebview_FindAllAsync('\(find ?? "")');"
|
||||
evaluateJavaScript(startSearch, completionHandler: completionHandler)
|
||||
|
|
|
@ -14,7 +14,7 @@ public class Options: NSObject {
|
|||
super.init()
|
||||
}
|
||||
|
||||
func parse(options: [String: Any]) -> Options {
|
||||
func parse(options: [String: Any?]) -> Options {
|
||||
for (key, value) in options {
|
||||
if self.responds(to: Selector(key)) {
|
||||
self.setValue(value, forKey: key)
|
||||
|
@ -23,8 +23,8 @@ public class Options: NSObject {
|
|||
return self
|
||||
}
|
||||
|
||||
func getHashMap() -> [String: Any] {
|
||||
var options: [String: Any] = [:]
|
||||
func getHashMap() -> [String: Any?] {
|
||||
var options: [String: Any?] = [:]
|
||||
var counts = UInt32();
|
||||
let properties = class_copyPropertyList(object_getClass(self), &counts);
|
||||
for i in 0..<counts {
|
||||
|
|
|
@ -9,16 +9,34 @@ import Foundation
|
|||
import SafariServices
|
||||
|
||||
@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 safariOptions: SafariBrowserOptions?
|
||||
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()
|
||||
super.viewWillAppear(animated)
|
||||
onChromeSafariBrowserOpened()
|
||||
}
|
||||
|
||||
func prepareSafariBrowser() {
|
||||
|
@ -45,50 +63,64 @@ class SafariViewController: SFSafariViewController, SFSafariViewControllerDelega
|
|||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
|
||||
if (self.statusDelegate != nil) {
|
||||
self.statusDelegate?.safariExit(uuid: self.uuid)
|
||||
}
|
||||
self.onChromeSafariBrowserClosed()
|
||||
self.dispose()
|
||||
})
|
||||
}
|
||||
|
||||
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
|
||||
public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
|
||||
close()
|
||||
}
|
||||
|
||||
func safariViewController(_ controller: SFSafariViewController,
|
||||
public func safariViewController(_ controller: SFSafariViewController,
|
||||
didCompleteInitialLoad didLoadSuccessfully: Bool) {
|
||||
if didLoadSuccessfully {
|
||||
statusDelegate?.onChromeSafariBrowserCompletedInitialLoad(uuid: self.uuid)
|
||||
onChromeSafariBrowserCompletedInitialLoad()
|
||||
}
|
||||
else {
|
||||
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(URL)
|
||||
// print(title)
|
||||
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(URL)
|
||||
// print(title)
|
||||
return []
|
||||
}
|
||||
|
||||
func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
|
||||
public func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
|
||||
// print("initialLoadDidRedirectTo")
|
||||
// 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
|
||||
// Assumes input like "#00FF00" (#RRGGBB).
|
||||
// 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 {
|
||||
|
||||
// Convert hex string to an integer
|
||||
|
|
|
@ -22,22 +22,16 @@ import Foundation
|
|||
import AVFoundation
|
||||
import SafariServices
|
||||
|
||||
let WEBVIEW_STORYBOARD = "WebView"
|
||||
let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
|
||||
|
||||
extension Dictionary where Key: ExpressibleByStringLiteral {
|
||||
public mutating func lowercaseKeys() {
|
||||
for key in self.keys {
|
||||
self[String(describing: key).lowercased() as! Key] = self.removeValue(forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||
|
||||
static var instance: SwiftFlutterPlugin?
|
||||
var registrar: FlutterPluginRegistrar?
|
||||
var channel: FlutterMethodChannel?
|
||||
var inAppWebViewStatic: InAppWebViewStatic?
|
||||
var myCookieManager: Any?
|
||||
var myWebStorageManager: Any?
|
||||
var credentialDatabase: CredentialDatabase?
|
||||
var inAppBrowserManager: InAppBrowserManager?
|
||||
var chromeSafariBrowserManager: ChromeSafariBrowserManager?
|
||||
|
||||
var webViewControllers: [String: InAppBrowserWebViewController?] = [:]
|
||||
var safariViewControllers: [String: Any?] = [:]
|
||||
|
@ -49,855 +43,21 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||
super.init()
|
||||
|
||||
self.registrar = registrar
|
||||
self.channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
|
||||
registrar.addMethodCallDelegate(self, channel: channel!)
|
||||
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: "com.pichillilorenzo/flutter_inappwebview")
|
||||
|
||||
inAppBrowserManager = InAppBrowserManager(registrar: registrar)
|
||||
chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar)
|
||||
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
|
||||
if #available(iOS 11.0, *) {
|
||||
myCookieManager = MyCookieManager(registrar: registrar)
|
||||
}
|
||||
if #available(iOS 9.0, *) {
|
||||
myWebStorageManager = MyWebStorageManager(registrar: registrar)
|
||||
}
|
||||
credentialDatabase = CredentialDatabase(registrar: registrar)
|
||||
}
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
SwiftFlutterPlugin.instance = SwiftFlutterPlugin(with: registrar)
|
||||
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: "com.pichillilorenzo/flutter_inappwebview")
|
||||
|
||||
InAppWebViewStatic(registrar: registrar)
|
||||
if #available(iOS 11.0, *) {
|
||||
MyCookieManager(registrar: registrar)
|
||||
}
|
||||
if #available(iOS 9.0, *) {
|
||||
MyWebStorageManager(registrar: registrar)
|
||||
}
|
||||
CredentialDatabase(registrar: registrar)
|
||||
}
|
||||
|
||||
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":
|
||||
self.open(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "getUrl":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.webView.url?.absoluteString)
|
||||
}
|
||||
else {
|
||||
result(nil)
|
||||
}
|
||||
break
|
||||
case "getTitle":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.webView.title)
|
||||
}
|
||||
else {
|
||||
result(nil)
|
||||
}
|
||||
break
|
||||
case "getProgress":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
let progress = Int(webViewController!.webView.estimatedProgress * 100)
|
||||
result(progress)
|
||||
}
|
||||
else {
|
||||
result(nil)
|
||||
}
|
||||
break
|
||||
case "loadUrl":
|
||||
self.loadUrl(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "loadData":
|
||||
self.loadData(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "postUrl":
|
||||
self.postUrl(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "loadFile":
|
||||
self.loadFile(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "close":
|
||||
self.close(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "show":
|
||||
self.show(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "hide":
|
||||
self.hide(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "reload":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.reload()
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "goBack":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.goBack()
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "canGoBack":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.canGoBack())
|
||||
}
|
||||
else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "goForward":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.goForward()
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "canGoForward":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.canGoForward())
|
||||
}
|
||||
else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "goBackOrForward":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
let steps = arguments!["steps"] as! Int
|
||||
webViewController!.goBackOrForward(steps: steps)
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "canGoBackOrForward":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
let steps = arguments!["steps"] as! Int
|
||||
result(webViewController!.canGoBackOrForward(steps: steps))
|
||||
}
|
||||
else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "isLoading":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.webView.isLoading == true)
|
||||
}
|
||||
else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "stopLoading":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.stopLoading()
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "isHidden":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
result(webViewController!.isHidden == true)
|
||||
}
|
||||
else {
|
||||
result(false)
|
||||
}
|
||||
break
|
||||
case "evaluateJavascript":
|
||||
self.evaluateJavascript(uuid: uuid, arguments: arguments!, result: result)
|
||||
break
|
||||
case "injectJavascriptFileFromUrl":
|
||||
self.injectJavascriptFileFromUrl(uuid: uuid, arguments: arguments!)
|
||||
result(true)
|
||||
break
|
||||
case "injectCSSCode":
|
||||
self.injectCSSCode(uuid: uuid, arguments: arguments!)
|
||||
result(true)
|
||||
break
|
||||
case "injectCSSFileFromUrl":
|
||||
self.injectCSSFileFromUrl(uuid: uuid, arguments: arguments!)
|
||||
result(true)
|
||||
break
|
||||
case "takeScreenshot":
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.takeScreenshot(completionHandler: { (screenshot) -> Void in
|
||||
result(screenshot)
|
||||
})
|
||||
}
|
||||
else {
|
||||
result(nil)
|
||||
}
|
||||
break
|
||||
case "setOptions":
|
||||
let optionsType = arguments!["optionsType"] as! String
|
||||
switch (optionsType){
|
||||
case "InAppBrowserOptions":
|
||||
let inAppBrowserOptions = InAppBrowserOptions()
|
||||
let inAppBrowserOptionsMap = arguments!["options"] as! [String: Any]
|
||||
inAppBrowserOptions.parse(options: inAppBrowserOptionsMap)
|
||||
self.setOptions(uuid: uuid, options: inAppBrowserOptions, optionsMap: inAppBrowserOptionsMap)
|
||||
break
|
||||
default:
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "Options " + optionsType + " not available.", details: nil))
|
||||
}
|
||||
result(true)
|
||||
break
|
||||
case "getOptions":
|
||||
result(self.getOptions(uuid: uuid))
|
||||
break
|
||||
case "getCopyBackForwardList":
|
||||
result(self.getCopyBackForwardList(uuid: uuid))
|
||||
break
|
||||
case "findAllAsync":
|
||||
let find = arguments!["find"] as! String
|
||||
self.findAllAsync(uuid: uuid, find: find)
|
||||
result(true)
|
||||
break
|
||||
case "findNext":
|
||||
let forward = arguments!["forward"] as! Bool
|
||||
self.findNext(uuid: uuid, forward: forward, result: result)
|
||||
break
|
||||
case "clearMatches":
|
||||
self.clearMatches(uuid: uuid, result: result)
|
||||
break
|
||||
case "clearCache":
|
||||
self.clearCache(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "scrollTo":
|
||||
let x = arguments!["x"] as! Int
|
||||
let y = arguments!["y"] as! Int
|
||||
self.scrollTo(uuid: uuid, x: x, y: y)
|
||||
result(true)
|
||||
break
|
||||
case "scrollBy":
|
||||
let x = arguments!["x"] as! Int
|
||||
let y = arguments!["y"] as! Int
|
||||
self.scrollTo(uuid: uuid, x: x, y: y)
|
||||
result(true)
|
||||
break
|
||||
case "pauseTimers":
|
||||
self.pauseTimers(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "resumeTimers":
|
||||
self.resumeTimers(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "printCurrentPage":
|
||||
self.printCurrentPage(uuid: uuid, result: result)
|
||||
break
|
||||
case "getContentHeight":
|
||||
result(self.getContentHeight(uuid: uuid))
|
||||
break
|
||||
case "reloadFromOrigin":
|
||||
self.reloadFromOrigin(uuid: uuid)
|
||||
result(true)
|
||||
break
|
||||
case "getScale":
|
||||
result(self.getScale(uuid: uuid))
|
||||
break
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func close(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
// Things are cleaned up in browserExit.
|
||||
webViewController?.close()
|
||||
}
|
||||
else {
|
||||
print("IAB.close() called but it was already closed.")
|
||||
}
|
||||
}
|
||||
|
||||
func isSystemUrl(_ url: URL) -> Bool {
|
||||
if (url.host == "itunes.apple.com") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func open(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
let isData: Bool = (arguments["isData"] as? Bool)!
|
||||
|
||||
if !isData {
|
||||
let url: String = (arguments["url"] as? String)!
|
||||
|
||||
let headers = (arguments["headers"] as? [String: String])!
|
||||
var absoluteUrl = URL(string: url)?.absoluteURL
|
||||
|
||||
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)!
|
||||
|
||||
if useChromeSafariBrowser {
|
||||
let uuidFallback = (arguments["uuidFallback"] as? String)!
|
||||
let safariOptions = (arguments["options"] as? [String: Any])!
|
||||
|
||||
let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
|
||||
|
||||
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result)
|
||||
}
|
||||
else {
|
||||
let options = (arguments["options"] as? [String: Any])!
|
||||
|
||||
let isLocalFile = (arguments["isLocalFile"] as? Bool)!
|
||||
var openWithSystemBrowser = (arguments["openWithSystemBrowser"] as? Bool)!
|
||||
|
||||
if isLocalFile {
|
||||
let key = self.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
|
||||
}
|
||||
absoluteUrl = assetURL!
|
||||
}
|
||||
|
||||
if isSystemUrl(absoluteUrl!) {
|
||||
openWithSystemBrowser = true
|
||||
}
|
||||
|
||||
if (openWithSystemBrowser) {
|
||||
open(inSystem: absoluteUrl!, result: result)
|
||||
}
|
||||
else {
|
||||
open(uuid: uuid, uuidFallback: nil, inAppBrowser: absoluteUrl!, headers: headers, withOptions: options, useChromeSafariBrowser: false, withOptionsFallback: nil, result: result)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
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)!
|
||||
open(uuid: uuid, options: options, data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||
result(true)
|
||||
}
|
||||
}
|
||||
|
||||
func open(uuid: String, uuidFallback: String?, inAppBrowser url: URL, headers: [String: String], withOptions options: [String: Any], useChromeSafariBrowser: Bool, withOptionsFallback optionsFallback: [String: Any]?, result: @escaping FlutterResult) {
|
||||
|
||||
var uuid = uuid
|
||||
|
||||
if self.webViewControllers[uuid] != nil {
|
||||
close(uuid: uuid)
|
||||
}
|
||||
|
||||
let safariViewController = self.safariViewControllers[uuid]
|
||||
if safariViewController != nil {
|
||||
if #available(iOS 9.0, *) {
|
||||
(safariViewController! as! SafariViewController).close()
|
||||
self.safariViewControllers[uuid] = nil
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
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 webViewOptions: InAppWebViewOptions
|
||||
|
||||
if useChromeSafariBrowser == true {
|
||||
if #available(iOS 9.0, *) {
|
||||
let safariOptions = SafariBrowserOptions()
|
||||
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: url, configuration: config)
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
safari = SafariViewController(url: url)
|
||||
}
|
||||
|
||||
safari.uuid = uuid
|
||||
safari.delegate = safari
|
||||
safari.statusDelegate = self
|
||||
safari.tmpWindow = tmpWindow
|
||||
safari.safariOptions = safariOptions
|
||||
|
||||
self.safariViewControllers[uuid] = safari
|
||||
tmpController.present(self.safariViewControllers[uuid]! as! SFSafariViewController, animated: true) {
|
||||
self.onChromeSafariBrowserOpened(uuid: uuid)
|
||||
result(true)
|
||||
}
|
||||
return
|
||||
}
|
||||
else {
|
||||
if uuidFallback == nil {
|
||||
print("No WebView fallback declared.")
|
||||
result(true)
|
||||
|
||||
return
|
||||
}
|
||||
uuid = uuidFallback!
|
||||
browserOptions = InAppBrowserOptions()
|
||||
browserOptions.parse(options: optionsFallback!)
|
||||
|
||||
webViewOptions = InAppWebViewOptions()
|
||||
webViewOptions.parse(options: optionsFallback!)
|
||||
}
|
||||
}
|
||||
else {
|
||||
browserOptions = InAppBrowserOptions()
|
||||
browserOptions.parse(options: options)
|
||||
|
||||
webViewOptions = InAppWebViewOptions()
|
||||
webViewOptions.parse(options: options)
|
||||
}
|
||||
|
||||
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppWebViewFlutterPlugin.self))
|
||||
let vc = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID)
|
||||
self.webViewControllers[uuid] = vc as? InAppBrowserWebViewController
|
||||
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
|
||||
webViewController.uuid = uuid
|
||||
webViewController.browserOptions = browserOptions
|
||||
webViewController.webViewOptions = webViewOptions
|
||||
webViewController.isHidden = browserOptions.hidden
|
||||
webViewController.tmpWindow = tmpWindow
|
||||
webViewController.initURL = url
|
||||
webViewController.initHeaders = headers
|
||||
webViewController.navigationDelegate = self
|
||||
|
||||
if browserOptions.hidden {
|
||||
webViewController.view.isHidden = true
|
||||
tmpController.present(webViewController, animated: false, completion: {() -> Void in
|
||||
// if self.previousStatusBarStyle != -1 {
|
||||
// UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||
// }
|
||||
})
|
||||
// if self.previousStatusBarStyle != -1 {
|
||||
// UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||
// }
|
||||
webViewController.presentingViewController?.dismiss(animated: false, completion: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
})
|
||||
}
|
||||
else {
|
||||
tmpController.present(webViewController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
result(true)
|
||||
}
|
||||
|
||||
func open(uuid: String, options: [String: Any], data: String, mimeType: String, encoding: String, baseUrl: String) {
|
||||
|
||||
var uuid = uuid
|
||||
|
||||
if self.webViewControllers[uuid] != nil {
|
||||
close(uuid: uuid)
|
||||
}
|
||||
|
||||
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 webViewOptions: InAppWebViewOptions
|
||||
|
||||
browserOptions = InAppBrowserOptions()
|
||||
browserOptions.parse(options: options)
|
||||
|
||||
webViewOptions = InAppWebViewOptions()
|
||||
webViewOptions.parse(options: options)
|
||||
|
||||
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppWebViewFlutterPlugin.self))
|
||||
let vc = storyboard.instantiateViewController(withIdentifier: WEBVIEW_STORYBOARD_CONTROLLER_ID)
|
||||
self.webViewControllers[uuid] = vc as? InAppBrowserWebViewController
|
||||
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
|
||||
webViewController.uuid = uuid
|
||||
webViewController.browserOptions = browserOptions
|
||||
webViewController.webViewOptions = webViewOptions
|
||||
webViewController.isHidden = browserOptions.hidden
|
||||
webViewController.tmpWindow = tmpWindow
|
||||
webViewController.initData = data
|
||||
webViewController.initMimeType = mimeType
|
||||
webViewController.initEncoding = encoding
|
||||
webViewController.initBaseUrl = baseUrl
|
||||
webViewController.navigationDelegate = self
|
||||
|
||||
if browserOptions.hidden {
|
||||
webViewController.view.isHidden = true
|
||||
tmpController.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 {
|
||||
tmpController.present(webViewController, animated: true, completion: {() -> Void in
|
||||
webViewController.webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func open(inSystem url: URL, result: @escaping FlutterResult) {
|
||||
if !UIApplication.shared.canOpenURL(url) {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url.absoluteString + " cannot be opened!", details: nil))
|
||||
return
|
||||
}
|
||||
else {
|
||||
if #available(iOS 10.0, *) {
|
||||
UIApplication.shared.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
|
||||
} else {
|
||||
UIApplication.shared.openURL(url)
|
||||
}
|
||||
}
|
||||
result(true)
|
||||
}
|
||||
|
||||
public func show(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
if webViewController != nil {
|
||||
webViewController?.isHidden = false
|
||||
webViewController?.view.isHidden = false
|
||||
|
||||
// Run later to avoid the "took a long time" log message.
|
||||
DispatchQueue.main.async(execute: {() -> Void in
|
||||
if webViewController != nil {
|
||||
let baseWindowLevel = UIApplication.shared.keyWindow?.windowLevel
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(baseWindowLevel!.rawValue + 1.0)
|
||||
self.tmpWindow?.makeKeyAndVisible()
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
self.tmpWindow?.rootViewController?.present(webViewController!, animated: true, completion: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
print("Tried to hide IAB after it was closed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func hide(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
if webViewController != nil {
|
||||
webViewController?.isHidden = true
|
||||
|
||||
// Run later to avoid the "took a long time" log message.
|
||||
DispatchQueue.main.async(execute: {() -> Void in
|
||||
if webViewController != nil {
|
||||
webViewController?.presentingViewController?.dismiss(animated: true, completion: {() -> Void in
|
||||
self.tmpWindow?.windowLevel = UIWindow.Level(rawValue: 0.0)
|
||||
UIApplication.shared.delegate?.window??.makeKeyAndVisible()
|
||||
if self.previousStatusBarStyle != -1 {
|
||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: self.previousStatusBarStyle)!
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
print("Tried to hide IAB after it was closed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
if let url = arguments["url"] as? String {
|
||||
let headers = (arguments["headers"] as? [String: String])!
|
||||
let absoluteUrl = URL(string: url)!.absoluteURL
|
||||
webViewController!.loadUrl(url: absoluteUrl, headers: headers)
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||
}
|
||||
}
|
||||
|
||||
public func loadData(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
let data = (arguments["data"] as? String)!
|
||||
let mimeType = (arguments["mimeType"] as? String)!
|
||||
let encoding = (arguments["encoding"] as? String)!
|
||||
let baseUrl = (arguments["baseUrl"] as? String)!
|
||||
webViewController!.webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
|
||||
result(true)
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||
}
|
||||
}
|
||||
|
||||
public func postUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
if let url = arguments["url"] as? String {
|
||||
let postData = (arguments["postData"] as? FlutterStandardTypedData)!
|
||||
let absoluteUrl = URL(string: url)!.absoluteURL
|
||||
webViewController!.webView.postUrl(url: absoluteUrl, postData: postData.data, completionHandler: { () -> Void in
|
||||
result(true)
|
||||
})
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
||||
return
|
||||
}
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||
}
|
||||
}
|
||||
|
||||
public func loadFile(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
if let url = arguments["url"] as? String {
|
||||
let headers = (arguments["headers"] as? [String: String])!
|
||||
do {
|
||||
try webViewController!.webView.loadFile(url: url, headers: headers)
|
||||
}
|
||||
catch let error as NSError {
|
||||
dump(error)
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: error.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||
}
|
||||
}
|
||||
|
||||
public func evaluateJavascript(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.evaluateJavascript(source: arguments["source"] as! String, result: result)
|
||||
}
|
||||
else {
|
||||
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "webView is null", details: nil))
|
||||
}
|
||||
}
|
||||
|
||||
public func injectJavascriptFileFromUrl(uuid: String, arguments: NSDictionary) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.injectJavascriptFileFromUrl(urlFile: arguments["urlFile"] as! String)
|
||||
}
|
||||
}
|
||||
|
||||
public func injectCSSCode(uuid: String, arguments: NSDictionary) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.injectCSSCode(source: arguments["source"] as! String)
|
||||
}
|
||||
}
|
||||
|
||||
public func injectCSSFileFromUrl(uuid: String, arguments: NSDictionary) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.injectCSSFileFromUrl(urlFile: arguments["urlFile"] as! String)
|
||||
}
|
||||
}
|
||||
|
||||
public func onBrowserCreated(uuid: String, webView: WKWebView) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
self.channel!.invokeMethod("onBrowserCreated", arguments: ["uuid": uuid])
|
||||
}
|
||||
}
|
||||
|
||||
public func onExit(uuid: String) {
|
||||
self.channel!.invokeMethod("onExit", arguments: ["uuid": uuid])
|
||||
}
|
||||
|
||||
public func onChromeSafariBrowserOpened(uuid: String) {
|
||||
if self.safariViewControllers[uuid] != nil {
|
||||
self.channel!.invokeMethod("onChromeSafariBrowserOpened", arguments: ["uuid": uuid])
|
||||
}
|
||||
}
|
||||
|
||||
public func onChromeSafariBrowserCompletedInitialLoad(uuid: String) {
|
||||
if self.safariViewControllers[uuid] != nil {
|
||||
self.channel!.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: ["uuid": uuid])
|
||||
}
|
||||
}
|
||||
|
||||
public func onChromeSafariBrowserClosed(uuid: String) {
|
||||
self.channel!.invokeMethod("onChromeSafariBrowserClosed", arguments: ["uuid": uuid])
|
||||
}
|
||||
|
||||
public func safariExit(uuid: String) {
|
||||
if let safariViewController = self.safariViewControllers[uuid] {
|
||||
if #available(iOS 9.0, *) {
|
||||
(safariViewController as! SafariViewController).statusDelegate = nil
|
||||
(safariViewController as! SafariViewController).delegate = nil
|
||||
}
|
||||
self.safariViewControllers[uuid] = nil
|
||||
onChromeSafariBrowserClosed(uuid: uuid)
|
||||
}
|
||||
}
|
||||
|
||||
public func browserExit(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
// Set navigationDelegate to nil to ensure no callbacks are received from it.
|
||||
webViewController?.navigationDelegate = nil
|
||||
// Don't recycle the ViewController since it may be consuming a lot of memory.
|
||||
// Also - this is required for the PDF/User-Agent bug work-around.
|
||||
self.webViewControllers[uuid] = nil
|
||||
|
||||
if previousStatusBarStyle != -1 {
|
||||
UIApplication.shared.statusBarStyle = UIStatusBarStyle(rawValue: previousStatusBarStyle)!
|
||||
}
|
||||
|
||||
onExit(uuid: uuid)
|
||||
}
|
||||
}
|
||||
|
||||
public func setOptions(uuid: String, options: InAppBrowserOptions, optionsMap: [String: Any]) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.setOptions(newOptions: options, newOptionsMap: optionsMap)
|
||||
}
|
||||
}
|
||||
|
||||
public func getOptions(uuid: String) -> [String: Any]? {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
return webViewController!.getOptions()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func getCopyBackForwardList(uuid: String) -> [String: Any]? {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
return webViewController!.webView.getCopyBackForwardList()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func findAllAsync(uuid: String, find: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.findAllAsync(find: find, completionHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
public func findNext(uuid: String, forward: Bool, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.findNext(forward: forward, completionHandler: {(value, error) in
|
||||
if error != nil {
|
||||
result(FlutterError(code: "FlutterWebViewController", message: error?.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
}
|
||||
|
||||
public func clearMatches(uuid: String, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.clearMatches(completionHandler: {(value, error) in
|
||||
if error != nil {
|
||||
result(FlutterError(code: "FlutterWebViewController", message: error?.localizedDescription, details: nil))
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
}
|
||||
|
||||
public func clearCache(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.clearCache()
|
||||
}
|
||||
}
|
||||
|
||||
public func scrollTo(uuid: String, x: Int, y: Int) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.scrollTo(x: x, y: y)
|
||||
}
|
||||
}
|
||||
|
||||
public func scrollBy(uuid: String, x: Int, y: Int) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.scrollBy(x: x, y: y)
|
||||
}
|
||||
}
|
||||
|
||||
public func pauseTimers(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.pauseTimers()
|
||||
}
|
||||
}
|
||||
|
||||
public func resumeTimers(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.resumeTimers()
|
||||
}
|
||||
}
|
||||
|
||||
public func printCurrentPage(uuid: String, result: @escaping FlutterResult) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.printCurrentPage(printCompletionHandler: {(completed, error) in
|
||||
if !completed, let e = error {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
result(true)
|
||||
})
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
}
|
||||
|
||||
public func getContentHeight(uuid: String) -> Int64? {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
return webViewController!.webView.getContentHeight()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func reloadFromOrigin(uuid: String) {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
webViewController!.webView.reloadFromOrigin()
|
||||
}
|
||||
}
|
||||
|
||||
public func getScale(uuid: String) -> Float? {
|
||||
if let webViewController = self.webViewControllers[uuid] {
|
||||
return webViewController!.webView.getScale()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// 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)})
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ library flutter_inappwebview;
|
|||
export 'src/types.dart';
|
||||
export 'src/in_app_webview.dart';
|
||||
export 'src/in_app_browser.dart';
|
||||
export 'src/channel_manager.dart';
|
||||
export 'src/cookie_manager.dart';
|
||||
export 'src/chrome_safari_browser.dart';
|
||||
export 'src/chrome_safari_browser.dart';
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
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';
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'types.dart';
|
||||
import 'channel_manager.dart';
|
||||
import 'in_app_browser.dart';
|
||||
|
||||
///ChromeSafariBrowser class.
|
||||
|
@ -18,12 +17,16 @@ class ChromeSafariBrowser {
|
|||
String uuid;
|
||||
InAppBrowser browserFallback;
|
||||
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`.
|
||||
ChromeSafariBrowser({bFallback}) {
|
||||
uuid = uuidGenerator.v4();
|
||||
browserFallback = bFallback;
|
||||
ChannelManager.addListener(uuid, handleMethod);
|
||||
this._channel =
|
||||
MethodChannel('com.pichillilorenzo/flutter_chromesafaribrowser_$uuid');
|
||||
this._channel.setMethodCallHandler(handleMethod);
|
||||
_isOpened = false;
|
||||
}
|
||||
|
||||
|
@ -94,15 +97,13 @@ class ChromeSafariBrowser {
|
|||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('uuidFallback',
|
||||
() => (browserFallback != null) ? browserFallback.uuid : '');
|
||||
args.putIfAbsent('url', () => url);
|
||||
args.putIfAbsent('headers', () => headersFallback);
|
||||
args.putIfAbsent('options', () => optionsMap);
|
||||
args.putIfAbsent('uuidFallback',
|
||||
() => (browserFallback != null) ? browserFallback.uuid : '');
|
||||
args.putIfAbsent('headersFallback', () => headersFallback);
|
||||
args.putIfAbsent('optionsFallback', () => optionsFallbackMap);
|
||||
args.putIfAbsent('isData', () => false);
|
||||
args.putIfAbsent('useChromeSafariBrowser', () => true);
|
||||
await ChannelManager.channel.invokeMethod('open', args);
|
||||
await _sharedChannel.invokeMethod('open', args);
|
||||
this._isOpened = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
|
|||
import 'webview_options.dart';
|
||||
|
||||
import 'types.dart';
|
||||
import 'channel_manager.dart';
|
||||
import 'in_app_webview.dart' show InAppWebViewController;
|
||||
|
||||
///InAppBrowser class. [webViewController] can be used to access the [InAppWebView] API.
|
||||
|
@ -18,6 +17,8 @@ class InAppBrowser {
|
|||
Map<String, JavaScriptHandlerCallback> javaScriptHandlersMap =
|
||||
HashMap<String, JavaScriptHandlerCallback>();
|
||||
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.
|
||||
InAppWebViewController webViewController;
|
||||
|
@ -25,10 +26,12 @@ class InAppBrowser {
|
|||
///
|
||||
InAppBrowser() {
|
||||
uuid = uuidGenerator.v4();
|
||||
ChannelManager.addListener(uuid, handleMethod);
|
||||
this._channel =
|
||||
MethodChannel('com.pichillilorenzo/flutter_inappbrowser_$uuid');
|
||||
this._channel.setMethodCallHandler(handleMethod);
|
||||
_isOpened = false;
|
||||
webViewController = new InAppWebViewController.fromInAppBrowser(
|
||||
uuid, ChannelManager.channel, this);
|
||||
uuid, this._channel, this);
|
||||
}
|
||||
|
||||
Future<dynamic> handleMethod(MethodCall call) async {
|
||||
|
@ -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.
|
||||
///
|
||||
///[options]: Options for the [InAppBrowser].
|
||||
Future<void> open(
|
||||
{String url = "about:blank",
|
||||
Future<void> openUrl(
|
||||
{@required String url,
|
||||
Map<String, String> headers = const {},
|
||||
InAppBrowserClassOptions options}) async {
|
||||
assert(url != null && url.isNotEmpty);
|
||||
|
@ -83,14 +86,10 @@ class InAppBrowser {
|
|||
args.putIfAbsent('url', () => url);
|
||||
args.putIfAbsent('headers', () => headers);
|
||||
args.putIfAbsent('options', () => optionsMap);
|
||||
args.putIfAbsent('openWithSystemBrowser', () => false);
|
||||
args.putIfAbsent('isLocalFile', () => false);
|
||||
args.putIfAbsent('isData', () => false);
|
||||
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||
await ChannelManager.channel.invokeMethod('open', args);
|
||||
await _sharedChannel.invokeMethod('openUrl', 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!
|
||||
///
|
||||
|
@ -153,11 +152,7 @@ class InAppBrowser {
|
|||
args.putIfAbsent('url', () => assetFilePath);
|
||||
args.putIfAbsent('headers', () => headers);
|
||||
args.putIfAbsent('options', () => optionsMap);
|
||||
args.putIfAbsent('openWithSystemBrowser', () => false);
|
||||
args.putIfAbsent('isLocalFile', () => true);
|
||||
args.putIfAbsent('isData', () => false);
|
||||
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||
await ChannelManager.channel.invokeMethod('open', args);
|
||||
await _sharedChannel.invokeMethod('openFile', args);
|
||||
}
|
||||
|
||||
///Opens a new [InAppBrowser] instance with [data] as a content, using [baseUrl] as the base URL for it.
|
||||
|
@ -203,26 +198,16 @@ class InAppBrowser {
|
|||
args.putIfAbsent('mimeType', () => mimeType);
|
||||
args.putIfAbsent('encoding', () => encoding);
|
||||
args.putIfAbsent('baseUrl', () => baseUrl);
|
||||
args.putIfAbsent('openWithSystemBrowser', () => false);
|
||||
args.putIfAbsent('isLocalFile', () => false);
|
||||
args.putIfAbsent('isData', () => true);
|
||||
args.putIfAbsent('useChromeSafariBrowser', () => false);
|
||||
await ChannelManager.channel.invokeMethod('open', args);
|
||||
args.putIfAbsent('historyUrl', () => androidHistoryUrl);
|
||||
await _sharedChannel.invokeMethod('openData', args);
|
||||
}
|
||||
|
||||
///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 {
|
||||
assert(url != null && url.isNotEmpty);
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => "");
|
||||
args.putIfAbsent('url', () => url);
|
||||
args.putIfAbsent('headers', () => {});
|
||||
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);
|
||||
return await _sharedChannel.invokeMethod('openWithSystemBrowser', args);
|
||||
}
|
||||
|
||||
///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 {
|
|||
this.throwIsNotOpened();
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
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.
|
||||
Future<void> hide() async {
|
||||
this.throwIsNotOpened();
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
await ChannelManager.channel.invokeMethod('hide', args);
|
||||
await _channel.invokeMethod('hide', args);
|
||||
}
|
||||
|
||||
///Closes the [InAppBrowser] window.
|
||||
Future<void> close() async {
|
||||
this.throwIsNotOpened();
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
await ChannelManager.channel.invokeMethod('close', args);
|
||||
await _channel.invokeMethod('close', args);
|
||||
}
|
||||
|
||||
///Check if the Web View of the [InAppBrowser] instance is hidden.
|
||||
Future<bool> isHidden() async {
|
||||
this.throwIsNotOpened();
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
return await ChannelManager.channel.invokeMethod('isHidden', args);
|
||||
return await _channel.invokeMethod('isHidden', args);
|
||||
}
|
||||
|
||||
///Sets the [InAppBrowser] options with the new [options] and evaluates them.
|
||||
|
@ -280,23 +262,19 @@ class InAppBrowser {
|
|||
}
|
||||
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('options', () => optionsMap);
|
||||
args.putIfAbsent('optionsType', () => "InAppBrowserOptions");
|
||||
await ChannelManager.channel.invokeMethod('setOptions', args);
|
||||
await _channel.invokeMethod('setOptions', args);
|
||||
}
|
||||
|
||||
///Gets the current [InAppBrowser] options as a `Map`. Returns `null` if the options are not setted yet.
|
||||
Future<InAppBrowserClassOptions> getOptions() async {
|
||||
this.throwIsNotOpened();
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('uuid', () => uuid);
|
||||
args.putIfAbsent('optionsType', () => "InAppBrowserOptions");
|
||||
|
||||
InAppBrowserClassOptions inAppBrowserClassOptions =
|
||||
InAppBrowserClassOptions();
|
||||
Map<dynamic, dynamic> options =
|
||||
await ChannelManager.channel.invokeMethod('getOptions', args);
|
||||
await _channel.invokeMethod('getOptions', args);
|
||||
if (options != null) {
|
||||
options = options.cast<String, dynamic>();
|
||||
inAppBrowserClassOptions.crossPlatform =
|
||||
|
|
|
@ -9,8 +9,6 @@ import 'webview_options.dart';
|
|||
|
||||
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.
|
||||
///
|
||||
///The Android implementation uses [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String)).
|
||||
|
|
Loading…
Reference in New Issue