updated web support

This commit is contained in:
Lorenzo Pichilli 2022-04-22 02:24:50 +02:00
parent 176d41d328
commit 46fcafcf44
11 changed files with 218 additions and 26 deletions

View File

@ -119,7 +119,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
key: webViewKey, key: webViewKey,
// contextMenu: contextMenu, // contextMenu: contextMenu,
initialUrlRequest: initialUrlRequest:
URLRequest(url: Uri.parse("http://flutter.dev/")), URLRequest(url: Uri.parse("https://flutter.dev")),
// initialFile: "assets/index.html", // initialFile: "assets/index.html",
initialUserScripts: UnmodifiableListView<UserScript>([]), initialUserScripts: UnmodifiableListView<UserScript>([]),
initialSettings: settings, initialSettings: settings,

View File

@ -31,6 +31,9 @@
<title>flutter_inappwebview_example</title> <title>flutter_inappwebview_example</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<!-- Load flutter_inappwebview web_support js library -->
<script src="/packages/flutter_inappwebview/assets/web/web_support.js" defer></script>
</head> </head>
<body> <body>
<!-- This script installs service_worker.js to provide PWA functionality to <!-- This script installs service_worker.js to provide PWA functionality to

26
example/web/page-2.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="Demonstrates how to use the flutter_inappwebview plugin.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="flutter_inappwebview_example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>flutter_inappwebview_example</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<h1>Simple Page 2</h1>
<a href="/page.html">Go to page 1</a>
</body>
</html>

26
example/web/page.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="Demonstrates how to use the flutter_inappwebview plugin.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="flutter_inappwebview_example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>flutter_inappwebview_example</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<h1>Simple Page 1</h1>
<a href="/page-2.html">Go to page 2</a>
</body>
</html>

View File

@ -0,0 +1,63 @@
window.flutter_inappwebview = {
viewId: null,
iframeId: null,
iframe: null,
prepare: function () {
var iframe = document.getElementById(window.flutter_inappwebview.iframeId);
if (iframe != null) {
window.flutter_inappwebview.iframe = iframe;
iframe.addEventListener('load', function (event) {
var url = iframe.src;
try {
url = iframe.contentWindow.location.href;
} catch (e) {
console.log(e);
}
window.flutter_inappwebview.nativeCommunication('iframeLoaded', window.flutter_inappwebview.viewId, [url]);
});
}
},
reload: function () {
var iframe = window.flutter_inappwebview.iframe;
if (iframe != null && iframe.contentWindow != null) {
try {
iframe.contentWindow.location.reload();
} catch (e) {
console.log(e);
iframe.contentWindow.location.href = iframe.src;
}
}
},
goBack: function () {
var iframe = window.flutter_inappwebview.iframe;
if (iframe != null) {
try {
iframe.contentWindow.history.back();
} catch (e) {
console.log(e);
}
}
},
goForward: function () {
var iframe = window.flutter_inappwebview.iframe;
if (iframe != null) {
try {
iframe.contentWindow.history.forward();
} catch (e) {
console.log(e);
}
}
},
evaluateJavascript: function (source) {
var iframe = window.flutter_inappwebview.iframe;
var result = null;
if (iframe != null) {
try {
result = iframe.contentWindow.eval(source);
} catch (e) {
console.log(e);
}
}
return result;
}
};

View File

