diff --git a/example/integration_test/in_app_webview/on_update_visited_history.dart b/example/integration_test/in_app_webview/on_update_visited_history.dart index ea6e0e1d..f228e6d5 100644 --- a/example/integration_test/in_app_webview/on_update_visited_history.dart +++ b/example/integration_test/in_app_webview/on_update_visited_history.dart @@ -65,10 +65,10 @@ setTimeout(function() { await firstPushCompleter.future; expect((await controller.getUrl())?.toString(), - '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}/first-push'); + '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}first-push'); await secondPushCompleter.future; expect((await controller.getUrl())?.toString(), - '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}/second-push'); + '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}second-push'); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_webview/programmatic_scroll.dart b/example/integration_test/in_app_webview/programmatic_scroll.dart index b5bc87a0..e26b0c52 100644 --- a/example/integration_test/in_app_webview/programmatic_scroll.dart +++ b/example/integration_test/in_app_webview/programmatic_scroll.dart @@ -77,16 +77,16 @@ void programmaticScroll() { final InAppWebViewController controller = await controllerCompleter.future; await pageLoaded.future; - await controller.scrollTo(x: 0, y: 0); - await tester.pumpAndSettle(Duration(seconds: 3)); + await tester.pump(); + + await controller.scrollTo(x: 0, y: 0); // Check scrollTo() const int X_SCROLL = 123; const int Y_SCROLL = 321; await controller.scrollTo(x: X_SCROLL, y: Y_SCROLL); - await tester.pumpAndSettle(Duration(seconds: 2)); int? scrollPosX = await controller.getScrollX(); int? scrollPosY = await controller.getScrollY(); expect(scrollPosX, X_SCROLL); @@ -94,7 +94,6 @@ void programmaticScroll() { // Check scrollBy() (on top of scrollTo()) await controller.scrollBy(x: X_SCROLL, y: Y_SCROLL); - await tester.pumpAndSettle(Duration(seconds: 2)); scrollPosX = await controller.getScrollX(); scrollPosY = await controller.getScrollY(); expect(scrollPosX, X_SCROLL * 2); diff --git a/example/integration_test/in_app_webview/reload.dart b/example/integration_test/in_app_webview/reload.dart index 7c622554..7029e878 100644 --- a/example/integration_test/in_app_webview/reload.dart +++ b/example/integration_test/in_app_webview/reload.dart @@ -26,7 +26,7 @@ void reload() { TargetPlatform.macOS, ].contains(defaultTargetPlatform); - testWidgets('reload from origin', (WidgetTester tester) async { + testWidgets('from origin', (WidgetTester tester) async { final Completer controllerCompleter = Completer<InAppWebViewController>(); final Completer<void> pageLoaded = Completer<void>(); diff --git a/example/integration_test/in_app_webview/web_message.dart b/example/integration_test/in_app_webview/web_message.dart index 0cd7a02a..83b957ff 100644 --- a/example/integration_test/in_app_webview/web_message.dart +++ b/example/integration_test/in_app_webview/web_message.dart @@ -111,11 +111,9 @@ void webMessage() { controllerCompleter.complete(controller); }, onConsoleMessage: (controller, consoleMessage) { - print(consoleMessage); webMessageCompleter.complete(consoleMessage.message); }, onLoadStop: (controller, url) async { - print(url); if (url.toString() == TEST_URL_EXAMPLE.toString()) { pageLoaded.complete(); } diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 11a59e7c..f821ac6e 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -1,5 +1,4 @@ import 'dart:collection'; -import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; @@ -169,6 +168,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> { this.url = url.toString(); urlController.text = this.url; }); + print("getContentHeight: " + (await controller.getContentHeight()).toString()); }, onLoadError: (controller, url, code, message) { pullToRefreshController?.endRefreshing(); @@ -216,7 +216,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> { ElevatedButton( child: Icon(Icons.refresh), onPressed: () { - webViewController?.reload(); + webViewController?.reloadFromOrigin(); }, ), ], diff --git a/lib/assets/web/web_support.js b/lib/assets/web/web_support.js index 96444d79..b291d828 100644 --- a/lib/assets/web/web_support.js +++ b/lib/assets/web/web_support.js @@ -500,7 +500,7 @@ window.flutter_inappwebview = { getScrollX: function() { var iframe = webView.iframe; try { - return Math.round(iframe.contentWindow.scrollX); + return iframe.contentWindow.scrollX; } catch (e) { console.log(e); } @@ -509,7 +509,7 @@ window.flutter_inappwebview = { getScrollY: function() { var iframe = webView.iframe; try { - return Math.round(iframe.contentWindow.scrollY); + return iframe.contentWindow.scrollY; } catch (e) { console.log(e); } diff --git a/lib/src/in_app_webview/android/in_app_webview_controller.dart b/lib/src/in_app_webview/android/in_app_webview_controller.dart index 227d6880..3f700e02 100644 --- a/lib/src/in_app_webview/android/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/android/in_app_webview_controller.dart @@ -3,122 +3,81 @@ import 'dart:core'; import 'package:flutter/services.dart'; import '../../types/main.dart'; -import '../../android/webview_feature.dart'; import '../in_app_webview_controller.dart'; -///Class mixin that contains only Android-specific methods for the WebView. -abstract class AndroidInAppWebViewControllerMixin { +///Use [InAppWebViewController] instead. +@Deprecated("Use InAppWebViewController instead") +class AndroidInAppWebViewController { late MethodChannel _channel; - ///Starts Safe Browsing initialization. - /// - ///URL loads are not guaranteed to be protected by Safe Browsing until after the this method returns true. - ///Safe Browsing is not fully supported on all devices. For those devices this method will returns false. - /// - ///This should not be called if Safe Browsing has been disabled by manifest tag or [AndroidInAppWebViewOptions.safeBrowsingEnabled]. - ///This prepares resources used for Safe Browsing. - /// - ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.START_SAFE_BROWSING]. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.startSafeBrowsing](https://developer.android.com/reference/android/webkit/WebView#startSafeBrowsing(android.content.Context,%20android.webkit.ValueCallback%3Cjava.lang.Boolean%3E))) + AndroidInAppWebViewController({required MethodChannel channel}) { + this._channel = channel; + } + + ///Use [InAppWebViewController.startSafeBrowsing] instead. + @Deprecated("Use InAppWebViewController.startSafeBrowsing instead") Future<bool> startSafeBrowsing() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('startSafeBrowsing', args); } - ///Clears the SSL preferences table stored in response to proceeding with SSL certificate errors. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.clearSslPreferences](https://developer.android.com/reference/android/webkit/WebView#clearSslPreferences())) + ///Use [InAppWebViewController.clearSslPreferences] instead. + @Deprecated("Use InAppWebViewController.clearSslPreferences instead") Future<void> clearSslPreferences() async { Map<String, dynamic> args = <String, dynamic>{}; await _channel.invokeMethod('clearSslPreferences', args); } - ///Does a best-effort attempt to pause any processing that can be paused safely, such as animations and geolocation. Note that this call does not pause JavaScript. - ///To pause JavaScript globally, use [InAppWebViewController.pauseTimers]. To resume WebView, call [resume]. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.onPause](https://developer.android.com/reference/android/webkit/WebView#onPause())) + ///Use [InAppWebViewController.pause] instead. + @Deprecated("Use InAppWebViewController.pause instead") Future<void> pause() async { Map<String, dynamic> args = <String, dynamic>{}; await _channel.invokeMethod('pause', args); } - ///Resumes a WebView after a previous call to [pause]. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.onResume](https://developer.android.com/reference/android/webkit/WebView#onResume())) + ///Use [InAppWebViewController.resume] instead. + @Deprecated("Use InAppWebViewController.resume instead") Future<void> resume() async { Map<String, dynamic> args = <String, dynamic>{}; await _channel.invokeMethod('resume', args); } - ///Scrolls the contents of this WebView down by half the page size. - ///Returns `true` if the page was scrolled. - /// - ///[bottom] `true` to jump to bottom of page. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.pageDown](https://developer.android.com/reference/android/webkit/WebView#pageDown(boolean))) + ///Use [InAppWebViewController.pageDown] instead. + @Deprecated("Use InAppWebViewController.pageDown instead") Future<bool> pageDown({required bool bottom}) async { Map<String, dynamic> args = <String, dynamic>{}; args.putIfAbsent("bottom", () => bottom); return await _channel.invokeMethod('pageDown', args); } - ///Scrolls the contents of this WebView up by half the view size. - ///Returns `true` if the page was scrolled. - /// - ///[top] `true` to jump to the top of the page. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.pageUp](https://developer.android.com/reference/android/webkit/WebView#pageUp(boolean))) + ///Use [InAppWebViewController.pageUp] instead. + @Deprecated("Use InAppWebViewController.pageUp instead") Future<bool> pageUp({required bool top}) async { Map<String, dynamic> args = <String, dynamic>{}; args.putIfAbsent("top", () => top); return await _channel.invokeMethod('pageUp', args); } - ///Performs zoom in in this WebView. - ///Returns `true` if zoom in succeeds, `false` if no zoom changes. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.zoomIn](https://developer.android.com/reference/android/webkit/WebView#zoomIn())) + ///Use [InAppWebViewController.zoomIn] instead. + @Deprecated("Use InAppWebViewController.zoomIn instead") Future<bool> zoomIn() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('zoomIn', args); } - ///Performs zoom out in this WebView. - ///Returns `true` if zoom out succeeds, `false` if no zoom changes. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.zoomOut](https://developer.android.com/reference/android/webkit/WebView#zoomOut())) + ///Use [InAppWebViewController.zoomOut] instead. + @Deprecated("Use InAppWebViewController.zoomOut instead") Future<bool> zoomOut() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('zoomOut', args); } - ///Clears the internal back/forward list. - /// - ///**Supported Platforms/Implementations**: - ///- Android native WebView ([Official API - WebView.clearHistory](https://developer.android.com/reference/android/webkit/WebView#clearHistory())) + ///Use [InAppWebViewController.clearHistory] instead. + @Deprecated("Use InAppWebViewController.clearHistory instead") Future<void> clearHistory() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('clearHistory', args); } -} - -///Use [InAppWebViewController] instead. -@Deprecated("Use InAppWebViewController instead") -class AndroidInAppWebViewController with AndroidInAppWebViewControllerMixin { - late MethodChannel _channel; - - AndroidInAppWebViewController({required MethodChannel channel}) { - this._channel = channel; - } ///Use [InAppWebViewController.clearClientCertPreferences] instead. @Deprecated("Use InAppWebViewController.clearClientCertPreferences instead") diff --git a/lib/src/in_app_webview/apple/in_app_webview_controller.dart b/lib/src/in_app_webview/apple/in_app_webview_controller.dart index 233250fe..e4949738 100644 --- a/lib/src/in_app_webview/apple/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/apple/in_app_webview_controller.dart @@ -6,120 +6,48 @@ import 'package:flutter/services.dart'; import '../../types/main.dart'; import '../in_app_webview_controller.dart'; -///Class mixin that contains only iOS-specific methods for the WebView. -abstract class AppleInAppWebViewControllerMixin { +///Use [InAppWebViewController] instead. +@Deprecated("Use InAppWebViewController instead") +class IOSInAppWebViewController { late MethodChannel _channel; + IOSInAppWebViewController({required MethodChannel channel}) { + this._channel = channel; + } - ///Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.reloadFromOrigin](https://developer.apple.com/documentation/webkit/wkwebview/1414956-reloadfromorigin)) + ///Use [InAppWebViewController.reloadFromOrigin] instead. + @Deprecated("Use InAppWebViewController.reloadFromOrigin instead") Future<void> reloadFromOrigin() async { Map<String, dynamic> args = <String, dynamic>{}; await _channel.invokeMethod('reloadFromOrigin', args); } - ///Generates PDF data from the web view’s contents asynchronously. - ///Returns `null` if a problem occurred. - /// - ///[pdfConfiguration] represents the object that specifies the portion of the web view to capture as PDF data. - /// - ///**NOTE**: available only on iOS 14.0+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.createPdf](https://developer.apple.com/documentation/webkit/wkwebview/3650490-createpdf)) + ///Use [InAppWebViewController.createPdf] instead. + @Deprecated("Use InAppWebViewController.createPdf instead") Future<Uint8List?> createPdf( {@Deprecated("Use pdfConfiguration instead") - // ignore: deprecated_member_use_from_same_package - IOSWKPDFConfiguration? iosWKPdfConfiguration, - PDFConfiguration? pdfConfiguration}) async { + // ignore: deprecated_member_use_from_same_package + IOSWKPDFConfiguration? iosWKPdfConfiguration, + PDFConfiguration? pdfConfiguration}) async { Map<String, dynamic> args = <String, dynamic>{}; args.putIfAbsent('pdfConfiguration', - () => pdfConfiguration?.toMap() ?? iosWKPdfConfiguration?.toMap()); + () => pdfConfiguration?.toMap() ?? iosWKPdfConfiguration?.toMap()); return await _channel.invokeMethod('createPdf', args); } - ///Creates a web archive of the web view’s current contents asynchronously. - ///Returns `null` if a problem occurred. - /// - ///**NOTE**: available only on iOS 14.0+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.createWebArchiveData](https://developer.apple.com/documentation/webkit/wkwebview/3650491-createwebarchivedata)) + ///Use [InAppWebViewController.createWebArchiveData] instead. + @Deprecated("Use InAppWebViewController.createWebArchiveData instead") Future<Uint8List?> createWebArchiveData() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('createWebArchiveData', args); } - ///A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.hasOnlySecureContent](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent)) + ///Use [InAppWebViewController.hasOnlySecureContent] instead. + @Deprecated("Use InAppWebViewController.hasOnlySecureContent instead") Future<bool> hasOnlySecureContent() async { Map<String, dynamic> args = <String, dynamic>{}; return await _channel.invokeMethod('hasOnlySecureContent', args); } - ///Pauses playback of all media in the web view. - /// - ///**NOTE for iOS**: available on iOS 15.0+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.pauseAllMediaPlayback](https://developer.apple.com/documentation/webkit/wkwebview/3752240-pauseallmediaplayback)). - Future<void> pauseAllMediaPlayback() async { - Map<String, dynamic> args = <String, dynamic>{}; - return await _channel.invokeMethod('pauseAllMediaPlayback', args); - } - - ///Changes whether the webpage is suspending playback of all media in the page. - ///Pass `true` to pause all media the web view is playing. Neither the user nor the webpage can resume playback until you call this method again with `false`. - /// - ///[suspended] represents a [bool] value that indicates whether the webpage should suspend media playback. - /// - ///**NOTE for iOS**: available on iOS 15.0+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.setAllMediaPlaybackSuspended](https://developer.apple.com/documentation/webkit/wkwebview/3752242-setallmediaplaybacksuspended)). - Future<void> setAllMediaPlaybackSuspended({required bool suspended}) async { - Map<String, dynamic> args = <String, dynamic>{}; - args.putIfAbsent("suspended", () => suspended); - return await _channel.invokeMethod('setAllMediaPlaybackSuspended', args); - } - - ///Closes all media the web view is presenting, including picture-in-picture video and fullscreen video. - /// - ///**NOTE for iOS**: available on iOS 14.5+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.closeAllMediaPresentations](https://developer.apple.com/documentation/webkit/wkwebview/3752235-closeallmediapresentations)). - Future<void> closeAllMediaPresentations() async { - Map<String, dynamic> args = <String, dynamic>{}; - return await _channel.invokeMethod('closeAllMediaPresentations', args); - } - - ///Requests the playback status of media in the web view. - ///Returns a [MediaPlaybackState] that indicates whether the media in the web view is playing, paused, or suspended. - ///If there’s no media in the web view to play, this method provides [MediaPlaybackState.NONE]. - /// - ///**NOTE for iOS**: available on iOS 15.0+. - /// - ///**Supported Platforms/Implementations**: - ///- iOS ([Official API - WKWebView.requestMediaPlaybackState](https://developer.apple.com/documentation/webkit/wkwebview/3752241-requestmediaplaybackstate)). - Future<MediaPlaybackState?> requestMediaPlaybackState() async { - Map<String, dynamic> args = <String, dynamic>{}; - return MediaPlaybackState.fromValue( - await _channel.invokeMethod('requestMediaPlaybackState', args)); - } -} - -///Use [InAppWebViewController] instead. -@Deprecated("Use InAppWebViewController instead") -class IOSInAppWebViewController with AppleInAppWebViewControllerMixin { - late MethodChannel _channel; - IOSInAppWebViewController({required MethodChannel channel}) { - this._channel = channel; - } - ///Use [InAppWebViewController.handlesURLScheme] instead. @Deprecated("Use InAppWebViewController.handlesURLScheme instead") static Future<bool> handlesURLScheme(String urlScheme) async { diff --git a/lib/src/in_app_webview/in_app_webview_controller.dart b/lib/src/in_app_webview/in_app_webview_controller.dart index f9b3f32f..3226c542 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -47,8 +47,7 @@ final _JAVASCRIPT_HANDLER_FORBIDDEN_NAMES = UnmodifiableListView<String>([ /// ///If you are using the [InAppWebView] widget, an [InAppWebViewController] instance can be obtained by setting the [InAppWebView.onWebViewCreated] ///callback. Instead, if you are using an [InAppBrowser] instance, you can get it through the [InAppBrowser.webViewController] attribute. -class InAppWebViewController - with AndroidInAppWebViewControllerMixin, AppleInAppWebViewControllerMixin { +class InAppWebViewController { WebView? _webview; late MethodChannel _channel; static MethodChannel _staticChannel = IN_APP_WEBVIEW_STATIC_CHANNEL; @@ -2198,7 +2197,15 @@ class InAppWebViewController ///- Web ([Official API - Document.documentElement.scrollHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight)) Future<int?> getContentHeight() async { Map<String, dynamic> args = <String, dynamic>{}; - return await _channel.invokeMethod('getContentHeight', args); + var height = await _channel.invokeMethod('getContentHeight', args); + if (height == null || height == 0) { + // try to use javascript + var scrollHeight = await evaluateJavascript(source: "document.documentElement.scrollHeight;"); + if (scrollHeight != null && scrollHeight is num) { + height = scrollHeight.toInt(); + } + } + return height; } ///Performs a zoom operation in this WebView. @@ -2984,6 +2991,207 @@ class InAppWebViewController return await _channel.invokeMethod('canScrollHorizontally', args); } + ///Starts Safe Browsing initialization. + /// + ///URL loads are not guaranteed to be protected by Safe Browsing until after the this method returns true. + ///Safe Browsing is not fully supported on all devices. For those devices this method will returns false. + /// + ///This should not be called if Safe Browsing has been disabled by manifest tag or [AndroidInAppWebViewOptions.safeBrowsingEnabled]. + ///This prepares resources used for Safe Browsing. + /// + ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.START_SAFE_BROWSING]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.startSafeBrowsing](https://developer.android.com/reference/android/webkit/WebView#startSafeBrowsing(android.content.Context,%20android.webkit.ValueCallback%3Cjava.lang.Boolean%3E))) + Future<bool> startSafeBrowsing() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('startSafeBrowsing', args); + } + + ///Clears the SSL preferences table stored in response to proceeding with SSL certificate errors. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.clearSslPreferences](https://developer.android.com/reference/android/webkit/WebView#clearSslPreferences())) + Future<void> clearSslPreferences() async { + Map<String, dynamic> args = <String, dynamic>{}; + await _channel.invokeMethod('clearSslPreferences', args); + } + + ///Does a best-effort attempt to pause any processing that can be paused safely, such as animations and geolocation. Note that this call does not pause JavaScript. + ///To pause JavaScript globally, use [InAppWebViewController.pauseTimers]. To resume WebView, call [resume]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.onPause](https://developer.android.com/reference/android/webkit/WebView#onPause())) + Future<void> pause() async { + Map<String, dynamic> args = <String, dynamic>{}; + await _channel.invokeMethod('pause', args); + } + + ///Resumes a WebView after a previous call to [pause]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.onResume](https://developer.android.com/reference/android/webkit/WebView#onResume())) + Future<void> resume() async { + Map<String, dynamic> args = <String, dynamic>{}; + await _channel.invokeMethod('resume', args); + } + + ///Scrolls the contents of this WebView down by half the page size. + ///Returns `true` if the page was scrolled. + /// + ///[bottom] `true` to jump to bottom of page. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.pageDown](https://developer.android.com/reference/android/webkit/WebView#pageDown(boolean))) + Future<bool> pageDown({required bool bottom}) async { + Map<String, dynamic> args = <String, dynamic>{}; + args.putIfAbsent("bottom", () => bottom); + return await _channel.invokeMethod('pageDown', args); + } + + ///Scrolls the contents of this WebView up by half the view size. + ///Returns `true` if the page was scrolled. + /// + ///[top] `true` to jump to the top of the page. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.pageUp](https://developer.android.com/reference/android/webkit/WebView#pageUp(boolean))) + Future<bool> pageUp({required bool top}) async { + Map<String, dynamic> args = <String, dynamic>{}; + args.putIfAbsent("top", () => top); + return await _channel.invokeMethod('pageUp', args); + } + + ///Performs zoom in in this WebView. + ///Returns `true` if zoom in succeeds, `false` if no zoom changes. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.zoomIn](https://developer.android.com/reference/android/webkit/WebView#zoomIn())) + Future<bool> zoomIn() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('zoomIn', args); + } + + ///Performs zoom out in this WebView. + ///Returns `true` if zoom out succeeds, `false` if no zoom changes. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.zoomOut](https://developer.android.com/reference/android/webkit/WebView#zoomOut())) + Future<bool> zoomOut() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('zoomOut', args); + } + + ///Clears the internal back/forward list. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView ([Official API - WebView.clearHistory](https://developer.android.com/reference/android/webkit/WebView#clearHistory())) + Future<void> clearHistory() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('clearHistory', args); + } + + ///Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.reloadFromOrigin](https://developer.apple.com/documentation/webkit/wkwebview/1414956-reloadfromorigin)) + Future<void> reloadFromOrigin() async { + Map<String, dynamic> args = <String, dynamic>{}; + await _channel.invokeMethod('reloadFromOrigin', args); + } + + ///Generates PDF data from the web view’s contents asynchronously. + ///Returns `null` if a problem occurred. + /// + ///[pdfConfiguration] represents the object that specifies the portion of the web view to capture as PDF data. + /// + ///**NOTE**: available only on iOS 14.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.createPdf](https://developer.apple.com/documentation/webkit/wkwebview/3650490-createpdf)) + Future<Uint8List?> createPdf( + {@Deprecated("Use pdfConfiguration instead") + // ignore: deprecated_member_use_from_same_package + IOSWKPDFConfiguration? iosWKPdfConfiguration, + PDFConfiguration? pdfConfiguration}) async { + Map<String, dynamic> args = <String, dynamic>{}; + args.putIfAbsent('pdfConfiguration', + () => pdfConfiguration?.toMap() ?? iosWKPdfConfiguration?.toMap()); + return await _channel.invokeMethod('createPdf', args); + } + + ///Creates a web archive of the web view’s current contents asynchronously. + ///Returns `null` if a problem occurred. + /// + ///**NOTE**: available only on iOS 14.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.createWebArchiveData](https://developer.apple.com/documentation/webkit/wkwebview/3650491-createwebarchivedata)) + Future<Uint8List?> createWebArchiveData() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('createWebArchiveData', args); + } + + ///A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.hasOnlySecureContent](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent)) + Future<bool> hasOnlySecureContent() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('hasOnlySecureContent', args); + } + + ///Pauses playback of all media in the web view. + /// + ///**NOTE for iOS**: available on iOS 15.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.pauseAllMediaPlayback](https://developer.apple.com/documentation/webkit/wkwebview/3752240-pauseallmediaplayback)). + Future<void> pauseAllMediaPlayback() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('pauseAllMediaPlayback', args); + } + + ///Changes whether the webpage is suspending playback of all media in the page. + ///Pass `true` to pause all media the web view is playing. Neither the user nor the webpage can resume playback until you call this method again with `false`. + /// + ///[suspended] represents a [bool] value that indicates whether the webpage should suspend media playback. + /// + ///**NOTE for iOS**: available on iOS 15.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.setAllMediaPlaybackSuspended](https://developer.apple.com/documentation/webkit/wkwebview/3752242-setallmediaplaybacksuspended)). + Future<void> setAllMediaPlaybackSuspended({required bool suspended}) async { + Map<String, dynamic> args = <String, dynamic>{}; + args.putIfAbsent("suspended", () => suspended); + return await _channel.invokeMethod('setAllMediaPlaybackSuspended', args); + } + + ///Closes all media the web view is presenting, including picture-in-picture video and fullscreen video. + /// + ///**NOTE for iOS**: available on iOS 14.5+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.closeAllMediaPresentations](https://developer.apple.com/documentation/webkit/wkwebview/3752235-closeallmediapresentations)). + Future<void> closeAllMediaPresentations() async { + Map<String, dynamic> args = <String, dynamic>{}; + return await _channel.invokeMethod('closeAllMediaPresentations', args); + } + + ///Requests the playback status of media in the web view. + ///Returns a [MediaPlaybackState] that indicates whether the media in the web view is playing, paused, or suspended. + ///If there’s no media in the web view to play, this method provides [MediaPlaybackState.NONE]. + /// + ///**NOTE for iOS**: available on iOS 15.0+. + /// + ///**Supported Platforms/Implementations**: + ///- iOS ([Official API - WKWebView.requestMediaPlaybackState](https://developer.apple.com/documentation/webkit/wkwebview/3752241-requestmediaplaybackstate)). + Future<MediaPlaybackState?> requestMediaPlaybackState() async { + Map<String, dynamic> args = <String, dynamic>{}; + return MediaPlaybackState.fromValue( + await _channel.invokeMethod('requestMediaPlaybackState', args)); + } + ///Returns the iframe `id` attribute used on the Web platform. /// ///**Supported Platforms/Implementations**: @@ -3108,7 +3316,7 @@ class InAppWebViewController return await _staticChannel.invokeMethod('handlesURLScheme', args); } - ///Gets the html (with javascript) of the Chromium's t-rex runner game. Used in combination with [getTRexRunnerCss]. + ///Gets the html (with javascript) of the Chromium's t-rex runner game. Used in combination with [tRexRunnerCss]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView @@ -3116,7 +3324,7 @@ class InAppWebViewController static Future<String> get tRexRunnerHtml async => await rootBundle.loadString( 'packages/flutter_inappwebview/assets/t_rex_runner/t-rex.html'); - ///Gets the css of the Chromium's t-rex runner game. Used in combination with [getTRexRunnerHtml]. + ///Gets the css of the Chromium's t-rex runner game. Used in combination with [tRexRunnerHtml]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView 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 90304bee..92d70591 100644 --- a/lib/src/web/in_app_web_view_web_element.dart +++ b/lib/src/web/in_app_web_view_web_element.dart @@ -322,7 +322,7 @@ class InAppWebViewWebElement { } Future<int?> getContentHeight() async { - return _callMethod('getContentHeight'); + return (_callMethod('getContentHeight') as num?)?.toInt(); } Future<String?> getOriginalUrl() async { @@ -334,11 +334,11 @@ class InAppWebViewWebElement { } Future<int?> getScrollX() async { - return _callMethod('getScrollX'); + return (_callMethod('getScrollX') as num?)?.toInt(); } Future<int?> getScrollY() async { - return _callMethod('getScrollY'); + return (_callMethod('getScrollY') as num?)?.toInt(); } Future<bool> isSecureContext() async {