Commit 4ebdba09 authored by pichillilorenzo's avatar pichillilorenzo

removed download method, injectScriptCode now returns result of the code injected #2, code cleanup

parent d89cd5df
This diff is collapsed.
...@@ -38,5 +38,4 @@ android { ...@@ -38,5 +38,4 @@ android {
dependencies { dependencies {
implementation 'com.android.support:customtabs:27.1.1' implementation 'com.android.support:customtabs:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
} }
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
package="com.pichillilorenzo.flutter_inappbrowser"> package="com.pichillilorenzo.flutter_inappbrowser">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
......
...@@ -30,13 +30,16 @@ import android.net.Uri; ...@@ -30,13 +30,16 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.util.JsonReader;
import android.util.JsonToken;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import android.webkit.ValueCallback;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import java.time.Duration; import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -44,11 +47,10 @@ import io.flutter.plugin.common.MethodCall; ...@@ -44,11 +47,10 @@ import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar; import io.flutter.plugin.common.PluginRegistry.Registrar;
/** InAppBrowser */ /** InAppBrowserFlutterPlugin */
public class InAppBrowser implements MethodCallHandler { public class InAppBrowserFlutterPlugin implements MethodCallHandler {
public static Registrar registrar; public static Registrar registrar;
public Activity activity; public Activity activity;
...@@ -56,10 +58,10 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -56,10 +58,10 @@ public class InAppBrowser implements MethodCallHandler {
public static WebViewActivity webViewActivity; public static WebViewActivity webViewActivity;
private static final String NULL = "null"; private static final String NULL = "null";
protected static final String LOG_TAG = "InAppBrowser"; protected static final String LOG_TAG = "InAppBrowserFlutterP";
public InAppBrowser(Registrar r, Activity activity) { public InAppBrowserFlutterPlugin(Registrar r, Activity activity) {
registrar = r; registrar = r;
this.activity = activity; this.activity = activity;
channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser"); channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
...@@ -68,7 +70,7 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -68,7 +70,7 @@ public class InAppBrowser implements MethodCallHandler {
/** Plugin registration. */ /** Plugin registration. */
public static void registerWith(Registrar registrar) { public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser"); final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.pichillilorenzo/flutter_inappbrowser");
channel.setMethodCallHandler(new InAppBrowser(registrar, registrar.activity())); channel.setMethodCallHandler(new InAppBrowserFlutterPlugin(registrar, registrar.activity()));
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
...@@ -111,9 +113,9 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -111,9 +113,9 @@ public class InAppBrowser implements MethodCallHandler {
Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); Log.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
} }
} }
// load in InAppBrowser // load in InAppBrowserFlutterPlugin
else { else {
Log.d(LOG_TAG, "loading in InAppBrowser"); Log.d(LOG_TAG, "loading in InAppBrowserFlutterPlugin");
open(url, options); open(url, options);
} }
} }
...@@ -141,26 +143,25 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -141,26 +143,25 @@ public class InAppBrowser implements MethodCallHandler {
break; break;
case "injectScriptCode": case "injectScriptCode":
source = call.argument("source").toString(); source = call.argument("source").toString();
jsWrapper = "(function(){JSON.stringify([eval(%s)])})()"; jsWrapper = "(function(){return JSON.stringify(eval(%s));})();";
injectDeferredObject(source, jsWrapper); injectDeferredObject(source, jsWrapper, result);
result.success(true);
break; break;
case "injectScriptFile": case "injectScriptFile":
urlFile = call.argument("urlFile").toString(); urlFile = call.argument("urlFile").toString();
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)"; jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document);";
injectDeferredObject(urlFile, jsWrapper); injectDeferredObject(urlFile, jsWrapper, null);
result.success(true); result.success(true);
break; break;
case "injectStyleCode": case "injectStyleCode":
source = call.argument("source").toString(); source = call.argument("source").toString();
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)"; jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document);";
injectDeferredObject(source, jsWrapper); injectDeferredObject(source, jsWrapper, null);
result.success(true); result.success(true);
break; break;
case "injectStyleFile": case "injectStyleFile":
urlFile = call.argument("urlFile").toString(); 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)"; jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document);";
injectDeferredObject(urlFile, jsWrapper); injectDeferredObject(urlFile, jsWrapper, null);
result.success(true); result.success(true);
break; break;
case "show": case "show":
...@@ -203,7 +204,7 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -203,7 +204,7 @@ public class InAppBrowser implements MethodCallHandler {
} }
/** /**
* Inject an object (script or style) into the InAppBrowser WebView. * Inject an object (script or style) into the InAppBrowserFlutterPlugin WebView.
* *
* This is a helper method for the inject{Script|Style}{Code|File} API calls, which * This is a helper method for the inject{Script|Style}{Code|File} API calls, which
* provides a consistent method for injecting JavaScript code into the document. * provides a consistent method for injecting JavaScript code into the document.
...@@ -211,15 +212,14 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -211,15 +212,14 @@ public class InAppBrowser implements MethodCallHandler {
* If a wrapper string is supplied, then the source string will be JSON-encoded (adding * If a wrapper string is supplied, then the source string will be JSON-encoded (adding
* quotes) and wrapped using string formatting. (The wrapper string should have a single * quotes) and wrapped using string formatting. (The wrapper string should have a single
* '%s' marker) * '%s' marker)
*
* @param source The source object (filename or script/style text) to inject into * @param source The source object (filename or script/style text) to inject into
* the document. * the document.
* @param jsWrapper A JavaScript string to wrap the source string in, so that the object * @param jsWrapper A JavaScript string to wrap the source string in, so that the object
* is properly injected, or null if the source string is JavaScript text * is properly injected, or null if the source string is JavaScript text
* which should be executed directly. * @param result
*/ */
private void injectDeferredObject(String source, String jsWrapper) { private void injectDeferredObject(String source, String jsWrapper, final Result result) {
if (webViewActivity!=null) { if (webViewActivity != null) {
String scriptToInject; String scriptToInject;
if (jsWrapper != null) { if (jsWrapper != null) {
org.json.JSONArray jsonEsc = new org.json.JSONArray(); org.json.JSONArray jsonEsc = new org.json.JSONArray();
...@@ -232,14 +232,46 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -232,14 +232,46 @@ public class InAppBrowser implements MethodCallHandler {
} }
final String finalScriptToInject = scriptToInject; final String finalScriptToInject = scriptToInject;
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@SuppressLint("NewApi")
@Override @Override
public void run() { public void run() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
// This action will have the side-effect of blurring the currently focused element // This action will have the side-effect of blurring the currently focused element
webViewActivity.webView.loadUrl("javascript:" + finalScriptToInject); webViewActivity.webView.loadUrl("javascript:" + finalScriptToInject);
} else { } else {
webViewActivity.webView.evaluateJavascript(finalScriptToInject, null); webViewActivity.webView.evaluateJavascript(finalScriptToInject, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
if (result == null)
return;
JsonReader reader = new JsonReader(new StringReader(s));
// Must set lenient to parse single values
reader.setLenient(true);
try {
String msg;
msg = reader.nextString();
JsonReader reader2 = new JsonReader(new StringReader(msg));
reader2.setLenient(true);
if (reader2.peek() == JsonToken.STRING)
msg = reader2.nextString();
result.success(msg);
} catch (IOException e) {
Log.e(LOG_TAG, "IOException", e);
} finally {
try {
reader.close();
} catch (IOException e) {
// NOOP
}
}
}
});
} }
} }
}); });
...@@ -279,7 +311,7 @@ public class InAppBrowser implements MethodCallHandler { ...@@ -279,7 +311,7 @@ public class InAppBrowser implements MethodCallHandler {
activity.startActivity(intent); activity.startActivity(intent);
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it // not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) { } catch (java.lang.RuntimeException e) {
Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString()); Log.d(LOG_TAG, "InAppBrowserFlutterPlugin: Error loading url "+url+":"+ e.toString());
} }
} }
......
...@@ -104,7 +104,7 @@ public class InAppBrowserWebViewClient extends WebViewClient { ...@@ -104,7 +104,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("url", url); obj.put("url", url);
InAppBrowser.channel.invokeMethod("loadstart", obj); InAppBrowserFlutterPlugin.channel.invokeMethod("loadstart", obj);
} }
...@@ -114,7 +114,7 @@ public class InAppBrowserWebViewClient extends WebViewClient { ...@@ -114,7 +114,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
activity.isLoading = false; activity.isLoading = false;
// CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage // CB-10395 InAppBrowserFlutterPlugin's WebView not storing cookies reliable to local device storage
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush(); CookieManager.getInstance().flush();
} else { } else {
...@@ -127,7 +127,7 @@ public class InAppBrowserWebViewClient extends WebViewClient { ...@@ -127,7 +127,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
obj.put("url", url); obj.put("url", url);
InAppBrowser.channel.invokeMethod("loadstop", obj); InAppBrowserFlutterPlugin.channel.invokeMethod("loadstop", obj);
} }
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
...@@ -139,7 +139,7 @@ public class InAppBrowserWebViewClient extends WebViewClient { ...@@ -139,7 +139,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
obj.put("url", failingUrl); obj.put("url", failingUrl);
obj.put("code", errorCode); obj.put("code", errorCode);
obj.put("message", description); obj.put("message", description);
InAppBrowser.channel.invokeMethod("loaderror", obj); InAppBrowserFlutterPlugin.channel.invokeMethod("loaderror", obj);
} }
/** /**
......
...@@ -13,8 +13,6 @@ import java.util.Map; ...@@ -13,8 +13,6 @@ import java.util.Map;
public abstract class RequestPermissionHandler implements ActivityCompat.OnRequestPermissionsResultCallback { public abstract class RequestPermissionHandler implements ActivityCompat.OnRequestPermissionsResultCallback {
public static int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 0;
private static Map<Integer, List<Runnable>> actionDictionary = new HashMap<>(); private static Map<Integer, List<Runnable>> actionDictionary = new HashMap<>();
public static void checkAndRun(Activity activity, String permission, int requestCode, Runnable runnable) { public static void checkAndRun(Activity activity, String permission, int requestCode, Runnable runnable) {
......
package com.pichillilorenzo.flutter_inappbrowser; package com.pichillilorenzo.flutter_inappbrowser;
import android.Manifest;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.webkit.CookieManager; import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebView; import android.webkit.WebView;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.SearchView; import android.widget.SearchView;
import android.widget.Toast;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -64,7 +48,7 @@ public class WebViewActivity extends AppCompatActivity { ...@@ -64,7 +48,7 @@ public class WebViewActivity extends AppCompatActivity {
options = new InAppBrowserOptions(); options = new InAppBrowserOptions();
options.parse((HashMap<String, Object>) b.getSerializable("options")); options.parse((HashMap<String, Object>) b.getSerializable("options"));
InAppBrowser.webViewActivity = this; InAppBrowserFlutterPlugin.webViewActivity = this;
actionBar = getSupportActionBar(); actionBar = getSupportActionBar();
...@@ -82,39 +66,39 @@ public class WebViewActivity extends AppCompatActivity { ...@@ -82,39 +66,39 @@ public class WebViewActivity extends AppCompatActivity {
inAppBrowserWebViewClient = new InAppBrowserWebViewClient(this); inAppBrowserWebViewClient = new InAppBrowserWebViewClient(this);
webView.setWebViewClient(inAppBrowserWebViewClient); webView.setWebViewClient(inAppBrowserWebViewClient);
final Activity activity = this; // final Activity activity = this;
//
webView.setDownloadListener(new DownloadListener() { // webView.setDownloadListener(new DownloadListener() {
@Override // @Override
public void onDownloadStart(final String url, final String userAgent, // public void onDownloadStart(final String url, final String userAgent,
final String contentDisposition, final String mimetype, // final String contentDisposition, final String mimetype,
final long contentLength) { // final long contentLength) {
//
RequestPermissionHandler.checkAndRun(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, RequestPermissionHandler.REQUEST_CODE_WRITE_EXTERNAL_STORAGE, new Runnable(){ // RequestPermissionHandler.checkAndRun(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE, RequestPermissionHandler.REQUEST_CODE_WRITE_EXTERNAL_STORAGE, new Runnable(){
@Override // @Override
public void run(){ // public void run(){
DownloadManager.Request request = new DownloadManager.Request( // DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url)); // Uri.parse(url));
//
final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype); // final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype);
request.allowScanningByMediaScanner(); // request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed! // request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed!
request.setVisibleInDownloadsUi(true); // request.setVisibleInDownloadsUi(true);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); // request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); // DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
if (dm != null) { // if (dm != null) {
dm.enqueue(request); // dm.enqueue(request);
Toast.makeText(getApplicationContext(), "Downloading File: " + filename, //To notify the Client that the file is being downloaded // Toast.makeText(getApplicationContext(), "Downloading File: " + filename, //To notify the Client that the file is being downloaded
Toast.LENGTH_LONG).show(); // Toast.LENGTH_LONG).show();
} // }
else { // else {
Toast.makeText(getApplicationContext(), "Cannot Download File: " + filename, //To notify the Client that the file cannot be downloaded // Toast.makeText(getApplicationContext(), "Cannot Download File: " + filename, //To notify the Client that the file cannot be downloaded
Toast.LENGTH_LONG).show(); // Toast.LENGTH_LONG).show();
} // }
} // }
}); // });
} // }
}); // });
WebSettings settings = webView.getSettings(); WebSettings settings = webView.getSettings();
...@@ -261,18 +245,6 @@ public class WebViewActivity extends AppCompatActivity { ...@@ -261,18 +245,6 @@ public class WebViewActivity extends AppCompatActivity {
return super.onKeyDown(keyCode, event); 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<String>() {
// @Override
// public void onReceiveValue(String value) {
// result.success(value);
// }
// });
// }
public void close() { public void close() {
finish(); finish();
} }
......
...@@ -54,6 +54,7 @@ target 'Runner' do ...@@ -54,6 +54,7 @@ target 'Runner' do
File.symlink(p[:path], symlink) File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(symlink, 'ios') pod p[:name], :path => File.join(symlink, 'ios')
} }
end end
post_install do |installer| post_install do |installer|
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>
...@@ -11,9 +11,24 @@ class MyInAppBrowser extends InAppBrowser { ...@@ -11,9 +11,24 @@ class MyInAppBrowser extends InAppBrowser {
} }
@override @override
void onLoadStop(String url) { void onLoadStop(String url) async {
super.onLoadStop(url); super.onLoadStop(url);
print("\n\nStopped $url\n\n"); print("\n\nStopped $url\n\n");
print(await this.injectScriptCode("document.body.innerHTML"));
print(await this.injectScriptCode("3"));
print(await this.injectScriptCode("""
function asd (a,b) {
return a+b;
};
asd(3,5);
"""));
print(await this.injectScriptCode("""
["3",56,"sdf"];
"""));
print(await this.injectScriptCode("""
var x = {"as":4, "dfdfg": 6};
x;
"""));
/*this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js"); /*this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js");
this.injectScriptCode(""" this.injectScriptCode("""
\$( "body" ).html( "Next Step..." ) \$( "body" ).html( "Next Step..." )
...@@ -68,7 +83,7 @@ class _MyAppState extends State<MyApp> { ...@@ -68,7 +83,7 @@ class _MyAppState extends State<MyApp> {
child: new RaisedButton(onPressed: () { child: new RaisedButton(onPressed: () {
inAppBrowser.open("https://flutter.io/", options: { inAppBrowser.open("https://flutter.io/", options: {
//"toolbarTopFixedTitle": "Fixed title", //"toolbarTopFixedTitle": "Fixed title",
"hideUrlBar": true, //"hideUrlBar": true,
//"toolbarTop": false, //"toolbarTop": false,
//"toolbarBottom": false //"toolbarBottom": false
}); });
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" /> <excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" /> <excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" /> <excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/build" />
<excludeFolder url="file://$MODULE_DIR$/example/flutter_plugin/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" />
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#import <Flutter/Flutter.h> #import <Flutter/Flutter.h>
@interface InAppBrowser : NSObject<FlutterPlugin> @interface InAppBrowserFlutterPlugin : NSObject<FlutterPlugin>
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar; + (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar;
@end @end
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
under the License. under the License.
*/ */
#import "InAppBrowser.h" #import "InAppBrowserFlutterPlugin.h"
#import <flutter_inappbrowser/flutter_inappbrowser-Swift.h> #import <flutter_inappbrowser/flutter_inappbrowser-Swift.h>
@implementation InAppBrowser : NSObject @implementation InAppBrowserFlutterPlugin : NSObject
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
[SwiftFlutterPlugin registerWithRegistrar:registrar]; [SwiftFlutterPlugin registerWithRegistrar:registrar];
} }
......
...@@ -433,6 +433,40 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio ...@@ -433,6 +433,40 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
decisionHandler(.allow) decisionHandler(.allow)
} }
// func webView(_ webView: WKWebView,
// decidePolicyFor navigationResponse: WKNavigationResponse,
// decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
// let mimeType = navigationResponse.response.mimeType
// if mimeType != nil && !mimeType!.starts(with: "text/") {
// download(url: webView.url)
// decisionHandler(.cancel)
// return
// }
// decisionHandler(.allow)
// }
//
// func download (url: URL?) {
// let filename = url?.lastPathComponent
//
// let destination: DownloadRequest.DownloadFileDestination = { _, _ in
// let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
// let fileURL = documentsURL.appendingPathComponent(filename!)
//
// return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
// }
//
// Alamofire.download((url?.absoluteString)!, to: destination).downloadProgress { progress in
// print("Download Progress: \(progress.fractionCompleted)")
// }.response { response in
// if response.error == nil, let path = response.destinationURL?.path {
// UIAlertView(title: nil, message: "File saved to " + path, delegate: nil, cancelButtonTitle: nil).show()
// }
// else {
// UIAlertView(title: nil, message: "Cannot save " + filename!, delegate: nil, cancelButtonTitle: nil).show()
// }
// }
// }
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
// loading url, start spinner, update back/forward // loading url, start spinner, update back/forward
backButton.isEnabled = webView.canGoBack backButton.isEnabled = webView.canGoBack
......
...@@ -88,22 +88,22 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -88,22 +88,22 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
result(true) result(true)
break break
case "injectScriptCode": case "injectScriptCode":
self.injectScriptCode(arguments: arguments!) self.injectScriptCode(arguments: arguments!, result: result)
result(true)
break break
case "injectScriptFile": case "injectScriptFile":
self.injectScriptFile(arguments: arguments!) self.injectScriptFile(arguments: arguments!, result: nil)
result(true) result(true)
break break
case "injectStyleCode": case "injectStyleCode":
self.injectStyleCode(arguments: arguments!) self.injectStyleCode(arguments: arguments!, result: nil)
result(true) result(true)
break break
case "injectStyleFile": case "injectStyleFile":
self.injectStyleFile(arguments: arguments!) self.injectStyleFile(arguments: arguments!, result: nil)
result(true) result(true)
break break
default: default:
result(FlutterMethodNotImplemented)
break break
} }
} }
...@@ -151,7 +151,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -151,7 +151,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
else { else {
print("url is empty") print("url is empty")
result(false) result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
} }
result(true) result(true)
} }
...@@ -166,7 +166,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -166,7 +166,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
else { else {
print("url is empty") print("url is empty")
result(false) result(FlutterError(code: "InAppBrowserFlutterPlugin", message: "url is empty", details: nil))
} }
result(true) result(true)
} }
...@@ -265,39 +265,54 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { ...@@ -265,39 +265,54 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
// '%@' marker). // '%@' marker).
// //
// If no wrapper is supplied, then the source string is executed directly. // If no wrapper is supplied, then the source string is executed directly.
func injectDeferredObject(_ source: String, withWrapper jsWrapper: String) { func injectDeferredObject(_ source: String, withWrapper jsWrapper: String, result: FlutterResult?) {
//if jsWrapper != nil {
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: []) let jsonData: Data? = try? JSONSerialization.data(withJSONObject: [source], options: [])
let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8) let sourceArrayString = String(data: jsonData!, encoding: String.Encoding.utf8)
if sourceArrayString != nil { if sourceArrayString != nil {
let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.characters.count ?? 0) - 2)) let sourceString: String? = (sourceArrayString! as NSString).substring(with: NSRange(location: 1, length: (sourceArrayString?.characters.count ?? 0) - 2))
let jsToInject = String(format: jsWrapper, sourceString!) let jsToInject = String(format: jsWrapper, sourceString!)
webViewController?.webView?.evaluateJavaScript(jsToInject)
webViewController?.webView?.evaluateJavaScript(jsToInject, completionHandler: {(value, error) in
if result == nil {
return
}
do {
let data: Data = ("[" + String(describing: value!) + "]").data(using: String.Encoding.utf8, allowLossyConversion: false)!
let json: Array<Any> = try JSONSerialization.jsonObject(with: data, options: []) as! Array<Any>
if json[0] is String {
result!(json[0])
}
else {
result!(value)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
result!(FlutterError(code: "InAppBrowserFlutterPlugin", message: "Failed to load: \(error.localizedDescription)", details: error))
}
})
} }
//}
//else {
// webViewController?.webView?.evaluateJavaScript(source)
//}
} }
public func injectScriptCode(arguments: NSDictionary) { public func injectScriptCode(arguments: NSDictionary, result: FlutterResult?) {
let jsWrapper = "(function(){JSON.stringify([eval(%@)])})()" let jsWrapper = "(function(){return JSON.stringify(eval(%@));})();"
injectDeferredObject(arguments["source"] as! String, withWrapper: jsWrapper) injectDeferredObject(arguments["source"] as! String, withWrapper: jsWrapper, result: result)
} }
public func injectScriptFile(arguments: NSDictionary) { public func injectScriptFile(arguments: NSDictionary, result: FlutterResult?) {
let jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)" let jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document);"
injectDeferredObject(arguments["urlFile"] as! String, withWrapper: jsWrapper) injectDeferredObject(arguments["urlFile"] as! String, withWrapper: jsWrapper, result: result)
} }
public func injectStyleCode(arguments: NSDictionary) { public func injectStyleCode(arguments: NSDictionary, result: FlutterResult?) {
let jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document)" let jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document);"
injectDeferredObject(arguments["source"] as! String, withWrapper: jsWrapper) injectDeferredObject(arguments["source"] as! String, withWrapper: jsWrapper, result: result)
} }
public func injectStyleFile(arguments: NSDictionary) { public func injectStyleFile(arguments: NSDictionary, result: FlutterResult?) {
let jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)" let jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document);"
injectDeferredObject(arguments["urlFile"] as! String, withWrapper: jsWrapper) injectDeferredObject(arguments["urlFile"] as! String, withWrapper: jsWrapper, result: result)
} }
func webViewDidStartLoad(_ webView: WKWebView) { func webViewDidStartLoad(_ webView: WKWebView) {
......
...@@ -174,7 +174,7 @@ class InAppBrowser { ...@@ -174,7 +174,7 @@ class InAppBrowser {
} }
///Injects JavaScript code into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`) ///Injects JavaScript code into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`)
Future<void> injectScriptCode(String source) async { Future<dynamic> injectScriptCode(String source) async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('source', () => source); args.putIfAbsent('source', () => source);
return await _channel.invokeMethod('injectScriptCode', args); return await _channel.invokeMethod('injectScriptCode', args);
...@@ -221,9 +221,4 @@ class InAppBrowser { ...@@ -221,9 +221,4 @@ class InAppBrowser {
} }
///
void onCustomScheme(String url) {
}
} }
...@@ -18,7 +18,7 @@ dependencies: ...@@ -18,7 +18,7 @@ dependencies:
flutter: flutter:
plugin: plugin:
androidPackage: com.pichillilorenzo.flutter_inappbrowser androidPackage: com.pichillilorenzo.flutter_inappbrowser
pluginClass: InAppBrowser pluginClass: InAppBrowserFlutterPlugin
# To add assets to your plugin package, add an assets section, like this: # To add assets to your plugin package, add an assets section, like this:
# assets: # assets:
......
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