added new events
This commit is contained in:
parent
922fd0c142
commit
61a439893b
@ -22,7 +22,8 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
mediaPlaybackRequiresUserGesture: false,
|
||||
useHybridComposition: true,
|
||||
allowsInlineMediaPlayback: true,
|
||||
iframeAllow: "camera; microphone"
|
||||
iframeAllow: "camera; microphone",
|
||||
iframeAllowFullscreen: true
|
||||
);
|
||||
|
||||
PullToRefreshController? pullToRefreshController;
|
||||
@ -46,7 +47,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
await webViewController?.clearFocus();
|
||||
})
|
||||
],
|
||||
options: ContextMenuOptions(hideDefaultSystemContextMenuItems: false),
|
||||
settings: ContextMenuSettings(hideDefaultSystemContextMenuItems: false),
|
||||
onCreateContextMenu: (hitTestResult) async {
|
||||
print("onCreateContextMenu");
|
||||
print(hitTestResult.extra);
|
||||
@ -184,6 +185,9 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||
onConsoleMessage: (controller, consoleMessage) {
|
||||
print(consoleMessage);
|
||||
},
|
||||
onZoomScaleChanged: (controller, oldScale, newScale) {
|
||||
print("$oldScale $newScale");
|
||||
},
|
||||
),
|
||||
!kIsWeb && progress < 1.0
|
||||
? LinearProgressIndicator(value: progress)
|
||||
|
@ -2,11 +2,34 @@ window.flutter_inappwebview = {
|
||||
viewId: null,
|
||||
iframeId: null,
|
||||
iframe: null,
|
||||
windowAutoincrementId: 0,
|
||||
windows: {},
|
||||
isFullscreen: false,
|
||||
documentTitle: null,
|
||||
prepare: function () {
|
||||
var iframe = document.getElementById(window.flutter_inappwebview.iframeId);
|
||||
|
||||
document.addEventListener('fullscreenchange', function(event) {
|
||||
// document.fullscreenElement will point to the element that
|
||||
// is in fullscreen mode if there is one. If there isn't one,
|
||||
// the value of the property is null.
|
||||
if (document.fullscreenElement && document.fullscreenElement.id == window.flutter_inappwebview.iframeId) {
|
||||
window.flutter_inappwebview.isFullscreen = true;
|
||||
window.flutter_inappwebview.nativeCommunication('onEnterFullscreen', window.flutter_inappwebview.viewId);
|
||||
} else if (!document.fullscreenElement && window.flutter_inappwebview.isFullscreen) {
|
||||
window.flutter_inappwebview.isFullscreen = false;
|
||||
window.flutter_inappwebview.nativeCommunication('onExitFullscreen', window.flutter_inappwebview.viewId);
|
||||
} else {
|
||||
window.flutter_inappwebview.isFullscreen = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (iframe != null) {
|
||||
window.flutter_inappwebview.iframe = iframe;
|
||||
iframe.addEventListener('load', function (event) {
|
||||
window.flutter_inappwebview.windowAutoincrementId = 0;
|
||||
window.flutter_inappwebview.windows = {};
|
||||
|
||||
try {
|
||||
var oldLogs = {
|
||||
'log': iframe.contentWindow.console.log,
|
||||
@ -80,6 +103,41 @@ window.flutter_inappwebview = {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
try {
|
||||
var originalOpen = iframe.contentWindow.open;
|
||||
iframe.contentWindow.open = function (url, target, windowFeatures) {
|
||||
var newWindow = originalOpen.call(iframe.contentWindow, ...arguments);
|
||||
var windowId = window.flutter_inappwebview.windowAutoincrementId;
|
||||
window.flutter_inappwebview.windowAutoincrementId++;
|
||||
window.flutter_inappwebview.windows[windowId] = newWindow;
|
||||
window.flutter_inappwebview.nativeCommunication('onCreateWindow', window.flutter_inappwebview.viewId, [windowId, url, target, windowFeatures]).then(function(){}, function(handledByClient) {
|
||||
console.log(handledByClient);
|
||||
if (handledByClient) {
|
||||
newWindow.close();
|
||||
}
|
||||
});
|
||||
return newWindow;
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
try {
|
||||
var originalPrint = iframe.contentWindow.print;
|
||||
iframe.contentWindow.print = function () {
|
||||
var iframeUrl = iframe.src;
|
||||
try {
|
||||
iframeUrl = iframe.contentWindow.location.href;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
window.flutter_inappwebview.nativeCommunication('onPrint', window.flutter_inappwebview.viewId, [iframeUrl]);
|
||||
originalPrint.call(iframe.contentWindow);
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
iframe.contentWindow.addEventListener('scroll', function (event) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
@ -91,6 +149,45 @@ window.flutter_inappwebview = {
|
||||
}
|
||||
window.flutter_inappwebview.nativeCommunication('onScrollChanged', window.flutter_inappwebview.viewId, [x, y]);
|
||||
});
|
||||
|
||||
iframe.contentWindow.addEventListener('focus', function (event) {
|
||||
window.flutter_inappwebview.nativeCommunication('onWindowFocus', window.flutter_inappwebview.viewId);
|
||||
});
|
||||
|
||||
iframe.contentWindow.addEventListener('blur', function (event) {
|
||||
window.flutter_inappwebview.nativeCommunication('onWindowBlur', window.flutter_inappwebview.viewId);
|
||||
});
|
||||
|
||||
try {
|
||||
var initialTitle = iframe.contentDocument.title;
|
||||
window.flutter_inappwebview.documentTitle = initialTitle;
|
||||
window.flutter_inappwebview.nativeCommunication('onTitleChanged', window.flutter_inappwebview.viewId, [initialTitle]);
|
||||
new MutationObserver(function(mutations) {
|
||||
var title = mutations[0].target.nodeValue;
|
||||
if (title != window.flutter_inappwebview.documentTitle) {
|
||||
window.flutter_inappwebview.documentTitle = title;
|
||||
window.flutter_inappwebview.nativeCommunication('onTitleChanged', window.flutter_inappwebview.viewId, [title]);
|
||||
}
|
||||
}).observe(
|
||||
iframe.contentDocument.querySelector('title'),
|
||||
{ subtree: true, characterData: true, childList: true }
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
try {
|
||||
var oldPixelRatio = iframe.contentWindow.devicePixelRatio;
|
||||
iframe.contentWindow.addEventListener('resize', function (e) {
|
||||
var newPixelRatio = iframe.contentWindow.devicePixelRatio;
|
||||
if(newPixelRatio !== oldPixelRatio){
|
||||
window.flutter_inappwebview.nativeCommunication('onZoomScaleChanged', window.flutter_inappwebview.viewId, [oldPixelRatio, newPixelRatio]);
|
||||
oldPixelRatio = newPixelRatio;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -157,4 +254,4 @@ window.flutter_inappwebview = {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
@ -19,7 +19,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
@JS()
|
||||
library flutter_inappwebview;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
|
||||
export 'src/main.dart';
|
||||
export 'src/web/main.dart';
|
@ -994,6 +994,27 @@ class InAppWebViewController
|
||||
_inAppBrowser!.onOverScrolled(x, y, clampedX, clampedY);
|
||||
}
|
||||
break;
|
||||
case "onWindowFocus":
|
||||
if (_webview != null && _webview!.onWindowFocus != null)
|
||||
_webview!.onWindowFocus!(this);
|
||||
else if (_inAppBrowser != null) _inAppBrowser!.onWindowFocus();
|
||||
break;
|
||||
case "onWindowBlur":
|
||||
if (_webview != null && _webview!.onWindowBlur != null)
|
||||
_webview!.onWindowBlur!(this);
|
||||
else if (_inAppBrowser != null) _inAppBrowser!.onWindowBlur();
|
||||
break;
|
||||
case "onPrint":
|
||||
if ((_webview != null && _webview!.onPrint != null) ||
|
||||
_inAppBrowser != null) {
|
||||
String? url = call.arguments["url"];
|
||||
Uri? uri = url != null ? Uri.parse(url) : null;
|
||||
if (_webview != null && _webview!.onPrint != null)
|
||||
_webview!.onPrint!(this, uri);
|
||||
else
|
||||
_inAppBrowser!.onPrint(uri);
|
||||
}
|
||||
break;
|
||||
case "onCallJsHandler":
|
||||
String handlerName = call.arguments["handlerName"];
|
||||
// decode args to json
|
||||
|
@ -188,9 +188,13 @@ abstract class WebView {
|
||||
///Also, note that calling [InAppWebViewController.setSettings] method using the controller of the new created WebView,
|
||||
///it will update also the WebView options of the caller WebView.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///Also, there is no way to block the opening the window in a synchronous way, so returning `true` will just close it quickly.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onCreateWindow](https://developer.android.com/reference/android/webkit/WebChromeClient#onCreateWindow(android.webkit.WebView,%20boolean,%20boolean,%20android.os.Message)))
|
||||
///- iOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview))
|
||||
///- Web
|
||||
final Future<bool?> Function(InAppWebViewController controller,
|
||||
CreateWindowAction createWindowAction)? onCreateWindow;
|
||||
|
||||
@ -205,17 +209,23 @@ abstract class WebView {
|
||||
///Event fired when the JavaScript `window` object of the WebView has received focus.
|
||||
///This is the result of the `focus` JavaScript event applied to the `window` object.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- Web ([Official API - Window.onfocus](https://developer.mozilla.org/en-US/docs/Web/API/Window/focus_event))
|
||||
final void Function(InAppWebViewController controller)? onWindowFocus;
|
||||
|
||||
///Event fired when the JavaScript `window` object of the WebView has lost focus.
|
||||
///This is the result of the `blur` JavaScript event applied to the `window` object.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- Web ([Official API - Window.onblur](https://developer.mozilla.org/en-US/docs/Web/API/Window/blur_event))
|
||||
final void Function(InAppWebViewController controller)? onWindowBlur;
|
||||
|
||||
///Event fired when javascript calls the `alert()` method to display an alert dialog.
|
||||
@ -400,9 +410,12 @@ abstract class WebView {
|
||||
///
|
||||
///[url] represents the url on which is called.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView
|
||||
///- iOS
|
||||
///- Web
|
||||
final void Function(InAppWebViewController controller, Uri? url)? onPrint;
|
||||
|
||||
///Event fired when an HTML element of the webview has been clicked and held.
|
||||
@ -420,6 +433,7 @@ abstract class WebView {
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onShowCustomView](https://developer.android.com/reference/android/webkit/WebChromeClient#onShowCustomView(android.view.View,%20android.webkit.WebChromeClient.CustomViewCallback)))
|
||||
///- iOS ([Official API - UIWindow.didBecomeVisibleNotification](https://developer.apple.com/documentation/uikit/uiwindow/1621621-didbecomevisiblenotification))
|
||||
///- Web ([Official API - Document.onfullscreenchange](https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenchange_event))
|
||||
final void Function(InAppWebViewController controller)? onEnterFullscreen;
|
||||
|
||||
///Event fired when the current page has exited full screen mode.
|
||||
@ -431,6 +445,7 @@ abstract class WebView {
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onHideCustomView](https://developer.android.com/reference/android/webkit/WebChromeClient#onHideCustomView()))
|
||||
///- iOS ([Official API - UIWindow.didBecomeHiddenNotification](https://developer.apple.com/documentation/uikit/uiwindow/1621617-didbecomehiddennotification))
|
||||
///- Web ([Official API - Document.onfullscreenchange](https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenchange_event))
|
||||
final void Function(InAppWebViewController controller)? onExitFullscreen;
|
||||
|
||||
///Called when the web view begins to receive web content.
|
||||
@ -450,9 +465,12 @@ abstract class WebView {
|
||||
///
|
||||
///[title] represents the string containing the new title of the document.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebChromeClient.onReceivedTitle](https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)))
|
||||
///- iOS
|
||||
///- Web
|
||||
final void Function(InAppWebViewController controller, String? title)?
|
||||
onTitleChanged;
|
||||
|
||||
@ -478,9 +496,12 @@ abstract class WebView {
|
||||
///
|
||||
///[newScale] The new zoom scale factor.
|
||||
///
|
||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
||||
///
|
||||
///**Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebViewClient.onScaleChanged](https://developer.android.com/reference/android/webkit/WebViewClient#onScaleChanged(android.webkit.WebView,%20float,%20float)))
|
||||
///- iOS ([Official API - UIScrollViewDelegate.scrollViewDidZoom](https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619409-scrollviewdidzoom))
|
||||
///- Web
|
||||
final void Function(
|
||||
InAppWebViewController controller, double oldScale, double newScale)?
|
||||
onZoomScaleChanged;
|
||||
|
@ -201,40 +201,40 @@ class InAppWebViewWebElement {
|
||||
settings = newSettings;
|
||||
}
|
||||
|
||||
onLoadStart(String url) async {
|
||||
void onLoadStart(String url) async {
|
||||
isLoading = true;
|
||||
|
||||
var obj = {
|
||||
"url": url
|
||||
};
|
||||
_channel.invokeMethod("onLoadStart", obj);
|
||||
await _channel.invokeMethod("onLoadStart", obj);
|
||||
}
|
||||
|
||||
onLoadStop(String url) async {
|
||||
void onLoadStop(String url) async {
|
||||
isLoading = false;
|
||||
|
||||
var obj = {
|
||||
"url": url
|
||||
};
|
||||
_channel.invokeMethod("onLoadStop", obj);
|
||||
await _channel.invokeMethod("onLoadStop", obj);
|
||||
}
|
||||
|
||||
onUpdateVisitedHistory(String url) async {
|
||||
void onUpdateVisitedHistory(String url) async {
|
||||
var obj = {
|
||||
"url": url
|
||||
};
|
||||
_channel.invokeMethod("onUpdateVisitedHistory", obj);
|
||||
await _channel.invokeMethod("onUpdateVisitedHistory", obj);
|
||||
}
|
||||
|
||||
onScrollChanged(int x, int y) async {
|
||||
void onScrollChanged(int x, int y) async {
|
||||
var obj = {
|
||||
"x": x,
|
||||
"y": y
|
||||
};
|
||||
_channel.invokeMethod("onScrollChanged", obj);
|
||||
await _channel.invokeMethod("onScrollChanged", obj);
|
||||
}
|
||||
|
||||
onConsoleMessage(String type, String? message) async {
|
||||
void onConsoleMessage(String type, String? message) async {
|
||||
int messageLevel = 1;
|
||||
switch (type) {
|
||||
case 'debug':
|
||||
@ -255,6 +255,75 @@ class InAppWebViewWebElement {
|
||||
"messageLevel": messageLevel,
|
||||
"message": message
|
||||
};
|
||||
_channel.invokeMethod("onConsoleMessage", obj);
|
||||
await _channel.invokeMethod("onConsoleMessage", obj);
|
||||
}
|
||||
|
||||
Future<bool?> onCreateWindow(int windowId, String url, String? target, String? windowFeatures) async {
|
||||
Map<String, dynamic> windowFeaturesMap = {};
|
||||
List<String> features = windowFeatures?.split(",") ?? [];
|
||||
for (var feature in features) {
|
||||
var keyValue = feature.trim().split("=");
|
||||
if (keyValue.length == 2) {
|
||||
var key = keyValue[0].trim();
|
||||
var value = keyValue[1].trim();
|
||||
if (['height', 'width', 'x', 'y'].contains(key)) {
|
||||
windowFeaturesMap[key] = double.parse(value);
|
||||
} else {
|
||||
windowFeaturesMap[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
"windowId": windowId,
|
||||
"isForMainFrame": true,
|
||||
"request": {
|
||||
"url": url,
|
||||
"method": "GET"
|
||||
},
|
||||
"windowFeatures": windowFeaturesMap
|
||||
};
|
||||
return await _channel.invokeMethod("onCreateWindow", obj);
|
||||
}
|
||||
|
||||
void onWindowFocus() async {
|
||||
await _channel.invokeMethod("onWindowFocus");
|
||||
}
|
||||
|
||||
void onWindowBlur() async {
|
||||
await _channel.invokeMethod("onWindowBlur");
|
||||
}
|
||||
|
||||
void onPrint(String? url) async {
|
||||
var obj = {
|
||||
"url": url
|
||||
};
|
||||
|
||||
await _channel.invokeMethod("onPrint", obj);
|
||||
}
|
||||
|
||||
void onEnterFullscreen() async {
|
||||
await _channel.invokeMethod("onEnterFullscreen");
|
||||
}
|
||||
|
||||
void onExitFullscreen() async {
|
||||
await _channel.invokeMethod("onExitFullscreen");
|
||||
}
|
||||
|
||||
void onTitleChanged(String? title) async {
|
||||
var obj = {
|
||||
"title": title
|
||||
};
|
||||
|
||||
await _channel.invokeMethod("onTitleChanged", obj);
|
||||
}
|
||||
|
||||
void onZoomScaleChanged(double oldScale, double newScale) async {
|
||||
var obj = {
|
||||
"oldScale": oldScale,
|
||||
"newScale": newScale
|
||||
};
|
||||
|
||||
await _channel.invokeMethod("onZoomScaleChanged", obj);
|
||||
}
|
||||
}
|
||||
|
@ -43,38 +43,69 @@ 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);
|
||||
external set _nativeCommunication(Future<dynamic> Function(String method, int viewId, [List? args]) f);
|
||||
|
||||
/// Allows calling the assigned function from Dart as well.
|
||||
@JS()
|
||||
external void nativeCommunication();
|
||||
external Future<dynamic> nativeCommunication(String method, int viewId, [List? args]);
|
||||
|
||||
void _dartNativeCommunication(String method, int viewId, [List? args]) {
|
||||
Future<dynamic> _dartNativeCommunication(String method, int viewId, [List? args]) async {
|
||||
if (WebPlatformManager.webViews.containsKey(viewId)) {
|
||||
var webViewHtmlElement = WebPlatformManager.webViews[viewId] as InAppWebViewWebElement;
|
||||
switch (method) {
|
||||
case 'onLoadStart':
|
||||
String url = args![0] as String;
|
||||
var url = args![0] as String;
|
||||
webViewHtmlElement.onLoadStart(url);
|
||||
break;
|
||||
case 'onLoadStop':
|
||||
String url = args![0] as String;
|
||||
var url = args![0] as String;
|
||||
webViewHtmlElement.onLoadStop(url);
|
||||
break;
|
||||
case 'onUpdateVisitedHistory':
|
||||
String url = args![0] as String;
|
||||
var url = args![0] as String;
|
||||
webViewHtmlElement.onUpdateVisitedHistory(url);
|
||||
break;
|
||||
case 'onScrollChanged':
|
||||
int x = args![0] as int;
|
||||
int y = args[1] as int;
|
||||
var x = (args![0] as double).toInt();
|
||||
var y = (args[1] as double).toInt();
|
||||
webViewHtmlElement.onScrollChanged(x, y);
|
||||
break;
|
||||
case 'onConsoleMessage':
|
||||
String type = args![0] as String;
|
||||
String? message = args[1] as String?;
|
||||
var type = args![0] as String;
|
||||
var message = args[1] as String?;
|
||||
webViewHtmlElement.onConsoleMessage(type, message);
|
||||
break;
|
||||
case 'onCreateWindow':
|
||||
var windowId = args![0] as int;
|
||||
var url = args[1] as String? ?? 'about:blank';
|
||||
var target = args[2] as String?;
|
||||
var windowFeatures = args[3] as String?;
|
||||
return await webViewHtmlElement.onCreateWindow(windowId, url, target, windowFeatures);
|
||||
case 'onWindowFocus':
|
||||
webViewHtmlElement.onWindowFocus();
|
||||
break;
|
||||
case 'onWindowBlur':
|
||||
webViewHtmlElement.onWindowBlur();
|
||||
break;
|
||||
case 'onPrint':
|
||||
var url = args![0] as String?;
|
||||
webViewHtmlElement.onPrint(url);
|
||||
break;
|
||||
case 'onEnterFullscreen':
|
||||
webViewHtmlElement.onEnterFullscreen();
|
||||
break;
|
||||
case 'onExitFullscreen':
|
||||
webViewHtmlElement.onExitFullscreen();
|
||||
break;
|
||||
case 'onTitleChanged':
|
||||
var title = args![0] as String?;
|
||||
webViewHtmlElement.onTitleChanged(title);
|
||||
break;
|
||||
case 'onZoomScaleChanged':
|
||||
var oldScale = args![0] as double;
|
||||
var newScale = args[1] as double;
|
||||
webViewHtmlElement.onZoomScaleChanged(oldScale, newScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user