diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 76a4cce8..78af5349 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,31 +7,18 @@
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -52,11 +39,11 @@
-
+
-
-
+
+
@@ -64,11 +51,11 @@
-
+
-
-
+
+
@@ -155,15 +142,15 @@
-
+
-
+
-
+
@@ -190,6 +177,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -227,6 +240,7 @@
+
@@ -400,7 +414,7 @@
-
+
@@ -409,17 +423,17 @@
-
+
-
+
-
-
+
+
-
+
@@ -674,13 +688,6 @@
-
-
-
-
-
-
-
@@ -814,24 +821,32 @@
-
+
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index b3fb1d28..bf47aef8 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -5,8 +5,8 @@
-
+ android:theme="@style/AppTheme" >
+
\ No newline at end of file
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java
index 7819ad2c..c78678de 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java
@@ -24,54 +24,21 @@ package com.pichillilorenzo.flutter_inappbrowser;
import android.annotation.TargetApi;
import android.app.Activity;
import android.annotation.SuppressLint;
-import android.content.Context;
import android.content.Intent;
-import android.os.Parcelable;
import android.provider.Browser;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
-import android.text.InputType;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.CookieManager;
import android.webkit.MimeTypeMap;
-import android.webkit.ValueCallback;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
import android.util.Log;
-import android.support.v7.app.AppCompatActivity;
+import android.widget.Toast;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
+import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
-import java.util.StringTokenizer;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@@ -90,60 +57,12 @@ public class InAppBrowser implements MethodCallHandler {
private static final String NULL = "null";
protected static final String LOG_TAG = "InAppBrowser";
- private static final String SELF = "_self";
- private static final String SYSTEM = "_system";
- private static final String EXIT_EVENT = "exit";
- private static final String LOCATION = "location";
- private static final String ZOOM = "zoom";
- private static final String HIDDEN = "hidden";
- private static final String CLEAR_ALL_CACHE = "clearcache";
- private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
- private static final String HARDWARE_BACK_BUTTON = "hardwareback";
- private static final String MEDIA_PLAYBACK_REQUIRES_USER_ACTION = "mediaPlaybackRequiresUserAction";
- private static final String SHOULD_PAUSE = "shouldPauseOnSuspend";
- private static final Boolean DEFAULT_HARDWARE_BACK = true;
- private static final String USER_WIDE_VIEW_PORT = "useWideViewPort";
- private static final String TOOLBAR_COLOR = "toolbarcolor";
- private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
- private static final String CLOSE_BUTTON_COLOR = "closebuttoncolor";
- private static final String HIDE_NAVIGATION = "hidenavigationbuttons";
- private static final String NAVIGATION_COLOR = "navigationbuttoncolor";
- private static final String HIDE_URL = "hideurlbar";
- private static final String FOOTER = "footer";
- private static final String FOOTER_COLOR = "footercolor";
- private static final List customizableOptions = Arrays.asList(CLOSE_BUTTON_CAPTION, TOOLBAR_COLOR, NAVIGATION_COLOR, CLOSE_BUTTON_COLOR, FOOTER_COLOR);
- private InAppBrowserDialog dialog;
- private WebView inAppWebView;
- private EditText edittext;
- private boolean showLocationBar = true;
- private boolean showZoomControls = true;
- private boolean openWindowHidden = false;
- private boolean clearAllCache = false;
- private boolean clearSessionCache = false;
- private boolean hadwareBackButton = true;
- private boolean mediaPlaybackRequiresUserGesture = false;
- private boolean shouldPauseInAppBrowser = false;
- private boolean useWideViewPort = true;
- private ValueCallback mUploadCallback;
- private ValueCallback mUploadCallbackLollipop;
- private final static int FILECHOOSER_REQUESTCODE = 1;
- private final static int FILECHOOSER_REQUESTCODE_LOLLIPOP = 2;
- private String closeButtonCaption = "";
- private String closeButtonColor = "";
- private int toolbarColor = android.graphics.Color.LTGRAY;
- private boolean hideNavigationButtons = false;
- private String navigationButtonColor = "";
- private boolean hideUrlBar = false;
- private boolean showFooter = false;
- private String footerColor = "";
- private String[] allowedSchemes;
-
- public InAppBrowser(Registrar registrar, Activity activity) {
- this.registrar = registrar;
+ public InAppBrowser(Registrar r, Activity activity) {
+ registrar = r;
this.activity = activity;
- this.channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
+ channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
}
/** Plugin registration. */
@@ -165,9 +84,10 @@ public class InAppBrowser implements MethodCallHandler {
String t = call.argument("target").toString();
if (t == null || t.equals("") || t.equals(NULL)) {
- t = SELF;
+ t = "_self";
}
final String target = t;
+
final InAppBrowserOptions options = new InAppBrowserOptions();
options.parse((HashMap) call.argument("options"));
@@ -176,9 +96,7 @@ public class InAppBrowser implements MethodCallHandler {
this.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
- String r = "";
- // SELF
- if (SELF.equals(target)) {
+ if ("_self".equals(target)) {
Log.d(LOG_TAG, "in self");
//Load the dialer
@@ -196,26 +114,29 @@ public class InAppBrowser implements MethodCallHandler {
// load in InAppBrowser
else {
Log.d(LOG_TAG, "loading in InAppBrowser");
- r = showWebPage(url, options);
+ open(url, options);
}
}
// SYSTEM
- else if (SYSTEM.equals(target)) {
+ else if ("_system".equals(target)) {
Log.d(LOG_TAG, "in system");
- r = openExternal(url);
+ openExternal(url, result);
}
// BLANK - or anything else
else {
Log.d(LOG_TAG, "in blank");
- r = showWebPage(url, options);
+ open(url, options);
}
- result.success(r);
+ result.success(true);
}
});
break;
+ case "loadUrl":
+ loadUrl(call.argument("url").toString(), (Map) call.argument("headers"), result);
+ break;
case "close":
- closeDialog();
+ close();
result.success(true);
break;
case "injectScriptCode":
@@ -243,21 +164,36 @@ public class InAppBrowser implements MethodCallHandler {
result.success(true);
break;
case "show":
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- dialog.show();
- }
- });
+ show();
result.success(true);
break;
case "hide":
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- dialog.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 "isLoading":
+ result.success(isLoading());
+ break;
+ case "stopLoading":
+ stopLoading();
result.success(true);
break;
default:
@@ -283,7 +219,7 @@ public class InAppBrowser implements MethodCallHandler {
* which should be executed directly.
*/
private void injectDeferredObject(String source, String jsWrapper) {
- if (inAppWebView!=null) {
+ if (webViewActivity!=null) {
String scriptToInject;
if (jsWrapper != null) {
org.json.JSONArray jsonEsc = new org.json.JSONArray();
@@ -301,9 +237,9 @@ public class InAppBrowser implements MethodCallHandler {
public void run() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
// This action will have the side-effect of blurring the currently focused element
- inAppWebView.loadUrl("javascript:" + finalScriptToInject);
+ webViewActivity.webView.loadUrl("javascript:" + finalScriptToInject);
} else {
- inAppWebView.evaluateJavascript(finalScriptToInject, null);
+ webViewActivity.webView.evaluateJavascript(finalScriptToInject, null);
}
}
});
@@ -327,9 +263,9 @@ public class InAppBrowser implements MethodCallHandler {
* @param url the url to load.
* @return "" if ok, or error message.
*/
- public String openExternal(String url) {
+ public void openExternal(String url, Result result) {
try {
- Intent intent = null;
+ 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.
@@ -341,16 +277,14 @@ public class InAppBrowser implements MethodCallHandler {
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
activity.startActivity(intent);
- return "";
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) {
Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString());
- return e.toString();
}
}
@TargetApi(8)
- private String showWebPage(final String url, InAppBrowserOptions options) {
+ private void open(final String url, InAppBrowserOptions options) {
Intent intent = new Intent(activity, WebViewActivity.class);
Bundle extras = new Bundle();
@@ -361,11 +295,7 @@ public class InAppBrowser implements MethodCallHandler {
activity.startActivity(intent);
- //webViewActivity.loadUrl(url);
-
- return "";
-
- // Determine if we should hide the location bar.
+ // Determine if we should hide the location bar.
// showLocationBar = true;
// showZoomControls = true;
// openWindowHidden = false;
@@ -802,162 +732,87 @@ public class InAppBrowser implements MethodCallHandler {
//return "";
}
- /**
- * Put the list of features into a hash map
- *
- * @param optString
- * @return
- */
- private HashMap parseFeature(String optString) {
- if (optString.equals(NULL)) {
- return null;
- } else {
- HashMap map = new HashMap();
- StringTokenizer features = new StringTokenizer(optString, ",");
- StringTokenizer option;
- while(features.hasMoreElements()) {
- option = new StringTokenizer(features.nextToken(), "=");
- if (option.hasMoreElements()) {
- String key = option.nextToken();
- String value = option.nextToken();
- if (!customizableOptions.contains(key)){
- value = value.equals("yes") || value.equals("no") ? value : "yes";
- }
- map.put(key, value);
- }
- }
- return map;
+ public void loadUrl(String url, Map headers, Result result) {
+ if (webViewActivity != null) {
+ if (headers != null)
+ webViewActivity.loadUrl(url, headers, result);
+ else
+ webViewActivity.loadUrl(url, result);
}
}
+ public void show() {
+ if (webViewActivity != null)
+ webViewActivity.show();
+ }
+ public void hide() {
+ if (webViewActivity != null)
+ webViewActivity.hide();
+ }
+ public void reload() {
+ if (webViewActivity != null)
+ webViewActivity.reload();
+ }
+ public boolean isLoading() {
+ if (webViewActivity != null)
+ return webViewActivity.isLoading();
+ return false;
+ }
+ public void stopLoading() {
+ if (webViewActivity != null)
+ webViewActivity.stopLoading();
+ }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /**
- * Checks to see if it is possible to go back one page in history, then does so.
- */
public void goBack() {
- if (this.inAppWebView.canGoBack()) {
- this.inAppWebView.goBack();
- }
+ if (webViewActivity != null)
+ webViewActivity.goBack();
}
- /**
- * Can the web browser go back?
- * @return boolean
- */
public boolean canGoBack() {
- return this.inAppWebView.canGoBack();
+ if (webViewActivity != null)
+ return webViewActivity.canGoBack();
+ return false;
}
- /**
- * Has the user set the hardware back button to go back
- * @return boolean
- */
- public boolean hardwareBack() {
- return hadwareBackButton;
+ public void goForward() {
+ if (webViewActivity != null)
+ webViewActivity.goForward();
}
- /**
- * Checks to see if it is possible to go forward one page in history, then does so.
- */
- private void goForward() {
- if (this.inAppWebView.canGoForward()) {
- this.inAppWebView.goForward();
- }
- }
-
- /**
- * Navigate to the new page
- *
- * @param url to load
- */
- @TargetApi(3)
- private void navigate(String url) {
- InputMethodManager imm = (InputMethodManager)this.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
-
- if (!url.startsWith("http") && !url.startsWith("file:")) {
- this.inAppWebView.loadUrl("http://" + url);
- } else {
- this.inAppWebView.loadUrl(url);
- }
- this.inAppWebView.requestFocus();
+ public boolean canGoForward() {
+ if (webViewActivity != null)
+ return webViewActivity.canGoForward();
+ return false;
}
- /**
- * Should we show the location bar?
- *
- * @return boolean
- */
- private boolean getShowLocationBar() {
- return this.showLocationBar;
- }
-
- private InAppBrowser getInAppBrowser(){
- return this;
- }
-
- /**
- * Closes the dialog
- */
- public void closeDialog() {
+ public void close() {
this.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
- final WebView childView = inAppWebView;
// The JS protects against multiple calls, so this should happen only when
- // closeDialog() is called by other native code.
- if (childView == null) {
+ // close() is called by other native code.
+ if (webViewActivity == null)
return;
- }
- childView.setWebViewClient(new WebViewClient() {
+ webViewActivity.webView.setWebViewClient(new WebViewClient() {
// NB: wait for about:blank before dismissing
public void onPageFinished(WebView view, String url) {
- if (dialog != null) {
- dialog.dismiss();
- dialog = null;
- }
+ webViewActivity.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
- childView.loadUrl("about:blank");
+ webViewActivity.webView.loadUrl("about:blank");
Map obj = new HashMap<>();
- obj.put("type", EXIT_EVENT);
- channel.invokeMethod(EXIT_EVENT, obj);
+ channel.invokeMethod("exit", obj);
}
});
}
-
- /**
- * Called by AccelBroker when listener is to be shut down.
- * Stop listener.
- */
- public void onDestroy() {
- closeDialog();
- }
-
}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserDialog.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserDialog.java
deleted file mode 100644
index 6b06c66f..00000000
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserDialog.java
+++ /dev/null
@@ -1,53 +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_inappbrowser;
-
-import android.app.Dialog;
-import android.content.Context;
-
-public class InAppBrowserDialog extends Dialog {
- Context context;
- InAppBrowser inAppBrowser = null;
-
- public InAppBrowserDialog(Context context, int theme) {
- super(context, theme);
- this.context = context;
- }
-
- public void setInAppBroswer(InAppBrowser browser) {
- this.inAppBrowser = browser;
- }
-
- public void onBackPressed () {
- if (this.inAppBrowser == null) {
- this.dismiss();
- } else {
- // better to go through the in inAppBrowser
- // because it does a clean up
- if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) {
- this.inAppBrowser.goBack();
- } else {
- this.inAppBrowser.closeDialog();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java
index 6d37d213..a35515ae 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java
@@ -13,23 +13,21 @@ public class InAppBrowserOptions {
boolean clearCache = false;
boolean clearSessionCache = false;
+ String userAgent = "";
boolean spinner = true;
boolean hidden = false;
boolean toolbarTop = true;
String toolbarTopColor = "toolbarTopColor";
boolean hideUrlBar = false;
- boolean enableViewportScale = false;
- boolean keyboardDisplayRequiresUserAction = true;
- boolean suppressesIncrementalRendering = false;
- boolean allowsAirPlayForMediaPlayback = true;
- boolean mediaTypesRequiringUserActionForPlayback = true;
- boolean allowsBackForwardNavigationGestures = true;
- boolean allowsLinkPreview = true;
- boolean ignoresViewportScaleLimits = false;
- boolean allowsInlineMediaPlayback = false;
- boolean allowsPictureInPictureMediaPlayback = true;
+ boolean mediaPlaybackRequiresUserGesture = true;
boolean javaScriptCanOpenWindowsAutomatically = false;
boolean javaScriptEnabled = true;
+ boolean builtInZoomControls = false;
+ boolean supportZoom = true;
+ boolean databaseEnabled = true;
+ boolean domStorageEnabled = true;
+ boolean useWideViewPort = true;
+ boolean safeBrowsingEnabled = true;
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void parse(HashMap options) {
@@ -42,7 +40,6 @@ public class InAppBrowserOptions {
// silent
}
}
-
}
public HashMap getHashMap() {
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebChromeClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebChromeClient.java
new file mode 100644
index 00000000..bc229aa6
--- /dev/null
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebChromeClient.java
@@ -0,0 +1,112 @@
+package com.pichillilorenzo.flutter_inappbrowser;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.util.Log;
+import android.view.View;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import android.webkit.WebView;
+
+public class InAppBrowserWebChromeClient extends WebChromeClient {
+
+ protected static final String LOG_TAG = "IABWebChromeClient";
+ private WebViewActivity activity;
+ private ValueCallback mUploadMessageArray;
+ private ValueCallback mUploadMessage;
+ private final static int FILECHOOSER_RESULTCODE=1;
+
+ public InAppBrowserWebChromeClient(WebViewActivity activity) {
+ super();
+ this.activity = activity;
+ }
+
+ @Override
+ public void onProgressChanged(WebView view, int progress) {
+ if (activity.progressBar != null) {
+ activity.progressBar.setVisibility(View.VISIBLE);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ activity.progressBar.setProgress(progress, true);
+ }
+ else {
+ activity.progressBar.setProgress(progress);
+ }
+ if (progress == 100) {
+ activity.progressBar.setVisibility(View.GONE);
+ }
+ }
+ super.onProgressChanged(view, progress);
+ }
+
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ super.onReceivedTitle(view, title);
+ if (activity.getSupportActionBar() != null)
+ activity.getSupportActionBar().setTitle(title);
+ }
+
+ @Override
+ public void onReceivedIcon(WebView view, Bitmap icon) {
+ super.onReceivedIcon(view, icon);
+ }
+
+ //The undocumented magic method override
+ //Eclipse will swear at you if you try to put @Override here
+ // For Android 3.0+
+ public void openFileChooser(ValueCallback uploadMsg) {
+
+ mUploadMessage = uploadMsg;
+ Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+ i.addCategory(Intent.CATEGORY_OPENABLE);
+ i.setType("image/*");
+ activity.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);
+
+ }
+
+ // For Android 3.0+
+ public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
+ mUploadMessage = uploadMsg;
+ Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+ i.addCategory(Intent.CATEGORY_OPENABLE);
+ i.setType("*/*");
+ activity.startActivityForResult(
+ Intent.createChooser(i, "File Browser"),
+ FILECHOOSER_RESULTCODE);
+ }
+
+ //For Android 4.1
+ public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture){
+ mUploadMessage = uploadMsg;
+ Intent i = new Intent(Intent.ACTION_GET_CONTENT);
+ i.addCategory(Intent.CATEGORY_OPENABLE);
+ i.setType("image/*");
+ activity.startActivityForResult( Intent.createChooser( i, "File Chooser" ), FILECHOOSER_RESULTCODE );
+
+ }
+
+ //For Android 5.0+
+ public boolean onShowFileChooser(
+ WebView webView, ValueCallback filePathCallback,
+ FileChooserParams fileChooserParams){
+ if(mUploadMessageArray != null){
+ mUploadMessageArray.onReceiveValue(null);
+ }
+ mUploadMessageArray = filePathCallback;
+
+ Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
+ contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
+ contentSelectionIntent.setType("*/*");
+ Intent[] intentArray;
+ intentArray = new Intent[0];
+
+ Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
+ chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
+ chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
+ chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
+ activity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
+ return true;
+ }
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
similarity index 51%
rename from android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserClient.java
rename to android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
index c242196a..74216d85 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserClient.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
@@ -1,84 +1,31 @@
-/*
- *
- * 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_inappbrowser;
-import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.widget.EditText;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
-import io.flutter.plugin.common.MethodChannel;
+public class InAppBrowserWebViewClient extends WebViewClient {
-/**
- * The webview client receives notifications about appView
- */
-public class InAppBrowserClient extends WebViewClient {
+ protected static final String LOG_TAG = "IABWebViewClient";
+ private WebViewActivity activity;
- protected static final String LOG_TAG = "InAppBrowser";
- private static final String LOAD_START_EVENT = "loadstart";
- private static final String LOAD_STOP_EVENT = "loadstop";
- private static final String LOAD_ERROR_EVENT = "loaderror";
-
- private String[] allowedSchemes;
-
- private EditText edittext;
- private Activity activity;
- private final MethodChannel channel;
-
- /**
- * Constructor.
- *
- * @param mEditText
- * @param activity
- */
- public InAppBrowserClient(EditText mEditText, Activity activity, MethodChannel channel) {
- this.edittext = mEditText;
+ public InAppBrowserWebViewClient(WebViewActivity activity) {
+ super();
this.activity = activity;
- this.channel = channel;
}
- /**
- * Override the URL that should be loaded
- *
- * This handles a small subset of all the URIs that would be encountered.
- *
- * @param webView
- * @param url
- */
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
+
if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
@@ -88,7 +35,8 @@ public class InAppBrowserClient extends WebViewClient {
} catch (android.content.ActivityNotFoundException e) {
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
}
- } else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) {
+ }
+ else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:") || url.startsWith("intent:")) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
@@ -104,7 +52,7 @@ public class InAppBrowserClient extends WebViewClient {
Intent intent = new Intent(Intent.ACTION_VIEW);
// Get address
- String address = null;
+ String address;
int parmIndex = url.indexOf('?');
if (parmIndex == -1) {
address = url.substring(4);
@@ -129,25 +77,8 @@ public class InAppBrowserClient extends WebViewClient {
Log.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
}
}
- // Test for whitelisted custom scheme names like mycoolapp:// or twitteroauthresponse:// (Twitter Oauth Response)
- else if (!url.startsWith("http:") && !url.startsWith("https:") && url.matches("^[A-Za-z0-9+.-]*://.*?$")) {
- if (allowedSchemes == null) {
- String allowed = activity.getPreferences(0).getString("AllowedSchemes", null);
- if(allowed != null) {
- allowedSchemes = allowed.split(",");
- }
- }
- if (allowedSchemes != null) {
- for (String scheme : allowedSchemes) {
- if (url.startsWith(scheme)) {
- Map obj = new HashMap<>();
- obj.put("type", "customscheme");
- obj.put("url", url);
- channel.invokeMethod("customscheme", obj);
- return true;
- }
- }
- }
+ else {
+ return super.shouldOverrideUrlLoading(webView, url);
}
return false;
@@ -164,27 +95,16 @@ public class InAppBrowserClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
- String newloc = "";
- if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
- newloc = url;
- }
- else
- {
- // Assume that everything is HTTP at this point, because if we don't specify,
- // it really should be. Complain loudly about this!!!
- Log.e(LOG_TAG, "Possible Uncaught/Unknown URI");
- newloc = "http://" + url;
- }
- // Update the UI if we haven't already
- if (!newloc.equals(edittext.getText().toString())) {
- edittext.setText(newloc);
+ activity.isLoading = true;
+
+ if (activity.searchView != null && !url.equals(activity.searchView.getQuery().toString())) {
+ activity.searchView.setQuery(url, false);
}
Map obj = new HashMap<>();
- obj.put("type", LOAD_START_EVENT);
- obj.put("url", newloc);
- channel.invokeMethod(LOAD_START_EVENT, obj);
+ obj.put("url", url);
+ InAppBrowser.channel.invokeMethod("loadstart", obj);
}
@@ -192,6 +112,8 @@ public class InAppBrowserClient extends WebViewClient {
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
+ activity.isLoading = false;
+
// CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush();
@@ -204,20 +126,20 @@ public class InAppBrowserClient extends WebViewClient {
view.requestFocus();
Map obj = new HashMap<>();
- obj.put("type", LOAD_STOP_EVENT);
obj.put("url", url);
- channel.invokeMethod(LOAD_STOP_EVENT, obj);
+ InAppBrowser.channel.invokeMethod("loadstop", obj);
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
+ activity.isLoading = false;
+
Map obj = new HashMap<>();
- obj.put("type", LOAD_ERROR_EVENT);
obj.put("url", failingUrl);
obj.put("code", errorCode);
obj.put("message", description);
- channel.invokeMethod(LOAD_ERROR_EVENT, obj);
+ InAppBrowser.channel.invokeMethod("loaderror", obj);
}
/**
@@ -228,4 +150,4 @@ public class InAppBrowserClient extends WebViewClient {
// By default handle 401 like we'd normally do!
super.onReceivedHttpAuthRequest(view, handler, host, realm);
}
-}
\ No newline at end of file
+}
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java
index 1396c828..ae724116 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java
@@ -1,6 +1,7 @@
package com.pichillilorenzo.flutter_inappbrowser;
-import android.app.SearchManager;
+import android.annotation.TargetApi;
+import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
@@ -8,37 +9,98 @@ import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
+import android.view.Display;
+import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.webkit.CookieManager;
+import android.webkit.ValueCallback;
+import android.webkit.WebSettings;
import android.webkit.WebView;
-import android.widget.EditText;
+import android.widget.ProgressBar;
import android.widget.SearchView;
import java.util.HashMap;
+import java.util.Map;
+
+import io.flutter.plugin.common.MethodChannel;
public class WebViewActivity extends AppCompatActivity {
- WebView wv;
+ WebView webView;
+ InAppBrowserWebViewClient inAppBrowserWebViewClient;
+ InAppBrowserWebChromeClient inAppBrowserWebChromeClient;
SearchView searchView;
InAppBrowserOptions options;
+ ProgressBar progressBar;
+ public boolean isLoading = false;
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_web_view);
+
+ webView = findViewById(R.id.webView);
+ progressBar = findViewById(R.id.progressBar);
+ progressBar.setMax(100);
+
Bundle b = getIntent().getExtras();
String url = b.getString("url");
options = new InAppBrowserOptions();
options.parse((HashMap) b.getSerializable("options"));
-
- setContentView(R.layout.activity_web_view);
- wv = (WebView) findViewById(R.id.webView);
-
InAppBrowser.webViewActivity = this;
- wv.loadUrl(url);
- getSupportActionBar().setTitle(wv.getTitle());
+ prepareWebView();
+
+ webView.loadUrl(url);
+
+ }
+
+ public void prepareWebView() {
+
+ inAppBrowserWebChromeClient = new InAppBrowserWebChromeClient(this);
+ webView.setWebChromeClient(inAppBrowserWebChromeClient);
+
+ inAppBrowserWebViewClient = new InAppBrowserWebViewClient(this);
+ webView.setWebViewClient(inAppBrowserWebViewClient);
+
+ WebSettings settings = webView.getSettings();
+
+ settings.setJavaScriptEnabled(options.javaScriptEnabled);
+ settings.setJavaScriptCanOpenWindowsAutomatically(options.javaScriptCanOpenWindowsAutomatically);
+ settings.setBuiltInZoomControls(options.builtInZoomControls);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ settings.setSafeBrowsingEnabled(options.safeBrowsingEnabled);
+ }
+
+ settings.setMediaPlaybackRequiresUserGesture(options.mediaPlaybackRequiresUserGesture);
+
+ settings.setDatabaseEnabled(options.databaseEnabled);
+ settings.setDomStorageEnabled(options.domStorageEnabled);
+
+ if (!options.userAgent.isEmpty()) {
+ settings.setUserAgentString(options.userAgent);
+ }
+
+ if (options.clearCache) {
+ clearCache();
+ } else if (options.clearSessionCache) {
+ CookieManager.getInstance().removeSessionCookie();
+ }
+
+ // Enable Thirdparty Cookies on >=Android 5.0 device
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ CookieManager.getInstance().setAcceptThirdPartyCookies(webView,true);
+ }
+
+ settings.setLoadWithOverviewMode(true);
+ settings.setUseWideViewPort(options.useWideViewPort);
+ settings.setSupportZoom(options.supportZoom);
}
@@ -49,13 +111,13 @@ public class WebViewActivity extends AppCompatActivity {
inflater.inflate(R.menu.menu_main, menu);
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
- searchView.setQuery(wv.getUrl(), false);
- getSupportActionBar().setTitle(wv.getTitle());
+ searchView.setQuery(webView.getUrl(), false);
+ getSupportActionBar().setTitle(webView.getTitle());
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
- wv.loadUrl(query);
+ webView.loadUrl(query);
return false;
}
@@ -68,4 +130,131 @@ public class WebViewActivity extends AppCompatActivity {
return true;
}
+ public void loadUrl (String url, MethodChannel.Result result) {
+ if (webView != null && !url.isEmpty()) {
+ webView.loadUrl(url);
+ }
+ else {
+ result.error("Cannot load url", "", null);
+ }
+ }
+
+ public void loadUrl (String url, Map headers, MethodChannel.Result result) {
+ if (webView != null && !url.isEmpty()) {
+ webView.loadUrl(url, headers);
+ }
+ else {
+ result.error("Cannot load url", "", null);
+ }
+ }
+
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if ((keyCode == KeyEvent.KEYCODE_BACK)) {
+ goBack();
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+// @TargetApi(Build.VERSION_CODES.KITKAT)
+// void eval(MethodCall call, final MethodChannel.Result result) {
+// String code = call.argument("code");
+//
+// webView.evaluateJavascript(code, new ValueCallback() {
+// @Override
+// public void onReceiveValue(String value) {
+// result.success(value);
+// }
+// });
+// }
+
+ public void close() {
+ finish();
+ }
+
+ public void reload() {
+ if (webView != null)
+ webView.reload();
+ }
+
+ public void goBack() {
+ if (webView != null && canGoBack())
+ webView.goBack();
+ }
+
+ public void goForward() {
+ if (webView != null && canGoForward())
+ webView.goForward();
+ }
+
+ public boolean canGoBack() {
+ return webView.canGoBack();
+ }
+
+ public boolean canGoForward() {
+ return webView.canGoForward();
+ }
+
+ public void hide() {
+ if (webView != null)
+ webView.setVisibility(View.INVISIBLE);
+ }
+ public void show() {
+ if (webView != null)
+ webView.setVisibility(View.VISIBLE);
+ }
+
+ public boolean isLoading() {
+ if (webView != null)
+ return isLoading;
+ return false;
+ }
+
+ public void stopLoading(){
+ if (webView != null)
+ webView.stopLoading();
+ }
+
+ private void clearCookies() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ CookieManager.getInstance().removeAllCookies(new ValueCallback() {
+ @Override
+ public void onReceiveValue(Boolean aBoolean) {
+
+ }
+ });
+ } else {
+ CookieManager.getInstance().removeAllCookie();
+ }
+ }
+
+ private void clearCache() {
+ webView.clearCache(true);
+ clearCookies();
+ webView.clearFormData();
+ }
+
+ public void goBackButtonClicked(MenuItem item) {
+ goBack();
+ }
+
+ public void goForwardButtonClicked(MenuItem item) {
+ goForward();
+ }
+
+ public void shareButtonClicked(MenuItem item) {
+ Intent share = new Intent(Intent.ACTION_SEND);
+ share.setType("text/plain");
+ share.putExtra(Intent.EXTRA_TEXT, webView.getUrl());
+ startActivity(Intent.createChooser(share, "Share"));
+ }
+
+ public void reloadButtonClicked(MenuItem item) {
+ reload();
+ }
+
+ public void closeButtonClicked(MenuItem item) {
+ close();
+ }
+
}
diff --git a/android/src/main/res/drawable/ic_more_vert_black_24dp.xml b/android/src/main/res/drawable/ic_more_vert_black_24dp.xml
deleted file mode 100644
index 5176d8a4..00000000
--- a/android/src/main/res/drawable/ic_more_vert_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/android/src/main/res/layout/activity_web_view.xml b/android/src/main/res/layout/activity_web_view.xml
index d1bb58d2..82f65299 100644
--- a/android/src/main/res/layout/activity_web_view.xml
+++ b/android/src/main/res/layout/activity_web_view.xml
@@ -8,6 +8,15 @@
android:orientation="vertical"
tools:context=".WebViewActivity">
+
+
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index c9199621..9301a93e 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -1,5 +1,9 @@
- Settings
+ Go Back
+ Go Forward
+ Reload
+ Share
+ Close
Search
diff --git a/ios/Classes/InAppBrowserOptions.swift b/ios/Classes/InAppBrowserOptions.swift
index d3cc2f32..3e966e24 100644
--- a/ios/Classes/InAppBrowserOptions.swift
+++ b/ios/Classes/InAppBrowserOptions.swift
@@ -9,10 +9,11 @@ import Foundation
@objcMembers
public class InAppBrowserOptions: NSObject {
+
var closeButtonCaption = ""
var closeButtonColor = ""
var clearCache = false
- var clearSessionCache = false
+ var userAgent = ""
var spinner = true
var hidden = false
var disallowOverScroll = false
@@ -38,6 +39,10 @@ public class InAppBrowserOptions: NSObject {
var javaScriptCanOpenWindowsAutomatically = false
var javaScriptEnabled = true
+ override init(){
+ super.init()
+ }
+
public func parse(options: [String: Any]) {
for (key, value) in options {
if self.value(forKey: key) != nil {
diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift
index 06fa6896..e1875040 100644
--- a/ios/Classes/InAppBrowserWebViewController.swift
+++ b/ios/Classes/InAppBrowserWebViewController.swift
@@ -78,6 +78,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
var currentURL: URL?
var tmpWindow: UIWindow?
var browserOptions: InAppBrowserOptions?
+ var initHeaders: [String: String]?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
@@ -117,7 +118,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
spinner.isHidden = false
spinner.stopAnimating()
- navigate(to: self.currentURL!)
+ loadUrl(url: self.currentURL!, headers: self.initHeaders)
}
// Prevent crashes on closing windows
@@ -223,6 +224,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
} else {
// Fallback on earlier versions
+ self.webView.configuration.mediaPlaybackRequiresUserAction = true
}
}
@@ -248,6 +250,33 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
}
self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = (browserOptions?.javaScriptCanOpenWindowsAutomatically)!
self.webView.configuration.preferences.javaScriptEnabled = (browserOptions?.javaScriptEnabled)!
+
+ if ((browserOptions?.userAgent)! != "") {
+ if #available(iOS 9.0, *) {
+ self.webView.customUserAgent = (browserOptions?.userAgent)!
+ } else {
+ // Fallback on earlier versions
+ }
+ }
+
+ if (browserOptions?.clearCache)! {
+ clearCache()
+ }
+
+ }
+
+ func loadUrl(url: URL, headers: [String: String]?) {
+ var request = URLRequest(url: url)
+ currentURL = url
+ updateUrlTextField(url: (currentURL?.absoluteString)!)
+
+ if headers != nil {
+ for (key, value) in headers! {
+ request.setValue(value, forHTTPHeaderField: key)
+ }
+ }
+
+ webView.load(request)
}
// Load user requested url
@@ -270,6 +299,24 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
webView.frame = frame
}
+ func clearCache() {
+ if #available(iOS 9.0, *) {
+ //let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
+ let date = NSDate(timeIntervalSince1970: 0)
+ WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), modifiedSince: date as Date, completionHandler:{ })
+ } else {
+ var libraryPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, false).first!
+ libraryPath += "/Cookies"
+
+ do {
+ try FileManager.default.removeItem(atPath: libraryPath)
+ } catch {
+ print("can't clear cache")
+ }
+ URLCache.shared.removeAllCachedResponses()
+ }
+ }
+
@objc func reload () {
webView.reload()
}
@@ -305,22 +352,23 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
})
}
- func navigate(to url: URL) {
- let request = URLRequest(url: url)
- currentURL = url
- updateUrlTextField(url: (currentURL?.absoluteString)!)
- webView.load(request)
+ func canGoBack() -> Bool {
+ return webView.canGoBack
}
@objc func goBack() {
- if webView.canGoBack {
+ if canGoBack() {
webView.goBack()
updateUrlTextField(url: (webView?.url?.absoluteString)!)
}
}
+ func canGoForward() -> Bool {
+ return webView.canGoForward
+ }
+
@objc func goForward() {
- if webView.canGoForward {
+ if canGoForward() {
webView.goForward()
updateUrlTextField(url: (webView?.url?.absoluteString)!)
}
diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift
index 95b7b263..7a4788b9 100644
--- a/ios/Classes/SwiftFlutterPlugin.swift
+++ b/ios/Classes/SwiftFlutterPlugin.swift
@@ -47,6 +47,9 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
case "open":
self.open(arguments: arguments!, result: result)
break
+ case "loadUrl":
+ self.loadUrl(arguments: arguments!, result: result)
+ break
case "close":
self.close()
result(true)
@@ -67,12 +70,18 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
self.webViewController?.goBack()
result(true)
break
+ case "canGoBack":
+ result(self.webViewController?.canGoBack() ?? false)
+ break
case "goForward":
self.webViewController?.goForward()
result(true)
break
+ case "canGoForward":
+ result(self.webViewController?.canGoForward() ?? false)
+ break
case "isLoading":
- result(self.webViewController?.webView.isLoading == true)
+ result((self.webViewController?.webView.isLoading ?? false) == true)
break
case "stopLoading":
self.webViewController?.webView.stopLoading()
@@ -117,6 +126,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
public func open(arguments: NSDictionary, result: @escaping FlutterResult) {
let url: String? = (arguments["url"] as? String)!
+ let headers = (arguments["headers"] as? [String: String])!
var target: String? = (arguments["target"] as? String)!
target = target != nil ? target : "_self"
let options = (arguments["options"] as? [String: Any])!
@@ -129,45 +139,42 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
}
if (target == "_self" || target == "_target") {
- openIn(inAppBrowser: absoluteUrl!, withOptions: options)
+ open(inAppBrowser: absoluteUrl!, headers: headers, withOptions: options)
}
else if (target == "_system") {
open(inSystem: absoluteUrl!)
}
else {
// anything else
- openIn(inAppBrowser: absoluteUrl!, withOptions: options)
+ open(inAppBrowser: absoluteUrl!, headers: headers,withOptions: options)
}
}
else {
+ print("url is empty")
result(false)
}
result(true)
}
- func openIn(inAppBrowser url: URL, withOptions options: [String: Any]) {
+ public func loadUrl(arguments: NSDictionary, result: @escaping FlutterResult) {
+ let url: String? = (arguments["url"] as? String)!
+ let headers = (arguments["headers"] as? [String: String])!
+
+ if url != nil {
+ let absoluteUrl = URL(string: url!)!.absoluteURL
+ webViewController?.loadUrl(url: absoluteUrl, headers: headers)
+ }
+ else {
+ print("url is empty")
+ result(false)
+ }
+ result(true)
+ }
+
+ func open(inAppBrowser url: URL, headers: [String: String], withOptions options: [String: Any]) {
let browserOptions = InAppBrowserOptions()
browserOptions.parse(options: options)
-
- if browserOptions.clearCache {
- let _: HTTPCookie?
- let storage = HTTPCookieStorage.shared
- for cookie in storage.cookies! {
- if !(cookie.domain.isEqual(".^filecookies^") ) {
- storage.deleteCookie(cookie)
- }
- }
- }
-
- if browserOptions.clearSessionCache {
- let storage = HTTPCookieStorage.shared
- for cookie in storage.cookies! {
- if !(cookie.domain.isEqual(".^filecookies^") && cookie.isSessionOnly) {
- storage.deleteCookie(cookie)
- }
- }
- }
if webViewController == nil {
@@ -182,6 +189,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
webViewController?.browserOptions = browserOptions
webViewController?.tmpWindow = tmpWindow
webViewController?.currentURL = url
+ webViewController?.initHeaders = headers
webViewController?.navigationDelegate = self
}
@@ -258,18 +266,18 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
//
// If no wrapper is supplied, then the source string is executed directly.
func injectDeferredObject(_ source: String, withWrapper jsWrapper: String) {
- if jsWrapper != nil {
- let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: [])
- let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8)
- if sourceArrayString != nil {
- let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.characters.count ?? 0) - 2))
- let jsToInject = String(format: jsWrapper, sourceString!)
- webViewController?.webView?.evaluateJavaScript(jsToInject)
- }
- }
- else {
- webViewController?.webView?.evaluateJavaScript(source)
+ //if jsWrapper != nil {
+ let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: [])
+ let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8)
+ if sourceArrayString != nil {
+ let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.characters.count ?? 0) - 2))
+ let jsToInject = String(format: jsWrapper, sourceString!)
+ webViewController?.webView?.evaluateJavaScript(jsToInject)
}
+ //}
+ //else {
+ // webViewController?.webView?.evaluateJavaScript(source)
+ //}
}
public func injectScriptCode(arguments: NSDictionary) {
@@ -294,23 +302,23 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
func webViewDidStartLoad(_ webView: WKWebView) {
let url: String = webViewController!.currentURL!.absoluteString
- channel.invokeMethod("loadstart", arguments: ["type": "loadstart", "url": url])
+ channel.invokeMethod("loadstart", arguments: ["url": url])
}
func webViewDidFinishLoad(_ webView: WKWebView) {
let url: String = webViewController!.currentURL!.absoluteString
- channel.invokeMethod("loadstop", arguments: ["type": "loadstop", "url": url])
+ channel.invokeMethod("loadstop", arguments: ["url": url])
}
func webView(_ webView: WKWebView, didFailLoadWithError error: Error) {
let url: String = webViewController!.currentURL!.absoluteString
- let arguments = ["type": "loaderror", "url": url, "code": error._code, "message": error.localizedDescription] as [String : Any]
+ let arguments = ["url": url, "code": error._code, "message": error.localizedDescription] as [String : Any]
channel.invokeMethod("loaderror", arguments: arguments)
}
func browserExit() {
- channel.invokeMethod("exit", arguments: ["type": "exit"])
+ channel.invokeMethod("exit", arguments: [])
// Set navigationDelegate to nil to ensure no callbacks are received from it.
webViewController?.navigationDelegate = nil
diff --git a/lib/flutter_inappbrowser.dart b/lib/flutter_inappbrowser.dart
index e5b4194b..2413c31f 100644
--- a/lib/flutter_inappbrowser.dart
+++ b/lib/flutter_inappbrowser.dart
@@ -51,10 +51,6 @@ class InAppBrowser {
case "exit":
onExit();
break;
- case "customscheme":
- String url = call.arguments["url"];
- onCustomScheme(url);
- break;
}
return new Future.value("");
}
@@ -121,14 +117,22 @@ class InAppBrowser {
/// - __transitionstyle__: Set to `fliphorizontal`, `crossdissolve` or `coververtical` to set the [transition style](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (defaults to `coververtical`).
/// - __toolbarposition__: Set to `top` or `bottom` (default is `bottom`). Causes the toolbar to be at the top or bottom of the window.
/// - __hidespinner__: Set to `yes` or `no` to change the visibility of the loading indicator (defaults to `no`).
- Future open(String url, {String target = "_self", Map options = const {}}) async {
+ Future open(String url, {Map headers = const {}, String target = "_self", Map options = const {}}) async {
Map args = {};
args.putIfAbsent('url', () => url);
+ args.putIfAbsent('headers', () => headers);
args.putIfAbsent('target', () => target);
args.putIfAbsent('options', () => options);
return await _channel.invokeMethod('open', args);
}
+ Future loadUrl(String url, {Map headers = const {}}) async {
+ Map args = {};
+ args.putIfAbsent('url', () => url);
+ args.putIfAbsent('headers', () => headers);
+ return await _channel.invokeMethod('loadUrl', args);
+ }
+
///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible.
Future show() async {
return await _channel.invokeMethod('show');