@ -1385,9 +1385,13 @@ class InAppWebViewController
/// ///
///**NOTE for Android**: when loading an URL Request using "POST" method, headers are ignored. ///**NOTE for Android**: when loading an URL Request using "POST" method, headers are ignored.
/// ///
///**NOTE for Web**: if method is "GET" and headers are empty, it will change the `src` of the iframe.
///For all other cases 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.loadUrl](https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String))). If method is "POST", [Official API - WebView.postUrl](https://developer.android.com/reference/android/webkit/WebView#postUrl(java.lang.String,%20byte[])) ///- Android native WebView ([Official API - WebView.loadUrl](https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String))). If method is "POST", [Official API - WebView.postUrl](https://developer.android.com/reference/android/webkit/WebView#postUrl(java.lang.String,%20byte[]))
///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl)) ///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl))
///- Web
Future<void> loadUrl( Future<void> loadUrl(
{required URLRequest urlRequest, {required URLRequest urlRequest,
@Deprecated('Use allowingReadAccessTo instead') @Deprecated('Use allowingReadAccessTo instead')
@ -1432,7 +1436,9 @@ class InAppWebViewController
/// ///
///- [mimeType] argument specifies the format of the data. The default value is `"text/html"`. ///- [mimeType] argument specifies the format of the data. The default value is `"text/html"`.
///- [encoding] argument specifies the encoding of the data. The default value is `"utf8"`. ///- [encoding] argument specifies the encoding of the data. The default value is `"utf8"`.
///**NOTE**: not used on Web.
///- [historyUrl] is an Android-specific argument that represents the URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL. ///- [historyUrl] is an Android-specific argument that represents the URL to use as the history entry. The default value is `about:blank`. If non-null, this must be a valid URL.
///**NOTE**: not used on Web.
///- [allowingReadAccessTo], used in combination with [baseUrl] (using the `file://` scheme), ///- [allowingReadAccessTo], used in combination with [baseUrl] (using the `file://` scheme),
///it represents the URL from which to read the web content. ///it represents the URL from which to read the web content.
///This [baseUrl] must be a file-based URL (using the `file://` scheme). ///This [baseUrl] must be a file-based URL (using the `file://` scheme).
@ -1443,6 +1449,7 @@ class InAppWebViewController
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.loadDataWithBaseURL](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String))) ///- Android native WebView ([Official API - WebView.loadDataWithBaseURL](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String)))
///- iOS ([Official API - WKWebView.loadHTMLString](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring) or [Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1415011-load)) ///- iOS ([Official API - WKWebView.loadHTMLString](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring) or [Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1415011-load))
///- Web
Future<void> loadData( Future<void> loadData(
{required String data, {required String data,
String mimeType = "text/html", String mimeType = "text/html",
@ -1511,6 +1518,7 @@ class InAppWebViewController
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.loadUrl](https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String))) ///- Android native WebView ([Official API - WebView.loadUrl](https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String)))
///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load)) ///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load))
///- Web
Future<void> loadFile({required String assetFilePath}) async { Future<void> loadFile({required String assetFilePath}) async {
assert(assetFilePath.isNotEmpty); assert(assetFilePath.isNotEmpty);
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
@ -1520,9 +1528,12 @@ class InAppWebViewController
///Reloads the WebView. ///Reloads the WebView.
/// ///
///**NOTE**: on Web, if `window.location.reload()` is not accessible inside the iframe, it will reload using the iframe `src` attribute.
///
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.reload](https://developer.android.com/reference/android/webkit/WebView#reload())) ///- Android native WebView ([Official API - WebView.reload](https://developer.android.com/reference/android/webkit/WebView#reload()))
///- iOS ([Official API - WKWebView.reload](https://developer.apple.com/documentation/webkit/wkwebview/1414969-reload)) ///- iOS ([Official API - WKWebView.reload](https://developer.apple.com/documentation/webkit/wkwebview/1414969-reload))
///- Web ([Official API - Location.reload](https://developer.mozilla.org/en-US/docs/Web/API/Location/reload))
Future<void> reload() async { Future<void> reload() async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
await _channel.invokeMethod('reload', args); await _channel.invokeMethod('reload', args);
@ -1533,6 +1544,7 @@ class InAppWebViewController
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.goBack](https://developer.android.com/reference/android/webkit/WebView#goBack())) ///- Android native WebView ([Official API - WebView.goBack](https://developer.android.com/reference/android/webkit/WebView#goBack()))
///- iOS ([Official API - WKWebView.goBack](https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback)) ///- iOS ([Official API - WKWebView.goBack](https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback))
///- Web ([Official API - History.back](https://developer.mozilla.org/en-US/docs/Web/API/History/back))
Future<void> goBack() async { Future<void> goBack() async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
await _channel.invokeMethod('goBack', args); await _channel.invokeMethod('goBack', args);
@ -1553,6 +1565,7 @@ class InAppWebViewController
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.goForward](https://developer.android.com/reference/android/webkit/WebView#goForward())) ///- Android native WebView ([Official API - WebView.goForward](https://developer.android.com/reference/android/webkit/WebView#goForward()))
///- iOS ([Official API - WKWebView.goForward](https://developer.apple.com/documentation/webkit/wkwebview/1414993-goforward)) ///- iOS ([Official API - WKWebView.goForward](https://developer.apple.com/documentation/webkit/wkwebview/1414993-goforward))
///- Web ([Official API - History.forward](https://developer.mozilla.org/en-US/docs/Web/API/History/forward))
Future<void> goForward() async { Future<void> goForward() async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
await _channel.invokeMethod('goForward', args); await _channel.invokeMethod('goForward', args);
@ -1630,6 +1643,7 @@ class InAppWebViewController
///Those changes remain visible to all scripts, regardless of which content world you specify. ///Those changes remain visible to all scripts, regardless of which content world you specify.
///For more information about content worlds, see [ContentWorld]. ///For more information about content worlds, see [ContentWorld].
///Available on iOS 14.0+. ///Available on iOS 14.0+.
///**NOTE**: not used on Web.
/// ///
///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events,
///because, in these events, the [WebView] is not ready to handle it yet. ///because, in these events, the [WebView] is not ready to handle it yet.
@ -1639,6 +1653,7 @@ class InAppWebViewController
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebView.evaluateJavascript](https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E))) ///- Android native WebView ([Official API - WebView.evaluateJavascript](https://developer.android.com/reference/android/webkit/WebView#evaluateJavascript(java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)))
///- iOS ([Official API - WKWebView.evaluateJavascript](https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript)) ///- iOS ([Official API - WKWebView.evaluateJavascript](https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript))
///- Web ([Official API - Window.eval](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval?retiredLocale=it))
Future<dynamic> evaluateJavascript( Future<dynamic> evaluateJavascript(
{required String source, ContentWorld? contentWorld}) async { {required String source, ContentWorld? contentWorld}) async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};

View File

@ -20,6 +20,7 @@ abstract class WebView {
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- Web
final void Function(InAppWebViewController controller)? onWebViewCreated; final void Function(InAppWebViewController controller)? onWebViewCreated;
///Event fired when the [WebView] starts to load an [url]. ///Event fired when the [WebView] starts to load an [url].
@ -27,6 +28,7 @@ abstract class WebView {
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap))) ///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)))
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview)) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
///- Web
final void Function(InAppWebViewController controller, Uri? url)? onLoadStart; final void Function(InAppWebViewController controller, Uri? url)? onLoadStart;
///Event fired when the [WebView] finishes loading an [url]. ///Event fired when the [WebView] finishes loading an [url].
@ -34,6 +36,7 @@ abstract class WebView {
///**Supported Platforms/Implementations**: ///**Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String))) ///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)))
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview)) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
///- Web ([Official API - Window.onload](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event))
final void Function(InAppWebViewController controller, Uri? url)? onLoadStop; final void Function(InAppWebViewController controller, Uri? url)? onLoadStop;
///Event fired when the [WebView] encounters an error loading an [url]. ///Event fired when the [WebView] encounters an error loading an [url].

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'dart:html'; import 'dart:html';
import 'dart:js' as js;
import '../in_app_webview/in_app_webview_settings.dart'; import '../in_app_webview/in_app_webview_settings.dart';
import '../types.dart'; import '../types.dart';
@ -16,12 +17,16 @@ class InAppWebViewWebElement {
String? initialFile; String? initialFile;
late InAppWebViewSettings settings; late InAppWebViewSettings settings;
late js.JsObject bridgeJsObject;
WebHistory webHistory = WebHistory(list: [], currentIndex: -1);
InAppWebViewWebElement({required int viewId, required BinaryMessenger messenger}) { InAppWebViewWebElement({required int viewId, required BinaryMessenger messenger}) {
this._viewId = viewId; this._viewId = viewId;
this._messenger = messenger; this._messenger = messenger;
iframe = IFrameElement() iframe = IFrameElement()
..id = 'flutter_inappwebview-$_viewId' ..id = 'flutter_inappwebview-$_viewId'
..style.height = '100%'
..style.width = '100%'
..style.border = 'none'; ..style.border = 'none';
_channel = MethodChannel( _channel = MethodChannel(
@ -32,19 +37,16 @@ class InAppWebViewWebElement {
this._channel.setMethodCallHandler(handleMethodCall); this._channel.setMethodCallHandler(handleMethodCall);
iframe.addEventListener('load', (event) async { bridgeJsObject = js.JsObject.fromBrowserObject(js.context['flutter_inappwebview']);
var obj = { bridgeJsObject['viewId'] = _viewId;
"url": iframe.src bridgeJsObject['iframeId'] = iframe.id;
};
_channel.invokeMethod("onLoadStart", obj);
await Future.delayed(Duration(milliseconds: 100));
_channel.invokeMethod("onLoadStop", obj);
});
} }
/// Handles method calls over the MethodChannel of this plugin. /// Handles method calls over the MethodChannel of this plugin.
Future<dynamic> handleMethodCall(MethodCall call) async { Future<dynamic> handleMethodCall(MethodCall call) async {
switch (call.method) { switch (call.method) {
case "getIFrameId":
return iframe.id;
case "loadUrl": case "loadUrl":
URLRequest urlRequest = URLRequest.fromMap(call.arguments["urlRequest"].cast<String, dynamic>())!; URLRequest urlRequest = URLRequest.fromMap(call.arguments["urlRequest"].cast<String, dynamic>())!;
await _loadUrl(urlRequest: urlRequest); await _loadUrl(urlRequest: urlRequest);
@ -61,8 +63,15 @@ class InAppWebViewWebElement {
case "reload": case "reload":
await _reload(); await _reload();
break; break;
case "getIFrameId": case "goBack":
return iframe.id; await _goBack();
break;
case "goForward":
await _goForward();
break;
case "evaluateJavascript":
String source = call.arguments["source"];
return await _evaluateJavascript(source: source);
default: default:
throw PlatformException( throw PlatformException(
code: 'Unimplemented', code: 'Unimplemented',
@ -78,19 +87,13 @@ class InAppWebViewWebElement {
if (settings.iframeSandox != null) { if (settings.iframeSandox != null) {
iframe.setAttribute("sandbox", settings.iframeSandox ?? ""); iframe.setAttribute("sandbox", settings.iframeSandox ?? "");
} }
var width = settings.iframeWidth ?? iframe.width; iframe.style.width = settings.iframeWidth ?? iframe.style.width;
if (width == null || width.isEmpty) { iframe.style.height = settings.iframeHeight ?? iframe.style.height;
width = '100%';
}
var height = settings.iframeHeight ?? iframe.height;
if (height == null || height.isEmpty) {
height = '100%';
}
iframe.width = iframe.style.width = width;
iframe.height = iframe.style.height = height;
iframe.referrerPolicy = settings.iframeReferrerPolicy ?? iframe.referrerPolicy; iframe.referrerPolicy = settings.iframeReferrerPolicy ?? iframe.referrerPolicy;
iframe.name = settings.iframeName ?? iframe.name; iframe.name = settings.iframeName ?? iframe.name;
iframe.csp = settings.iframeCsp ?? iframe.csp; iframe.csp = settings.iframeCsp ?? iframe.csp;
bridgeJsObject.callMethod("prepare");
} }
void makeInitialLoad() async { void makeInitialLoad() async {
@ -129,20 +132,48 @@ class InAppWebViewWebElement {
} else { } else {
iframe.src = _convertHttpResponseToData(await _makeRequest(urlRequest)); iframe.src = _convertHttpResponseToData(await _makeRequest(urlRequest));
} }
var obj = {
"url": iframe.src
};
_channel.invokeMethod("onLoadStart", obj);
} }
Future<void> _loadData({required String data, String mimeType = "text/html"}) async { Future<void> _loadData({required String data, String mimeType = "text/html"}) async {
iframe.src = 'data:$mimeType,' + Uri.encodeFull(data); iframe.src = 'data:$mimeType,' + Uri.encodeFull(data);
var obj = {
"url": iframe.src
};
_channel.invokeMethod("onLoadStart", obj);
} }
Future<void> _loadFile({required String assetFilePath}) async { Future<void> _loadFile({required String assetFilePath}) async {
iframe.src = assetFilePath; iframe.src = assetFilePath;
var obj = {
"url": iframe.src
};
_channel.invokeMethod("onLoadStart", obj);
} }
Future<void> _reload() async { Future<void> _reload() async {
var src = iframe.src; bridgeJsObject.callMethod("reload");
if (src != null) { }
iframe.contentWindow?.location.href = src;
} Future<void> _goBack() async {
bridgeJsObject.callMethod("goBack");
}
Future<void> _goForward() async {
bridgeJsObject.callMethod("goForward");
}
Future<dynamic> _evaluateJavascript({required String source}) async {
return bridgeJsObject.callMethod("evaluateJavascript", [source]);
}
onIFrameLoaded(String url) async {
var obj = {
"url": url
};
_channel.invokeMethod("onLoadStop", obj);
} }
} }

View File

@ -6,6 +6,8 @@ import 'shims/dart_ui.dart' as ui;
import 'in_app_web_view_web_element.dart'; import 'in_app_web_view_web_element.dart';
import 'package:js/js.dart';
/// Builds an iframe based WebView. /// Builds an iframe based WebView.
/// ///
/// This is used as the default implementation for [WebView] on web. /// This is used as the default implementation for [WebView] on web.
@ -24,6 +26,7 @@ class FlutterInAppWebViewWebPlatform {
static void registerWith(Registrar registrar) { static void registerWith(Registrar registrar) {
final pluginInstance = FlutterInAppWebViewWebPlatform(registrar); final pluginInstance = FlutterInAppWebViewWebPlatform(registrar);
_nativeCommunication = allowInterop(_dartNativeCommunication);
} }
/// Handles method calls over the MethodChannel of this plugin. /// Handles method calls over the MethodChannel of this plugin.
@ -36,4 +39,24 @@ class FlutterInAppWebViewWebPlatform {
); );
} }
} }
}
/// Allows assigning a function to be callable from `window.flutter_inappwebview.nativeCommunication()`
@JS('flutter_inappwebview.nativeCommunication')
external set _nativeCommunication(void Function(String method, int viewId, [List? args]) f);
/// Allows calling the assigned function from Dart as well.
@JS()
external void nativeCommunication();
void _dartNativeCommunication(String method, int viewId, [List? args]) {
if (WebPlatformManager.webViews.containsKey(viewId)) {
var webViewHtmlElement = WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
switch (method) {
case 'iframeLoaded':
String url = args![0] as String;
webViewHtmlElement.onIFrameLoaded(url);
break;
}
}
} }

View File

@ -1,3 +1,3 @@
class WebPlatformManager { abstract class WebPlatformManager {
static final Map<int, dynamic> webViews = {}; static final Map<int, dynamic> webViews = {};
} }

View File

@ -10,6 +10,7 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
js: ^0.6.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -38,6 +39,7 @@ flutter:
assets: assets:
- packages/flutter_inappwebview/assets/t_rex_runner/t-rex.html - packages/flutter_inappwebview/assets/t_rex_runner/t-rex.html
- packages/flutter_inappwebview/assets/t_rex_runner/t-rex.css - packages/flutter_inappwebview/assets/t_rex_runner/t-rex.css
- packages/flutter_inappwebview/assets/web/web_support.js
# To add assets to your plugin package, add an assets section, like this: # To add assets to your plugin package, add an assets section, like this:
# assets: # assets:
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg