Commit 7756aa86 authored by pichillilorenzo's avatar pichillilorenzo

v0.5.0

parent ee7910b0
This diff is collapsed.
## 0.5.0
- added initial support for Inline WebViews using the `InAppWebView` widget
- added `InAppBrowser.openFile()` method
- added `InAppBrowser.onProgressChanged()` event
- moved `InAppBrowser` WebView related functions on the `InAppWebViewController` class
- added `InAppLocalhostServer` class
- added `InAppWebView.canGoBack()` and `InAppWebView.canGoForward()` methods
- removed `openWithSystemBrowser` and `isLocalFile` option. Now use the corresponding method
- code refactoring
## 0.4.1 ## 0.4.1
- added `InAppBrowser.takeScreenshot()` - added `InAppBrowser.takeScreenshot()`
......
This diff is collapsed.
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application> <application>
<activity android:theme="@style/AppTheme" android:name=".WebViewActivity" android:configChanges="orientation|screenSize"></activity> <activity android:theme="@style/AppTheme" android:name=".InAppBrowserActivity" android:configChanges="orientation|screenSize"></activity>
<activity android:theme="@style/ThemeTransparent" android:name=".chrome_custom_tabs.ChromeCustomTabsActivity" android:configChanges="orientation|screenSize"></activity> <activity android:theme="@style/ThemeTransparent" android:name=".ChromeCustomTabs.ChromeCustomTabsActivity" android:configChanges="orientation|screenSize"></activity>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
...@@ -6,10 +6,8 @@ import android.graphics.Color; ...@@ -6,10 +6,8 @@ import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent; import android.support.customtabs.CustomTabsIntent;
import android.util.Log;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin; import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserOptions;
import com.pichillilorenzo.flutter_inappbrowser.R; import com.pichillilorenzo.flutter_inappbrowser.R;
import java.util.HashMap; import java.util.HashMap;
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import com.pichillilorenzo.flutter_inappbrowser.Options; import com.pichillilorenzo.flutter_inappbrowser.Options;
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.app.Activity; import android.app.Activity;
import android.net.Uri; import android.net.Uri;
...@@ -10,8 +10,6 @@ import android.support.customtabs.CustomTabsSession; ...@@ -10,8 +10,6 @@ import android.support.customtabs.CustomTabsSession;
import java.util.List; import java.util.List;
import static android.support.v4.app.ActivityCompat.startActivityForResult;
/** /**
* This is a helper class to manage the connection to the Custom Tabs Service. * This is a helper class to manage the connection to the Custom Tabs Service.
*/ */
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
...@@ -6,7 +6,6 @@ import android.content.IntentFilter; ...@@ -6,7 +6,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.support.customtabs.CustomTabsClient;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.content.ComponentName; import android.content.ComponentName;
import android.support.customtabs.CustomTabsClient; import android.support.customtabs.CustomTabsClient;
......
package com.pichillilorenzo.flutter_inappbrowser.chrome_custom_tabs; package com.pichillilorenzo.flutter_inappbrowser.ChromeCustomTabs;
import android.support.customtabs.CustomTabsClient; import android.support.customtabs.CustomTabsClient;
......
package com.pichillilorenzo.flutter_inappbrowser;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView;
import com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebViewOptions;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import static io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import static io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.platform.PlatformView;
public class FlutterWebView implements PlatformView, MethodCallHandler {
static final String LOG_TAG = "FlutterWebView";
public final Activity activity;
public InAppWebView webView;
public MethodChannel channel;
public final Registrar registrar;
public final Context context;
public FlutterWebView(Registrar registrar, int id, HashMap<String, Object> params) {
this.registrar = registrar;
this.activity = registrar.activity();
this.context = registrar.context();
String initialUrl = (String) params.get("initialUrl");
String initialFile = (String) params.get("initialFile");
Map<String, String> initialHeaders = (Map<String, String>) params.get("initialHeaders");
HashMap<String, Object> initialOptions = (HashMap<String, Object>) params.get("initialOptions");
InAppWebViewOptions options = new InAppWebViewOptions();
options.parse(initialOptions);
if (initialFile != null) {
try {
initialUrl = Util.getUrlAsset(registrar, initialFile);
} catch (IOException e) {
e.printStackTrace();
Log.e(LOG_TAG, initialFile + " asset file cannot be found!", e);
return;
}
}
webView = new InAppWebView(context, this, id, options);
webView.prepare();
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappwebview_" + id);
channel.setMethodCallHandler(this);
webView.loadUrl(initialUrl, initialHeaders);
}
@Override
public View getView() {
return webView;
}
@Override
public void onMethodCall(MethodCall call, Result result) {
String source;
String jsWrapper;
String urlFile;
switch (call.method) {
case "loadUrl":
if (webView != null)
webView.loadUrl(call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
else
result.success(false);
break;
case "loadFile":
if (webView != null)
webView.loadFile(call.argument("url").toString(), (Map<String, String>) call.argument("headers"), result);
else
result.success(false);
break;
case "injectScriptCode":
if (webView != null) {
source = call.argument("source").toString();
jsWrapper = "(function(){return JSON.stringify(eval(%s));})();";
webView.injectDeferredObject(source, jsWrapper, result);
}
else {
result.success("");
}
break;
case "injectScriptFile":
if (webView != null) {
urlFile = call.argument("urlFile").toString();
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
webView.injectDeferredObject(urlFile, jsWrapper, null);
}
result.success(true);
break;
case "injectStyleCode":
if (webView != null) {
source = call.argument("source").toString();
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document);";
webView.injectDeferredObject(source, jsWrapper, null);
}
result.success(true);
break;
case "injectStyleFile":
if (webView != null) {
urlFile = call.argument("urlFile").toString();
jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
webView.injectDeferredObject(urlFile, jsWrapper, null);
}
result.success(true);
break;
case "reload":
if (webView != null)
webView.reload();
result.success(true);
break;
case "goBack":
if (webView != null)
webView.goBack();
result.success(true);
break;
case "canGoBack":
result.success((webView != null) && webView.canGoBack());
break;
case "goForward":
if (webView != null)
webView.goForward();
result.success(true);
break;
case "canGoForward":
result.success((webView != null) && webView.canGoForward());
break;
case "stopLoading":
if (webView != null)
webView.stopLoading();
result.success(true);
break;
case "isLoading":
result.success((webView != null) && webView.isLoading());
break;
case "takeScreenshot":
result.success((webView != null) ? webView.takeScreenshot() : null);
break;
case "setOptions":
if (webView != null) {
InAppWebViewOptions inAppWebViewOptions = new InAppWebViewOptions();
HashMap<String, Object> inAppWebViewOptionsMap = (HashMap<String, Object>) call.argument("options");
inAppWebViewOptions.parse(inAppWebViewOptionsMap);
webView.setOptions(inAppWebViewOptions, inAppWebViewOptionsMap);
}
result.success(true);
break;
case "getOptions":
result.success((webView != null) ? webView.getOptions() : null);
break;
case "dispose":
dispose();
result.success(true);
break;
default:
result.notImplemented();
}
}
@Override
public void dispose() {
if (webView != null) {
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
webView = null;
}
});
webView.loadUrl("about:blank");
}
}
}
\ No newline at end of file
package com.pichillilorenzo.flutter_inappbrowser;
import android.app.Activity;
import android.content.Context;
import java.util.HashMap;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class FlutterWebViewFactory extends PlatformViewFactory {
private final BinaryMessenger messenger;
private final Registrar registrar;
private final Activity activity;
public FlutterWebViewFactory(Registrar registrar, Activity activity) {
super(StandardMessageCodec.INSTANCE);
this.registrar = registrar;
this.messenger = registrar.messenger();
this.activity = activity;
}
@Override
public PlatformView create(Context context, int id, Object args) {
HashMap<String, Object> params = (HashMap<String, Object>) args;
return new FlutterWebView(registrar, id, params);
}
}
...@@ -4,29 +4,13 @@ public class InAppBrowserOptions extends Options { ...@@ -4,29 +4,13 @@ public class InAppBrowserOptions extends Options {
static final String LOG_TAG = "InAppBrowserOptions"; static final String LOG_TAG = "InAppBrowserOptions";
public boolean useShouldOverrideUrlLoading = false;
public boolean useOnLoadResource = false;
public boolean openWithSystemBrowser = false;
public boolean clearCache = false;
public String userAgent = "";
public boolean javaScriptEnabled = true;
public boolean javaScriptCanOpenWindowsAutomatically = false;
public boolean hidden = false; public boolean hidden = false;
public boolean toolbarTop = true; public boolean toolbarTop = true;
public String toolbarTopBackgroundColor = ""; public String toolbarTopBackgroundColor = "";
public String toolbarTopFixedTitle = ""; public String toolbarTopFixedTitle = "";
public boolean hideUrlBar = false; public boolean hideUrlBar = false;
public boolean mediaPlaybackRequiresUserGesture = true;
public boolean isLocalFile = false;
public boolean hideTitleBar = false; public boolean hideTitleBar = false;
public boolean closeOnCannotGoBack = true; public boolean closeOnCannotGoBack = true;
public boolean clearSessionCache = false;
public boolean builtInZoomControls = false;
public boolean supportZoom = true;
public boolean databaseEnabled = false;
public boolean domStorageEnabled = false;
public boolean useWideViewPort = true;
public boolean safeBrowsingEnabled = true;
public boolean progressBar = true; public boolean progressBar = true;
} }
package com.pichillilorenzo.flutter_inappbrowser; package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.view.View; import android.view.View;
import android.webkit.ConsoleMessage; import android.webkit.ConsoleMessage;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import android.webkit.WebChromeClient; import android.webkit.WebChromeClient;
import android.webkit.WebView; import android.webkit.WebView;
import com.pichillilorenzo.flutter_inappbrowser.FlutterWebView;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity;
import com.pichillilorenzo.flutter_inappbrowser.InAppBrowserFlutterPlugin;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class InAppBrowserWebChromeClient extends WebChromeClient { import io.flutter.plugin.common.MethodChannel;
public class InAppWebChromeClient extends WebChromeClient {
protected static final String LOG_TAG = "IABWebChromeClient"; protected static final String LOG_TAG = "IABWebChromeClient";
private WebViewActivity activity; private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity;
private ValueCallback<Uri[]> mUploadMessageArray; private ValueCallback<Uri[]> mUploadMessageArray;
private ValueCallback<Uri> mUploadMessage; private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1; private final static int FILECHOOSER_RESULTCODE = 1;
public InAppBrowserWebChromeClient(WebViewActivity activity) { public InAppWebChromeClient(Object obj) {
super(); super();
this.activity = activity; if (obj instanceof InAppBrowserActivity)
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj;
} }
@Override @Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) { public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", activity.uuid); if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("sourceURL", consoleMessage.sourceId()); obj.put("sourceURL", consoleMessage.sourceId());
obj.put("lineNumber", consoleMessage.lineNumber()); obj.put("lineNumber", consoleMessage.lineNumber());
obj.put("message", consoleMessage.message()); obj.put("message", consoleMessage.message());
obj.put("messageLevel", consoleMessage.messageLevel().toString()); obj.put("messageLevel", consoleMessage.messageLevel().toString());
InAppBrowserFlutterPlugin.channel.invokeMethod("onConsoleMessage", obj); getChannel().invokeMethod("onConsoleMessage", obj);
return true; return true;
} }
@Override @Override
public void onProgressChanged(WebView view, int progress) { public void onProgressChanged(WebView view, int progress) {
if (activity.progressBar != null) { if (inAppBrowserActivity != null && inAppBrowserActivity.progressBar != null) {
activity.progressBar.setVisibility(View.VISIBLE); inAppBrowserActivity.progressBar.setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
activity.progressBar.setProgress(progress, true); inAppBrowserActivity.progressBar.setProgress(progress, true);
} else { } else {
activity.progressBar.setProgress(progress); inAppBrowserActivity.progressBar.setProgress(progress);
} }
if (progress == 100) { if (progress == 100) {
activity.progressBar.setVisibility(View.GONE); inAppBrowserActivity.progressBar.setVisibility(View.GONE);
} }
} }
Map<String, Object> obj = new HashMap<>();
if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("progress", progress);
getChannel().invokeMethod("onProgressChanged", obj);
super.onProgressChanged(view, progress); super.onProgressChanged(view, progress);
} }
@Override @Override
public void onReceivedTitle(WebView view, String title) { public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title); super.onReceivedTitle(view, title);
if (activity.actionBar != null && activity.options.toolbarTopFixedTitle.isEmpty()) if (inAppBrowserActivity != null && inAppBrowserActivity.actionBar != null && inAppBrowserActivity.options.toolbarTopFixedTitle.isEmpty())
activity.actionBar.setTitle(title); inAppBrowserActivity.actionBar.setTitle(title);
} }
@Override @Override
...@@ -76,7 +93,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient { ...@@ -76,7 +93,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
Intent i = new Intent(Intent.ACTION_GET_CONTENT); Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE); i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*"); i.setType("image/*");
activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE); ((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
} }
...@@ -86,7 +103,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient { ...@@ -86,7 +103,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
Intent i = new Intent(Intent.ACTION_GET_CONTENT); Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE); i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*"); i.setType("*/*");
activity.startActivityForResult( ((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(
Intent.createChooser(i, "File Browser"), Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE); FILECHOOSER_RESULTCODE);
} }
...@@ -97,7 +114,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient { ...@@ -97,7 +114,7 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
Intent i = new Intent(Intent.ACTION_GET_CONTENT); Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE); i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*"); i.setType("image/*");
activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE); ((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
} }
...@@ -120,7 +137,11 @@ public class InAppBrowserWebChromeClient extends WebChromeClient { ...@@ -120,7 +137,11 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
activity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE); ((inAppBrowserActivity != null) ? inAppBrowserActivity : flutterWebView.activity).startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
return true; return true;
} }
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppBrowserFlutterPlugin.channel : flutterWebView.channel;
}
} }
package com.pichillilorenzo.flutter_inappbrowser.InAppWebView;
import com.pichillilorenzo.flutter_inappbrowser.Options;
public class InAppWebViewOptions extends Options {
static final String LOG_TAG = "InAppWebViewOptions";
public boolean useShouldOverrideUrlLoading = false;
public boolean useOnLoadResource = false;
public boolean clearCache = false;
public String userAgent = "";
public boolean javaScriptEnabled = true;
public boolean javaScriptCanOpenWindowsAutomatically = false;
public boolean mediaPlaybackRequiresUserGesture = true;
public boolean clearSessionCache = false;
public boolean builtInZoomControls = false;
public boolean supportZoom = true;
public boolean databaseEnabled = false;
public boolean domStorageEnabled = false;
public boolean useWideViewPort = true;
public boolean safeBrowsingEnabled = true;
}
...@@ -5,25 +5,36 @@ import android.webkit.JavascriptInterface; ...@@ -5,25 +5,36 @@ import android.webkit.JavascriptInterface;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import io.flutter.plugin.common.MethodChannel;
public class JavaScriptBridgeInterface { public class JavaScriptBridgeInterface {
private static final String LOG_TAG = "JSBridgeInterface"; private static final String LOG_TAG = "JSBridgeInterface";
static final String name = "flutter_inappbrowser"; public static final String name = "flutter_inappbrowser";
WebViewActivity activity; private FlutterWebView flutterWebView;
private InAppBrowserActivity inAppBrowserActivity;
static final String flutterInAppBroserJSClass = "window." + name + ".callHandler = function(handlerName, ...args) {" + public static final String flutterInAppBroserJSClass = "window." + name + ".callHandler = function(handlerName, ...args) {" +
"window." + name + "._callHandler(handlerName, JSON.stringify(args));" + "window." + name + "._callHandler(handlerName, JSON.stringify(args));" +
"}"; "}";
JavaScriptBridgeInterface(WebViewActivity a) { public JavaScriptBridgeInterface(Object obj) {
activity = a; if (obj instanceof InAppBrowserActivity)
this.inAppBrowserActivity = (InAppBrowserActivity) obj;
else if (obj instanceof FlutterWebView)
this.flutterWebView = (FlutterWebView) obj;
} }
@JavascriptInterface @JavascriptInterface
public void _callHandler(String handlerName, String args) { public void _callHandler(String handlerName, String args) {
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("uuid", activity.uuid); if (inAppBrowserActivity != null)
obj.put("uuid", inAppBrowserActivity.uuid);
obj.put("handlerName", handlerName); obj.put("handlerName", handlerName);
obj.put("args", args); obj.put("args", args);
InAppBrowserFlutterPlugin.channel.invokeMethod("onCallJsHandler", obj); getChannel().invokeMethod("onCallJsHandler", obj);
}
private MethodChannel getChannel() {
return (inAppBrowserActivity != null) ? InAppBrowserFlutterPlugin.channel : flutterWebView.channel;
} }
} }
...@@ -9,7 +9,7 @@ import java.util.HashMap; ...@@ -9,7 +9,7 @@ import java.util.HashMap;
public class Options { public class Options {
static String LOG_TAG = ""; static String LOG_TAG = "Options";
public Options parse(HashMap<String, Object> options) { public Options parse(HashMap<String, Object> options) {
Iterator it = options.entrySet().iterator(); Iterator it = options.entrySet().iterator();
......
package com.pichillilorenzo.flutter_inappbrowser;
import android.content.res.AssetManager;
import java.io.IOException;
import java.io.InputStream;
import io.flutter.plugin.common.PluginRegistry;
public class Util {
public static final String ANDROID_ASSET_URL = "file:///android_asset/";
public static String getUrlAsset (PluginRegistry.Registrar registrar, String assetFilePath) throws IOException {
String key = registrar.lookupKeyForAsset(assetFilePath);
AssetManager mg = registrar.activeContext().getResources().getAssets();
InputStream is = null;
IOException e = null;
try {
is = mg.open(key);
} catch (IOException ex) {
e = ex;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {
e = ex;
}
}
}
if (e != null) {
throw e;
}
return ANDROID_ASSET_URL + key;
}
}
...@@ -7,15 +7,13 @@ ...@@ -7,15 +7,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true" android:clickable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
tools:context=".WebViewActivity" tools:context=".InAppBrowserActivity"
android:focusable="true"> android:focusable="true">
<WebView <com.pichillilorenzo.flutter_inappbrowser.InAppWebView.InAppWebView
android:id="@+id/webView" android:id="@+id/webView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent" />
</WebView>
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
xmlns:appcompat="http://schemas.android.com/apk/res-auto" xmlns:appcompat="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context=".WebViewActivity"> tools:context=".InAppBrowserActivity">
<item <item
android:id="@+id/action_go_back" android:id="@+id/action_go_back"
......
This diff is collapsed.
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" /> <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" /> <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" /> <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappbrowser/example/ios/Flutter/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" /> <excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
</content> </content>
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
......
...@@ -10,21 +10,12 @@ import Foundation ...@@ -10,21 +10,12 @@ import Foundation
@objcMembers @objcMembers
public class InAppBrowserOptions: Options { public class InAppBrowserOptions: Options {
var useShouldOverrideUrlLoading = false
var useOnLoadResource = false
var openWithSystemBrowser = false;
var clearCache = false
var userAgent = ""
var javaScriptEnabled = true
var javaScriptCanOpenWindowsAutomatically = false
var hidden = false var hidden = false
var toolbarTop = true var toolbarTop = true
var toolbarTopBackgroundColor = "" var toolbarTopBackgroundColor = ""
var toolbarTopFixedTitle = ""
var hideUrlBar = false var hideUrlBar = false
var mediaPlaybackRequiresUserGesture = true
var isLocalFile = false
var disallowOverScroll = false
var toolbarBottom = true var toolbarBottom = true
var toolbarBottomBackgroundColor = "" var toolbarBottomBackgroundColor = ""
var toolbarBottomTranslucent = true var toolbarBottomTranslucent = true
...@@ -32,15 +23,6 @@ public class InAppBrowserOptions: Options { ...@@ -32,15 +23,6 @@ public class InAppBrowserOptions: Options {
var closeButtonColor = "" var closeButtonColor = ""
var presentationStyle = 0 //fullscreen var presentationStyle = 0 //fullscreen
var transitionStyle = 0 //crossDissolve var transitionStyle = 0 //crossDissolve
var enableViewportScale = false
//var keyboardDisplayRequiresUserAction = true
var suppressesIncrementalRendering = false
var allowsAirPlayForMediaPlayback = true
var allowsBackForwardNavigationGestures = true
var allowsLinkPreview = true
var ignoresViewportScaleLimits = false
var allowsInlineMediaPlayback = false
var allowsPictureInPictureMediaPlayback = true
var spinner = true var spinner = true
override init(){ override init(){
......
//
// InAppWebView.swift
// flutter_inappbrowser
//
// Created by Lorenzo on 21/10/18.
//
import Foundation
import WebKit
public class InAppWebView: WKWebView {
}
//
// InAppWebViewOptions.swift
// flutter_inappbrowser
//
// Created by Lorenzo on 21/10/18.
//
import Foundation
@objcMembers
public class InAppWebViewOptions: Options {
var useShouldOverrideUrlLoading = false
var useOnLoadResource = false
var clearCache = false
var userAgent = ""
var javaScriptEnabled = true
var javaScriptCanOpenWindowsAutomatically = false
var mediaPlaybackRequiresUserGesture = true
var disallowOverScroll = false
var enableViewportScale = false
//var keyboardDisplayRequiresUserAction = true
var suppressesIncrementalRendering = false
var allowsAirPlayForMediaPlayback = true
var allowsBackForwardNavigationGestures = true
var allowsLinkPreview = true
var ignoresViewportScaleLimits = false
var allowsInlineMediaPlayback = false
var allowsPictureInPictureMediaPlayback = true
override init(){
super.init()
}
}
...@@ -68,6 +68,9 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -68,6 +68,9 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
case "loadUrl": case "loadUrl":
self.loadUrl(uuid: uuid, arguments: arguments!, result: result) self.loadUrl(uuid: uuid, arguments: arguments!, result: result)
break break
case "loadFile":
self.loadFile(uuid: uuid, arguments: arguments!, result: result)
break
case "close": case "close":
self.close(uuid: uuid) self.close(uuid: uuid)
result(true) result(true)
...@@ -205,29 +208,39 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -205,29 +208,39 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
let url: String = (arguments["url"] as? String)! let url: String = (arguments["url"] as? String)!
let headers = (arguments["headers"] as? [String: String])! let headers = (arguments["headers"] as? [String: String])!
let absoluteUrl = URL(string: url)?.absoluteURL var absoluteUrl = URL(string: url)?.absoluteURL
let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool) let useChromeSafariBrowser = (arguments["useChromeSafariBrowser"] as? Bool)!
if useChromeSafariBrowser! { if useChromeSafariBrowser {
let uuidFallback = (arguments["uuidFallback"] as? String)! let uuidFallback = (arguments["uuidFallback"] as? String)!
let safariOptions = SafariBrowserOptions() let safariOptions = (arguments["options"] as? [String: Any])!
safariOptions.parse(options: (arguments["options"] as? [String: Any])!)
let optionsFallback = InAppBrowserOptions() let optionsFallback = (arguments["optionsFallback"] as? [String: Any])!
optionsFallback.parse(options: (arguments["optionsFallback"] as? [String: Any])!)
open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result); open(uuid: uuid, uuidFallback: uuidFallback, inAppBrowser: absoluteUrl!, headers: headers, withOptions: safariOptions, useChromeSafariBrowser: true, withOptionsFallback: optionsFallback, result: result);
} }
else { else {
let options = InAppBrowserOptions() let options = (arguments["options"] as? [String: Any])!
options.parse(options: (arguments["options"] as? [String: Any])!)
let isLocalFile = (arguments["isLocalFile"] as? Bool)!
var openWithSystemBrowser = (arguments["openWithSystemBrowser"] as? Bool)!
if isLocalFile {
let key = SwiftFlutterPlugin.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!) { if isSystemUrl(absoluteUrl!) {
options.openWithSystemBrowser = true openWithSystemBrowser = true
} }
if (options.openWithSystemBrowser) { if (openWithSystemBrowser) {
open(inSystem: absoluteUrl!, result: result) open(inSystem: absoluteUrl!, result: result)
} }
else { else {
...@@ -236,7 +249,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -236,7 +249,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
} }
func open(uuid: String, uuidFallback: String?, inAppBrowser url: URL, headers: [String: String], withOptions options: Options, useChromeSafariBrowser: Bool, withOptionsFallback optionsFallback: Options?, result: @escaping FlutterResult) { 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 var uuid = uuid
...@@ -270,10 +283,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -270,10 +283,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
self.tmpWindow?.makeKeyAndVisible() self.tmpWindow?.makeKeyAndVisible()
let browserOptions: InAppBrowserOptions let browserOptions: InAppBrowserOptions
let webViewOptions: InAppWebViewOptions
if useChromeSafariBrowser == true { if useChromeSafariBrowser == true {
if #available(iOS 9.0, *) { if #available(iOS 9.0, *) {
let safariOptions = options as! SafariBrowserOptions let safariOptions = SafariBrowserOptions()
safariOptions.parse(options: options)
let safari: SafariViewController let safari: SafariViewController
...@@ -310,23 +325,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -310,23 +325,19 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
return return
} }
uuid = uuidFallback! uuid = uuidFallback!
browserOptions = optionsFallback as! InAppBrowserOptions browserOptions = InAppBrowserOptions()
browserOptions.parse(options: optionsFallback!)
webViewOptions = InAppWebViewOptions()
webViewOptions.parse(options: optionsFallback!)
} }
} }
else { else {
browserOptions = options as! InAppBrowserOptions browserOptions = InAppBrowserOptions()
} browserOptions.parse(options: options)
var currentURL = url webViewOptions = InAppWebViewOptions()
webViewOptions.parse(options: options)
if browserOptions.isLocalFile {
let key = SwiftFlutterPlugin.registrar!.lookupKey(forAsset: url.absoluteString)
let assetURL = Bundle.main.url(forResource: key, withExtension: nil)
if assetURL == nil {
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: url.absoluteString + " asset file cannot be found!", details: nil))
return
}
currentURL = assetURL!
} }
let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppBrowserFlutterPlugin.self)) let storyboard = UIStoryboard(name: WEBVIEW_STORYBOARD, bundle: Bundle(for: InAppBrowserFlutterPlugin.self))
...@@ -335,9 +346,10 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -335,9 +346,10 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
webViewController.uuid = uuid webViewController.uuid = uuid
webViewController.browserOptions = browserOptions webViewController.browserOptions = browserOptions
webViewController.webViewOptions = webViewOptions
webViewController.isHidden = browserOptions.hidden webViewController.isHidden = browserOptions.hidden
webViewController.tmpWindow = tmpWindow webViewController.tmpWindow = tmpWindow
webViewController.currentURL = currentURL webViewController.currentURL = url
webViewController.initHeaders = headers webViewController.initHeaders = headers
webViewController.navigationDelegate = self webViewController.navigationDelegate = self
...@@ -365,11 +377,29 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -365,11 +377,29 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) { public func loadUrl(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
let url: String? = (arguments["url"] as? String)! if let url = arguments["url"] as? String {
let headers = (arguments["headers"] as? [String: String])! let headers = (arguments["headers"] as? [String: String])!
let absoluteUrl = URL(string: url)!.absoluteURL
if url != nil { webViewController.loadUrl(url: absoluteUrl, headers: headers)
let absoluteUrl = URL(string: url!)!.absoluteURL }
else {
result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
}
result(true)
}
public func loadFile(uuid: String, arguments: NSDictionary, result: @escaping FlutterResult) {
let webViewController: InAppBrowserWebViewController = self.webViewControllers[uuid] as! InAppBrowserWebViewController
if let url = arguments["url"] as? String {
let headers = (arguments["headers"] as? [String: String])!
let key = SwiftFlutterPlugin.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
}
let absoluteUrl = URL(string: url)!.absoluteURL
webViewController.loadUrl(url: absoluteUrl, headers: headers) webViewController.loadUrl(url: absoluteUrl, headers: headers)
} }
else { else {
...@@ -530,6 +560,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -530,6 +560,12 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
} }
func onProgressChanged(uuid: String, webView: WKWebView, progress: Int) {
if let webViewController = self.webViewControllers[uuid] {
channel.invokeMethod("onProgressChanged", arguments: ["uuid": uuid, "progress": progress])
}
}
func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int, duration: Int) { func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int, duration: Int) {
if self.webViewControllers[uuid] != nil { if self.webViewControllers[uuid] != nil {
var headersResponse = (response as! HTTPURLResponse).allHeaderFields as! [String: String] var headersResponse = (response as! HTTPURLResponse).allHeaderFields as! [String: String]
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/> <rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gA9-n8-qaQ" customClass="WKWebView_IBWrapper" customModule="flutter_inappbrowser"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gA9-n8-qaQ" customClass="InAppWebView_IBWrapper" customModule="flutter_inappbrowser">
<rect key="frame" x="0.0" y="66" width="414" height="626"/> <rect key="frame" x="0.0" y="66" width="414" height="626"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view> </view>
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
<outlet property="toolbarTop" destination="vlz-kT-71x" id="WgC-80-Z28"/> <outlet property="toolbarTop" destination="vlz-kT-71x" id="WgC-80-Z28"/>
<outlet property="toolbarTop_BottomToWebViewTopConstraint" destination="Sjd-dV-din" id="vkO-Yu-xaE"/> <outlet property="toolbarTop_BottomToWebViewTopConstraint" destination="Sjd-dV-din" id="vkO-Yu-xaE"/>
<outlet property="urlField" destination="sy2-Vx-Cxd" id="MCW-lJ-Ehl"/> <outlet property="urlField" destination="sy2-Vx-Cxd" id="MCW-lJ-Ehl"/>
<outlet property="webView" destination="gA9-n8-qaQ" id="7JE-lp-bwe"/> <outlet property="webView" destination="gA9-n8-qaQ" id="439-rj-hHB"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cYA-mw-BIR" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="cYA-mw-BIR" userLabel="First Responder" sceneMemberID="firstResponder"/>
......
This diff is collapsed.
name: flutter_inappbrowser name: flutter_inappbrowser
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser). description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
version: 0.4.1 version: 0.5.0
author: Lorenzo Pichilli <pichillilorenzo@gmail.com> author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment