v0.2.1, fixed InAppBrowser.injectScriptCode() method when there is not a return value, added InAppBrowser.onConsoleMessage() method to manage console messages #5

This commit is contained in:
pichillilorenzo 2018-10-10 01:52:27 +02:00
parent db65f7a042
commit f032b7f635
24 changed files with 718 additions and 577 deletions

View File

@ -1,5 +1,5 @@
<component name="libraryTable">
<library name="Flutter Plugins" type="FlutterPluginsLibraryType">
<library name="Flutter Plugins">
<CLASSES>
<root url="file://$PROJECT_DIR$" />
</CLASSES>

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
## 0.2.1
- added InAppBrowser.onConsoleMessage() method to manage console messages
- fixed InAppBrowser.injectScriptCode() method when there is not a return value
## 0.2.0
- added support of Chrome CustomTabs for Android

View File

@ -41,6 +41,11 @@ class MyInAppBrowser extends InAppBrowser {
print("\n\nStopped $url\n\n");
// print body html
print(await this.injectScriptCode("document.body.innerHTML"));
// console messages
await this.injectScriptCode("console.log({'testObject': 5});"); // the message will be: [object Object]
await this.injectScriptCode("console.log('testObjectStringify', JSON.stringify({'testObject': 5}));"); // the message will be: testObjectStringify {"testObject": 5}
await this.injectScriptCode("console.error('testError', false);"); // the message will be: testError false
// add jquery library and custom javascript
await this.injectScriptFile("https://code.jquery.com/jquery-3.3.1.min.js");
@ -73,6 +78,17 @@ class MyInAppBrowser extends InAppBrowser {
this.loadUrl(url);
}
@override
void onConsoleMessage(ConsoleMessage consoleMessage) {
print("""
console output:
sourceURL: ${consoleMessage.sourceURL}
lineNumber: ${consoleMessage.lineNumber}
message: ${consoleMessage.message}
messageLevel: ${consoleMessage.messageLevel}
""");
}
}
MyInAppBrowser inAppBrowser = new MyInAppBrowser();
@ -228,6 +244,14 @@ Event fires when the `InAppBrowser` window is closed.
}
```
Event fires when the `InAppBrowser` webview receives a `ConsoleMessage`.
```dart
@override
void onConsoleMessage(ConsoleMessage consoleMessage) {
}
```
Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
In order to be able to listen this event, you need to set `useShouldOverrideUrlLoading` option to `true`.
```dart

1
android/.idea/.name Normal file
View File

@ -0,0 +1 @@
flutter_inappbrowser

Binary file not shown.

View File

@ -0,0 +1,29 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>

17
android/.idea/gradle.xml Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

38
android/.idea/misc.xml Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/flutter_inappbrowser.iml" filepath="$PROJECT_DIR$/flutter_inappbrowser.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -285,15 +285,20 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
try {
String msg;
msg = reader.nextString();
if (reader.peek() == JsonToken.STRING) {
msg = reader.nextString();
JsonReader reader2 = new JsonReader(new StringReader(msg));
reader2.setLenient(true);
JsonReader reader2 = new JsonReader(new StringReader(msg));
reader2.setLenient(true);
if (reader2.peek() == JsonToken.STRING)
msg = reader2.nextString();
if (reader2.peek() == JsonToken.STRING)
msg = reader2.nextString();
result.success(msg);
result.success(msg);
}
else {
result.success("");
}
} catch (IOException e) {
Log.e(LOG_TAG, "IOException", e);

View File

@ -4,11 +4,16 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.webkit.ConsoleMessage;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import java.util.HashMap;
import java.util.Map;
public class InAppBrowserWebChromeClient extends WebChromeClient {
protected static final String LOG_TAG = "IABWebChromeClient";
@ -22,6 +27,18 @@ public class InAppBrowserWebChromeClient extends WebChromeClient {
this.activity = activity;
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Map<String, Object> obj = new HashMap<>();
obj.put("uuid", activity.uuid);
obj.put("sourceURL", consoleMessage.sourceId());
obj.put("lineNumber", consoleMessage.lineNumber());
obj.put("message", consoleMessage.message());
obj.put("messageLevel", consoleMessage.messageLevel().toString());
InAppBrowserFlutterPlugin.channel.invokeMethod("onConsoleMessage", obj);
return true;
}
@Override
public void onProgressChanged(WebView view, int progress) {
if (activity.progressBar != null) {

View File

@ -4,6 +4,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
@ -124,7 +125,7 @@ public class InAppBrowserWebViewClient extends WebViewClient {
activity.isLoading = false;
// 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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush();
} else {
CookieSyncManager.getInstance().sync();
@ -134,6 +135,10 @@ public class InAppBrowserWebViewClient extends WebViewClient {
view.clearFocus();
view.requestFocus();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
view.evaluateJavascript(activity.jsConsoleLogScript, null);
}
Map<String, Object> obj = new HashMap<>();
obj.put("uuid", activity.uuid);
obj.put("url", url);

View File

@ -38,6 +38,32 @@ public class WebViewActivity extends AppCompatActivity {
public boolean isLoading = false;
public boolean isHidden = false;
static final String jsConsoleLogScript = "(function() {\n"+
" var oldLogs = {\n"+
" 'log': console.log,\n"+
" 'debug': console.debug,\n"+
" 'error': console.error,\n"+
" 'info': console.info,\n"+
" 'warn': console.warn\n"+
" };\n"+
" for (var k in oldLogs) {\n"+
" (function(oldLog) {\n"+
" console[oldLog] = function() {\n"+
" var message = ''\n"+
" for (var i in arguments) {\n"+
" if (message == '') {\n"+
" message += arguments[i];\n"+
" }\n"+
" else {\n"+
" message += ' ' + arguments[i];\n"+
" }\n"+
" }\n"+
" oldLogs[oldLog].call(console, message);\n"+
" }\n"+
" })(k);\n"+
" }\n"+
"})();";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.android.tools.build:gradle:3.2.0'
}
}

View File

@ -1,6 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
#Fri Oct 05 14:08:48 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

View File

@ -12,7 +12,19 @@ class MyInAppBrowser extends InAppBrowser {
@override
Future onLoadStop(String url) async {
print("\n\nStopped $url\n\n");
// // javascript error
// await this.injectScriptCode("console.log({'testJavaScriptError': 5}));");
//
// await this.injectScriptCode("console.log({'testObject': 5});");
// await this.injectScriptCode("console.warn('testWarn',null);");
// await this.injectScriptCode("console.log('testObjectStringify', JSON.stringify({'asd': 5}));");
// await this.injectScriptCode("console.info('testInfo', 6);");
// await this.injectScriptCode("console.error('testError', false);");
// await this.injectScriptCode("console.debug('testDebug', true);");
// print(await this.injectScriptCode("document.body.innerHTML"));
// print(await this.injectScriptCode("null"));
// print(await this.injectScriptCode("undefined"));
// print(await this.injectScriptCode("3"));
// print(await this.injectScriptCode("""
// function asd (a,b) {
@ -58,6 +70,17 @@ class MyInAppBrowser extends InAppBrowser {
print("\n\n override $url\n\n");
this.loadUrl(url);
}
@override
void onConsoleMessage(ConsoleMessage consoleMessage) {
print("""
console output:
sourceURL: ${consoleMessage.sourceURL}
lineNumber: ${consoleMessage.lineNumber}
message: ${consoleMessage.message}
messageLevel: ${consoleMessage.messageLevel}
""");
}
}
MyInAppBrowser inAppBrowserFallback = new MyInAppBrowser();
@ -107,15 +130,15 @@ class _MyAppState extends State<MyApp> {
),
body: new Center(
child: new RaisedButton(onPressed: () {
chromeSafariBrowser.open("https://flutter.io/");
// inAppBrowserFallback.open("https://flutter.io/", options: {
// //"hidden": true,
// //"toolbarTopFixedTitle": "Fixed title",
// //"useShouldOverrideUrlLoading": true
// //"hideUrlBar": true,
// //"toolbarTop": false,
// //"toolbarBottom": false
// });
//chromeSafariBrowser.open("https://flutter.io/");
inAppBrowserFallback.open("https://flutter.io/", options: {
//"hidden": true,
//"toolbarTopFixedTitle": "Fixed title",
//"useShouldOverrideUrlLoading": true
//"hideUrlBar": true,
//"toolbarTop": false,
//"toolbarBottom": false
});
},
child: Text("Open InAppBrowser")

View File

@ -14,6 +14,36 @@ import AVFoundation
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
typealias NewerClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
// the message needs to be concatenated with '' in order to have the same behavior like on Android
let jsConsoleLog = """
(function() {
var oldLogs = {
'consoleLog': console.log,
'consoleDebug': console.debug,
'consoleError': console.error,
'consoleInfo': console.info,
'consoleWarn': console.warn
};
for (var k in oldLogs) {
(function(oldLog) {
console[oldLog.replace('console', '').toLowerCase()] = function() {
var message = '';
for (var i in arguments) {
if (message == '') {
message += arguments[i];
}
else {
message += ' ' + arguments[i];
}
}
window.webkit.messageHandlers[oldLog].postMessage(message);
}
})(k);
}
})();
"""
extension WKWebView{
var keyboardDisplayRequiresUserAction: Bool? {
@ -62,7 +92,7 @@ extension WKWebView{
}
class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate {
class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
@IBOutlet var webView: WKWebView!
@IBOutlet var closeButton: UIButton!
@IBOutlet var reloadButton: UIBarButtonItem!
@ -132,7 +162,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
}
func prepareWebView() {
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
self.webView.configuration.userContentController = WKUserContentController()
@ -208,6 +237,13 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
self.webView.configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
let jsConsoleLogScript = WKUserScript(source: jsConsoleLog, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
self.webView.configuration.userContentController.addUserScript(jsConsoleLogScript)
self.webView.configuration.userContentController.add(self, name: "consoleLog")
self.webView.configuration.userContentController.add(self, name: "consoleDebug")
self.webView.configuration.userContentController.add(self, name: "consoleError")
self.webView.configuration.userContentController.add(self, name: "consoleInfo")
self.webView.configuration.userContentController.add(self, name: "consoleWarn")
if #available(iOS 10.0, *) {
if (browserOptions?.mediaPlaybackRequiresUserGesture)! {
@ -481,6 +517,10 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// update url, stop spinner, update back/forward
// evaluate the console log script
webView.evaluateJavaScript(jsConsoleLog)
currentURL = webView.url
updateUrlTextField(url: (currentURL?.absoluteString)!)
backButton.isEnabled = webView.canGoBack
@ -506,4 +546,34 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
spinner.stopAnimating()
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.name)
if message.name.starts(with: "console") {
var messageLevel = "LOG"
switch (message.name) {
case "consoleLog":
messageLevel = "LOG"
break;
case "consoleDebug":
// on Android, console.debug is TIP
messageLevel = "TIP"
break;
case "consoleError":
messageLevel = "ERROR"
break;
case "consoleInfo":
// on Android, console.info is LOG
messageLevel = "LOG"
break;
case "consoleWarn":
messageLevel = "WARNING"
break;
default:
messageLevel = "LOG"
break;
}
navigationDelegate?.onConsoleMessage(uuid: self.uuid, sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
}
}
}

View File

@ -48,98 +48,98 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
let uuid: String = (arguments!["uuid"] as? String)!
switch call.method {
case "open":
self.open(uuid: uuid, arguments: arguments!, result: result)
break
case "loadUrl":
self.loadUrl(uuid: uuid, arguments: arguments!, result: result)
break
case "close":
self.close(uuid: uuid)
result(true)
break
case "show":
self.show(uuid: uuid)
result(true)
break
case "hide":
self.hide(uuid: uuid)
result(true)
break
case "reload":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.reload()
}
result(true)
break
case "goBack":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goBack()
}
result(true)
break
case "canGoBack":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoBack() ?? false)
}
else {
result(false)
}
break
case "goForward":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goForward()
}
result(true)
break
case "canGoForward":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoForward() ?? false)
}
else {
result(false)
}
break
case "isLoading":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.webView.isLoading ?? false) == true)
}
else {
result(false)
}
break
case "stopLoading":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.webView.stopLoading()
}
result(true)
break
case "isHidden":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.isHidden ?? false) == true)
}
else {
result(false)
}
break
case "injectScriptCode":
self.injectScriptCode(uuid: uuid, arguments: arguments!, result: result)
break
case "injectScriptFile":
self.injectScriptFile(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
case "injectStyleCode":
self.injectStyleCode(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
case "injectStyleFile":
self.injectStyleFile(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
default:
result(FlutterMethodNotImplemented)
break
case "open":
self.open(uuid: uuid, arguments: arguments!, result: result)
break
case "loadUrl":
self.loadUrl(uuid: uuid, arguments: arguments!, result: result)
break
case "close":
self.close(uuid: uuid)
result(true)
break
case "show":
self.show(uuid: uuid)
result(true)
break
case "hide":
self.hide(uuid: uuid)
result(true)
break
case "reload":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.reload()
}
result(true)
break
case "goBack":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goBack()
}
result(true)
break
case "canGoBack":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoBack() ?? false)
}
else {
result(false)
}
break
case "goForward":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.goForward()
}
result(true)
break
case "canGoForward":
if let webViewController = self.webViewControllers[uuid] {
result(webViewController?.canGoForward() ?? false)
}
else {
result(false)
}
break
case "isLoading":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.webView.isLoading ?? false) == true)
}
else {
result(false)
}
break
case "stopLoading":
if let webViewController = self.webViewControllers[uuid] {
webViewController?.webView.stopLoading()
}
result(true)
break
case "isHidden":
if let webViewController = self.webViewControllers[uuid] {
result((webViewController?.isHidden ?? false) == true)
}
else {
result(false)
}
break
case "injectScriptCode":
self.injectScriptCode(uuid: uuid, arguments: arguments!, result: result)
break
case "injectScriptFile":
self.injectScriptFile(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
case "injectStyleCode":
self.injectStyleCode(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
case "injectStyleFile":
self.injectStyleFile(uuid: uuid, arguments: arguments!, result: nil)
result(true)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
@ -410,6 +410,16 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
return
}
if error != nil {
let userInfo = (error! as NSError).userInfo
self.onConsoleMessage(uuid: uuid, sourceURL: (userInfo["WKJavaScriptExceptionSourceURL"] as! URL).absoluteString, lineNumber: userInfo["WKJavaScriptExceptionLineNumber"] as! Int, message: userInfo["WKJavaScriptExceptionMessage"] as! String, messageLevel: "ERROR")
}
if value == nil {
result!("")
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>
@ -476,19 +486,25 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
}
func shouldOverrideUrlLoading(uuid: String, webView: WKWebView, url: URL) {
if let webViewController = self.webViewControllers[uuid] {
if self.webViewControllers[uuid] != nil {
channel.invokeMethod("shouldOverrideUrlLoading", arguments: ["uuid": uuid, "url": url.absoluteString])
}
}
func onConsoleMessage(uuid: String, sourceURL: String, lineNumber: Int, message: String, messageLevel: String) {
if self.webViewControllers[uuid] != nil {
channel.invokeMethod("onConsoleMessage", arguments: ["uuid": uuid, "sourceURL": sourceURL, "lineNumber": lineNumber, "message": message, "messageLevel": messageLevel])
}
}
func onChromeSafariBrowserOpened(uuid: String) {
if let safariViewController = self.safariViewControllers[uuid] {
if self.safariViewControllers[uuid] != nil {
channel.invokeMethod("onChromeSafariBrowserOpened", arguments: ["uuid": uuid])
}
}
func onChromeSafariBrowserLoaded(uuid: String) {
if let safariViewController = self.safariViewControllers[uuid] {
if self.safariViewControllers[uuid] != nil {
channel.invokeMethod("onChromeSafariBrowserLoaded", arguments: ["uuid": uuid])
}
}

View File

@ -27,7 +27,26 @@ import 'package:uuid/uuid.dart';
typedef Future<dynamic> ListenerCallback(MethodCall call);
var uuidGenerator = new Uuid();
var _uuidGenerator = new Uuid();
///
enum ConsoleMessageLevel {
DEBUG, ERROR, LOG, TIP, WARNING
}
///Public class representing a JavaScript console message from WebCore.
///This could be a issued by a call to one of the console logging functions (e.g. console.log('...')) or a JavaScript error on the page.
///
///To receive notifications of these messages, override the [InAppBrowser.onConsoleMessage()] function.
class ConsoleMessage {
String sourceURL = "";
int lineNumber = 1;
String message = "";
ConsoleMessageLevel messageLevel = ConsoleMessageLevel.LOG;
ConsoleMessage(this.sourceURL, this.lineNumber, this.message, this.messageLevel);
}
class _ChannelManager {
static const MethodChannel channel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser');
@ -53,14 +72,14 @@ class _ChannelManager {
///InAppBrowser class.
///
/// This class uses the native WebView of the platform.
///This class uses the native WebView of the platform.
class InAppBrowser {
String uuid;
///
InAppBrowser () {
uuid = uuidGenerator.v4();
uuid = _uuidGenerator.v4();
_ChannelManager.addListener(uuid, _handleMethod);
}
@ -87,6 +106,19 @@ class InAppBrowser {
String url = call.arguments["url"];
shouldOverrideUrlLoading(url);
break;
case "onConsoleMessage":
String sourceURL = call.arguments["sourceURL"];
int lineNumber = call.arguments["lineNumber"];
String message = call.arguments["message"];
ConsoleMessageLevel messageLevel;
ConsoleMessageLevel.values.forEach((element) {
if ("ConsoleMessageLevel." + call.arguments["messageLevel"] == element.toString()) {
messageLevel = element;
return;
}
});
onConsoleMessage(ConsoleMessage(sourceURL, lineNumber, message, messageLevel));
break;
}
return new Future.value("");
}
@ -291,6 +323,11 @@ class InAppBrowser {
}
///Event fires when the [InAppBrowser] webview receives a [ConsoleMessage].
void onConsoleMessage(ConsoleMessage consoleMessage) {
}
}
///ChromeSafariBrowser class.
@ -305,7 +342,7 @@ class ChromeSafariBrowser {
///Initialize the [ChromeSafariBrowser] instance with a [InAppBrowser] fallback instance or `null`.
ChromeSafariBrowser (bf) {
uuid = uuidGenerator.v4();
uuid = _uuidGenerator.v4();
browserFallback = bf;
_ChannelManager.addListener(uuid, _handleMethod);
}

View File

@ -1,6 +1,6 @@
name: flutter_inappbrowser
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
version: 0.2.0
version: 0.2.1
author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser