From 2570cb38eb4eadb3043c16d85309af10d62650c1 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Fri, 22 Apr 2022 14:41:05 +0200 Subject: [PATCH] added onConsoleMessage and onScrollChanged web support --- example/web/page.html | 9 ++++- lib/assets/web/web_support.js | 40 ++++++++++++++++++++ lib/src/in_app_webview/webview.dart | 14 +++++-- lib/src/web/in_app_web_view_web_element.dart | 32 ++++++++++++++++ lib/src/web/web_platform.dart | 10 +++++ 5 files changed, 101 insertions(+), 4 deletions(-) diff --git a/example/web/page.html b/example/web/page.html index 86c5838e..5410bbfc 100644 --- a/example/web/page.html +++ b/example/web/page.html @@ -19,10 +19,17 @@ flutter_inappwebview_example - +

Simple Page 1

Go to page 2
Go to heavy-page + diff --git a/lib/assets/web/web_support.js b/lib/assets/web/web_support.js index f6b79352..1f393135 100644 --- a/lib/assets/web/web_support.js +++ b/lib/assets/web/web_support.js @@ -7,6 +7,34 @@ window.flutter_inappwebview = { if (iframe != null) { window.flutter_inappwebview.iframe = iframe; iframe.addEventListener('load', function (event) { + try { + var oldLogs = { + 'log': iframe.contentWindow.console.log, + 'debug': iframe.contentWindow.console.debug, + 'error': iframe.contentWindow.console.error, + 'info': iframe.contentWindow.console.info, + 'warn': iframe.contentWindow.console.warn + }; + for (var k in oldLogs) { + (function(oldLog) { + iframe.contentWindow.console[oldLog] = function() { + var message = ''; + for (var i in arguments) { + if (message == '') { + message += arguments[i]; + } else { + message += ' ' + arguments[i]; + } + } + oldLogs[oldLog].call(iframe.contentWindow.console, ...arguments); + window.flutter_inappwebview.nativeCommunication('onConsoleMessage', window.flutter_inappwebview.viewId, [oldLog, message]); + } + })(k); + } + } catch (e) { + console.log(e); + } + var url = iframe.src; try { url = iframe.contentWindow.location.href; @@ -51,6 +79,18 @@ window.flutter_inappwebview = { } catch (e) { console.log(e); } + + iframe.contentWindow.addEventListener('scroll', function (event) { + var x = 0; + var y = 0; + try { + x = iframe.contentWindow.scrollX; + y = iframe.contentWindow.scrollY; + } catch (e) { + console.log(e); + } + window.flutter_inappwebview.nativeCommunication('onScrollChanged', window.flutter_inappwebview.viewId, [x, y]); + }); }); } }, diff --git a/lib/src/in_app_webview/webview.dart b/lib/src/in_app_webview/webview.dart index 86a28188..c3ca4f9b 100644 --- a/lib/src/in_app_webview/webview.dart +++ b/lib/src/in_app_webview/webview.dart @@ -25,7 +25,7 @@ abstract class WebView { ///Event fired when the [WebView] starts to load an [url]. /// - ///**NOTE**: on Web it will be dispatched at the same time of [onLoadStop] event + ///**NOTE for Web**: it will be dispatched at the same time of [onLoadStop] event ///because there isn't any way to capture the real load start event from an iframe. /// ///**Supported Platforms/Implementations**: @@ -76,9 +76,12 @@ abstract class WebView { ///Event fired when the [WebView] receives a [ConsoleMessage]. /// + ///**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.onConsoleMessage](https://developer.android.com/reference/android/webkit/WebChromeClient#onConsoleMessage(android.webkit.ConsoleMessage))) ///- iOS + ///- Web final void Function( InAppWebViewController controller, ConsoleMessage consoleMessage)? onConsoleMessage; @@ -120,9 +123,12 @@ abstract class WebView { /// ///[y] represents the current vertical scroll origin in pixels. /// + ///**NOTE for Web**: this event will be called only if the iframe has the same origin. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.onScrollChanged](https://developer.android.com/reference/android/webkit/WebView#onScrollChanged(int,%20int,%20int,%20int))) ///- iOS ([Official API - UIScrollViewDelegate.scrollViewDidScroll](https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll)) + ///- Web ([Official API - Window.onscroll](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onscroll)) final void Function(InAppWebViewController controller, int x, int y)? onScrollChanged; @@ -164,10 +170,10 @@ abstract class WebView { /// ///**NOTE**: to allow JavaScript to open windows, you need to set [InAppWebViewSettings.javaScriptCanOpenWindowsAutomatically] option to `true`. /// - ///**NOTE**: on Android you need to set [InAppWebViewSettings.supportMultipleWindows] option to `true`. + ///**NOTE for Android**: you need to set [InAppWebViewSettings.supportMultipleWindows] option to `true`. ///Also, if the request has been created using JavaScript (`window.open()`), then there are some limitation: check the [NavigationAction] class. /// - ///**NOTE**: on iOS, setting these initial options: [InAppWebViewSettings.supportZoom], [InAppWebViewSettings.useOnLoadResource], [InAppWebViewSettings.useShouldInterceptAjaxRequest], + ///**NOTE for iOS**: setting these initial options: [InAppWebViewSettings.supportZoom], [InAppWebViewSettings.useOnLoadResource], [InAppWebViewSettings.useShouldInterceptAjaxRequest], ///[InAppWebViewSettings.useShouldInterceptFetchRequest], [InAppWebViewSettings.applicationNameForUserAgent], [InAppWebViewSettings.javaScriptCanOpenWindowsAutomatically], ///[InAppWebViewSettings.javaScriptEnabled], [InAppWebViewSettings.minimumFontSize], [InAppWebViewSettings.preferredContentMode], [InAppWebViewSettings.incognito], ///[InAppWebViewSettings.cacheEnabled], [InAppWebViewSettings.mediaPlaybackRequiresUserGesture], @@ -380,6 +386,8 @@ abstract class WebView { /// ///[isReload] indicates if this url is being reloaded. Available only on Android. /// + ///**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.doUpdateVisitedHistory](https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean))) ///- iOS diff --git a/lib/src/web/in_app_web_view_web_element.dart b/lib/src/web/in_app_web_view_web_element.dart index 02e697da..62170224 100644 --- a/lib/src/web/in_app_web_view_web_element.dart +++ b/lib/src/web/in_app_web_view_web_element.dart @@ -233,4 +233,36 @@ class InAppWebViewWebElement { }; _channel.invokeMethod("onUpdateVisitedHistory", obj); } + + onScrollChanged(int x, int y) async { + var obj = { + "x": x, + "y": y + }; + _channel.invokeMethod("onScrollChanged", obj); + } + + onConsoleMessage(String type, String? message) async { + int messageLevel = 1; + switch (type) { + case 'debug': + messageLevel = 0; + break; + case 'error': + messageLevel = 3; + break; + case 'warn': + messageLevel = 2; + break; + case 'info': + case 'log': + default: + messageLevel = 1; + } + var obj = { + "messageLevel": messageLevel, + "message": message + }; + _channel.invokeMethod("onConsoleMessage", obj); + } } diff --git a/lib/src/web/web_platform.dart b/lib/src/web/web_platform.dart index 54c656cf..245f3598 100644 --- a/lib/src/web/web_platform.dart +++ b/lib/src/web/web_platform.dart @@ -65,6 +65,16 @@ void _dartNativeCommunication(String method, int viewId, [List? args]) { String url = args![0] as String; webViewHtmlElement.onUpdateVisitedHistory(url); break; + case 'onScrollChanged': + int x = args![0] as int; + int y = args[1] as int; + webViewHtmlElement.onScrollChanged(x, y); + break; + case 'onConsoleMessage': + String type = args![0] as String; + String? message = args[1] as String?; + webViewHtmlElement.onConsoleMessage(type, message); + break; } } } \ No newline at end of file