updated web support
This commit is contained in:
parent
3bad02d6e4
commit
68f25d0d4d
|
@ -30,3 +30,5 @@ build/
|
||||||
.fvm/
|
.fvm/
|
||||||
|
|
||||||
flutter_driver_tests.log
|
flutter_driver_tests.log
|
||||||
|
tool/chromedriver
|
||||||
|
tool/chromedriver.*
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
@ -114,16 +115,17 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
children: [
|
children: [
|
||||||
InAppWebView(
|
InAppWebView(
|
||||||
key: webViewKey,
|
key: webViewKey,
|
||||||
|
// initialUrlRequest:
|
||||||
|
// URLRequest(url: Uri.parse("https://flutter.dev")),
|
||||||
initialUrlRequest:
|
initialUrlRequest:
|
||||||
URLRequest(url: Uri.parse("https://flutter.dev")),
|
URLRequest(url: Uri.parse(Uri.base.toString().replaceFirst("/#/", "/") + 'page.html')),
|
||||||
// initialFile: "assets/index.html",
|
// initialFile: "assets/index.html",
|
||||||
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
initialUserScripts: UnmodifiableListView<UserScript>([]),
|
||||||
initialSettings: settings,
|
initialSettings: settings,
|
||||||
// contextMenu: contextMenu,
|
// contextMenu: contextMenu,
|
||||||
pullToRefreshController: pullToRefreshController,
|
pullToRefreshController: pullToRefreshController,
|
||||||
onWebViewCreated: (controller) async {
|
onWebViewCreated: (controller) {
|
||||||
webViewController = controller;
|
webViewController = controller;
|
||||||
print(await controller.getUrl());
|
|
||||||
},
|
},
|
||||||
onLoadStart: (controller, url) async {
|
onLoadStart: (controller, url) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -149,10 +151,10 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
"javascript",
|
"javascript",
|
||||||
"about"
|
"about"
|
||||||
].contains(uri.scheme)) {
|
].contains(uri.scheme)) {
|
||||||
if (await canLaunch(url)) {
|
if (await canLaunchUrl(uri)) {
|
||||||
// Launch the App
|
// Launch the App
|
||||||
await launch(
|
await launchUrl(
|
||||||
url,
|
uri,
|
||||||
);
|
);
|
||||||
// and cancel the request
|
// and cancel the request
|
||||||
return NavigationActionPolicy.CANCEL;
|
return NavigationActionPolicy.CANCEL;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>flutter_inappwebview_example</title>
|
<title>heavy page</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>flutter_inappwebview_example</title>
|
<title>page 2</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>flutter_inappwebview_example</title>
|
<title>page</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body style="min-height: 3000px;min-width: 3000px;">
|
<body style="min-height: 3000px;min-width: 3000px;">
|
||||||
|
|
|
@ -365,6 +365,138 @@ window.flutter_inappwebview = {
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
getTitle: function() {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
var title = null;
|
||||||
|
try {
|
||||||
|
title = iframe.contentDocument.title;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
},
|
||||||
|
injectJavascriptFileFromUrl: function(urlFile, scriptHtmlTagAttributes) {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
var d = iframe.contentDocument;
|
||||||
|
var script = d.createElement('script');
|
||||||
|
for (var key of Object.keys(scriptHtmlTagAttributes)) {
|
||||||
|
if (scriptHtmlTagAttributes[key] != null) {
|
||||||
|
script[key] = scriptHtmlTagAttributes[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (script.id != null) {
|
||||||
|
script.onload = function() {
|
||||||
|
window.flutter_inappwebview.nativeCommunication('onInjectedScriptLoaded', webView.viewId, [script.id]);
|
||||||
|
}
|
||||||
|
script.onerror = function() {
|
||||||
|
window.flutter_inappwebview.nativeCommunication('onInjectedScriptError', webView.viewId, [script.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
script.src = urlFile;
|
||||||
|
if (d.body != null) {
|
||||||
|
d.body.appendChild(script);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
injectCSSCode: function(source) {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
var d = iframe.contentDocument;
|
||||||
|
var style = d.createElement('style');
|
||||||
|
style.innerHTML = source;
|
||||||
|
if (d.head != null) {
|
||||||
|
d.head.appendChild(style);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
injectCSSFileFromUrl: function(urlFile, cssLinkHtmlTagAttributes) {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
var d = iframe.contentDocument;
|
||||||
|
var link = d.createElement('link');
|
||||||
|
for (var key of Object.keys(cssLinkHtmlTagAttributes)) {
|
||||||
|
if (cssLinkHtmlTagAttributes[key] != null) {
|
||||||
|
link[key] = cssLinkHtmlTagAttributes[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
link.type = 'text/css';
|
||||||
|
var alternateStylesheet = "";
|
||||||
|
if (cssLinkHtmlTagAttributes.alternateStylesheet) {
|
||||||
|
alternateStylesheet = "alternate ";
|
||||||
|
}
|
||||||
|
link.rel = alternateStylesheet + "stylesheet";
|
||||||
|
link.href = urlFile;
|
||||||
|
if (d.head != null) {
|
||||||
|
d.head.appendChild(link);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollTo: function(x, y, animated) {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
if (animated) {
|
||||||
|
iframe.contentWindow.scrollTo({top: y, left: x, behavior: 'smooth'});
|
||||||
|
} else {
|
||||||
|
iframe.contentWindow.scrollTo(x, y);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollBy: function(x, y, animated) {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
if (animated) {
|
||||||
|
iframe.contentWindow.scrollBy({top: y, left: x, behavior: 'smooth'});
|
||||||
|
} else {
|
||||||
|
iframe.contentWindow.scrollBy(x, y);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
printCurrentPage: function() {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
iframe.contentWindow.print();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getContentHeight: function() {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
return iframe.contentDocument.documentElement.scrollHeight;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
getSelectedText: function() {
|
||||||
|
var iframe = webView.iframe;
|
||||||
|
try {
|
||||||
|
var txt;
|
||||||
|
var w = iframe.contentWindow;
|
||||||
|
if (w.getSelection) {
|
||||||
|
txt = w.getSelection().toString();
|
||||||
|
} else if (w.document.getSelection) {
|
||||||
|
txt = w.document.getSelection().toString();
|
||||||
|
} else if (w.document.selection) {
|
||||||
|
txt = w.document.selection.createRange().text;
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return webView;
|
return webView;
|
||||||
|
|
|
@ -1034,6 +1034,22 @@ class InAppWebViewController
|
||||||
_inAppBrowser!.onPrint(uri);
|
_inAppBrowser!.onPrint(uri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "onInjectedScriptLoaded":
|
||||||
|
String id = call.arguments[0];
|
||||||
|
var onLoadCallback = _injectedScriptsFromURL[id]?.onLoad;
|
||||||
|
if ((_webview != null || _inAppBrowser != null) &&
|
||||||
|
onLoadCallback != null) {
|
||||||
|
onLoadCallback();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
case "onInjectedScriptError":
|
||||||
|
String id = call.arguments[0];
|
||||||
|
var onErrorCallback = _injectedScriptsFromURL[id]?.onError;
|
||||||
|
if ((_webview != null || _inAppBrowser != null) &&
|
||||||
|
onErrorCallback != null) {
|
||||||
|
onErrorCallback();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
case "onCallJsHandler":
|
case "onCallJsHandler":
|
||||||
String handlerName = call.arguments["handlerName"];
|
String handlerName = call.arguments["handlerName"];
|
||||||
// decode args to json
|
// decode args to json
|
||||||
|
@ -1165,7 +1181,7 @@ class InAppWebViewController
|
||||||
try {
|
try {
|
||||||
return jsonEncode(await javaScriptHandlersMap[handlerName]!(args));
|
return jsonEncode(await javaScriptHandlersMap[handlerName]!(args));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
print(error);
|
developer.log(error.toString(), name: this.runtimeType.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1194,9 +1210,12 @@ class InAppWebViewController
|
||||||
|
|
||||||
///Gets the title for the current page.
|
///Gets the title for the current page.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebView.getTitle](https://developer.android.com/reference/android/webkit/WebView#getTitle()))
|
///- Android native WebView ([Official API - WebView.getTitle](https://developer.android.com/reference/android/webkit/WebView#getTitle()))
|
||||||
///- iOS ([Official API - WKWebView.title](https://developer.apple.com/documentation/webkit/wkwebview/1415015-title))
|
///- iOS ([Official API - WKWebView.title](https://developer.apple.com/documentation/webkit/wkwebview/1415015-title))
|
||||||
|
///- Web
|
||||||
Future<String?> getTitle() async {
|
Future<String?> getTitle() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
return await _channel.invokeMethod('getTitle', args);
|
return await _channel.invokeMethod('getTitle', args);
|
||||||
|
@ -1222,6 +1241,7 @@ class InAppWebViewController
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<String?> getHtml() async {
|
Future<String?> getHtml() async {
|
||||||
String? html;
|
String? html;
|
||||||
|
|
||||||
|
@ -1245,13 +1265,13 @@ class InAppWebViewController
|
||||||
html = utf8.decode(bytes.buffer.asUint8List());
|
html = utf8.decode(bytes.buffer.asUint8List());
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
} else {
|
} else {
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
try {
|
try {
|
||||||
|
HttpClient client = HttpClient();
|
||||||
var htmlRequest = await client.getUrl(webviewUrl);
|
var htmlRequest = await client.getUrl(webviewUrl);
|
||||||
html =
|
html =
|
||||||
await (await htmlRequest.close()).transform(Utf8Decoder()).join();
|
await (await htmlRequest.close()).transform(Utf8Decoder()).join();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
developer.log(e.toString(), name: this.runtimeType.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,13 +1280,15 @@ class InAppWebViewController
|
||||||
|
|
||||||
///Gets the list of all favicons for the current page.
|
///Gets the list of all favicons for the current page.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<List<Favicon>> getFavicons() async {
|
Future<List<Favicon>> getFavicons() async {
|
||||||
List<Favicon> favicons = [];
|
List<Favicon> favicons = [];
|
||||||
|
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
var webviewUrl = await getUrl();
|
var webviewUrl = await getUrl();
|
||||||
|
|
||||||
if (webviewUrl == null) {
|
if (webviewUrl == null) {
|
||||||
|
@ -1336,6 +1358,7 @@ class InAppWebViewController
|
||||||
|
|
||||||
// try to get /favicon.ico
|
// try to get /favicon.ico
|
||||||
try {
|
try {
|
||||||
|
HttpClient client = HttpClient();
|
||||||
var faviconUrl =
|
var faviconUrl =
|
||||||
webviewUrl.scheme + "://" + webviewUrl.host + "/favicon.ico";
|
webviewUrl.scheme + "://" + webviewUrl.host + "/favicon.ico";
|
||||||
var faviconUri = Uri.parse(faviconUrl);
|
var faviconUri = Uri.parse(faviconUrl);
|
||||||
|
@ -1345,8 +1368,8 @@ class InAppWebViewController
|
||||||
favicons.add(Favicon(url: faviconUri, rel: "shortcut icon"));
|
favicons.add(Favicon(url: faviconUri, rel: "shortcut icon"));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("/favicon.ico file not found: " + e.toString());
|
developer.log("/favicon.ico file not found: " + e.toString(),
|
||||||
// print(stacktrace);
|
name: this.runtimeType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to get the manifest file
|
// try to get the manifest file
|
||||||
|
@ -1358,13 +1381,14 @@ class InAppWebViewController
|
||||||
webviewUrl.scheme + "://" + webviewUrl.host + "/manifest.json";
|
webviewUrl.scheme + "://" + webviewUrl.host + "/manifest.json";
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
HttpClient client = HttpClient();
|
||||||
manifestRequest = await client.getUrl(Uri.parse(manifestUrl));
|
manifestRequest = await client.getUrl(Uri.parse(manifestUrl));
|
||||||
manifestResponse = await manifestRequest.close();
|
manifestResponse = await manifestRequest.close();
|
||||||
manifestFound = manifestResponse.statusCode == 200 &&
|
manifestFound = manifestResponse.statusCode == 200 &&
|
||||||
manifestResponse.headers.contentType?.mimeType == "application/json";
|
manifestResponse.headers.contentType?.mimeType == "application/json";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Manifest file not found: " + e.toString());
|
developer.log("Manifest file not found: " + e.toString(),
|
||||||
// print(stacktrace);
|
name: this.runtimeType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manifestFound) {
|
if (manifestFound) {
|
||||||
|
@ -1470,9 +1494,12 @@ class InAppWebViewController
|
||||||
///controller.postUrl(url: Uri.parse("https://www.example.com/"), postData: postData);
|
///controller.postUrl(url: Uri.parse("https://www.example.com/"), postData: postData);
|
||||||
///```
|
///```
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: it will try to create an XMLHttpRequest and load the result inside the iframe.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebView.postUrl](https://developer.android.com/reference/android/webkit/WebView#postUrl(java.lang.String,%20byte[])))
|
///- Android native WebView ([Official API - WebView.postUrl](https://developer.android.com/reference/android/webkit/WebView#postUrl(java.lang.String,%20byte[])))
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<void> postUrl({required Uri url, required Uint8List postData}) async {
|
Future<void> postUrl({required Uri url, required Uint8List postData}) async {
|
||||||
assert(url.toString().isNotEmpty);
|
assert(url.toString().isNotEmpty);
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -1745,9 +1772,12 @@ class InAppWebViewController
|
||||||
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
///where you know the page is ready "enough".
|
///where you know the page is ready "enough".
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<void> injectJavascriptFileFromUrl(
|
Future<void> injectJavascriptFileFromUrl(
|
||||||
{required Uri urlFile,
|
{required Uri urlFile,
|
||||||
ScriptHtmlTagAttributes? scriptHtmlTagAttributes}) async {
|
ScriptHtmlTagAttributes? scriptHtmlTagAttributes}) async {
|
||||||
|
@ -1770,9 +1800,12 @@ class InAppWebViewController
|
||||||
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
///where you know the page is ready "enough".
|
///where you know the page is ready "enough".
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<dynamic> injectJavascriptFileFromAsset(
|
Future<dynamic> injectJavascriptFileFromAsset(
|
||||||
{required String assetFilePath}) async {
|
{required String assetFilePath}) async {
|
||||||
String source = await rootBundle.loadString(assetFilePath);
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
|
@ -1786,9 +1819,12 @@ class InAppWebViewController
|
||||||
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
///where you know the page is ready "enough".
|
///where you know the page is ready "enough".
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<void> injectCSSCode({required String source}) async {
|
Future<void> injectCSSCode({required String source}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('source', () => source);
|
args.putIfAbsent('source', () => source);
|
||||||
|
@ -1804,9 +1840,12 @@ class InAppWebViewController
|
||||||
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
///where you know the page is ready "enough".
|
///where you know the page is ready "enough".
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<void> injectCSSFileFromUrl(
|
Future<void> injectCSSFileFromUrl(
|
||||||
{required Uri urlFile,
|
{required Uri urlFile,
|
||||||
CSSLinkHtmlTagAttributes? cssLinkHtmlTagAttributes}) async {
|
CSSLinkHtmlTagAttributes? cssLinkHtmlTagAttributes}) async {
|
||||||
|
@ -1825,9 +1864,12 @@ class InAppWebViewController
|
||||||
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
///Instead, you should call this method, for example, inside the [WebView.onLoadStop] event or in any other events
|
||||||
///where you know the page is ready "enough".
|
///where you know the page is ready "enough".
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<void> injectCSSFileFromAsset({required String assetFilePath}) async {
|
Future<void> injectCSSFileFromAsset({required String assetFilePath}) async {
|
||||||
String source = await rootBundle.loadString(assetFilePath);
|
String source = await rootBundle.loadString(assetFilePath);
|
||||||
await injectCSSCode(source: source);
|
await injectCSSCode(source: source);
|
||||||
|
@ -2076,9 +2118,12 @@ class InAppWebViewController
|
||||||
///
|
///
|
||||||
///[animated] `true` to animate the scroll transition, `false` to make the scoll transition immediate.
|
///[animated] `true` to animate the scroll transition, `false` to make the scoll transition immediate.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - View.scrollTo](https://developer.android.com/reference/android/view/View#scrollTo(int,%20int)))
|
///- Android native WebView ([Official API - View.scrollTo](https://developer.android.com/reference/android/view/View#scrollTo(int,%20int)))
|
||||||
///- iOS ([Official API - UIScrollView.setContentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619400-setcontentoffset))
|
///- iOS ([Official API - UIScrollView.setContentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619400-setcontentoffset))
|
||||||
|
///- Web ([Official API - Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo))
|
||||||
Future<void> scrollTo(
|
Future<void> scrollTo(
|
||||||
{required int x, required int y, bool animated = false}) async {
|
{required int x, required int y, bool animated = false}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -2096,9 +2141,12 @@ class InAppWebViewController
|
||||||
///
|
///
|
||||||
///[animated] `true` to animate the scroll transition, `false` to make the scoll transition immediate.
|
///[animated] `true` to animate the scroll transition, `false` to make the scoll transition immediate.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - View.scrollBy](https://developer.android.com/reference/android/view/View#scrollBy(int,%20int)))
|
///- Android native WebView ([Official API - View.scrollBy](https://developer.android.com/reference/android/view/View#scrollBy(int,%20int)))
|
||||||
///- iOS ([Official API - UIScrollView.setContentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619400-setcontentoffset))
|
///- iOS ([Official API - UIScrollView.setContentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619400-setcontentoffset))
|
||||||
|
///- Web ([Official API - Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy))
|
||||||
Future<void> scrollBy(
|
Future<void> scrollBy(
|
||||||
{required int x, required int y, bool animated = false}) async {
|
{required int x, required int y, bool animated = false}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
@ -2137,9 +2185,12 @@ class InAppWebViewController
|
||||||
///
|
///
|
||||||
///**NOTE**: available on Android 21+.
|
///**NOTE**: available on Android 21+.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - PrintManager](https://developer.android.com/reference/android/print/PrintManager))
|
///- Android native WebView ([Official API - PrintManager](https://developer.android.com/reference/android/print/PrintManager))
|
||||||
///- iOS ([Official API - UIPrintInteractionController](https://developer.apple.com/documentation/uikit/uiprintinteractioncontroller))
|
///- iOS ([Official API - UIPrintInteractionController](https://developer.apple.com/documentation/uikit/uiprintinteractioncontroller))
|
||||||
|
///- Web ([Official API - Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window/print))
|
||||||
Future<void> printCurrentPage() async {
|
Future<void> printCurrentPage() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
await _channel.invokeMethod('printCurrentPage', args);
|
await _channel.invokeMethod('printCurrentPage', args);
|
||||||
|
@ -2147,9 +2198,12 @@ class InAppWebViewController
|
||||||
|
|
||||||
///Gets the height of the HTML content.
|
///Gets the height of the HTML content.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebView.getContentHeight](https://developer.android.com/reference/android/webkit/WebView#getContentHeight()))
|
///- Android native WebView ([Official API - WebView.getContentHeight](https://developer.android.com/reference/android/webkit/WebView#getContentHeight()))
|
||||||
///- iOS ([Official API - UIScrollView.contentSize](https://developer.apple.com/documentation/uikit/uiscrollview/1619399-contentsize))
|
///- iOS ([Official API - UIScrollView.contentSize](https://developer.apple.com/documentation/uikit/uiscrollview/1619399-contentsize))
|
||||||
|
///- Web ([Official API - Document.documentElement.scrollHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight))
|
||||||
Future<int?> getContentHeight() async {
|
Future<int?> getContentHeight() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
return await _channel.invokeMethod('getContentHeight', args);
|
return await _channel.invokeMethod('getContentHeight', args);
|
||||||
|
@ -2186,9 +2240,12 @@ class InAppWebViewController
|
||||||
///This is not always the same as the URL passed to [InAppWebView.onLoadStart] because although the load for that URL has begun,
|
///This is not always the same as the URL passed to [InAppWebView.onLoadStart] because although the load for that URL has begun,
|
||||||
///the current page may not have changed. Also, there may have been redirects resulting in a different URL to that originally requested.
|
///the current page may not have changed. Also, there may have been redirects resulting in a different URL to that originally requested.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: it will return the current value of the `iframe.src` attribute.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView ([Official API - WebView.getOriginalUrl](https://developer.android.com/reference/android/webkit/WebView#getOriginalUrl()))
|
///- Android native WebView ([Official API - WebView.getOriginalUrl](https://developer.android.com/reference/android/webkit/WebView#getOriginalUrl()))
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<Uri?> getOriginalUrl() async {
|
Future<Uri?> getOriginalUrl() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
String? url = await _channel.invokeMethod('getOriginalUrl', args);
|
String? url = await _channel.invokeMethod('getOriginalUrl', args);
|
||||||
|
@ -2217,9 +2274,12 @@ class InAppWebViewController
|
||||||
///
|
///
|
||||||
///**NOTE for Android native WebView**: available only on Android 19+.
|
///**NOTE for Android native WebView**: available only on Android 19+.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<String?> getSelectedText() async {
|
Future<String?> getSelectedText() async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
return await _channel.invokeMethod('getSelectedText', args);
|
return await _channel.invokeMethod('getSelectedText', args);
|
||||||
|
@ -2314,9 +2374,12 @@ class InAppWebViewController
|
||||||
///
|
///
|
||||||
///**NOTE**: It is implemented using JavaScript.
|
///**NOTE**: It is implemented using JavaScript.
|
||||||
///
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS
|
///- iOS
|
||||||
|
///- Web
|
||||||
Future<List<MetaTag>> getMetaTags() async {
|
Future<List<MetaTag>> getMetaTags() async {
|
||||||
List<MetaTag> metaTags = [];
|
List<MetaTag> metaTags = [];
|
||||||
|
|
||||||
|
@ -2379,11 +2442,14 @@ class InAppWebViewController
|
||||||
///Returns an instance of [Color] representing the `content` value of the
|
///Returns an instance of [Color] representing the `content` value of the
|
||||||
///`<meta name="theme-color" content="">` tag of the current WebView, if available, otherwise `null`.
|
///`<meta name="theme-color" content="">` tag of the current WebView, if available, otherwise `null`.
|
||||||
///
|
///
|
||||||
///**NOTE**: on Android and iOS < 15.0, it is implemented using JavaScript.
|
///**NOTE**: on Android, Web and iOS < 15.0, it is implemented using JavaScript.
|
||||||
|
///
|
||||||
|
///**NOTE for Web**: this method will have effect only if the iframe has the same origin.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android native WebView
|
///- Android native WebView
|
||||||
///- iOS ([Official API - WKWebView.themeColor](https://developer.apple.com/documentation/webkit/wkwebview/3794258-themecolor))
|
///- iOS ([Official API - WKWebView.themeColor](https://developer.apple.com/documentation/webkit/wkwebview/3794258-themecolor))
|
||||||
|
///- Web
|
||||||
Future<Color?> getMetaThemeColor() async {
|
Future<Color?> getMetaThemeColor() async {
|
||||||
Color? themeColor;
|
Color? themeColor;
|
||||||
|
|
||||||
|
@ -2391,16 +2457,12 @@ class InAppWebViewController
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
themeColor = UtilColor.fromStringRepresentation(
|
themeColor = UtilColor.fromStringRepresentation(
|
||||||
await _channel.invokeMethod('getMetaThemeColor', args));
|
await _channel.invokeMethod('getMetaThemeColor', args));
|
||||||
|
return themeColor;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// not implemented
|
// not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
if (themeColor != null) {
|
|
||||||
return themeColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try using javascript
|
// try using javascript
|
||||||
|
|
||||||
var metaTags = await getMetaTags();
|
var metaTags = await getMetaTags();
|
||||||
MetaTag? metaTagThemeColor;
|
MetaTag? metaTagThemeColor;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
import 'dart:js' as js;
|
import 'dart:js' as js;
|
||||||
|
@ -49,7 +50,7 @@ class InAppWebViewWebElement {
|
||||||
Future<dynamic> handleMethodCall(MethodCall call) async {
|
Future<dynamic> handleMethodCall(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "getIFrameId":
|
case "getIFrameId":
|
||||||
return iframe.id;
|
return getIFrameId();
|
||||||
case "loadUrl":
|
case "loadUrl":
|
||||||
URLRequest urlRequest = URLRequest.fromMap(
|
URLRequest urlRequest = URLRequest.fromMap(
|
||||||
call.arguments["urlRequest"].cast<String, dynamic>())!;
|
call.arguments["urlRequest"].cast<String, dynamic>())!;
|
||||||
|
@ -90,10 +91,51 @@ class InAppWebViewWebElement {
|
||||||
case "setSettings":
|
case "setSettings":
|
||||||
InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap(
|
InAppWebViewSettings newSettings = InAppWebViewSettings.fromMap(
|
||||||
call.arguments["settings"].cast<String, dynamic>());
|
call.arguments["settings"].cast<String, dynamic>());
|
||||||
setSettings(newSettings);
|
await setSettings(newSettings);
|
||||||
break;
|
break;
|
||||||
case "getUrl":
|
case "getUrl":
|
||||||
return getUrl();
|
return await getUrl();
|
||||||
|
case "getTitle":
|
||||||
|
return await getTitle();
|
||||||
|
case "postUrl":
|
||||||
|
String url = call.arguments["url"];
|
||||||
|
Uint8List postData = call.arguments["postData"];
|
||||||
|
return await postUrl(url: url, postData: postData);
|
||||||
|
case "injectJavascriptFileFromUrl":
|
||||||
|
String urlFile = call.arguments["urlFile"];
|
||||||
|
Map<String, dynamic> scriptHtmlTagAttributes = call.arguments["scriptHtmlTagAttributes"].cast<String, dynamic>();
|
||||||
|
await injectJavascriptFileFromUrl(urlFile: urlFile, scriptHtmlTagAttributes: scriptHtmlTagAttributes);
|
||||||
|
break;
|
||||||
|
case "injectCSSCode":
|
||||||
|
String source = call.arguments["source"];
|
||||||
|
await injectCSSCode(source: source);
|
||||||
|
break;
|
||||||
|
case "injectCSSFileFromUrl":
|
||||||
|
String urlFile = call.arguments["urlFile"];
|
||||||
|
Map<String, dynamic> cssLinkHtmlTagAttributes = call.arguments["cssLinkHtmlTagAttributes"].cast<String, dynamic>();
|
||||||
|
await injectCSSFileFromUrl(urlFile: urlFile, cssLinkHtmlTagAttributes: cssLinkHtmlTagAttributes);
|
||||||
|
break;
|
||||||
|
case "scrollTo":
|
||||||
|
int x = call.arguments["x"];
|
||||||
|
int y = call.arguments["y"];
|
||||||
|
bool animated = call.arguments["animated"];
|
||||||
|
await scrollTo(x: x, y: y, animated: animated);
|
||||||
|
break;
|
||||||
|
case "scrollBy":
|
||||||
|
int x = call.arguments["x"];
|
||||||
|
int y = call.arguments["y"];
|
||||||
|
bool animated = call.arguments["animated"];
|
||||||
|
await scrollBy(x: x, y: y, animated: animated);
|
||||||
|
break;
|
||||||
|
case "printCurrentPage":
|
||||||
|
await printCurrentPage();
|
||||||
|
break;
|
||||||
|
case "getContentHeight":
|
||||||
|
return await getContentHeight();
|
||||||
|
case "getOriginalUrl":
|
||||||
|
return await getOriginalUrl();
|
||||||
|
case "getSelectedText":
|
||||||
|
return await getSelectedText();
|
||||||
case "dispose":
|
case "dispose":
|
||||||
dispose();
|
dispose();
|
||||||
break;
|
break;
|
||||||
|
@ -177,6 +219,10 @@ class InAppWebViewWebElement {
|
||||||
Uri.encodeFull(httpRequest.responseText ?? '');
|
Uri.encodeFull(httpRequest.responseText ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getIFrameId() {
|
||||||
|
return iframe.id;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> loadUrl({required URLRequest urlRequest}) async {
|
Future<void> loadUrl({required URLRequest urlRequest}) async {
|
||||||
if ((urlRequest.method == null || urlRequest.method == "GET") &&
|
if ((urlRequest.method == null || urlRequest.method == "GET") &&
|
||||||
(urlRequest.headers == null || urlRequest.headers!.isEmpty)) {
|
(urlRequest.headers == null || urlRequest.headers!.isEmpty)) {
|
||||||
|
@ -227,6 +273,56 @@ class InAppWebViewWebElement {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> getTitle() async {
|
||||||
|
return _callMethod("getTitle");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> postUrl({required String url, required Uint8List postData}) async {
|
||||||
|
await loadUrl(urlRequest: URLRequest(url: Uri.parse(url), method: "POST", body: postData));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> injectJavascriptFileFromUrl({required String urlFile,
|
||||||
|
Map<String, dynamic>? scriptHtmlTagAttributes}) async {
|
||||||
|
_callMethod("injectJavascriptFileFromUrl",
|
||||||
|
[urlFile, scriptHtmlTagAttributes != null ?
|
||||||
|
js.JsObject.jsify(scriptHtmlTagAttributes) : null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> injectCSSCode({required String source}) async {
|
||||||
|
_callMethod("injectCSSCode", [source]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> injectCSSFileFromUrl({required String urlFile,
|
||||||
|
Map<String, dynamic>? cssLinkHtmlTagAttributes}) async {
|
||||||
|
_callMethod("injectCSSFileFromUrl",
|
||||||
|
[urlFile, cssLinkHtmlTagAttributes != null ?
|
||||||
|
js.JsObject.jsify(cssLinkHtmlTagAttributes) : null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> scrollTo({required int x, required int y, bool animated = false}) async {
|
||||||
|
_callMethod('scrollTo', [x, y, animated]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> scrollBy({required int x, required int y, bool animated = false}) async {
|
||||||
|
_callMethod('scrollBy', [x, y, animated]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> printCurrentPage() async {
|
||||||
|
_callMethod('printCurrentPage');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int?> getContentHeight() async {
|
||||||
|
return _callMethod('getContentHeight');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> getOriginalUrl() async {
|
||||||
|
return iframe.src;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> getSelectedText() async {
|
||||||
|
return _callMethod('getSelectedText');
|
||||||
|
}
|
||||||
|
|
||||||
Set<Sandbox> getSandbox() {
|
Set<Sandbox> getSandbox() {
|
||||||
var sandbox = iframe.sandbox;
|
var sandbox = iframe.sandbox;
|
||||||
Set<Sandbox> values = Set();
|
Set<Sandbox> values = Set();
|
||||||
|
@ -390,6 +486,14 @@ class InAppWebViewWebElement {
|
||||||
await _channel?.invokeMethod("onZoomScaleChanged", obj);
|
await _channel?.invokeMethod("onZoomScaleChanged", obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onInjectedScriptLoaded(String id) async {
|
||||||
|
await _channel?.invokeMethod("onInjectedScriptLoaded", [id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onInjectedScriptError(String id) async {
|
||||||
|
await _channel?.invokeMethod("onInjectedScriptError", [id]);
|
||||||
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_channel?.setMethodCallHandler(null);
|
_channel?.setMethodCallHandler(null);
|
||||||
_channel = null;
|
_channel = null;
|
||||||
|
|
|
@ -48,32 +48,32 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId,
|
||||||
WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
|
WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case 'onLoadStart':
|
case 'onLoadStart':
|
||||||
var url = args![0] as String;
|
String url = args![0];
|
||||||
webViewHtmlElement.onLoadStart(url);
|
webViewHtmlElement.onLoadStart(url);
|
||||||
break;
|
break;
|
||||||
case 'onLoadStop':
|
case 'onLoadStop':
|
||||||
var url = args![0] as String;
|
String url = args![0];
|
||||||
webViewHtmlElement.onLoadStop(url);
|
webViewHtmlElement.onLoadStop(url);
|
||||||
break;
|
break;
|
||||||
case 'onUpdateVisitedHistory':
|
case 'onUpdateVisitedHistory':
|
||||||
var url = args![0] as String;
|
String url = args![0];
|
||||||
webViewHtmlElement.onUpdateVisitedHistory(url);
|
webViewHtmlElement.onUpdateVisitedHistory(url);
|
||||||
break;
|
break;
|
||||||
case 'onScrollChanged':
|
case 'onScrollChanged':
|
||||||
var x = (args![0] as double).toInt();
|
int x = (args![0] as double).toInt();
|
||||||
var y = (args[1] as double).toInt();
|
int y = (args[1] as double).toInt();
|
||||||
webViewHtmlElement.onScrollChanged(x, y);
|
webViewHtmlElement.onScrollChanged(x, y);
|
||||||
break;
|
break;
|
||||||
case 'onConsoleMessage':
|
case 'onConsoleMessage':
|
||||||
var type = args![0] as String;
|
String type = args![0];
|
||||||
var message = args[1] as String?;
|
String? message = args[1];
|
||||||
webViewHtmlElement.onConsoleMessage(type, message);
|
webViewHtmlElement.onConsoleMessage(type, message);
|
||||||
break;
|
break;
|
||||||
case 'onCreateWindow':
|
case 'onCreateWindow':
|
||||||
var windowId = args![0] as int;
|
int windowId = args![0];
|
||||||
var url = args[1] as String? ?? 'about:blank';
|
String url = args[1] ?? 'about:blank';
|
||||||
var target = args[2] as String?;
|
String? target = args[2];
|
||||||
var windowFeatures = args[3] as String?;
|
String? windowFeatures = args[3];
|
||||||
return await webViewHtmlElement.onCreateWindow(
|
return await webViewHtmlElement.onCreateWindow(
|
||||||
windowId, url, target, windowFeatures);
|
windowId, url, target, windowFeatures);
|
||||||
case 'onWindowFocus':
|
case 'onWindowFocus':
|
||||||
|
@ -83,7 +83,7 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId,
|
||||||
webViewHtmlElement.onWindowBlur();
|
webViewHtmlElement.onWindowBlur();
|
||||||
break;
|
break;
|
||||||
case 'onPrint':
|
case 'onPrint':
|
||||||
var url = args![0] as String?;
|
String? url = args![0];
|
||||||
webViewHtmlElement.onPrint(url);
|
webViewHtmlElement.onPrint(url);
|
||||||
break;
|
break;
|
||||||
case 'onEnterFullscreen':
|
case 'onEnterFullscreen':
|
||||||
|
@ -93,14 +93,22 @@ Future<dynamic> _dartNativeCommunication(String method, dynamic viewId,
|
||||||
webViewHtmlElement.onExitFullscreen();
|
webViewHtmlElement.onExitFullscreen();
|
||||||
break;
|
break;
|
||||||
case 'onTitleChanged':
|
case 'onTitleChanged':
|
||||||
var title = args![0] as String?;
|
String? title = args![0];
|
||||||
webViewHtmlElement.onTitleChanged(title);
|
webViewHtmlElement.onTitleChanged(title);
|
||||||
break;
|
break;
|
||||||
case 'onZoomScaleChanged':
|
case 'onZoomScaleChanged':
|
||||||
var oldScale = args![0] as double;
|
double oldScale = args![0];
|
||||||
var newScale = args[1] as double;
|
double newScale = args[1];
|
||||||
webViewHtmlElement.onZoomScaleChanged(oldScale, newScale);
|
webViewHtmlElement.onZoomScaleChanged(oldScale, newScale);
|
||||||
break;
|
break;
|
||||||
|
case 'onInjectedScriptLoaded':
|
||||||
|
String id = args![0];
|
||||||
|
webViewHtmlElement.onInjectedScriptLoaded(id);
|
||||||
|
break;
|
||||||
|
case 'onInjectedScriptError':
|
||||||
|
String id = args![0];
|
||||||
|
webViewHtmlElement.onInjectedScriptError(id);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,13 @@ function error() {
|
||||||
# on macOS local IP can be found using something like $(ipconfig getifaddr en0)
|
# on macOS local IP can be found using something like $(ipconfig getifaddr en0)
|
||||||
# on linux local IP can be found using something like $(ifconfig en0 | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}') or $(ip route get 1 | awk '{print $NF;exit}')
|
# on linux local IP can be found using something like $(ifconfig en0 | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}') or $(ip route get 1 | awk '{print $NF;exit}')
|
||||||
export NODE_SERVER_IP=$1
|
export NODE_SERVER_IP=$1
|
||||||
|
PLATFORM=$2
|
||||||
FAILED=0
|
FAILED=0
|
||||||
|
|
||||||
|
if [ $PLATFORM = "web" ]; then
|
||||||
|
$PROJECT_DIR/tool/chromedriver --port=4444 &
|
||||||
|
fi
|
||||||
|
|
||||||
dart $PROJECT_DIR/tool/env.dart
|
dart $PROJECT_DIR/tool/env.dart
|
||||||
|
|
||||||
cd $PROJECT_DIR/nodejs_server_test_auth_basic_and_ssl
|
cd $PROJECT_DIR/nodejs_server_test_auth_basic_and_ssl
|
||||||
|
@ -21,7 +26,11 @@ flutter --version
|
||||||
flutter clean
|
flutter clean
|
||||||
cd $PROJECT_DIR/example
|
cd $PROJECT_DIR/example
|
||||||
flutter clean
|
flutter clean
|
||||||
|
if [ $PLATFORM = "web" ]; then
|
||||||
|
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart --device-id=chrome
|
||||||
|
else
|
||||||
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart
|
flutter driver --driver=test_driver/integration_test.dart --target=integration_test/webview_flutter_test.dart
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Integration tests passed successfully."
|
echo "Integration tests passed successfully."
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
readonly SCRIPT_PATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
readonly SCRIPT_PATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
readonly PROJECT_DIR="$(dirname $SCRIPT_PATH)"
|
readonly PROJECT_DIR="$(dirname $SCRIPT_PATH)"
|
||||||
|
|
||||||
$SCRIPT_PATH/test.sh $1 2>&1 | tee $PROJECT_DIR/flutter_driver_tests.log
|
$SCRIPT_PATH/test.sh $1 $2 2>&1 | tee $PROJECT_DIR/flutter_driver_tests.log
|
||||||
|
|
||||||
kill $(jobs -p)
|
kill $(jobs -p)
|
Loading…
Reference in New Issue