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:
parent
db65f7a042
commit
f032b7f635
|
@ -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
|
@ -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
|
||||
|
|
24
README.md
24
README.md
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
flutter_inappbrowser
|
Binary file not shown.
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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.
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue