diff --git a/.metadata b/.metadata index 14879c61..b0199f3a 100644 --- a/.metadata +++ b/.metadata @@ -1,10 +1,39 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: c860cba910319332564e1e9d470a17074c1f2dfd + revision: 18a827f3933c19f51862dde3fa472197683249d6 channel: stable project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 18a827f3933c19f51862dde3fa472197683249d6 + base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + - platform: android + create_revision: 18a827f3933c19f51862dde3fa472197683249d6 + base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + - platform: ios + create_revision: 18a827f3933c19f51862dde3fa472197683249d6 + base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + - platform: macos + create_revision: 18a827f3933c19f51862dde3fa472197683249d6 + base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + - platform: web + create_revision: 18a827f3933c19f51862dde3fa472197683249d6 + base_revision: 18a827f3933c19f51862dde3fa472197683249d6 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/CHANGELOG.md index 53ed632d..f9007b37 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 6.0.0-beta.3 + +- Added MacOS support +- Added `windowType`, `windowAlphaValue`, `windowStyleMask`, `windowTitlebarSeparatorStyle`, `windowFrame` for MacOS `InAppBrowserSettings` +- Added `PrintJobInfo.printer` +- Added `getContentWidth` WebView method + +### BREAKING CHANGES + +- Removed `PrintJobInfo.printerId` +- All `InAppWebViewSettings`, `InAppBrowserSettings` properties are optionals +- `InAppBrowser.webViewController` can be null + ## 6.0.0-beta.2 - Fixed web example @@ -33,6 +46,16 @@ - Removed `URLProtectionSpace.iosIsProxy` property - `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null` +## 5.5.0+3 + +- Fixed iOS `toolbarTopTintColor` InAppBrowser option +- Fixed iOS `InAppBrowserOptions.hideProgressBar` when getting options +- Fixed missing implementation `InAppBrowser.isHidden` method on Android and iOS +- Fixed "Attempt to invoke virtual method 'java.lang.String android.webkit.WebView.getUrl()' on a null object reference" [#1324](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1324) +- Fixed "(Crash) NullPointerException at in_app_browser.InAppBrowserActivity.close' on a null object reference" [#1278](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1278) +- Fixed "ios system version parser error" [#1355](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1355) +- Removed unnamed constructors for all Singleton classes to avoid incorrect usage + ## 5.5.0+2 - Fixed README diff --git a/README.md b/README.md index 18c2f84d..ad611f6e 100755 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Send a submission request to the [Submit App](https://inappwebview.dev/submit-ap - Flutter: ">=2.5.0" - Android: `minSdkVersion 19` and add support for `androidx` (see [AndroidX Migration](https://flutter.dev/docs/development/androidx-migration) to migrate an existing app) - iOS 9.0+: `--ios-language swift`, Xcode version `>= 14` +- MacOS 10.11+: Xcode version `>= 14` ## Installation diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserSettings.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserSettings.java index ff7ce54d..6e720949 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserSettings.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserSettings.java @@ -95,6 +95,7 @@ public class InAppBrowserSettings implements ISettings { @Override public Map getRealSettings(@NonNull InAppBrowserActivity inAppBrowserActivity) { Map realSettings = toMap(); + realSettings.put("hidden", inAppBrowserActivity.isHidden); realSettings.put("hideToolbarTop", inAppBrowserActivity.actionBar == null || !inAppBrowserActivity.actionBar.isShowing()); realSettings.put("hideUrlBar", inAppBrowserActivity.menu == null || !inAppBrowserActivity.menu.findItem(R.id.menu_search).isVisible()); realSettings.put("hideProgressBar", inAppBrowserActivity.progressBar == null || inAppBrowserActivity.progressBar.getMax() == 0); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PrintJobInfoExt.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PrintJobInfoExt.java index f2aafe6e..8c1305b0 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PrintJobInfoExt.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PrintJobInfoExt.java @@ -48,7 +48,9 @@ public class PrintJobInfoExt { obj.put("numberOfPages", numberOfPages); obj.put("creationTime", creationTime); obj.put("label", label); - obj.put("printerId", printerId); + Map printer = new HashMap<>(); + printer.put("id", printerId); + obj.put("printer", printer); obj.put("attributes", attributes != null ? attributes.toMap() : null); return obj; } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/InAppWebViewInterface.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/InAppWebViewInterface.java index 5c55642d..60bf917d 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/InAppWebViewInterface.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/InAppWebViewInterface.java @@ -69,6 +69,7 @@ public interface InAppWebViewInterface { String printCurrentPage(@Nullable PrintJobSettings settings); int getContentHeight(); void getContentHeight(ValueCallback callback); + void getContentWidth(ValueCallback callback); void zoomBy(float zoomFactor); String getOriginalUrl(); void getSelectedText(ValueCallback callback); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegate.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegate.java index 5dddfb13..b161a194 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegate.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegate.java @@ -263,6 +263,14 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl { result.notImplemented(); } break; + case isHidden: + if (webView != null && webView.getInAppBrowserDelegate() instanceof InAppBrowserActivity) { + InAppBrowserActivity inAppBrowserActivity = (InAppBrowserActivity) webView.getInAppBrowserDelegate(); + result.success(inAppBrowserActivity.isHidden); + } else { + result.notImplemented(); + } + break; case getCopyBackForwardList: result.success((webView != null) ? webView.getCopyBackForwardList() : null); break; @@ -370,6 +378,18 @@ public class WebViewChannelDelegate extends ChannelDelegateImpl { result.success(null); } break; + case getContentWidth: + if (webView instanceof InAppWebView) { + webView.getContentWidth(new ValueCallback() { + @Override + public void onReceiveValue(@Nullable Integer contentWidth) { + result.success(contentWidth); + } + }); + } else { + result.success(null); + } + break; case zoomBy: if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { double zoomFactor = (double) call.argument("zoomFactor"); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegateMethods.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegateMethods.java index 445667bd..d87954f6 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegateMethods.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/WebViewChannelDelegateMethods.java @@ -27,6 +27,7 @@ public enum WebViewChannelDelegateMethods { close, show, hide, + isHidden, getCopyBackForwardList, startSafeBrowsing, clearCache, @@ -46,6 +47,7 @@ public enum WebViewChannelDelegateMethods { resumeTimers, printCurrentPage, getContentHeight, + getContentWidth, zoomBy, getOriginalUrl, getZoomScale, diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebView.java index 881dc311..b7b022cc 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebView.java @@ -1910,6 +1910,19 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie callback.onReceiveValue(getContentHeight()); } + public void getContentWidth(final ValueCallback callback) { + evaluateJavascript("document.documentElement.scrollWidth;", new ValueCallback() { + @Override + public void onReceiveValue(@Nullable String value) { + Integer contentWidth = null; + if (value != null && !value.equalsIgnoreCase("null")) { + contentWidth = Integer.parseInt(value); + } + callback.onReceiveValue(contentWidth); + } + }); + } + @Override public void getHitTestResult(ValueCallback callback) { callback.onReceiveValue(com.pichillilorenzo.flutter_inappwebview.types.HitTestResult.fromWebViewHitTestResult(getHitTestResult())); diff --git a/build.yaml b/build.yaml new file mode 100644 index 00000000..e2b3acf3 --- /dev/null +++ b/build.yaml @@ -0,0 +1,5 @@ +targets: + $default: + sources: + exclude: + - example/**.dart diff --git a/dev_packages/flutter_inappwebview_internal_annotations/CHANGELOG.md b/dev_packages/flutter_inappwebview_internal_annotations/CHANGELOG.md index 35771889..a05f94be 100755 --- a/dev_packages/flutter_inappwebview_internal_annotations/CHANGELOG.md +++ b/dev_packages/flutter_inappwebview_internal_annotations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +- Added `ExchangeableObject.copyMethod`. + ## 1.0.0 Initial release. \ No newline at end of file diff --git a/dev_packages/flutter_inappwebview_internal_annotations/lib/src/exchangeable_object.dart b/dev_packages/flutter_inappwebview_internal_annotations/lib/src/exchangeable_object.dart index 6e1a9baf..1776e8fe 100644 --- a/dev_packages/flutter_inappwebview_internal_annotations/lib/src/exchangeable_object.dart +++ b/dev_packages/flutter_inappwebview_internal_annotations/lib/src/exchangeable_object.dart @@ -4,6 +4,7 @@ class ExchangeableObject { final bool fromMapFactory; final bool nullableFromMapFactory; final bool toStringMethod; + final bool copyMethod; const ExchangeableObject({ this.toMapMethod = true, @@ -11,5 +12,6 @@ class ExchangeableObject { this.fromMapFactory = true, this.nullableFromMapFactory = true, this.toStringMethod = true, + this.copyMethod = false }); } diff --git a/dev_packages/flutter_inappwebview_internal_annotations/pubspec.yaml b/dev_packages/flutter_inappwebview_internal_annotations/pubspec.yaml index c074d9a6..01aae9a6 100755 --- a/dev_packages/flutter_inappwebview_internal_annotations/pubspec.yaml +++ b/dev_packages/flutter_inappwebview_internal_annotations/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_inappwebview_internal_annotations description: Internal annotations used by the generator of flutter_inappwebview plugin -version: 1.0.0 +version: 1.1.0 homepage: https://github.com/pichillilorenzo/flutter_inappwebview environment: diff --git a/dev_packages/generators/lib/src/exchangeable_enum_generator.dart b/dev_packages/generators/lib/src/exchangeable_enum_generator.dart index 70724983..d5632d8d 100644 --- a/dev_packages/generators/lib/src/exchangeable_enum_generator.dart +++ b/dev_packages/generators/lib/src/exchangeable_enum_generator.dart @@ -284,7 +284,13 @@ class ExchangeableEnumGenerator if (annotation.read("bitwiseOrOperator").boolValue) { classBuffer.writeln( - "$extClassName operator |($extClassName value) => $extClassName._internal(value.toValue() | _value, value.toNativeValue() | _nativeValue);"); + "$extClassName operator |($extClassName value) => $extClassName._internal(value.toValue() | _value, "); + if (Util.typeIsNullable(enumNativeValue.type)) { + classBuffer.write("value.toNativeValue() != null && _nativeValue != null ? value.toNativeValue()! | _nativeValue! : _nativeValue"); + } else { + classBuffer.write("value.toNativeValue() | _nativeValue"); + } + classBuffer.write(");"); } if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") || diff --git a/dev_packages/generators/lib/src/exchangeable_object_generator.dart b/dev_packages/generators/lib/src/exchangeable_object_generator.dart index cbde4c7d..d0f0a8e3 100644 --- a/dev_packages/generators/lib/src/exchangeable_object_generator.dart +++ b/dev_packages/generators/lib/src/exchangeable_object_generator.dart @@ -443,6 +443,14 @@ class ExchangeableObjectGenerator classBuffer.writeln('}'); } + if (annotation.read("copyMethod").boolValue && (!visitor.methods.containsKey("copy") || + Util.methodHasIgnore(visitor.methods['copy']!))) { + classBuffer.writeln('///Returns a copy of $extClassName.'); + classBuffer.writeln('$extClassName copy() {'); + classBuffer.writeln('return $extClassName.fromMap(toMap()) ?? $extClassName();'); + classBuffer.writeln('}'); + } + if (annotation.read("toStringMethod").boolValue && (!visitor.methods.containsKey("toString") || Util.methodHasIgnore(visitor.methods['toString']!))) { classBuffer.writeln('@override'); diff --git a/dev_packages/generators/pubspec.lock b/dev_packages/generators/pubspec.lock index 3f1a113a..07f34add 100644 --- a/dev_packages/generators/pubspec.lock +++ b/dev_packages/generators/pubspec.lock @@ -187,7 +187,7 @@ packages: name: flutter_inappwebview_internal_annotations url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.0" frontend_server_client: dependency: transitive description: diff --git a/dev_packages/generators/pubspec.yaml b/dev_packages/generators/pubspec.yaml index 80b666dd..47509f8f 100755 --- a/dev_packages/generators/pubspec.yaml +++ b/dev_packages/generators/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: sdk: flutter build: ^2.3.1 source_gen: ^1.2.5 - flutter_inappwebview_internal_annotations: ^1.0.0 + flutter_inappwebview_internal_annotations: ^1.1.0 dev_dependencies: build_runner: ^2.2.1 diff --git a/example/integration_test/chrome_safari_browser/custom_menu_item.dart b/example/integration_test/chrome_safari_browser/custom_menu_item.dart index 0e6c3fe9..83c994a4 100644 --- a/example/integration_test/chrome_safari_browser/custom_menu_item.dart +++ b/example/integration_test/chrome_safari_browser/custom_menu_item.dart @@ -10,8 +10,7 @@ void customMenuItem() { ? true : ![ TargetPlatform.android, - TargetPlatform.iOS, - TargetPlatform.macOS, + TargetPlatform.iOS ].contains(defaultTargetPlatform); test('add custom menu item', () async { diff --git a/example/integration_test/chrome_safari_browser/main.dart b/example/integration_test/chrome_safari_browser/main.dart index 85dde745..a3cd7c44 100644 --- a/example/integration_test/chrome_safari_browser/main.dart +++ b/example/integration_test/chrome_safari_browser/main.dart @@ -8,7 +8,8 @@ import 'open_and_close.dart'; import 'trusted_web_activity.dart'; void main() { - const shouldSkip = kIsWeb; + final shouldSkip = + kIsWeb || [TargetPlatform.macOS].contains(defaultTargetPlatform); group('ChromeSafariBrowser', () { openAndClose(); diff --git a/example/integration_test/chrome_safari_browser/open_and_close.dart b/example/integration_test/chrome_safari_browser/open_and_close.dart index 6f4dba52..54898cca 100644 --- a/example/integration_test/chrome_safari_browser/open_and_close.dart +++ b/example/integration_test/chrome_safari_browser/open_and_close.dart @@ -10,8 +10,7 @@ void openAndClose() { ? true : ![ TargetPlatform.android, - TargetPlatform.iOS, - TargetPlatform.macOS, + TargetPlatform.iOS ].contains(defaultTargetPlatform); test('open and close', () async { diff --git a/example/integration_test/cookie_manager/set_get_delete.dart b/example/integration_test/cookie_manager/set_get_delete.dart index 6e804c34..badc3588 100644 --- a/example/integration_test/cookie_manager/set_get_delete.dart +++ b/example/integration_test/cookie_manager/set_get_delete.dart @@ -21,25 +21,40 @@ void setGetDelete() { final Completer controllerCompleter = Completer(); final Completer pageLoaded = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - initialSettings: InAppWebViewSettings( - clearCache: true, - ), - onLoadStop: (controller, url) { - pageLoaded.complete(url!.toString()); - }, - ), - ), + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, ); + if (defaultTargetPlatform == TargetPlatform.macOS) { + headlessWebView.onLoadStop = (controller, url) async { + pageLoaded.complete(url!.toString()); + }; + await headlessWebView.run(); + } else { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onLoadStop: (controller, url) { + pageLoaded.complete(url!.toString()); + }, + ), + ), + ); + } + final url = Uri.parse(await pageLoaded.future); await cookieManager.setCookie(url: url, name: "myCookie", value: "myValue"); @@ -57,5 +72,9 @@ void setGetDelete() { url: url, domain: ".${TEST_CROSS_PLATFORM_URL_1.host}"); cookies = await cookieManager.getCookies(url: url); expect(cookies, isEmpty); + + if (defaultTargetPlatform == TargetPlatform.macOS) { + headlessWebView.dispose(); + } }, skip: shouldSkip); } diff --git a/example/integration_test/find_interaction_controller/main.dart b/example/integration_test/find_interaction_controller/main.dart index ce8dc9d3..3ba56d80 100644 --- a/example/integration_test/find_interaction_controller/main.dart +++ b/example/integration_test/find_interaction_controller/main.dart @@ -4,7 +4,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'find_interactions.dart'; void main() { - final shouldSkip = kIsWeb; + final shouldSkip = + kIsWeb || [TargetPlatform.macOS].contains(defaultTargetPlatform); group('FindInteractionController', () { findInteractions(); diff --git a/example/integration_test/headless_in_app_webview/main.dart b/example/integration_test/headless_in_app_webview/main.dart index 8c9fa2cd..ce4f5d3f 100644 --- a/example/integration_test/headless_in_app_webview/main.dart +++ b/example/integration_test/headless_in_app_webview/main.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; -import '../in_app_webview/take_screenshot.dart'; +import 'take_screenshot.dart'; import 'custom_size.dart'; import 'run_and_dispose.dart'; import 'set_get_settings.dart'; diff --git a/example/integration_test/in_app_browser/hide_and_show.dart b/example/integration_test/in_app_browser/hide_and_show.dart new file mode 100644 index 00000000..1e1fa155 --- /dev/null +++ b/example/integration_test/in_app_browser/hide_and_show.dart @@ -0,0 +1,32 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void hideAndShow() { + final shouldSkip = kIsWeb + ? true + : ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('hide and show', () async { + var inAppBrowser = new MyInAppBrowser(); + await inAppBrowser.openUrlRequest( + urlRequest: URLRequest(url: TEST_URL_1), + settings: InAppBrowserClassSettings( + browserSettings: InAppBrowserSettings(hidden: true))); + await inAppBrowser.browserCreated.future; + await inAppBrowser.firstPageLoaded.future; + + expect(await inAppBrowser.isHidden(), true); + await expectLater(inAppBrowser.show(), completes); + expect(await inAppBrowser.isHidden(), false); + await expectLater(inAppBrowser.hide(), completes); + expect(await inAppBrowser.isHidden(), true); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_browser/main.dart b/example/integration_test/in_app_browser/main.dart index 13fc2bd1..4b20e930 100644 --- a/example/integration_test/in_app_browser/main.dart +++ b/example/integration_test/in_app_browser/main.dart @@ -5,6 +5,7 @@ import 'open_data_and_close.dart'; import 'open_file_and_close.dart'; import 'open_url_and_close.dart'; import 'set_get_settings.dart'; +import 'hide_and_show.dart'; void main() { final shouldSkip = kIsWeb; @@ -14,5 +15,6 @@ void main() { openFileAndClose(); openDataAndClose(); setGetSettings(); + hideAndShow(); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_browser/open_data_and_close.dart b/example/integration_test/in_app_browser/open_data_and_close.dart index 0fa26060..c36589cc 100644 --- a/example/integration_test/in_app_browser/open_data_and_close.dart +++ b/example/integration_test/in_app_browser/open_data_and_close.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -52,12 +51,12 @@ void openDataAndClose() { await inAppBrowser.firstPageLoaded.future; var controller = inAppBrowser.webViewController; - final String? url = (await controller.getUrl())?.toString(); + expect(controller, isNotNull); + final String? url = (await controller!.getUrl())?.toString(); expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); await inAppBrowser.close(); expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); + expect(inAppBrowser.webViewController, isNull); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_browser/open_file_and_close.dart b/example/integration_test/in_app_browser/open_file_and_close.dart index 92da4c7b..3a387b4e 100644 --- a/example/integration_test/in_app_browser/open_file_and_close.dart +++ b/example/integration_test/in_app_browser/open_file_and_close.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -34,12 +33,12 @@ void openFileAndClose() { await inAppBrowser.firstPageLoaded.future; var controller = inAppBrowser.webViewController; - final String? url = (await controller.getUrl())?.toString(); + expect(controller, isNotNull); + final String? url = (await controller!.getUrl())?.toString(); expect(url, endsWith("in_app_webview_initial_file_test.html")); await inAppBrowser.close(); expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); + expect(inAppBrowser.webViewController, isNull); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_browser/open_url_and_close.dart b/example/integration_test/in_app_browser/open_url_and_close.dart index 8f0659e5..57a3dd4d 100644 --- a/example/integration_test/in_app_browser/open_url_and_close.dart +++ b/example/integration_test/in_app_browser/open_url_and_close.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -33,12 +32,12 @@ void openUrlAndClose() { await inAppBrowser.firstPageLoaded.future; var controller = inAppBrowser.webViewController; - final String? url = (await controller.getUrl())?.toString(); + expect(controller, isNotNull); + final String? url = (await controller!.getUrl())?.toString(); expect(url, TEST_URL_1.toString()); await inAppBrowser.close(); expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); + expect(inAppBrowser.webViewController, isNull); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_localhost_server/load_asset_file.dart b/example/integration_test/in_app_localhost_server/load_asset_file.dart index 3f5cff73..6a7a7c9e 100644 --- a/example/integration_test/in_app_localhost_server/load_asset_file.dart +++ b/example/integration_test/in_app_localhost_server/load_asset_file.dart @@ -19,21 +19,38 @@ void loadAssetFile(InAppLocalhostServer localhostServer) { final Completer controllerCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: Uri.parse('http://localhost:8080/test_assets/index.html')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - ), - ), + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: URLRequest( + url: Uri.parse('http://localhost:8080/test_assets/index.html')), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, ); + + if (defaultTargetPlatform == TargetPlatform.macOS) { + await headlessWebView.run(); + } else { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: Uri.parse('http://localhost:8080/test_assets/index.html')), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ), + ), + ); + } final InAppWebViewController controller = await controllerCompleter.future; final String? currentUrl = (await controller.getUrl())?.toString(); expect(currentUrl, 'http://localhost:8080/test_assets/index.html'); + + if (defaultTargetPlatform == TargetPlatform.macOS) { + await headlessWebView.dispose(); + } }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_webview/main.dart b/example/integration_test/in_app_webview/main.dart index af64844e..31cfb5b0 100644 --- a/example/integration_test/in_app_webview/main.dart +++ b/example/integration_test/in_app_webview/main.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; import 'apple_pay_api.dart'; @@ -84,6 +85,8 @@ import 'web_message.dart'; import 'webview_windows.dart'; void main() { + final shouldSkip = [TargetPlatform.macOS].contains(defaultTargetPlatform); + group('InAppWebView', () { initialUrlRequest(); setGetSettings(); @@ -167,5 +170,5 @@ void main() { createPdf(); applePayAPI(); handlesURLScheme(); - }); + }, skip: shouldSkip); } diff --git a/example/lib/in_app_browser_example.screen.dart b/example/lib/in_app_browser_example.screen.dart index 37e87165..76da9d8d 100755 --- a/example/lib/in_app_browser_example.screen.dart +++ b/example/lib/in_app_browser_example.screen.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:collection'; import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; @@ -18,15 +19,19 @@ class MyInAppBrowser extends InAppBrowser { } @override - Future onLoadStart(url) async { - - } + Future onLoadStart(url) async {} @override Future onLoadStop(url) async { pullToRefreshController?.endRefreshing(); } + @override + Future onPermissionRequest(request) async { + return PermissionResponse( + resources: request.resources, action: PermissionResponseAction.GRANT); + } + @override void onLoadError(url, code, message) { pullToRefreshController?.endRefreshing(); @@ -61,26 +66,30 @@ class InAppBrowserExampleScreen extends StatefulWidget { } class _InAppBrowserExampleScreenState extends State { - late PullToRefreshController pullToRefreshController; + PullToRefreshController? pullToRefreshController; @override void initState() { super.initState(); - pullToRefreshController = PullToRefreshController( - settings: PullToRefreshSettings( - color: Colors.black, - ), - onRefresh: () async { - if (Platform.isAndroid) { - widget.browser.webViewController.reload(); - } else if (Platform.isIOS) { - widget.browser.webViewController.loadUrl( - urlRequest: URLRequest( - url: await widget.browser.webViewController.getUrl())); - } - }, - ); + pullToRefreshController = kIsWeb || + ![TargetPlatform.iOS, TargetPlatform.android] + .contains(defaultTargetPlatform) + ? null + : PullToRefreshController( + settings: PullToRefreshSettings( + color: Colors.black, + ), + onRefresh: () async { + if (Platform.isAndroid) { + widget.browser.webViewController?.reload(); + } else if (Platform.isIOS) { + widget.browser.webViewController?.loadUrl( + urlRequest: URLRequest( + url: await widget.browser.webViewController?.getUrl())); + } + }, + ); widget.browser.pullToRefreshController = pullToRefreshController; } @@ -103,9 +112,8 @@ class _InAppBrowserExampleScreenState extends State { URLRequest(url: Uri.parse("https://flutter.dev")), settings: InAppBrowserClassSettings( browserSettings: InAppBrowserSettings( - toolbarTopBackgroundColor: Colors.blue, - presentationStyle: ModalPresentationStyle.POPOVER - ), + toolbarTopBackgroundColor: Colors.blue, + presentationStyle: ModalPresentationStyle.POPOVER), webViewSettings: InAppWebViewSettings( useShouldOverrideUrlLoading: true, useOnLoadResource: true, diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 10586b29..ee37d50c 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -63,7 +63,7 @@ class _InAppWebViewExampleScreenState extends State { contextMenuItemClicked.title); }); - pullToRefreshController = kIsWeb + pullToRefreshController = kIsWeb || ![TargetPlatform.iOS, TargetPlatform.android].contains(defaultTargetPlatform) ? null : PullToRefreshController( settings: PullToRefreshSettings( diff --git a/example/lib/main.dart b/example/lib/main.dart index 8c7a1612..24450208 100755 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -33,26 +33,65 @@ Future main() async { } PointerInterceptor myDrawer({required BuildContext context}) { - final children = [ + var children = [ ListTile( title: Text('InAppWebView'), onTap: () { Navigator.pushReplacementNamed(context, '/'); }, - ) + ), + ListTile( + title: Text('InAppBrowser'), + onTap: () { + Navigator.pushReplacementNamed(context, '/InAppBrowser'); + }, + ), + ListTile( + title: Text('ChromeSafariBrowser'), + onTap: () { + Navigator.pushReplacementNamed(context, '/ChromeSafariBrowser'); + }, + ), + ListTile( + title: Text('WebAuthenticationSession'), + onTap: () { + Navigator.pushReplacementNamed(context, '/WebAuthenticationSession'); + }, + ), + ListTile( + title: Text('HeadlessInAppWebView'), + onTap: () { + Navigator.pushReplacementNamed(context, '/HeadlessInAppWebView'); + }, + ), ]; - if (!kIsWeb) { - children.addAll([ + if (kIsWeb) { + children = [ + ListTile( + title: Text('InAppWebView'), + onTap: () { + Navigator.pushReplacementNamed(context, '/'); + }, + ) + ]; + } else if (defaultTargetPlatform == TargetPlatform.macOS) { + children = [ + // ListTile( + // title: Text('InAppWebView'), + // onTap: () { + // Navigator.pushReplacementNamed(context, '/'); + // }, + // ), + // ListTile( + // title: Text('InAppBrowser'), + // onTap: () { + // Navigator.pushReplacementNamed(context, '/InAppBrowser'); + // }, + // ), ListTile( title: Text('InAppBrowser'), onTap: () { - Navigator.pushReplacementNamed(context, '/InAppBrowser'); - }, - ), - ListTile( - title: Text('ChromeSafariBrowser'), - onTap: () { - Navigator.pushReplacementNamed(context, '/ChromeSafariBrowser'); + Navigator.pushReplacementNamed(context, '/'); }, ), ListTile( @@ -67,7 +106,7 @@ PointerInterceptor myDrawer({required BuildContext context}) { Navigator.pushReplacementNamed(context, '/HeadlessInAppWebView'); }, ), - ]); + ]; } return PointerInterceptor( child: Drawer( @@ -110,6 +149,15 @@ class _MyAppState extends State { '/': (context) => InAppWebViewExampleScreen(), }); } + if (defaultTargetPlatform == TargetPlatform.macOS) { + return MaterialApp(initialRoute: '/', routes: { + // '/': (context) => InAppWebViewExampleScreen(), + // '/InAppBrowser': (context) => InAppBrowserExampleScreen(), + '/': (context) => InAppBrowserExampleScreen(), + '/HeadlessInAppWebView': (context) => HeadlessInAppWebViewExampleScreen(), + '/WebAuthenticationSession': (context) => WebAuthenticationSessionExampleScreen(), + }); + } return MaterialApp(initialRoute: '/', routes: { '/': (context) => InAppWebViewExampleScreen(), '/InAppBrowser': (context) => InAppBrowserExampleScreen(), diff --git a/example/lib/web_authentication_session_example.screen.dart b/example/lib/web_authentication_session_example.screen.dart index aaaec20b..541e5cc1 100755 --- a/example/lib/web_authentication_session_example.screen.dart +++ b/example/lib/web_authentication_session_example.screen.dart @@ -48,7 +48,8 @@ class _WebAuthenticationSessionExampleScreenState onPressed: () async { if (session == null && !kIsWeb && - defaultTargetPlatform == TargetPlatform.iOS && + [TargetPlatform.iOS, TargetPlatform.macOS] + .contains(defaultTargetPlatform) && await WebAuthenticationSession.isAvailable()) { session = await WebAuthenticationSession.create( url: Uri.parse( diff --git a/example/macos/.gitignore b/example/macos/.gitignore new file mode 100644 index 00000000..746adbb6 --- /dev/null +++ b/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/example/macos/Flutter/Flutter-Debug.xcconfig b/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 00000000..4b81f9b2 --- /dev/null +++ b/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/Flutter-Release.xcconfig b/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 00000000..5caa9d15 --- /dev/null +++ b/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 00000000..5d8a06dd --- /dev/null +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,16 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import flutter_inappwebview +import path_provider_macos +import url_launcher_macos + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) +} diff --git a/example/macos/Podfile b/example/macos/Podfile new file mode 100644 index 00000000..dade8dfa --- /dev/null +++ b/example/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.11' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..f53831be --- /dev/null +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,631 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 635B80423A5381B66E47F216 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A3C8BEF4D338BF1EDD832305 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* flutter_inappwebview_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = flutter_inappwebview_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 7D4269DF6E938B573DA3AB1B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + A3C8BEF4D338BF1EDD832305 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AC8274DF424C630859617712 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + B44881B5FC807BDF77BD81E9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 635B80423A5381B66E47F216 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + DE8EF0F1212CA8BCD731BA0F /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* flutter_inappwebview_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A3C8BEF4D338BF1EDD832305 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + DE8EF0F1212CA8BCD731BA0F /* Pods */ = { + isa = PBXGroup; + children = ( + AC8274DF424C630859617712 /* Pods-Runner.debug.xcconfig */, + 7D4269DF6E938B573DA3AB1B /* Pods-Runner.release.xcconfig */, + B44881B5FC807BDF77BD81E9 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 2233BC408EAD04A8B5721F92 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 7E9999C83038C5D12ED26B20 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* flutter_inappwebview_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2233BC408EAD04A8B5721F92 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 7E9999C83038C5D12ED26B20 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..958f17d6 --- /dev/null +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..21a3cc14 --- /dev/null +++ b/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/macos/Runner/AppDelegate.swift b/example/macos/Runner/AppDelegate.swift new file mode 100644 index 00000000..d53ef643 --- /dev/null +++ b/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..a2ec33f1 --- /dev/null +++ b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 00000000..82b6f9d9 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 00000000..13b35eba Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 00000000..0a3f5fa4 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 00000000..bdb57226 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 00000000..f083318e Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 00000000..326c0e72 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 00000000..2f1632cf Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/example/macos/Runner/Base.lproj/MainMenu.xib b/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 00000000..80e867a4 --- /dev/null +++ b/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/macos/Runner/Configs/AppInfo.xcconfig b/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 00000000..2165dd02 --- /dev/null +++ b/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = flutter_inappwebview_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutterInappwebviewExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 com.pichillilorenzo. All rights reserved. diff --git a/example/macos/Runner/Configs/Debug.xcconfig b/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 00000000..36b0fd94 --- /dev/null +++ b/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Release.xcconfig b/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 00000000..dff4f495 --- /dev/null +++ b/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Warnings.xcconfig b/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 00000000..42bcbf47 --- /dev/null +++ b/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 00000000..9f2a6f04 --- /dev/null +++ b/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,22 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.files.user-selected.read-write + + com.apple.security.network.client + + com.apple.security.network.server + + com.apple.security.print + + + diff --git a/example/macos/Runner/Info.plist b/example/macos/Runner/Info.plist new file mode 100644 index 00000000..4789daa6 --- /dev/null +++ b/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/example/macos/Runner/MainFlutterWindow.swift b/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 00000000..2722837e --- /dev/null +++ b/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/example/macos/Runner/Release.entitlements b/example/macos/Runner/Release.entitlements new file mode 100644 index 00000000..40c55dbc --- /dev/null +++ b/example/macos/Runner/Release.entitlements @@ -0,0 +1,20 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.files.user-selected.read-write + + com.apple.security.network.client + + com.apple.security.network.server + + com.apple.security.print + + + diff --git a/ios/Classes/InAppBrowser/InAppBrowserManager.swift b/ios/Classes/InAppBrowser/InAppBrowserManager.swift index 8d77a76a..ac621910 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserManager.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserManager.swift @@ -56,6 +56,7 @@ public class InAppBrowserManager: ChannelDelegate { let webViewController = InAppBrowserWebViewController() webViewController.browserSettings = browserSettings + webViewController.isHidden = browserSettings.hidden webViewController.webViewSettings = webViewSettings webViewController.previousStatusBarStyle = previousStatusBarStyle return webViewController @@ -110,7 +111,7 @@ public class InAppBrowserManager: ChannelDelegate { navController.tmpWindow = tmpWindow var animated = true - if let browserOptions = webViewController.browserSettings, browserOptions.hidden { + if let browserSettings = webViewController.browserSettings, browserSettings.hidden { tmpWindow.isHidden = true UIApplication.shared.delegate?.window??.makeKeyAndVisible() animated = false diff --git a/ios/Classes/InAppBrowser/InAppBrowserSettings.swift b/ios/Classes/InAppBrowser/InAppBrowserSettings.swift index ea265651..384acb4f 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserSettings.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserSettings.swift @@ -35,8 +35,9 @@ public class InAppBrowserSettings: ISettings { override func getRealSettings(obj: InAppBrowserWebViewController?) -> [String: Any?] { var realOptions: [String: Any?] = toMap() if let inAppBrowserWebViewController = obj { + realOptions["hidden"] = inAppBrowserWebViewController.isHidden realOptions["hideUrlBar"] = inAppBrowserWebViewController.searchBar.isHidden - realOptions["hideUrlBar"] = inAppBrowserWebViewController.progressBar.isHidden + realOptions["hideProgressBar"] = inAppBrowserWebViewController.progressBar.isHidden realOptions["closeButtonCaption"] = inAppBrowserWebViewController.closeButton.title realOptions["closeButtonColor"] = inAppBrowserWebViewController.closeButton.tintColor?.hexString if let navController = inAppBrowserWebViewController.navigationController { diff --git a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift index 2abbc95d..ab6d8c35 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift @@ -38,6 +38,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega var previousStatusBarStyle = -1 var initialUserScripts: [[String: Any]] = [] var pullToRefreshInitialSettings: [String: Any?] = [:] + var isHidden = false public override func loadView() { let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger()) @@ -254,7 +255,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega navigationController?.navigationBar.barTintColor = UIColor(hexString: barTintColor) } if let tintColor = browserOptions.toolbarTopTintColor, !tintColor.isEmpty { - navigationController?.navigationBar.barTintColor = UIColor(hexString: tintColor) + navigationController?.navigationBar.tintColor = UIColor(hexString: tintColor) } navigationController?.navigationBar.isTranslucent = browserOptions.toolbarTopTranslucent } @@ -363,6 +364,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega public func show(completion: (() -> Void)? = nil) { if let navController = navigationController as? InAppBrowserNavigationController, let window = navController.tmpWindow { + isHidden = false window.alpha = 0.0 window.isHidden = false window.makeKeyAndVisible() @@ -375,6 +377,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega public func hide(completion: (() -> Void)? = nil) { if let navController = navigationController as? InAppBrowserNavigationController, let window = navController.tmpWindow { + isHidden = true window.alpha = 1.0 UIView.animate(withDuration: 0.2) { window.alpha = 0.0 diff --git a/ios/Classes/InAppWebView/InAppWebView.swift b/ios/Classes/InAppWebView/InAppWebView.swift index b8c02f74..a9057d20 100755 --- a/ios/Classes/InAppWebView/InAppWebView.swift +++ b/ios/Classes/InAppWebView/InAppWebView.swift @@ -1562,8 +1562,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, } @available(iOS 15.0, *) - @available(macOS 12.0, *) - @available(macCatalyst 15.0, *) public func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, @@ -1605,8 +1603,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, } @available(iOS 15.0, *) - @available(macOS 12.0, *) - @available(macCatalyst 15.0, *) public func webView(_ webView: WKWebView, requestDeviceOrientationAndMotionPermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, @@ -2848,6 +2844,10 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { return Int64(scrollView.contentSize.height) } + public func getContentWidth() -> Int64 { + return Int64(scrollView.contentSize.width) + } + public func zoomBy(zoomFactor: Float, animated: Bool) { let currentZoomScale = scrollView.zoomScale scrollView.setZoomScale(currentZoomScale * CGFloat(zoomFactor), animated: animated) diff --git a/ios/Classes/InAppWebView/InAppWebViewSettings.swift b/ios/Classes/InAppWebView/InAppWebViewSettings.swift index c024626c..98c7dd74 100755 --- a/ios/Classes/InAppWebView/InAppWebViewSettings.swift +++ b/ios/Classes/InAppWebView/InAppWebViewSettings.swift @@ -119,7 +119,7 @@ public class InAppWebViewSettings: ISettings { } else { realSettings["mediaPlaybackRequiresUserGesture"] = configuration.mediaPlaybackRequiresUserAction } - realSettings["minimumFontSize"] = configuration.preferences.minimumFontSize + realSettings["minimumFontSize"] = Int(configuration.preferences.minimumFontSize) realSettings["suppressesIncrementalRendering"] = configuration.suppressesIncrementalRendering realSettings["allowsBackForwardNavigationGestures"] = webView.allowsBackForwardNavigationGestures realSettings["allowsInlineMediaPlayback"] = configuration.allowsInlineMediaPlayback diff --git a/ios/Classes/InAppWebView/WebViewChannelDelegate.swift b/ios/Classes/InAppWebView/WebViewChannelDelegate.swift index ed33c497..4b5e6cae 100644 --- a/ios/Classes/InAppWebView/WebViewChannelDelegate.swift +++ b/ios/Classes/InAppWebView/WebViewChannelDelegate.swift @@ -206,6 +206,13 @@ public class WebViewChannelDelegate : ChannelDelegate { result(FlutterMethodNotImplemented) } break + case .isHidden: + if let iabController = webView?.inAppBrowserDelegate as? InAppBrowserWebViewController { + result(iabController.isHidden) + } else { + result(FlutterMethodNotImplemented) + } + break case .getCopyBackForwardList: result(webView?.getCopyBackForwardList()) break @@ -290,6 +297,9 @@ public class WebViewChannelDelegate : ChannelDelegate { case .getContentHeight: result(webView?.getContentHeight()) break + case .getContentWidth: + result(webView?.getContentWidth()) + break case .zoomBy: let zoomFactor = (arguments!["zoomFactor"] as! NSNumber).floatValue let animated = arguments!["animated"] as! Bool @@ -572,8 +582,14 @@ public class WebViewChannelDelegate : ChannelDelegate { if let webView = self.webView, #available(iOS 14.5, *) { // closeAllMediaPresentations with completionHandler v15.0 makes the app crash // with error EXC_BAD_ACCESS, so use closeAllMediaPresentations v14.5 - webView.closeAllMediaPresentations() - result(true) + if #available(iOS 16.0, *) { + webView.closeAllMediaPresentations { + result(true) + } + } else { + webView.closeAllMediaPresentations() + result(true) + } } else { result(false) } diff --git a/ios/Classes/InAppWebView/WebViewChannelDelegateMethods.swift b/ios/Classes/InAppWebView/WebViewChannelDelegateMethods.swift index 658c096f..d9e99ad1 100644 --- a/ios/Classes/InAppWebView/WebViewChannelDelegateMethods.swift +++ b/ios/Classes/InAppWebView/WebViewChannelDelegateMethods.swift @@ -34,6 +34,7 @@ public enum WebViewChannelDelegateMethods: String { case close = "close" case show = "show" case hide = "hide" + case isHidden = "isHidden" case getCopyBackForwardList = "getCopyBackForwardList" @available(*, deprecated, message: "Use FindInteractionController.findAll instead.") case findAll = "findAll" @@ -48,6 +49,7 @@ public enum WebViewChannelDelegateMethods: String { case resumeTimers = "resumeTimers" case printCurrentPage = "printCurrentPage" case getContentHeight = "getContentHeight" + case getContentWidth = "getContentWidth" case zoomBy = "zoomBy" case reloadFromOrigin = "reloadFromOrigin" case getOriginalUrl = "getOriginalUrl" diff --git a/ios/Classes/PrintJob/PrintJobInfo.swift b/ios/Classes/PrintJob/PrintJobInfo.swift index 9eb8aba1..84a00261 100644 --- a/ios/Classes/PrintJob/PrintJobInfo.swift +++ b/ios/Classes/PrintJob/PrintJobInfo.swift @@ -37,7 +37,9 @@ public class PrintJobInfo : NSObject { "numberOfPages": numberOfPages, "creationTime": creationTime, "label": label, - "printerId": printerId + "printer": [ + "id": printerId + ] ] } } diff --git a/ios/Classes/Types/BaseCallbackResult.swift b/ios/Classes/Types/BaseCallbackResult.swift index f7edb4a5..a76caf72 100644 --- a/ios/Classes/Types/BaseCallbackResult.swift +++ b/ios/Classes/Types/BaseCallbackResult.swift @@ -1,8 +1,8 @@ // // BaseCallbackResult.swift -// flutter_inappwebview +// shared-apple // -// Created by Lorenzo Pichilli on 06/05/22. +// Created by Lorenzo Pichilli on 17/10/22. // import Foundation diff --git a/lib/src/android/proxy_controller.dart b/lib/src/android/proxy_controller.dart index ce0f438a..50d3210a 100644 --- a/lib/src/android/proxy_controller.dart +++ b/lib/src/android/proxy_controller.dart @@ -19,6 +19,8 @@ class ProxyController { static const MethodChannel _channel = const MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_proxycontroller'); + ProxyController._(); + ///Gets the [ProxyController] shared instance. /// ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.PROXY_OVERRIDE]. @@ -35,7 +37,7 @@ class ProxyController { print(e.stackTrace); } }); - _instance = ProxyController(); + _instance = ProxyController._(); return _instance!; } diff --git a/lib/src/android/service_worker_controller.dart b/lib/src/android/service_worker_controller.dart index 7b8cb042..8f180332 100644 --- a/lib/src/android/service_worker_controller.dart +++ b/lib/src/android/service_worker_controller.dart @@ -15,6 +15,8 @@ class ServiceWorkerController { static const MethodChannel _channel = const MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_serviceworkercontroller'); + ServiceWorkerController._(); + ///Gets the [ServiceWorkerController] shared instance. /// ///This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.SERVICE_WORKER_BASIC_USAGE]. @@ -47,7 +49,7 @@ class ServiceWorkerController { print(e.stackTrace); } }); - _instance = ServiceWorkerController(); + _instance = ServiceWorkerController._(); return _instance!; } diff --git a/lib/src/chrome_safari_browser/chrome_safari_browser.dart b/lib/src/chrome_safari_browser/chrome_safari_browser.dart index 643a0a92..c5082e3e 100755 --- a/lib/src/chrome_safari_browser/chrome_safari_browser.dart +++ b/lib/src/chrome_safari_browser/chrome_safari_browser.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:collection'; -import 'dart:developer' as developer; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -73,29 +72,12 @@ class ChromeSafariBrowser { } _debugLog(String method, dynamic args) { - if (ChromeSafariBrowser.debugLoggingSettings.enabled) { - for (var regExp - in ChromeSafariBrowser.debugLoggingSettings.excludeFilter) { - if (regExp.hasMatch(method)) return; - } - var maxLogMessageLength = - ChromeSafariBrowser.debugLoggingSettings.maxLogMessageLength; - String message = - "(${defaultTargetPlatform.name}) ChromeSafariBrowser ID " + - id + - " calling \"" + - method.toString() + - "\" using " + - args.toString(); - if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) { - message = message.substring(0, maxLogMessageLength) + "..."; - } - if (!ChromeSafariBrowser.debugLoggingSettings.usePrint) { - developer.log(message, name: this.runtimeType.toString()); - } else { - print("[${this.runtimeType.toString()}] $message"); - } - } + debugLog( + className: this.runtimeType.toString(), + id: id, + debugLoggingSettings: ChromeSafariBrowser.debugLoggingSettings, + method: method, + args: args); } Future _handleMethod(MethodCall call) async { diff --git a/lib/src/content_blocker.dart b/lib/src/content_blocker.dart index 9e6e448c..ae88732e 100755 --- a/lib/src/content_blocker.dart +++ b/lib/src/content_blocker.dart @@ -2,7 +2,7 @@ import 'types/main.dart'; ///Class that represents a set of rules to use block content in the browser window. /// -///On iOS, it uses [WKContentRuleListStore](https://developer.apple.com/documentation/webkit/wkcontentruleliststore). +///On iOS and MacOS, it uses [WKContentRuleListStore](https://developer.apple.com/documentation/webkit/wkcontentruleliststore). ///On Android, it uses a custom implementation because such functionality doesn't exist. /// ///In general, this [article](https://developer.apple.com/documentation/safariservices/creating_a_content_blocker) can be used to get an overview about this functionality @@ -27,6 +27,11 @@ class ContentBlocker { action: ContentBlockerAction.fromMap( Map.from(map["action"]!))); } + + @override + String toString() { + return 'ContentBlocker{trigger: $trigger, action: $action}'; + } } ///Trigger of the content blocker. The trigger tells to the WebView when to perform the corresponding action. @@ -39,40 +44,76 @@ class ContentBlockerTrigger { ///A list of regular expressions to match iframes URL against. /// - ///*NOTE*: available only on iOS. + ///**Supported Platforms/Implementations**: + ///- iOS + ///- MacOS List ifFrameUrl; ///A Boolean value. The default value is `false`. /// - ///*NOTE*: available only on iOS. + ///**Supported Platforms/Implementations**: + ///- iOS + ///- MacOS bool urlFilterIsCaseSensitive; ///A list of [ContentBlockerTriggerResourceType] representing the resource types (how the browser intends to use the resource) that the rule should match. ///If not specified, the rule matches all resource types. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List resourceType; ///A list of strings matched to a URL's domain; limits action to a list of specific domains. ///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.unlessDomain]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List ifDomain; ///A list of strings matched to a URL's domain; acts on any site except domains in a provided list. ///Values must be lowercase ASCII, or punycode for non-ASCII. Add * in front to match domain and subdomains. Can't be used with [ContentBlockerTrigger.ifDomain]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List unlessDomain; ///A list of [ContentBlockerTriggerLoadType] that can include one of two mutually exclusive values. If not specified, the rule matches all load types. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List loadType; ///A list of strings matched to the entire main document URL; limits the action to a specific list of URL patterns. ///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.unlessTopUrl]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List ifTopUrl; ///An array of strings matched to the entire main document URL; acts on any site except URL patterns in provided list. ///Values must be lowercase ASCII, or punycode for non-ASCII. Can't be used with [ContentBlockerTrigger.ifTopUrl]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS List unlessTopUrl; ///An array of strings that specify loading contexts. /// - ///*NOTE*: available only on iOS. + ///**Supported Platforms/Implementations**: + ///- iOS + ///- MacOS List loadContext; ContentBlockerTrigger( @@ -161,7 +202,7 @@ class ContentBlockerTrigger { return ContentBlockerTrigger( urlFilter: map["url-filter"], - ifFrameUrl: map["if-frame-url"], + ifFrameUrl: List.from(map["if-frame-url"] ?? []), urlFilterIsCaseSensitive: map["url-filter-is-case-sensitive"], ifDomain: List.from(map["if-domain"] ?? []), unlessDomain: List.from(map["unless-domain"] ?? []), @@ -171,6 +212,11 @@ class ContentBlockerTrigger { unlessTopUrl: List.from(map["unless-top-url"] ?? []), loadContext: loadContext); } + + @override + String toString() { + return 'ContentBlockerTrigger{urlFilter: $urlFilter, ifFrameUrl: $ifFrameUrl, urlFilterIsCaseSensitive: $urlFilterIsCaseSensitive, resourceType: $resourceType, ifDomain: $ifDomain, unlessDomain: $unlessDomain, loadType: $loadType, ifTopUrl: $ifTopUrl, unlessTopUrl: $unlessTopUrl, loadContext: $loadContext}'; + } } ///Action associated to the trigger. The action tells to the WebView what to do when the trigger is matched. @@ -213,4 +259,9 @@ class ContentBlockerAction { type: ContentBlockerActionType.fromNativeValue(map["type"])!, selector: map["selector"]); } + + @override + String toString() { + return 'ContentBlockerAction{type: $type, selector: $selector}'; + } } diff --git a/lib/src/cookie_manager.dart b/lib/src/cookie_manager.dart index f419c1a9..5d85d608 100755 --- a/lib/src/cookie_manager.dart +++ b/lib/src/cookie_manager.dart @@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'in_app_webview/in_app_webview_controller.dart'; -import 'in_app_webview/in_app_webview_settings.dart'; import 'in_app_webview/headless_in_app_webview.dart'; import 'platform_util.dart'; @@ -21,13 +20,15 @@ import 'types/main.dart'; ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS +///- MacOS ///- Web class CookieManager { static CookieManager? _instance; static const MethodChannel _channel = const MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_cookiemanager'); - ///Contains only iOS-specific methods of [CookieManager]. + CookieManager._(); + ///Use [CookieManager] instead. @Deprecated("Use CookieManager instead") late IOSCookieManager ios; @@ -46,7 +47,7 @@ class CookieManager { print(e.stackTrace); } }); - _instance = CookieManager(); + _instance = CookieManager._(); // ignore: deprecated_member_use_from_same_package _instance!.ios = IOSCookieManager.instance(); return _instance!; @@ -60,9 +61,9 @@ class CookieManager { ///The default value of [path] is `"/"`. /// ///[webViewController] could be used if you need to set a session-only cookie using JavaScript (so [isHttpOnly] cannot be set, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - ///on the current URL of the [WebView] managed by that controller when you need to target iOS below 11 and Web platform. In this case the [url] parameter is ignored. + ///on the current URL of the [WebView] managed by that controller when you need to target iOS below 11, MacOS below 10.13 and Web platform. In this case the [url] parameter is ignored. /// - ///**NOTE for iOS below 11.0**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] + ///**NOTE for iOS below 11.0 and MacOS below 10.13**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] ///to set the cookie (session-only cookie won't work! In that case, you should set also [expiresDate] or [maxAge]). /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. @@ -72,6 +73,7 @@ class CookieManager { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - CookieManager.setCookie](https://developer.android.com/reference/android/webkit/CookieManager#setCookie(java.lang.String,%20java.lang.String,%20android.webkit.ValueCallback%3Cjava.lang.Boolean%3E))) ///- iOS ([Official API - WKHTTPCookieStore.setCookie](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882007-setcookie)) + ///- MacOS ([Official API - WKHTTPCookieStore.setCookie](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882007-setcookie)) ///- Web Future setCookie( {required Uri url, @@ -94,27 +96,19 @@ class CookieManager { assert(value.isNotEmpty); assert(path.isNotEmpty); - if (defaultTargetPlatform == TargetPlatform.iOS || kIsWeb) { - var shouldUseJavascript = kIsWeb; - if (defaultTargetPlatform == TargetPlatform.iOS && !kIsWeb) { - var platformUtil = PlatformUtil.instance(); - var version = double.tryParse(await platformUtil.getSystemVersion()); - shouldUseJavascript = version != null && version < 11.0; - } - if (shouldUseJavascript) { - await _setCookieWithJavaScript( - url: url, - name: name, - value: value, - domain: domain, - path: path, - expiresDate: expiresDate, - maxAge: maxAge, - isSecure: isSecure, - sameSite: sameSite, - webViewController: webViewController); - return; - } + if (await _shouldUseJavascript()) { + await _setCookieWithJavaScript( + url: url, + name: name, + value: value, + domain: domain, + path: path, + expiresDate: expiresDate, + maxAge: maxAge, + isSecure: isSecure, + sameSite: sameSite, + webViewController: webViewController); + return; } Map args = {}; @@ -160,16 +154,17 @@ class CookieManager { cookieValue += ";"; if (webViewController != null) { - InAppWebViewSettings? settings = await webViewController.getSettings(); - if (settings != null && settings.javaScriptEnabled) { + final javaScriptEnabled = + (await webViewController.getSettings())?.javaScriptEnabled ?? false; + if (javaScriptEnabled) { await webViewController.evaluateJavascript( source: 'document.cookie="$cookieValue"'); return; } } - var setCookieCompleter = Completer(); - var headlessWebView = new HeadlessInAppWebView( + final setCookieCompleter = Completer(); + final headlessWebView = new HeadlessInAppWebView( initialUrlRequest: URLRequest(url: url), onLoadStop: (controller, url) async { await controller.evaluateJavascript( @@ -185,10 +180,10 @@ class CookieManager { ///Gets all the cookies for the given [url]. /// ///[webViewController] is used for getting the cookies (also session-only cookies) using JavaScript (cookies with `isHttpOnly` enabled cannot be found, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11 and Web platform. JavaScript must be enabled in order to work. + ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11, MacOS below 10.13 and Web platform. JavaScript must be enabled in order to work. ///In this case the [url] parameter is ignored. /// - ///**NOTE for iOS below 11.0**: All the cookies returned this way will have all the properties to `null` except for [Cookie.name] and [Cookie.value]. + ///**NOTE for iOS below 11.0 and MacOS below 10.13**: All the cookies returned this way will have all the properties to `null` except for [Cookie.name] and [Cookie.value]. ///If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] ///to get the cookies (session-only cookies and cookies with `isHttpOnly` enabled won't be found!). /// @@ -199,6 +194,7 @@ class CookieManager { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - CookieManager.getCookie](https://developer.android.com/reference/android/webkit/CookieManager#getCookie(java.lang.String))) ///- iOS ([Official API - WKHTTPCookieStore.getAllCookies](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882005-getallcookies)) + ///- MacOS ([Official API - WKHTTPCookieStore.getAllCookies](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882005-getallcookies)) ///- Web Future> getCookies( {required Uri url, @@ -209,17 +205,9 @@ class CookieManager { webViewController = webViewController ?? iosBelow11WebViewController; - if (defaultTargetPlatform == TargetPlatform.iOS || kIsWeb) { - var shouldUseJavascript = kIsWeb; - if (defaultTargetPlatform == TargetPlatform.iOS && !kIsWeb) { - var platformUtil = PlatformUtil.instance(); - var version = double.tryParse(await platformUtil.getSystemVersion()); - shouldUseJavascript = version != null && version < 11.0; - } - if (shouldUseJavascript) { - return await _getCookiesWithJavaScript( - url: url, webViewController: webViewController); - } + if (await _shouldUseJavascript()) { + return await _getCookiesWithJavaScript( + url: url, webViewController: webViewController); } List cookies = []; @@ -253,8 +241,9 @@ class CookieManager { List cookies = []; if (webViewController != null) { - InAppWebViewSettings? settings = await webViewController.getSettings(); - if (settings != null && settings.javaScriptEnabled) { + final javaScriptEnabled = + (await webViewController.getSettings())?.javaScriptEnabled ?? false; + if (javaScriptEnabled) { List documentCookies = (await webViewController .evaluateJavascript(source: 'document.cookie') as String) .split(';') @@ -273,8 +262,8 @@ class CookieManager { } } - var pageLoaded = Completer(); - var headlessWebView = new HeadlessInAppWebView( + final pageLoaded = Completer(); + final headlessWebView = new HeadlessInAppWebView( initialUrlRequest: URLRequest(url: url), onLoadStop: (controller, url) async { pageLoaded.complete(); @@ -304,10 +293,10 @@ class CookieManager { ///Gets a cookie by its [name] for the given [url]. /// ///[webViewController] is used for getting the cookie (also session-only cookie) using JavaScript (cookie with `isHttpOnly` enabled cannot be found, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11 and Web platform. JavaScript must be enabled in order to work. + ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11, MacOS below 10.13 and Web platform. JavaScript must be enabled in order to work. ///In this case the [url] parameter is ignored. /// - ///**NOTE for iOS below 11.0**: All the cookies returned this way will have all the properties to `null` except for [Cookie.name] and [Cookie.value]. + ///**NOTE for iOS below 11.0 and MacOS below 10.13**: All the cookies returned this way will have all the properties to `null` except for [Cookie.name] and [Cookie.value]. ///If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] ///to get the cookie (session-only cookie and cookie with `isHttpOnly` enabled won't be found!). /// @@ -318,6 +307,7 @@ class CookieManager { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future getCookie( {required Uri url, @@ -330,20 +320,12 @@ class CookieManager { webViewController = webViewController ?? iosBelow11WebViewController; - if (defaultTargetPlatform == TargetPlatform.iOS || kIsWeb) { - var shouldUseJavascript = kIsWeb; - if (defaultTargetPlatform == TargetPlatform.iOS && !kIsWeb) { - var platformUtil = PlatformUtil.instance(); - var version = double.tryParse(await platformUtil.getSystemVersion()); - shouldUseJavascript = version != null && version < 11.0; - } - if (shouldUseJavascript) { - List cookies = await _getCookiesWithJavaScript( - url: url, webViewController: webViewController); - return cookies - .cast() - .firstWhere((cookie) => cookie!.name == name, orElse: () => null); - } + if (await _shouldUseJavascript()) { + List cookies = await _getCookiesWithJavaScript( + url: url, webViewController: webViewController); + return cookies + .cast() + .firstWhere((cookie) => cookie!.name == name, orElse: () => null); } Map args = {}; @@ -373,10 +355,10 @@ class CookieManager { ///The default value of [path] is `"/"`. /// ///[webViewController] is used for deleting the cookie (also session-only cookie) using JavaScript (cookie with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11 and Web platform. JavaScript must be enabled in order to work. + ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11, MacOS below 10.13 and Web platform. JavaScript must be enabled in order to work. ///In this case the [url] parameter is ignored. /// - ///**NOTE for iOS below 11.0**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] + ///**NOTE for iOS below 11.0 and MacOS below 10.13**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] ///to delete the cookie (session-only cookie and cookie with `isHttpOnly` enabled won't be deleted!). /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. @@ -386,6 +368,7 @@ class CookieManager { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKHTTPCookieStore.delete](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882009-delete) + ///- MacOS ([Official API - WKHTTPCookieStore.delete](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882009-delete) ///- Web Future deleteCookie( {required Uri url, @@ -400,24 +383,16 @@ class CookieManager { webViewController = webViewController ?? iosBelow11WebViewController; - if (defaultTargetPlatform == TargetPlatform.iOS || kIsWeb) { - var shouldUseJavascript = kIsWeb; - if (defaultTargetPlatform == TargetPlatform.iOS && !kIsWeb) { - var platformUtil = PlatformUtil.instance(); - var version = double.tryParse(await platformUtil.getSystemVersion()); - shouldUseJavascript = version != null && version < 11.0; - } - if (shouldUseJavascript) { - await _setCookieWithJavaScript( - url: url, - name: name, - value: "", - path: path, - domain: domain, - maxAge: -1, - webViewController: webViewController); - return; - } + if (await _shouldUseJavascript()) { + await _setCookieWithJavaScript( + url: url, + name: name, + value: "", + path: path, + domain: domain, + maxAge: -1, + webViewController: webViewController); + return; } Map args = {}; @@ -433,10 +408,10 @@ class CookieManager { ///The default value of [path] is `"/"`. /// ///[webViewController] is used for deleting the cookies (also session-only cookies) using JavaScript (cookies with `isHttpOnly` enabled cannot be deleted, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11 and Web platform. JavaScript must be enabled in order to work. + ///from the current context of the [WebView] managed by that controller when you need to target iOS below 11, MacOS below 10.13 and Web platform. JavaScript must be enabled in order to work. ///In this case the [url] parameter is ignored. /// - ///**NOTE for iOS below 11.0**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] + ///**NOTE for iOS below 11.0 and MacOS below 10.13**: If [webViewController] is `null` or JavaScript is disabled for it, it will try to use a [HeadlessInAppWebView] ///to delete the cookies (session-only cookies and cookies with `isHttpOnly` enabled won't be deleted!). /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. @@ -446,6 +421,7 @@ class CookieManager { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future deleteCookies( {required Uri url, @@ -458,28 +434,20 @@ class CookieManager { webViewController = webViewController ?? iosBelow11WebViewController; - if (defaultTargetPlatform == TargetPlatform.iOS || kIsWeb) { - var shouldUseJavascript = kIsWeb; - if (defaultTargetPlatform == TargetPlatform.iOS && !kIsWeb) { - var platformUtil = PlatformUtil.instance(); - var version = double.tryParse(await platformUtil.getSystemVersion()); - shouldUseJavascript = version != null && version < 11.0; - } - if (shouldUseJavascript) { - List cookies = await _getCookiesWithJavaScript( - url: url, webViewController: webViewController); - for (var i = 0; i < cookies.length; i++) { - await _setCookieWithJavaScript( - url: url, - name: cookies[i].name, - value: "", - path: path, - domain: domain, - maxAge: -1, - webViewController: webViewController); - } - return; + if (await _shouldUseJavascript()) { + List cookies = await _getCookiesWithJavaScript( + url: url, webViewController: webViewController); + for (var i = 0; i < cookies.length; i++) { + await _setCookieWithJavaScript( + url: url, + name: cookies[i].name, + value: "", + path: path, + domain: domain, + maxAge: -1, + webViewController: webViewController); } + return; } Map args = {}; @@ -493,9 +461,12 @@ class CookieManager { /// ///**NOTE for iOS**: available from iOS 11.0+. /// + ///**NOTE for MacOS**: available from iOS 10.13+. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - CookieManager.removeAllCookies](https://developer.android.com/reference/android/webkit/CookieManager#removeAllCookies(android.webkit.ValueCallback%3Cjava.lang.Boolean%3E))) ///- iOS ([Official API - WKWebsiteDataStore.removeData](https://developer.apple.com/documentation/webkit/wkwebsitedatastore/1532938-removedata)) + ///- MacOS ([Official API - WKWebsiteDataStore.removeData](https://developer.apple.com/documentation/webkit/wkwebsitedatastore/1532938-removedata)) Future deleteAllCookies() async { Map args = {}; await _channel.invokeMethod('deleteAllCookies', args); @@ -503,10 +474,13 @@ class CookieManager { ///Fetches all stored cookies. /// - ///**NOTE**: available on iOS 11.0+. + ///**NOTE for iOS**: available on iOS 11.0+. + /// + ///**NOTE for MacOS**: available from iOS 10.13+. /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKHTTPCookieStore.getAllCookies](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882005-getallcookies)) + ///- MacOS ([Official API - WKHTTPCookieStore.getAllCookies](https://developer.apple.com/documentation/webkit/wkhttpcookiestore/2882005-getallcookies)) Future> getAllCookies() async { List cookies = []; @@ -542,6 +516,21 @@ class CookieManager { timezone: 'GMT') : await platformUtil.getWebCookieExpirationDate(date: dateTime); } + + Future _shouldUseJavascript() async { + if (kIsWeb) { + return true; + } + if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { + final platformUtil = PlatformUtil.instance(); + final systemVersion = await platformUtil.getSystemVersion(); + return defaultTargetPlatform == TargetPlatform.iOS + ? systemVersion.compareTo("11") == -1 + : systemVersion.compareTo("10.13") == -1; + } + return false; + } } ///Class that contains only iOS-specific methods of [CookieManager]. @@ -555,8 +544,10 @@ class IOSCookieManager { return (_instance != null) ? _instance! : _init(); } + IOSCookieManager._(); + static IOSCookieManager _init() { - _instance = IOSCookieManager(); + _instance = IOSCookieManager._(); return _instance!; } diff --git a/lib/src/find_interaction/find_interaction_controller.dart b/lib/src/find_interaction/find_interaction_controller.dart index b63fe7a5..a28366a7 100644 --- a/lib/src/find_interaction/find_interaction_controller.dart +++ b/lib/src/find_interaction/find_interaction_controller.dart @@ -1,14 +1,13 @@ -import 'dart:developer' as developer; - -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import '../in_app_webview/in_app_webview_settings.dart'; import '../debug_logging_settings.dart'; import '../types/main.dart'; +import '../util.dart'; ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS +///- MacOS class FindInteractionController { MethodChannel? _channel; @@ -29,6 +28,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.FindListener.onFindResultReceived](https://developer.android.com/reference/android/webkit/WebView.FindListener#onFindResultReceived(int,%20int,%20boolean))) ///- iOS + ///- MacOS final void Function( FindInteractionController controller, int activeMatchOrdinal, @@ -52,28 +52,11 @@ class FindInteractionController { } _debugLog(String method, dynamic args) { - if (FindInteractionController.debugLoggingSettings.enabled) { - for (var regExp - in FindInteractionController.debugLoggingSettings.excludeFilter) { - if (regExp.hasMatch(method)) return; - } - var maxLogMessageLength = - FindInteractionController.debugLoggingSettings.maxLogMessageLength; - String message = - "(${defaultTargetPlatform.name}) FindInteractionController " + - " calling \"" + - method.toString() + - "\" using " + - args.toString(); - if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) { - message = message.substring(0, maxLogMessageLength) + "..."; - } - if (!FindInteractionController.debugLoggingSettings.usePrint) { - developer.log(message, name: this.runtimeType.toString()); - } else { - print("[${this.runtimeType.toString()}] $message"); - } - } + debugLog( + className: this.runtimeType.toString(), + debugLoggingSettings: FindInteractionController.debugLoggingSettings, + method: method, + args: args); } Future _handleMethod(MethodCall call) async { @@ -108,6 +91,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.findAllAsync](https://developer.android.com/reference/android/webkit/WebView#findAllAsync(java.lang.String))) ///- iOS (if [InAppWebViewSettings.isFindInteractionEnabled] is `true`: [Official API - UIFindInteraction.presentFindNavigator](https://developer.apple.com/documentation/uikit/uifindinteraction/3975832-presentfindnavigator?changes=_2) with [Official API - UIFindInteraction.searchText](https://developer.apple.com/documentation/uikit/uifindinteraction/3975834-searchtext?changes=_2)) + ///- MacOS Future findAll({String? find}) async { Map args = {}; args.putIfAbsent('find', () => find); @@ -125,6 +109,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.findNext](https://developer.android.com/reference/android/webkit/WebView#findNext(boolean))) ///- iOS (if [InAppWebViewSettings.isFindInteractionEnabled] is `true`: [Official API - UIFindInteraction.findNext](https://developer.apple.com/documentation/uikit/uifindinteraction/3975829-findnext?changes=_2) and ([Official API - UIFindInteraction.findPrevious](https://developer.apple.com/documentation/uikit/uifindinteraction/3975830-findprevious?changes=_2))) + ///- MacOS Future findNext({bool forward = true}) async { Map args = {}; args.putIfAbsent('forward', () => forward); @@ -140,6 +125,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.clearMatches](https://developer.android.com/reference/android/webkit/WebView#clearMatches())) ///- iOS (if [InAppWebViewSettings.isFindInteractionEnabled] is `true`: [Official API - UIFindInteraction.dismissFindNavigator](https://developer.apple.com/documentation/uikit/uifindinteraction/3975827-dismissfindnavigator?changes=_2)) + ///- MacOS Future clearMatches() async { Map args = {}; await _channel?.invokeMethod('clearMatches', args); @@ -153,6 +139,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - UIFindInteraction.searchText](https://developer.apple.com/documentation/uikit/uifindinteraction/3975834-searchtext?changes=_2)) + ///- MacOS Future setSearchText(String? searchText) async { Map args = {}; args.putIfAbsent('searchText', () => searchText); @@ -167,6 +154,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - UIFindInteraction.searchText](https://developer.apple.com/documentation/uikit/uifindinteraction/3975834-searchtext?changes=_2)) + ///- MacOS Future getSearchText() async { Map args = {}; return await _channel?.invokeMethod('getSearchText', args); @@ -221,6 +209,7 @@ class FindInteractionController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - UIFindInteraction.activeFindSession](https://developer.apple.com/documentation/uikit/uifindinteraction/3975825-activefindsession?changes=_7____4_8&language=objc)) + ///- MacOS Future getActiveFindSession() async { Map args = {}; Map? result = diff --git a/lib/src/http_auth_credentials_database.dart b/lib/src/http_auth_credentials_database.dart index 2650eb53..8baa1368 100755 --- a/lib/src/http_auth_credentials_database.dart +++ b/lib/src/http_auth_credentials_database.dart @@ -4,7 +4,7 @@ import 'types/main.dart'; import 'package:flutter/services.dart'; ///Class that implements a singleton object (shared instance) which manages the shared HTTP auth credentials cache. -///On iOS, this class uses the [URLCredentialStorage](https://developer.apple.com/documentation/foundation/urlcredentialstorage) class. +///On iOS and MacOS, this class uses the [URLCredentialStorage](https://developer.apple.com/documentation/foundation/urlcredentialstorage) class. ///On Android, this class has a custom implementation using `android.database.sqlite.SQLiteDatabase` because ///[WebViewDatabase](https://developer.android.com/reference/android/webkit/WebViewDatabase) ///doesn't offer the same functionalities as iOS `URLCredentialStorage`. @@ -12,11 +12,14 @@ import 'package:flutter/services.dart'; ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS +///- MacOS class HttpAuthCredentialDatabase { static HttpAuthCredentialDatabase? _instance; static const MethodChannel _channel = const MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_credential_database'); + HttpAuthCredentialDatabase._(); + ///Gets the database shared instance. static HttpAuthCredentialDatabase instance() { return (_instance != null) ? _instance! : _init(); @@ -31,7 +34,7 @@ class HttpAuthCredentialDatabase { print(e.stackTrace); } }); - _instance = HttpAuthCredentialDatabase(); + _instance = HttpAuthCredentialDatabase._(); return _instance!; } @@ -44,6 +47,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - URLCredentialStorage.allCredentials](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1413859-allcredentials)) + ///- MacOS ([Official API - URLCredentialStorage.allCredentials](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1413859-allcredentials)) Future> getAllAuthCredentials() async { Map args = {}; @@ -67,6 +71,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future> getHttpAuthCredentials( {required URLProtectionSpace protectionSpace}) async { Map args = {}; @@ -91,6 +96,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - URLCredentialStorage.set](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1407227-set)) + ///- MacOS ([Official API - URLCredentialStorage.set](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1407227-set)) Future setHttpAuthCredential( {required URLProtectionSpace protectionSpace, required URLCredential credential}) async { @@ -109,6 +115,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - URLCredentialStorage.remove](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1408664-remove)) + ///- MacOS ([Official API - URLCredentialStorage.remove](https://developer.apple.com/documentation/foundation/urlcredentialstorage/1408664-remove)) Future removeHttpAuthCredential( {required URLProtectionSpace protectionSpace, required URLCredential credential}) async { @@ -127,6 +134,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future removeHttpAuthCredentials( {required URLProtectionSpace protectionSpace}) async { Map args = {}; @@ -142,6 +150,7 @@ class HttpAuthCredentialDatabase { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future clearAllAuthCredentials() async { Map args = {}; await _channel.invokeMethod('clearAllAuthCredentials', args); diff --git a/lib/src/in_app_browser/in_app_browser.dart b/lib/src/in_app_browser/in_app_browser.dart index 8084ed82..516645ca 100755 --- a/lib/src/in_app_browser/in_app_browser.dart +++ b/lib/src/in_app_browser/in_app_browser.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:collection'; -import 'dart:developer' as developer; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import '../context_menu.dart'; @@ -48,6 +46,7 @@ class InAppBrowserNotOpenedException implements Exception { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS +///- MacOS class InAppBrowser { ///Debug settings. static DebugLoggingSettings debugLoggingSettings = DebugLoggingSettings(); @@ -72,8 +71,13 @@ class InAppBrowser { static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_inappbrowser'); - /// WebView Controller that can be used to access the [InAppWebViewController] API. - late final InAppWebViewController webViewController; + late final InAppWebViewController _webViewController; + + ///WebView Controller that can be used to access the [InAppWebViewController] API. + ///When [onExit] is fired, this will be `null` and cannot be used anymore. + InAppWebViewController? get webViewController { + return _isOpened ? _webViewController : null; + } ///The window id of a [CreateWindowAction.windowId]. final int? windowId; @@ -98,32 +102,17 @@ class InAppBrowser { } }); _isOpened = false; - webViewController = new InAppWebViewController.fromInAppBrowser( + _webViewController = new InAppWebViewController.fromInAppBrowser( this._channel, this, this.initialUserScripts); } _debugLog(String method, dynamic args) { - if (InAppBrowser.debugLoggingSettings.enabled) { - for (var regExp in InAppBrowser.debugLoggingSettings.excludeFilter) { - if (regExp.hasMatch(method)) return; - } - var maxLogMessageLength = - InAppBrowser.debugLoggingSettings.maxLogMessageLength; - String message = "(${defaultTargetPlatform.name}) InAppBrowser ID " + - id + - " calling \"" + - method.toString() + - "\" using " + - args.toString(); - if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) { - message = message.substring(0, maxLogMessageLength) + "..."; - } - if (!InAppBrowser.debugLoggingSettings.usePrint) { - developer.log(message, name: this.runtimeType.toString()); - } else { - print("[${this.runtimeType.toString()}] $message"); - } - } + debugLog( + className: this.runtimeType.toString(), + id: id, + debugLoggingSettings: InAppBrowser.debugLoggingSettings, + method: method, + args: args); } Future _handleMethod(MethodCall call) async { @@ -141,7 +130,7 @@ class InAppBrowser { onExit(); break; default: - return webViewController.handleMethod(call); + return _webViewController.handleMethod(call); } } @@ -152,6 +141,11 @@ class InAppBrowser { ///[options]: Options for the [InAppBrowser]. /// ///[settings]: Settings for the [InAppBrowser]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future openUrlRequest( {required URLRequest urlRequest, // ignore: deprecated_member_use_from_same_package @@ -220,6 +214,11 @@ class InAppBrowser { ///[options]: Options for the [InAppBrowser]. /// ///[settings]: Settings for the [InAppBrowser]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future openFile( {required String assetFilePath, // ignore: deprecated_member_use_from_same_package @@ -262,6 +261,11 @@ class InAppBrowser { ///The [options] parameter specifies the options for the [InAppBrowser]. /// ///[settings]: Settings for the [InAppBrowser]. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future openData( {required String data, String mimeType = "text/html", @@ -303,6 +307,11 @@ class InAppBrowser { } ///This is a static method that opens an [url] in the system browser. You wont be able to use the [InAppBrowser] methods here! + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS static Future openWithSystemBrowser({required Uri url}) async { assert(url.toString().isNotEmpty); Map args = {}; @@ -311,6 +320,11 @@ class InAppBrowser { } ///Displays an [InAppBrowser] window that was opened hidden. Calling this has no effect if the [InAppBrowser] was already visible. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future show() async { this.throwIfNotOpened(); Map args = {}; @@ -318,6 +332,11 @@ class InAppBrowser { } ///Hides the [InAppBrowser] window. Calling this has no effect if the [InAppBrowser] was already hidden. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future hide() async { this.throwIfNotOpened(); Map args = {}; @@ -325,6 +344,11 @@ class InAppBrowser { } ///Closes the [InAppBrowser] window. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future close() async { this.throwIfNotOpened(); Map args = {}; @@ -332,6 +356,11 @@ class InAppBrowser { } ///Check if the Web View of the [InAppBrowser] instance is hidden. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future isHidden() async { this.throwIfNotOpened(); Map args = {}; @@ -365,6 +394,11 @@ class InAppBrowser { } ///Sets the [InAppBrowser] settings with the new [settings] and evaluates them. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future setSettings( {required InAppBrowserClassSettings settings}) async { this.throwIfNotOpened(); @@ -375,6 +409,11 @@ class InAppBrowser { } ///Gets the current [InAppBrowser] settings. Returns `null` if it wasn't able to get them. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS Future getSettings() async { this.throwIfNotOpened(); Map args = {}; @@ -391,14 +430,29 @@ class InAppBrowser { } ///Returns `true` if the [InAppBrowser] instance is opened, otherwise `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS bool isOpened() { return this._isOpened; } ///Event fired when the [InAppBrowser] is created. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS void onBrowserCreated() {} ///Event fired when the [InAppBrowser] window is closed. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS void onExit() {} ///Event fired when the [InAppBrowser] starts to load an [url]. @@ -406,6 +460,7 @@ class InAppBrowser { ///**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))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview)) void onLoadStart(Uri? url) {} ///Event fired when the [InAppBrowser] finishes loading an [url]. @@ -413,6 +468,7 @@ class InAppBrowser { ///**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))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview)) void onLoadStop(Uri? url) {} ///Use [onReceivedError] instead. @@ -424,6 +480,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onReceivedError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceError))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview)) void onReceivedError(WebResourceRequest request, WebResourceError error) {} ///Use [onReceivedHttpError] instead. @@ -441,6 +498,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onReceivedHttpError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview)) void onReceivedHttpError( WebResourceRequest request, WebResourceResponse errorResponse) {} @@ -449,6 +507,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onProgressChanged](https://developer.android.com/reference/android/webkit/WebChromeClient#onProgressChanged(android.webkit.WebView,%20int))) ///- iOS + ///- MacOS void onProgressChanged(int progress) {} ///Event fired when the [InAppBrowser] webview receives a [ConsoleMessage]. @@ -456,23 +515,25 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onConsoleMessage](https://developer.android.com/reference/android/webkit/WebChromeClient#onConsoleMessage(android.webkit.ConsoleMessage))) ///- iOS + ///- MacOS void onConsoleMessage(ConsoleMessage consoleMessage) {} ///Give the host application a chance to take control when a URL is about to be loaded in the current WebView. This event is not called on the initial load of the WebView. /// ///Note that on Android there isn't any way to load an URL for a frame that is not the main frame, so if the request is not for the main frame, the navigation is allowed by default. - ///However, if you want to cancel requests for subframes, you can use the [InAppWebViewSettings.regexToCancelSubFramesLoading] option + ///However, if you want to cancel requests for subframes, you can use the [InAppWebViewSettings.regexToCancelSubFramesLoading] setting ///to write a Regular Expression that, if the url request of a subframe matches, then the request of that subframe is canceled. /// ///Also, on Android, this method is not called for POST requests. /// ///[navigationAction] represents an object that contains information about an action that causes navigation to occur. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldOverrideUrlLoading] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldOverrideUrlLoading] setting to `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.shouldOverrideUrlLoading](https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview)) Future? shouldOverrideUrlLoading( NavigationAction navigationAction) { return null; @@ -480,11 +541,12 @@ class InAppBrowser { ///Event fired when the [InAppBrowser] webview loads a resource. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnLoadResource] and [InAppWebViewSettings.javaScriptEnabled] options to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnLoadResource] and [InAppWebViewSettings.javaScriptEnabled] setting to `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS void onLoadResource(LoadedResource resource) {} ///Event fired when the [InAppBrowser] webview scrolls. @@ -493,9 +555,12 @@ class InAppBrowser { /// ///[y] represents the current vertical scroll origin in pixels. /// + ///**NOTE for MacOS**: this method is implemented with using JavaScript. + /// ///**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)) + ///- MacOS void onScrollChanged(int x, int y) {} ///Use [onDownloadStartRequest] instead @@ -507,11 +572,12 @@ class InAppBrowser { /// ///[downloadStartRequest] represents the request of the file to download. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnDownloadStart] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnDownloadStart] setting to `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.setDownloadListener](https://developer.android.com/reference/android/webkit/WebView#setDownloadListener(android.webkit.DownloadListener))) ///- iOS + ///- MacOS void onDownloadStartRequest(DownloadStartRequest downloadStartRequest) {} ///Use [onLoadResourceWithCustomScheme] instead. @@ -526,6 +592,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKURLSchemeHandler](https://developer.apple.com/documentation/webkit/wkurlschemehandler)) + ///- MacOS ([Official API - WKURLSchemeHandler](https://developer.apple.com/documentation/webkit/wkurlschemehandler)) Future? onLoadResourceWithCustomScheme( WebResourceRequest request) { return null; @@ -539,11 +606,11 @@ class InAppBrowser { /// ///[createWindowAction] represents the request. /// - ///**NOTE**: to allow JavaScript to open windows, you need to set [InAppWebViewSettings.javaScriptCanOpenWindowsAutomatically] option to `true`. + ///**NOTE**: to allow JavaScript to open windows, you need to set [InAppWebViewSettings.javaScriptCanOpenWindowsAutomatically] setting to `true`. /// - ///**NOTE**: on Android you need to set [InAppWebViewSettings.supportMultipleWindows] option to `true`. + ///**NOTE**: on Android you need to set [InAppWebViewSettings.supportMultipleWindows] setting to `true`. /// - ///**NOTE**: on iOS, setting these initial options: [InAppWebViewSettings.supportZoom], [InAppWebViewSettings.useOnLoadResource], [InAppWebViewSettings.useShouldInterceptAjaxRequest], + ///**NOTE**: on iOS and MacOS, setting these initial settings: [InAppWebViewSettings.supportZoom], [InAppWebViewSettings.useOnLoadResource], [InAppWebViewSettings.useShouldInterceptAjaxRequest], ///[InAppWebViewSettings.useShouldInterceptFetchRequest], [InAppWebViewSettings.applicationNameForUserAgent], [InAppWebViewSettings.javaScriptCanOpenWindowsAutomatically], ///[InAppWebViewSettings.javaScriptEnabled], [InAppWebViewSettings.minimumFontSize], [InAppWebViewSettings.preferredContentMode], [InAppWebViewSettings.incognito], ///[InAppWebViewSettings.cacheEnabled], [InAppWebViewSettings.mediaPlaybackRequiresUserGesture], @@ -562,6 +629,7 @@ class InAppBrowser { ///**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)) + ///- MacOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1536907-webview)) Future? onCreateWindow(CreateWindowAction createWindowAction) { return null; } @@ -572,6 +640,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onCloseWindow](https://developer.android.com/reference/android/webkit/WebChromeClient#onCloseWindow(android.webkit.WebView))) ///- iOS ([Official API - WKUIDelegate.webViewDidClose](https://developer.apple.com/documentation/webkit/wkuidelegate/1537390-webviewdidclose)) + ///- MacOS ([Official API - WKUIDelegate.webViewDidClose](https://developer.apple.com/documentation/webkit/wkuidelegate/1537390-webviewdidclose)) void onCloseWindow() {} ///Event fired when the JavaScript `window` object of the WebView has received focus. @@ -580,6 +649,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS void onWindowFocus() {} ///Event fired when the JavaScript `window` object of the WebView has lost focus. @@ -588,6 +658,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS void onWindowBlur() {} ///Event fired when javascript calls the `alert()` method to display an alert dialog. @@ -598,6 +669,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onJsAlert](https://developer.android.com/reference/android/webkit/WebChromeClient#onJsAlert(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult))) ///- iOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview)) + ///- MacOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview)) Future? onJsAlert(JsAlertRequest jsAlertRequest) { return null; } @@ -610,6 +682,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onJsConfirm](https://developer.android.com/reference/android/webkit/WebChromeClient#onJsConfirm(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20android.webkit.JsResult))) ///- iOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview)) + ///- MacOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview)) Future? onJsConfirm(JsConfirmRequest jsConfirmRequest) { return null; } @@ -622,6 +695,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onJsPrompt](https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult))) ///- iOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview)) + ///- MacOS ([Official API - WKUIDelegate.webView](https://developer.apple.com/documentation/webkit/wkuidelegate/1538086-webview)) Future? onJsPrompt(JsPromptRequest jsPromptRequest) { return null; } @@ -633,6 +707,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onReceivedHttpAuthRequest](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) Future? onReceivedHttpAuthRequest( URLAuthenticationChallenge challenge) { return null; @@ -646,6 +721,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onReceivedSslError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%20android.webkit.SslErrorHandler,%20android.net.http.SslError))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) Future? onReceivedServerTrustAuthRequest( URLAuthenticationChallenge challenge) { return null; @@ -661,6 +737,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onReceivedClientCertRequest](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedClientCertRequest(android.webkit.WebView,%20android.webkit.ClientCertRequest))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview)) Future? onReceivedClientCertRequest( URLAuthenticationChallenge challenge) { return null; @@ -676,7 +753,7 @@ class InAppBrowser { /// ///[ajaxRequest] represents the `XMLHttpRequest`. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] setting to `true`. ///Also, unlike iOS that has [WKUserScript](https://developer.apple.com/documentation/webkit/wkuserscript) that ///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code ///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms). @@ -685,6 +762,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future? shouldInterceptAjaxRequest(AjaxRequest ajaxRequest) { return null; } @@ -694,7 +772,7 @@ class InAppBrowser { /// ///[ajaxRequest] represents the [XMLHttpRequest]. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] setting to `true`. ///Also, unlike iOS that has [WKUserScript](https://developer.apple.com/documentation/webkit/wkuserscript) that ///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code ///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms). @@ -703,6 +781,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future? onAjaxReadyStateChange(AjaxRequest ajaxRequest) { return null; } @@ -712,7 +791,7 @@ class InAppBrowser { /// ///[ajaxRequest] represents the [XMLHttpRequest]. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptAjaxRequest] setting to `true`. ///Also, unlike iOS that has [WKUserScript](https://developer.apple.com/documentation/webkit/wkuserscript) that ///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code ///used to intercept ajax requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms). @@ -721,6 +800,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future? onAjaxProgress(AjaxRequest ajaxRequest) { return null; } @@ -730,7 +810,7 @@ class InAppBrowser { /// ///[fetchRequest] represents a resource request. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptFetchRequest] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useShouldInterceptFetchRequest] setting to `true`. ///Also, unlike iOS that has [WKUserScript](https://developer.apple.com/documentation/webkit/wkuserscript) that ///can inject javascript code right after the document element is created but before any other content is loaded, in Android the javascript code ///used to intercept fetch requests is loaded as soon as possible so it won't be instantaneous as iOS but just after some milliseconds (< ~100ms). @@ -739,6 +819,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future? shouldInterceptFetchRequest( FetchRequest fetchRequest) { return null; @@ -756,6 +837,7 @@ class InAppBrowser { ///**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 + ///- MacOS void onUpdateVisitedHistory(Uri? url, bool? isReload) {} ///Use [onPrintRequest] instead @@ -773,6 +855,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future? onPrintRequest( Uri? url, PrintJobController? printJobController) { return null; @@ -792,6 +875,7 @@ class InAppBrowser { ///**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)) + ///- MacOS ([Official API - NSWindow.didEnterFullScreenNotification](https://developer.apple.com/documentation/appkit/nswindow/1419651-didenterfullscreennotification)) void onEnterFullscreen() {} ///Event fired when the current page has exited full screen mode. @@ -799,6 +883,7 @@ class InAppBrowser { ///**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)) + ///- MacOS ([Official API - NSWindow.didExitFullScreenNotification](https://developer.apple.com/documentation/appkit/nswindow/1419177-didexitfullscreennotification)) void onExitFullscreen() {} ///Called when the web view begins to receive web content. @@ -811,6 +896,7 @@ class InAppBrowser { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewClient.onPageCommitVisible](https://developer.android.com/reference/android/webkit/WebViewClient#onPageCommitVisible(android.webkit.WebView,%20java.lang.String))) ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455635-webview)) void onPageCommitVisible(Uri? url) {} ///Event fired when a change in the document title occurred. @@ -820,6 +906,7 @@ class InAppBrowser { ///**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 + ///- MacOS void onTitleChanged(String? title) {} ///Event fired to respond to the results of an over-scroll operation. @@ -888,9 +975,12 @@ class InAppBrowser { /// ///**NOTE for iOS**: available only on iOS 15.0+. The default [PermissionResponse.action] is [PermissionResponseAction.PROMPT]. /// + ///**NOTE for MacOS**: available only on iOS 12.0+. The default [PermissionResponse.action] is [PermissionResponseAction.PROMPT]. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebChromeClient.onPermissionRequest](https://developer.android.com/reference/android/webkit/WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest))) ///- iOS + ///- MacOS Future? onPermissionRequest( PermissionRequest permissionRequest) { return null; @@ -1112,6 +1202,7 @@ class InAppBrowser { /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKNavigationDelegate.webViewWebContentProcessDidTerminate](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi)) + ///- MacOS ([Official API - WKNavigationDelegate.webViewWebContentProcessDidTerminate](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi)) void onWebContentProcessDidTerminate() {} ///Use [onDidReceiveServerRedirectForProvisionalNavigation] instead. @@ -1122,6 +1213,7 @@ class InAppBrowser { /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455627-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455627-webview)) void onDidReceiveServerRedirectForProvisionalNavigation() {} ///Use [onNavigationResponse] instead. @@ -1135,10 +1227,11 @@ class InAppBrowser { /// ///[navigationResponse] represents the navigation response. /// - ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnNavigationResponse] option to `true`. + ///**NOTE**: In order to be able to listen this event, you need to set [InAppWebViewSettings.useOnNavigationResponse] setting to `true`. /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview)) Future? onNavigationResponse( NavigationResponse navigationResponse) { return null; @@ -1155,10 +1248,13 @@ class InAppBrowser { /// ///[challenge] represents the authentication challenge. /// - ///**NOTE**: available only on iOS 14.0+. + ///**NOTE for iOS**: available only on iOS 14.0+. + /// + ///**NOTE for MacOS**: available only on MacOS 11.0+. /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/3601237-webview)) + ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/3601237-webview)) Future? shouldAllowDeprecatedTLS( URLAuthenticationChallenge challenge) { return null; @@ -1166,10 +1262,13 @@ class InAppBrowser { ///Event fired when a change in the camera capture state occurred. /// - ///**NOTE**: available only on iOS 15.0+. + ///**NOTE for iOS**: available only on iOS 15.0+. + /// + ///**NOTE for MacOS**: available only on MacOS 12.0+. /// ///**Supported Platforms/Implementations**: ///- iOS + ///- MacOS void onCameraCaptureStateChanged( MediaCaptureState? oldState, MediaCaptureState? newState, @@ -1177,10 +1276,13 @@ class InAppBrowser { ///Event fired when a change in the microphone capture state occurred. /// - ///**NOTE**: available only on iOS 15.0+. + ///**NOTE for iOS**: available only on iOS 15.0+. + /// + ///**NOTE for MacOS**: available only on MacOS 12.0+. /// ///**Supported Platforms/Implementations**: ///- iOS + ///- MacOS void onMicrophoneCaptureStateChanged( MediaCaptureState? oldState, MediaCaptureState? newState, diff --git a/lib/src/in_app_browser/in_app_browser_settings.dart b/lib/src/in_app_browser/in_app_browser_settings.dart index cd4e66d4..c89336ac 100755 --- a/lib/src/in_app_browser/in_app_browser_settings.dart +++ b/lib/src/in_app_browser/in_app_browser_settings.dart @@ -2,7 +2,14 @@ import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter_inappwebview/src/types/main.dart'; +import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; +import '../types/in_app_webview_rect.dart'; +import '../types/modal_presentation_style.dart'; +import '../types/modal_transition_style.dart'; +import '../types/window_style_mask.dart'; +import '../types/window_titlebar_separator_style.dart'; +import '../types/window_type.dart'; import '../util.dart'; import '../in_app_webview/in_app_webview_settings.dart'; @@ -13,6 +20,8 @@ import '../in_app_webview/android/in_app_webview_options.dart'; import 'apple/in_app_browser_options.dart'; import '../in_app_webview/apple/in_app_webview_options.dart'; +part 'in_app_browser_settings.g.dart'; + ///Class that represents the settings that can be used for an [InAppBrowser] instance. class InAppBrowserClassSettings { ///Browser settings. @@ -50,8 +59,8 @@ class InAppBrowserClassSettings { if (instance == null) { instance = InAppBrowserClassSettings(); } - instance.browserSettings = InAppBrowserSettings.fromMap(options); - instance.webViewSettings = InAppWebViewSettings.fromMap(options); + instance.browserSettings = InAppBrowserSettings.fromMap(options) ?? InAppBrowserSettings(); + instance.webViewSettings = InAppWebViewSettings.fromMap(options) ?? InAppWebViewSettings(); return instance; } @@ -84,7 +93,8 @@ class BrowserOptions { } ///This class represents all [InAppBrowser] settings available. -class InAppBrowserSettings +@ExchangeableObject(copyMethod: true) +class InAppBrowserSettings_ implements BrowserOptions, AndroidOptions, IosOptions { ///Set to `true` to create the browser and load the page, but not show it. Omit or set to `false` to have the browser open and load normally. ///The default value is `false`. @@ -92,20 +102,23 @@ class InAppBrowserSettings ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool hidden; + ///- MacOS + bool? hidden; ///Set to `true` to hide the toolbar at the top of the WebView. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool hideToolbarTop; + ///- MacOS + bool? hideToolbarTop; ///Set the custom background color of the toolbar at the top. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Color? toolbarTopBackgroundColor; ///Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`. @@ -113,50 +126,53 @@ class InAppBrowserSettings ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool hideUrlBar; + ///- MacOS + bool? hideUrlBar; ///Set to `true` to hide the progress bar when the WebView is loading a page. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool hideProgressBar; + ///- MacOS + bool? hideProgressBar; ///Set to `true` if you want the title should be displayed. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool hideTitleBar; + bool? hideTitleBar; ///Set the action bar's title. /// ///**Supported Platforms/Implementations**: ///- Android native WebView + ///- MacOS String? toolbarTopFixedTitle; ///Set to `false` to not close the InAppBrowser when the user click on the Android back button and the WebView cannot go back to the history. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool closeOnCannotGoBack; + bool? closeOnCannotGoBack; ///Set to `false` to block the InAppBrowser WebView going back when the user click on the Android back button. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool allowGoBackWithBackButton; + bool? allowGoBackWithBackButton; ///Set to `true` to close the InAppBrowser when the user click on the Android back button. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool shouldCloseOnBackButtonPressed; + bool? shouldCloseOnBackButtonPressed; ///Set to `true` to set the toolbar at the top translucent. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool toolbarTopTranslucent; + bool? toolbarTopTranslucent; ///Set the tint color to apply to the navigation bar background. /// @@ -174,7 +190,7 @@ class InAppBrowserSettings /// ///**Supported Platforms/Implementations**: ///- iOS - bool hideToolbarBottom; + bool? hideToolbarBottom; ///Set the custom background color of the toolbar at the bottom. /// @@ -192,7 +208,7 @@ class InAppBrowserSettings /// ///**Supported Platforms/Implementations**: ///- iOS - bool toolbarBottomTranslucent; + bool? toolbarBottomTranslucent; ///Set the custom text for the close button. /// @@ -210,15 +226,50 @@ class InAppBrowserSettings /// ///**Supported Platforms/Implementations**: ///- iOS - ModalPresentationStyle presentationStyle; + ModalPresentationStyle_? presentationStyle; ///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL]. /// ///**Supported Platforms/Implementations**: ///- iOS - ModalTransitionStyle transitionStyle; + ModalTransitionStyle_? transitionStyle; - InAppBrowserSettings( + ///How the browser window should be added to the main window. + ///The default value is [WindowType.CHILD]. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowType_? windowType; + + ///The window’s alpha value. + ///The default value is `1.0`. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + double? windowAlphaValue; + + ///Flags that describe the window’s current style, such as if it’s resizable or in full-screen mode. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowStyleMask_? windowStyleMask; + + ///The type of separator that the app displays between the title bar and content of a window. + /// + ///**NOTE for MacOS**: available on MacOS 11.0+. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowTitlebarSeparatorStyle_? windowTitlebarSeparatorStyle; + + ///Sets the origin and size of the window’s frame rectangle according to a given frame rectangle, + ///thereby setting its position and size onscreen. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + InAppWebViewRect_? windowFrame; + + InAppBrowserSettings_( {this.hidden = false, this.hideToolbarTop = false, this.toolbarTopBackgroundColor, @@ -232,90 +283,35 @@ class InAppBrowserSettings this.toolbarBottomTranslucent = true, this.closeButtonCaption, this.closeButtonColor, - this.presentationStyle = ModalPresentationStyle.FULL_SCREEN, - this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL, + this.presentationStyle = ModalPresentationStyle_.FULL_SCREEN, + this.transitionStyle = ModalTransitionStyle_.COVER_VERTICAL, this.hideTitleBar = false, this.toolbarTopFixedTitle, this.closeOnCannotGoBack = true, this.allowGoBackWithBackButton = true, - this.shouldCloseOnBackButtonPressed = false}); + this.shouldCloseOnBackButtonPressed = false, + this.windowType, + this.windowAlphaValue = 1.0, + this.windowStyleMask, + this.windowTitlebarSeparatorStyle, + this.windowFrame}); @override - Map toMap() { - return { - "hidden": hidden, - "hideToolbarTop": hideToolbarTop, - "toolbarTopBackgroundColor": toolbarTopBackgroundColor?.toHex(), - "hideUrlBar": hideUrlBar, - "hideProgressBar": hideProgressBar, - "hideTitleBar": hideTitleBar, - "toolbarTopFixedTitle": toolbarTopFixedTitle, - "closeOnCannotGoBack": closeOnCannotGoBack, - "allowGoBackWithBackButton": allowGoBackWithBackButton, - "shouldCloseOnBackButtonPressed": shouldCloseOnBackButtonPressed, - "toolbarTopTranslucent": toolbarTopTranslucent, - "toolbarTopTintColor": toolbarTopTintColor?.toHex(), - "hideToolbarBottom": hideToolbarBottom, - "toolbarBottomBackgroundColor": toolbarBottomBackgroundColor?.toHex(), - "toolbarBottomTintColor": toolbarBottomTintColor?.toHex(), - "toolbarBottomTranslucent": toolbarBottomTranslucent, - "closeButtonCaption": closeButtonCaption, - "closeButtonColor": closeButtonColor?.toHex(), - "presentationStyle": presentationStyle.toNativeValue(), - "transitionStyle": transitionStyle.toNativeValue(), - }; - } - - static InAppBrowserSettings fromMap(Map map) { - var settings = InAppBrowserSettings(); - settings.hidden = map["hidden"]; - settings.hideToolbarTop = map["hideToolbarTop"]; - settings.toolbarTopBackgroundColor = - UtilColor.fromHex(map["toolbarTopBackgroundColor"]); - settings.hideUrlBar = map["hideUrlBar"]; - settings.hideProgressBar = map["hideProgressBar"]; - if (defaultTargetPlatform == TargetPlatform.android) { - settings.hideTitleBar = map["hideTitleBar"]; - settings.toolbarTopFixedTitle = map["toolbarTopFixedTitle"]; - settings.closeOnCannotGoBack = map["closeOnCannotGoBack"]; - settings.allowGoBackWithBackButton = map["allowGoBackWithBackButton"]; - settings.shouldCloseOnBackButtonPressed = - map["shouldCloseOnBackButtonPressed"]; - } - if (defaultTargetPlatform == TargetPlatform.iOS || - defaultTargetPlatform == TargetPlatform.macOS) { - settings.toolbarTopTranslucent = map["toolbarTopTranslucent"]; - settings.toolbarTopTintColor = - UtilColor.fromHex(map["toolbarTopTintColor"]); - settings.hideToolbarBottom = map["hideToolbarBottom"]; - settings.toolbarBottomBackgroundColor = - UtilColor.fromHex(map["toolbarBottomBackgroundColor"]); - settings.toolbarBottomTintColor = - UtilColor.fromHex(map["toolbarBottomTintColor"]); - settings.toolbarBottomTranslucent = map["toolbarBottomTranslucent"]; - settings.closeButtonCaption = map["closeButtonCaption"]; - settings.closeButtonColor = UtilColor.fromHex(map["closeButtonColor"]); - settings.presentationStyle = - ModalPresentationStyle.fromNativeValue(map["presentationStyle"])!; - settings.transitionStyle = - ModalTransitionStyle.fromNativeValue(map["transitionStyle"])!; - } - return settings; + @ExchangeableObjectMethod(ignore: true) + InAppBrowserSettings_ copy() { + throw UnimplementedError(); } @override + @ExchangeableObjectMethod(ignore: true) Map toJson() { - return this.toMap(); + throw UnimplementedError(); } @override - String toString() { - return toMap().toString(); - } - - @override - InAppBrowserSettings copy() { - return InAppBrowserSettings.fromMap(this.toMap()); + @ExchangeableObjectMethod(ignore: true) + Map toMap() { + throw UnimplementedError(); } } diff --git a/lib/src/in_app_browser/in_app_browser_settings.g.dart b/lib/src/in_app_browser/in_app_browser_settings.g.dart new file mode 100644 index 00000000..ad4d8747 --- /dev/null +++ b/lib/src/in_app_browser/in_app_browser_settings.g.dart @@ -0,0 +1,313 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'in_app_browser_settings.dart'; + +// ************************************************************************** +// ExchangeableObjectGenerator +// ************************************************************************** + +///This class represents all [InAppBrowser] settings available. +class InAppBrowserSettings + implements BrowserOptions, AndroidOptions, IosOptions { + ///Set to `true` to create the browser and load the page, but not show it. Omit or set to `false` to have the browser open and load normally. + ///The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + bool? hidden; + + ///Set to `true` to hide the toolbar at the top of the WebView. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + bool? hideToolbarTop; + + ///Set the custom background color of the toolbar at the top. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + Color? toolbarTopBackgroundColor; + + ///Set to `true` to hide the url bar on the toolbar at the top. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + bool? hideUrlBar; + + ///Set to `true` to hide the progress bar when the WebView is loading a page. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- MacOS + bool? hideProgressBar; + + ///Set to `true` if you want the title should be displayed. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + bool? hideTitleBar; + + ///Set the action bar's title. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- MacOS + String? toolbarTopFixedTitle; + + ///Set to `false` to not close the InAppBrowser when the user click on the Android back button and the WebView cannot go back to the history. The default value is `true`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + bool? closeOnCannotGoBack; + + ///Set to `false` to block the InAppBrowser WebView going back when the user click on the Android back button. The default value is `true`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + bool? allowGoBackWithBackButton; + + ///Set to `true` to close the InAppBrowser when the user click on the Android back button. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + bool? shouldCloseOnBackButtonPressed; + + ///Set to `true` to set the toolbar at the top translucent. The default value is `true`. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool? toolbarTopTranslucent; + + ///Set the tint color to apply to the navigation bar background. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? toolbarTopBarTintColor; + + ///Set the tint color to apply to the navigation items and bar button items. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? toolbarTopTintColor; + + ///Set to `true` to hide the toolbar at the bottom of the WebView. The default value is `false`. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool? hideToolbarBottom; + + ///Set the custom background color of the toolbar at the bottom. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? toolbarBottomBackgroundColor; + + ///Set the tint color to apply to the bar button items. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? toolbarBottomTintColor; + + ///Set to `true` to set the toolbar at the bottom translucent. The default value is `true`. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + bool? toolbarBottomTranslucent; + + ///Set the custom text for the close button. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + String? closeButtonCaption; + + ///Set the custom color for the close button. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + Color? closeButtonColor; + + ///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN]. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + ModalPresentationStyle? presentationStyle; + + ///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL]. + /// + ///**Supported Platforms/Implementations**: + ///- iOS + ModalTransitionStyle? transitionStyle; + + ///How the browser window should be added to the main window. + ///The default value is [WindowType.CHILD]. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowType? windowType; + + ///The window’s alpha value. + ///The default value is `1.0`. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + double? windowAlphaValue; + + ///Flags that describe the window’s current style, such as if it’s resizable or in full-screen mode. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowStyleMask? windowStyleMask; + + ///The type of separator that the app displays between the title bar and content of a window. + /// + ///**NOTE for MacOS**: available on MacOS 11.0+. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + WindowTitlebarSeparatorStyle? windowTitlebarSeparatorStyle; + + ///Sets the origin and size of the window’s frame rectangle according to a given frame rectangle, + ///thereby setting its position and size onscreen. + /// + ///**Supported Platforms/Implementations**: + ///- MacOS + InAppWebViewRect? windowFrame; + InAppBrowserSettings( + {this.hidden = false, + this.hideToolbarTop = false, + this.toolbarTopBackgroundColor, + this.hideUrlBar = false, + this.hideProgressBar = false, + this.hideTitleBar = false, + this.toolbarTopFixedTitle, + this.closeOnCannotGoBack = true, + this.allowGoBackWithBackButton = true, + this.shouldCloseOnBackButtonPressed = false, + this.toolbarTopTranslucent = true, + this.toolbarTopTintColor, + this.hideToolbarBottom = false, + this.toolbarBottomBackgroundColor, + this.toolbarBottomTintColor, + this.toolbarBottomTranslucent = true, + this.closeButtonCaption, + this.closeButtonColor, + this.presentationStyle = ModalPresentationStyle.FULL_SCREEN, + this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL, + this.windowType, + this.windowAlphaValue = 1.0, + this.windowStyleMask, + this.windowTitlebarSeparatorStyle, + this.windowFrame}); + + ///Gets a possible [InAppBrowserSettings] instance from a [Map] value. + static InAppBrowserSettings? fromMap(Map? map) { + if (map == null) { + return null; + } + final instance = InAppBrowserSettings( + toolbarTopBackgroundColor: map['toolbarTopBackgroundColor'] != null + ? UtilColor.fromStringRepresentation(map['toolbarTopBackgroundColor']) + : null, + toolbarTopFixedTitle: map['toolbarTopFixedTitle'], + toolbarTopTintColor: map['toolbarTopTintColor'] != null + ? UtilColor.fromStringRepresentation(map['toolbarTopTintColor']) + : null, + toolbarBottomBackgroundColor: map['toolbarBottomBackgroundColor'] != null + ? UtilColor.fromStringRepresentation( + map['toolbarBottomBackgroundColor']) + : null, + toolbarBottomTintColor: map['toolbarBottomTintColor'] != null + ? UtilColor.fromStringRepresentation(map['toolbarBottomTintColor']) + : null, + closeButtonCaption: map['closeButtonCaption'], + closeButtonColor: map['closeButtonColor'] != null + ? UtilColor.fromStringRepresentation(map['closeButtonColor']) + : null, + windowType: WindowType.fromNativeValue(map['windowType']), + windowStyleMask: WindowStyleMask.fromNativeValue(map['windowStyleMask']), + windowTitlebarSeparatorStyle: + WindowTitlebarSeparatorStyle.fromNativeValue( + map['windowTitlebarSeparatorStyle']), + windowFrame: + InAppWebViewRect.fromMap(map['windowFrame']?.cast()), + ); + instance.hidden = map['hidden']; + instance.hideToolbarTop = map['hideToolbarTop']; + instance.hideUrlBar = map['hideUrlBar']; + instance.hideProgressBar = map['hideProgressBar']; + instance.hideTitleBar = map['hideTitleBar']; + instance.closeOnCannotGoBack = map['closeOnCannotGoBack']; + instance.allowGoBackWithBackButton = map['allowGoBackWithBackButton']; + instance.shouldCloseOnBackButtonPressed = + map['shouldCloseOnBackButtonPressed']; + instance.toolbarTopTranslucent = map['toolbarTopTranslucent']; + instance.toolbarTopBarTintColor = map['toolbarTopBarTintColor'] != null + ? UtilColor.fromStringRepresentation(map['toolbarTopBarTintColor']) + : null; + instance.hideToolbarBottom = map['hideToolbarBottom']; + instance.toolbarBottomTranslucent = map['toolbarBottomTranslucent']; + instance.presentationStyle = + ModalPresentationStyle.fromNativeValue(map['presentationStyle']); + instance.transitionStyle = + ModalTransitionStyle.fromNativeValue(map['transitionStyle']); + instance.windowAlphaValue = map['windowAlphaValue']; + return instance; + } + + ///Converts instance to a map. + Map toMap() { + return { + "hidden": hidden, + "hideToolbarTop": hideToolbarTop, + "toolbarTopBackgroundColor": toolbarTopBackgroundColor?.toHex(), + "hideUrlBar": hideUrlBar, + "hideProgressBar": hideProgressBar, + "hideTitleBar": hideTitleBar, + "toolbarTopFixedTitle": toolbarTopFixedTitle, + "closeOnCannotGoBack": closeOnCannotGoBack, + "allowGoBackWithBackButton": allowGoBackWithBackButton, + "shouldCloseOnBackButtonPressed": shouldCloseOnBackButtonPressed, + "toolbarTopTranslucent": toolbarTopTranslucent, + "toolbarTopBarTintColor": toolbarTopBarTintColor?.toHex(), + "toolbarTopTintColor": toolbarTopTintColor?.toHex(), + "hideToolbarBottom": hideToolbarBottom, + "toolbarBottomBackgroundColor": toolbarBottomBackgroundColor?.toHex(), + "toolbarBottomTintColor": toolbarBottomTintColor?.toHex(), + "toolbarBottomTranslucent": toolbarBottomTranslucent, + "closeButtonCaption": closeButtonCaption, + "closeButtonColor": closeButtonColor?.toHex(), + "presentationStyle": presentationStyle?.toNativeValue(), + "transitionStyle": transitionStyle?.toNativeValue(), + "windowType": windowType?.toNativeValue(), + "windowAlphaValue": windowAlphaValue, + "windowStyleMask": windowStyleMask?.toNativeValue(), + "windowTitlebarSeparatorStyle": + windowTitlebarSeparatorStyle?.toNativeValue(), + "windowFrame": windowFrame?.toMap(), + }; + } + + ///Converts instance to a map. + Map toJson() { + return toMap(); + } + + ///Returns a copy of InAppBrowserSettings. + InAppBrowserSettings copy() { + return InAppBrowserSettings.fromMap(toMap()) ?? InAppBrowserSettings(); + } + + @override + String toString() { + return 'InAppBrowserSettings{hidden: $hidden, hideToolbarTop: $hideToolbarTop, toolbarTopBackgroundColor: $toolbarTopBackgroundColor, hideUrlBar: $hideUrlBar, hideProgressBar: $hideProgressBar, hideTitleBar: $hideTitleBar, toolbarTopFixedTitle: $toolbarTopFixedTitle, closeOnCannotGoBack: $closeOnCannotGoBack, allowGoBackWithBackButton: $allowGoBackWithBackButton, shouldCloseOnBackButtonPressed: $shouldCloseOnBackButtonPressed, toolbarTopTranslucent: $toolbarTopTranslucent, toolbarTopBarTintColor: $toolbarTopBarTintColor, toolbarTopTintColor: $toolbarTopTintColor, hideToolbarBottom: $hideToolbarBottom, toolbarBottomBackgroundColor: $toolbarBottomBackgroundColor, toolbarBottomTintColor: $toolbarBottomTintColor, toolbarBottomTranslucent: $toolbarBottomTranslucent, closeButtonCaption: $closeButtonCaption, closeButtonColor: $closeButtonColor, presentationStyle: $presentationStyle, transitionStyle: $transitionStyle, windowType: $windowType, windowAlphaValue: $windowAlphaValue, windowStyleMask: $windowStyleMask, windowTitlebarSeparatorStyle: $windowTitlebarSeparatorStyle, windowFrame: $windowFrame}'; + } +} diff --git a/lib/src/in_app_browser/main.dart b/lib/src/in_app_browser/main.dart index 069ebf66..0c541535 100644 --- a/lib/src/in_app_browser/main.dart +++ b/lib/src/in_app_browser/main.dart @@ -1,4 +1,10 @@ export 'in_app_browser.dart'; -export 'in_app_browser_settings.dart'; +export 'in_app_browser_settings.dart' + show + InAppBrowserClassSettings, + BrowserOptions, + InAppBrowserSettings, + InAppBrowserClassOptions, + InAppBrowserOptions; export 'android/main.dart'; export 'apple/main.dart'; diff --git a/lib/src/in_app_localhost_server.dart b/lib/src/in_app_localhost_server.dart index 57c74e49..452ddbb1 100755 --- a/lib/src/in_app_localhost_server.dart +++ b/lib/src/in_app_localhost_server.dart @@ -12,6 +12,7 @@ import 'mime_type_resolver.dart'; ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS +///- MacOS class InAppLocalhostServer { bool _started = false; HttpServer? _server; diff --git a/lib/src/in_app_webview/headless_in_app_webview.dart b/lib/src/in_app_webview/headless_in_app_webview.dart index 291b43b5..36400aeb 100644 --- a/lib/src/in_app_webview/headless_in_app_webview.dart +++ b/lib/src/in_app_webview/headless_in_app_webview.dart @@ -23,6 +23,7 @@ import '../types/disposable.dart'; ///- Android native WebView ///- iOS ///- Web +///- MacOS class HeadlessInAppWebView implements WebView, Disposable { ///View ID. late final String id; @@ -192,6 +193,7 @@ class HeadlessInAppWebView implements WebView, Disposable { ///- Android native WebView ///- iOS ///- Web + ///- MacOS Future run() async { if (_started) { return; @@ -236,6 +238,7 @@ class HeadlessInAppWebView implements WebView, Disposable { ///- Android native WebView ///- iOS ///- Web + ///- MacOS @override Future dispose() async { if (!_running) { @@ -253,6 +256,7 @@ class HeadlessInAppWebView implements WebView, Disposable { ///- Android native WebView ///- iOS ///- Web + ///- MacOS bool isRunning() { return _running; } @@ -270,6 +274,7 @@ class HeadlessInAppWebView implements WebView, Disposable { ///- Android native WebView ///- iOS ///- Web + ///- MacOS Future setSize(Size size) async { if (!_running) { return; @@ -288,6 +293,7 @@ class HeadlessInAppWebView implements WebView, Disposable { ///- Android native WebView ///- iOS ///- Web + ///- MacOS Future getSize() async { if (!_running) { return null; diff --git a/lib/src/in_app_webview/in_app_webview.dart b/lib/src/in_app_webview/in_app_webview.dart index fc0ff3b4..f60ea6ec 100755 --- a/lib/src/in_app_webview/in_app_webview.dart +++ b/lib/src/in_app_webview/in_app_webview.dart @@ -688,7 +688,7 @@ class _InAppWebViewState extends State { creationParamsCodec: const StandardMessageCodec(), ); } - } else if (defaultTargetPlatform == TargetPlatform.iOS) { + } else if (defaultTargetPlatform == TargetPlatform.iOS/* || defaultTargetPlatform == TargetPlatform.macOS*/) { return UiKitView( viewType: 'com.pichillilorenzo/flutter_inappwebview', onPlatformViewCreated: _onPlatformViewCreated, 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 eafba17b..d486450d 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -111,30 +111,13 @@ class InAppWebViewController { } _debugLog(String method, dynamic args) { - if (WebView.debugLoggingSettings.enabled) { - for (var regExp in WebView.debugLoggingSettings.excludeFilter) { - if (regExp.hasMatch(method)) return; - } - var maxLogMessageLength = - WebView.debugLoggingSettings.maxLogMessageLength; - String viewId = (getViewId() ?? _inAppBrowser?.id).toString(); - String message = "(${defaultTargetPlatform.name}) " + - (_inAppBrowser == null ? "WebView" : "InAppBrowser") + - " ID " + - viewId + - " calling \"" + - method.toString() + - "\" using " + - args.toString(); - if (maxLogMessageLength >= 0 && message.length > maxLogMessageLength) { - message = message.substring(0, maxLogMessageLength) + "..."; - } - if (!WebView.debugLoggingSettings.usePrint) { - developer.log(message, name: this.runtimeType.toString()); - } else { - print("[${this.runtimeType.toString()}] $message"); - } - } + debugLog( + className: this.runtimeType.toString(), + name: _inAppBrowser == null ? "WebView" : "InAppBrowser", + id: (getViewId() ?? _inAppBrowser?.id).toString(), + debugLoggingSettings: WebView.debugLoggingSettings, + method: method, + args: args); } Future handleMethod(MethodCall call) async { @@ -1343,6 +1326,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.getUrl](https://developer.android.com/reference/android/webkit/WebView#getUrl())) ///- iOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url)) + ///- MacOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url)) ///- Web Future getUrl() async { Map args = {}; @@ -1357,6 +1341,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ([Official API - WKWebView.title](https://developer.apple.com/documentation/webkit/wkwebview/1415015-title)) ///- Web Future getTitle() async { Map args = {}; @@ -1368,6 +1353,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.getProgress](https://developer.android.com/reference/android/webkit/WebView#getProgress())) ///- iOS ([Official API - WKWebView.estimatedProgress](https://developer.apple.com/documentation/webkit/wkwebview/1415007-estimatedprogress)) + ///- MacOS ([Official API - WKWebView.estimatedProgress](https://developer.apple.com/documentation/webkit/wkwebview/1415007-estimatedprogress)) Future getProgress() async { Map args = {}; return await _channel.invokeMethod('getProgress', args); @@ -1383,6 +1369,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future getHtml() async { String? html; @@ -1427,6 +1414,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future> getFavicons() async { List favicons = []; @@ -1611,6 +1599,7 @@ class InAppWebViewController { ///**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[])) ///- 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)) + ///- MacOS ([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 loadUrl( {required URLRequest urlRequest, @@ -1646,6 +1635,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.postUrl](https://developer.android.com/reference/android/webkit/WebView#postUrl(java.lang.String,%20byte[]))) ///- iOS + ///- MacOS ///- Web Future postUrl({required Uri url, required Uint8List postData}) async { assert(url.toString().isNotEmpty); @@ -1672,6 +1662,7 @@ class InAppWebViewController { ///**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))) ///- 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)) + ///- MacOS ([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 loadData( {required String data, @@ -1741,6 +1732,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load)) ///- Web Future loadFile({required String assetFilePath}) async { assert(assetFilePath.isNotEmpty); @@ -1756,6 +1748,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ([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 reload() async { Map args = {}; @@ -1769,6 +1762,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ([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 goBack() async { Map args = {}; @@ -1780,6 +1774,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.canGoBack](https://developer.android.com/reference/android/webkit/WebView#canGoBack())) ///- iOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback)) + ///- MacOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback)) Future canGoBack() async { Map args = {}; return await _channel.invokeMethod('canGoBack', args); @@ -1792,6 +1787,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ([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 goForward() async { Map args = {}; @@ -1803,6 +1799,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.canGoForward](https://developer.android.com/reference/android/webkit/WebView#canGoForward())) ///- iOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward)) + ///- MacOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward)) Future canGoForward() async { Map args = {}; return await _channel.invokeMethod('canGoForward', args); @@ -1815,6 +1812,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.goBackOrForward](https://developer.android.com/reference/android/webkit/WebView#goBackOrForward(int))) ///- iOS ([Official API - WKWebView.go](https://developer.apple.com/documentation/webkit/wkwebview/1414991-go)) + ///- MacOS ([Official API - WKWebView.go](https://developer.apple.com/documentation/webkit/wkwebview/1414991-go)) ///- Web ([Official API - History.go](https://developer.mozilla.org/en-US/docs/Web/API/History/go)) Future goBackOrForward({required int steps}) async { Map args = {}; @@ -1827,6 +1825,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.canGoBackOrForward](https://developer.android.com/reference/android/webkit/WebView#canGoBackOrForward(int))) ///- iOS + ///- MacOS Future canGoBackOrForward({required int steps}) async { Map args = {}; args.putIfAbsent('steps', () => steps); @@ -1840,6 +1839,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future goTo({required WebHistoryItem historyItem}) async { var steps = historyItem.offset; @@ -1853,6 +1853,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future isLoading() async { Map args = {}; @@ -1866,6 +1867,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.stopLoading](https://developer.android.com/reference/android/webkit/WebView#stopLoading())) ///- iOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading)) + ///- MacOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading)) ///- Web ([Official API - Window.stop](https://developer.mozilla.org/en-US/docs/Web/API/Window/stop)) Future stopLoading() async { Map args = {}; @@ -1879,7 +1881,7 @@ class InAppWebViewController { ///This parameter doesn’t apply to changes you make to the underlying web content, such as the document’s DOM structure. ///Those changes remain visible to all scripts, regardless of which content world you specify. ///For more information about content worlds, see [ContentWorld]. - ///Available on iOS 14.0+. + ///Available on iOS 14.0+ and MacOS 11.0+. ///**NOTE**: not used on Web. /// ///**NOTE**: This method shouldn't be called in the [WebView.onWebViewCreated] or [WebView.onLoadStart] events, @@ -1892,6 +1894,7 @@ class InAppWebViewController { ///**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))) ///- iOS ([Official API - WKWebView.evaluateJavascript](https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript)) + ///- MacOS ([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 evaluateJavascript( {required String source, ContentWorld? contentWorld}) async { @@ -1924,6 +1927,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future injectJavascriptFileFromUrl( {required Uri urlFile, @@ -1952,6 +1956,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future injectJavascriptFileFromAsset( {required String assetFilePath}) async { @@ -1971,6 +1976,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future injectCSSCode({required String source}) async { Map args = {}; @@ -1992,6 +1998,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future injectCSSFileFromUrl( {required Uri urlFile, @@ -2016,6 +2023,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future injectCSSFileFromAsset({required String assetFilePath}) async { String source = await rootBundle.loadString(assetFilePath); @@ -2076,6 +2084,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS void addJavaScriptHandler( {required String handlerName, required JavaScriptHandlerCallback callback}) { @@ -2091,6 +2100,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS JavaScriptHandlerCallback? removeJavaScriptHandler( {required String handlerName}) { return this.javaScriptHandlersMap.remove(handlerName); @@ -2102,9 +2112,12 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 11.0+. /// + ///**NOTE for MacOS**: available on MacOS 10.13+. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot)) + ///- MacOS ([Official API - WKWebView.takeSnapshot](https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot)) Future takeScreenshot( {ScreenshotConfiguration? screenshotConfiguration}) async { Map args = {}; @@ -2117,7 +2130,7 @@ class InAppWebViewController { @Deprecated('Use setSettings instead') Future setOptions({required InAppWebViewGroupOptions options}) async { InAppWebViewSettings settings = - InAppWebViewSettings.fromMap(options.toMap()); + InAppWebViewSettings.fromMap(options.toMap()) ?? InAppWebViewSettings(); await setSettings(settings: settings); } @@ -2140,6 +2153,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future setSettings({required InAppWebViewSettings settings}) async { Map args = {}; @@ -2153,6 +2167,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future getSettings() async { Map args = {}; @@ -2175,6 +2190,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.copyBackForwardList](https://developer.android.com/reference/android/webkit/WebView#copyBackForwardList())) ///- iOS ([Official API - WKWebView.backForwardList](https://developer.apple.com/documentation/webkit/wkwebview/1414977-backforwardlist)) + ///- MacOS ([Official API - WKWebView.backForwardList](https://developer.apple.com/documentation/webkit/wkwebview/1414977-backforwardlist)) Future getCopyBackForwardList() async { Map args = {}; Map? result = @@ -2188,6 +2204,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future clearCache() async { Map args = {}; await _channel.invokeMethod('clearCache', args); @@ -2238,9 +2255,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: this method is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ///- Web ([Official API - Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)) Future scrollTo( {required int x, required int y, bool animated = false}) async { @@ -2261,9 +2281,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: this method is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ///- Web ([Official API - Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)) Future scrollBy( {required int x, required int y, bool animated = false}) async { @@ -2277,11 +2300,14 @@ class InAppWebViewController { ///On Android native WebView, it pauses all layout, parsing, and JavaScript timers for all WebViews. ///This is a global requests, not restricted to just this WebView. This can be useful if the application has been paused. /// - ///On iOS, it is implemented using JavaScript and it is restricted to just this WebView. + ///**NOTE for iOS**: it is implemented using JavaScript and it is restricted to just this WebView. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript and it is restricted to just this WebView. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.pauseTimers](https://developer.android.com/reference/android/webkit/WebView#pauseTimers())) ///- iOS + ///- MacOS Future pauseTimers() async { Map args = {}; await _channel.invokeMethod('pauseTimers', args); @@ -2289,11 +2315,14 @@ class InAppWebViewController { ///On Android, it resumes all layout, parsing, and JavaScript timers for all WebViews. This will resume dispatching all timers. /// - ///On iOS, it is implemented using JavaScript and it resumes all layout, parsing, and JavaScript timers to just this WebView. + ///**NOTE for iOS**: it is implemented using JavaScript and it is restricted to just this WebView. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript and it is restricted to just this WebView. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.resumeTimers](https://developer.android.com/reference/android/webkit/WebView#resumeTimers())) ///- iOS + ///- MacOS Future resumeTimers() async { Map args = {}; await _channel.invokeMethod('resumeTimers', args); @@ -2304,13 +2333,16 @@ class InAppWebViewController { ///To obtain the [PrintJobController], use [settings] argument with [PrintJobSettings.handledByClient] to `true`. ///Otherwise this method will return `null` and the [PrintJobController] will be handled and disposed automatically by the system. /// - ///**NOTE**: available on Android 19+. + ///**NOTE for Android**: available on Android 19+. + /// + ///**NOTE for MacOS**: [PrintJobController] is available on MacOS 11.0+. /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. Also, [PrintJobController] is always `null`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - PrintManager.print](https://developer.android.com/reference/android/print/PrintManager#print(java.lang.String,%20android.print.PrintDocumentAdapter,%20android.print.PrintAttributes))) ///- iOS ([Official API - UIPrintInteractionController.present](https://developer.apple.com/documentation/uikit/uiprintinteractioncontroller/1618149-present)) + ///- MacOS (if 11.0+, [Official API - WKWebView.printOperation](https://developer.apple.com/documentation/webkit/wkwebview/3516861-printoperation), else [Official API - NSView.printView](https://developer.apple.com/documentation/appkit/nsview/1483705-printview)) ///- Web ([Official API - Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window/print)) Future printCurrentPage( {PrintJobSettings? settings}) async { @@ -2327,9 +2359,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- 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)) + ///- MacOS ///- Web ([Official API - Document.documentElement.scrollHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight)) Future getContentHeight() async { Map args = {}; @@ -2345,6 +2380,33 @@ class InAppWebViewController { return height; } + ///Gets the width of the HTML content. + /// + ///**NOTE for Android**: it is implemented using JavaScript. + /// + ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS ([Official API - UIScrollView.contentSize](https://developer.apple.com/documentation/uikit/uiscrollview/1619399-contentsize)) + ///- MacOS + ///- Web ([Official API - Document.documentElement.scrollWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth)) + Future getContentWidth() async { + Map args = {}; + var height = await _channel.invokeMethod('getContentWidth', args); + if (height == null || height == 0) { + // try to use javascript + var scrollHeight = await evaluateJavascript( + source: "document.documentElement.scrollWidth;"); + if (scrollHeight != null && scrollHeight is num) { + height = scrollHeight.toInt(); + } + } + return height; + } + ///Performs a zoom operation in this WebView. /// ///[zoomFactor] represents the zoom factor to apply. On Android, the zoom factor will be clamped to the Webview's zoom limits and, also, this value must be in the range 0.01 (excluded) to 100.0 (included). @@ -2381,6 +2443,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.getOriginalUrl](https://developer.android.com/reference/android/webkit/WebView#getOriginalUrl())) ///- iOS + ///- MacOS ///- Web Future getOriginalUrl() async { Map args = {}; @@ -2415,6 +2478,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future getSelectedText() async { Map args = {}; @@ -2515,6 +2579,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future> getMetaTags() async { List metaTags = []; @@ -2578,13 +2643,14 @@ class InAppWebViewController { ///Returns an instance of [Color] representing the `content` value of the ///`` tag of the current WebView, if available, otherwise `null`. /// - ///**NOTE**: on Android, Web and iOS < 15.0, it is implemented using JavaScript. + ///**NOTE**: on Android, Web, iOS < 15.0 and MacOS < 12.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**: ///- Android native WebView ///- iOS ([Official API - WKWebView.themeColor](https://developer.apple.com/documentation/webkit/wkwebview/3794258-themecolor)) + ///- MacOS ([Official API - WKWebView.themeColor](https://developer.apple.com/documentation/webkit/wkwebview/3794258-themecolor)) ///- Web Future getMetaThemeColor() async { Color? themeColor; @@ -2626,9 +2692,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - View.getScrollX](https://developer.android.com/reference/android/view/View#getScrollX())) ///- iOS ([Official API - UIScrollView.contentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619404-contentoffset)) + ///- MacOS ///- Web ([Official API - Window.scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollX)) Future getScrollX() async { Map args = {}; @@ -2639,9 +2708,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - View.getScrollY](https://developer.android.com/reference/android/view/View#getScrollY())) ///- iOS ([Official API - UIScrollView.contentOffset](https://developer.apple.com/documentation/uikit/uiscrollview/1619404-contentoffset)) + ///- MacOS ///- Web ([Official API - Window.scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY)) Future getScrollY() async { Map args = {}; @@ -2653,6 +2725,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.getCertificate](https://developer.android.com/reference/android/webkit/WebView#getCertificate())) ///- iOS + ///- MacOS Future getCertificate() async { Map args = {}; Map? sslCertificateMap = @@ -2663,13 +2736,14 @@ class InAppWebViewController { ///Injects the specified [userScript] into the webpage’s content. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKUserContentController.addUserScript](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537448-adduserscript)) + ///- MacOS ([Official API - WKUserContentController.addUserScript](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537448-adduserscript)) Future addUserScript({required UserScript userScript}) async { assert(_webview?.windowId == null || defaultTargetPlatform != TargetPlatform.iOS); @@ -2684,13 +2758,14 @@ class InAppWebViewController { ///Injects the [userScripts] into the webpage’s content. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future addUserScripts({required List userScripts}) async { assert(_webview?.windowId == null || defaultTargetPlatform != TargetPlatform.iOS); @@ -2704,13 +2779,14 @@ class InAppWebViewController { ///User scripts already loaded into the webpage's content cannot be removed. This will have effect only on the next page load. ///Returns `true` if [userScript] was in the list, `false` otherwise. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future removeUserScript({required UserScript userScript}) async { assert(_webview?.windowId == null || defaultTargetPlatform != TargetPlatform.iOS); @@ -2732,13 +2808,14 @@ class InAppWebViewController { ///Removes all the [UserScript]s with [groupName] as group name from the webpage’s content. ///User scripts already loaded into the webpage's content cannot be removed. This will have effect only on the next page load. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future removeUserScriptsByGroupName({required String groupName}) async { assert(_webview?.windowId == null || defaultTargetPlatform != TargetPlatform.iOS); @@ -2751,13 +2828,14 @@ class InAppWebViewController { ///Removes the [userScripts] from the webpage’s content. ///User scripts already loaded into the webpage's content cannot be removed. This will have effect only on the next page load. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future removeUserScripts( {required List userScripts}) async { assert(_webview?.windowId == null || @@ -2770,13 +2848,14 @@ class InAppWebViewController { ///Removes all the user scripts from the webpage’s content. /// - ///**NOTE for iOS**: this method will throw an error if the [WebView.windowId] has been set. - ///There isn't any way to add/remove user scripts specific to iOS window WebViews. - ///This is a limitation of the native iOS WebKit APIs. + ///**NOTE for iOS and MacOS**: this method will throw an error if the [WebView.windowId] has been set. + ///There isn't any way to add/remove user scripts specific to window WebViews. + ///This is a limitation of the native WebKit APIs. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKUserContentController.removeAllUserScripts](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1536540-removealluserscripts)) + ///- MacOS ([Official API - WKUserContentController.removeAllUserScripts](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1536540-removealluserscripts)) Future removeAllUserScripts() async { assert(_webview?.windowId == null || defaultTargetPlatform != TargetPlatform.iOS); @@ -2818,6 +2897,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS ([Official API - WKWebView.callAsyncJavaScript](https://developer.apple.com/documentation/webkit/wkwebview/3656441-callasyncjavascript)) + ///- MacOS ([Official API - WKWebView.callAsyncJavaScript](https://developer.apple.com/documentation/webkit/wkwebview/3656441-callasyncjavascript)) Future callAsyncJavaScript( {required String functionBody, Map arguments = const {}, @@ -2847,11 +2927,14 @@ class InAppWebViewController { /// ///**NOTE for iOS**: Available on iOS 14.0+. If [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.WEBARCHIVE] file extension. /// + ///**NOTE for MacOS**: Available on MacOS 11.0+. If [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.WEBARCHIVE] file extension. + /// ///**NOTE for Android**: if [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.MHT] file extension. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebView.saveWebArchive](https://developer.android.com/reference/android/webkit/WebView#saveWebArchive(java.lang.String,%20boolean,%20android.webkit.ValueCallback%3Cjava.lang.String%3E))) ///- iOS + ///- MacOS Future saveWebArchive( {required String filePath, bool autoname = false}) async { if (!autoname) { @@ -2879,6 +2962,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web ([Official API - Window.isSecureContext](https://developer.mozilla.org/en-US/docs/Web/API/Window/isSecureContext)) Future isSecureContext() async { Map args = {}; @@ -2894,11 +2978,14 @@ class InAppWebViewController { /// ///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL]. /// - ///**NOTE**: On iOS, it is implemented using JavaScript. + ///**NOTE for iOS**: it is implemented using JavaScript. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewCompat.createWebMessageChannel](https://developer.android.com/reference/androidx/webkit/WebViewCompat#createWebMessageChannel(android.webkit.WebView))) ///- iOS + ///- MacOS Future createWebMessageChannel() async { Map args = {}; Map? result = @@ -2914,11 +3001,14 @@ class InAppWebViewController { /// ///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.POST_WEB_MESSAGE]. /// - ///**NOTE**: On iOS, it is implemented using JavaScript. + ///**NOTE for iOS**: it is implemented using JavaScript. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewCompat.postWebMessage](https://developer.android.com/reference/androidx/webkit/WebViewCompat#postWebMessage(android.webkit.WebView,%20androidx.webkit.WebMessageCompat,%20android.net.Uri))) ///- iOS + ///- MacOS Future postWebMessage( {required WebMessage message, Uri? targetOrigin}) async { if (targetOrigin == null) { @@ -3086,11 +3176,14 @@ class InAppWebViewController { /// ///**NOTE for Android**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.WEB_MESSAGE_LISTENER]. /// - ///**NOTE for iOS**: This is implemented using Javascript. + ///**NOTE for iOS**: it is implemented using JavaScript. + /// + ///**NOTE for MacOS**: it is implemented using JavaScript. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebViewCompat.WebMessageListener](https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,%20java.lang.String,%20java.util.Set%3Cjava.lang.String%3E,%20androidx.webkit.WebViewCompat.WebMessageListener))) ///- iOS + ///- MacOS Future addWebMessageListener( WebMessageListener webMessageListener) async { assert( @@ -3107,9 +3200,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future canScrollVertically() async { Map args = {}; @@ -3120,9 +3216,12 @@ class InAppWebViewController { /// ///**NOTE for Web**: this method will have effect only if the iframe has the same origin. /// + ///**NOTE for MacOS**: it is implemented using JavaScript. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS ///- Web Future canScrollHorizontally() async { Map args = {}; @@ -3233,6 +3332,7 @@ class InAppWebViewController { /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.reloadFromOrigin](https://developer.apple.com/documentation/webkit/wkwebview/1414956-reloadfromorigin)) + ///- MacOS ([Official API - WKWebView.reloadFromOrigin](https://developer.apple.com/documentation/webkit/wkwebview/1414956-reloadfromorigin)) Future reloadFromOrigin() async { Map args = {}; await _channel.invokeMethod('reloadFromOrigin', args); @@ -3245,8 +3345,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available only on iOS 14.0+. /// + ///**NOTE for MacOS**: available only on MacOS 11.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.createPdf](https://developer.apple.com/documentation/webkit/wkwebview/3650490-createpdf)) + ///- MacOS ([Official API - WKWebView.createPdf](https://developer.apple.com/documentation/webkit/wkwebview/3650490-createpdf)) Future createPdf( {@Deprecated("Use pdfConfiguration instead") // ignore: deprecated_member_use_from_same_package @@ -3263,8 +3366,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available only on iOS 14.0+. /// + ///**NOTE for MacOS**: available only on MacOS 11.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.createWebArchiveData](https://developer.apple.com/documentation/webkit/wkwebview/3650491-createwebarchivedata)) + ///- MacOS ([Official API - WKWebView.createWebArchiveData](https://developer.apple.com/documentation/webkit/wkwebview/3650491-createwebarchivedata)) Future createWebArchiveData() async { Map args = {}; return await _channel.invokeMethod('createWebArchiveData', args); @@ -3274,6 +3380,7 @@ class InAppWebViewController { /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.hasOnlySecureContent](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent)) + ///- MacOS ([Official API - WKWebView.hasOnlySecureContent](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent)) Future hasOnlySecureContent() async { Map args = {}; return await _channel.invokeMethod('hasOnlySecureContent', args); @@ -3283,8 +3390,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.pauseAllMediaPlayback](https://developer.apple.com/documentation/webkit/wkwebview/3752240-pauseallmediaplayback)). + ///- MacOS ([Official API - WKWebView.pauseAllMediaPlayback](https://developer.apple.com/documentation/webkit/wkwebview/3752240-pauseallmediaplayback)). Future pauseAllMediaPlayback() async { Map args = {}; return await _channel.invokeMethod('pauseAllMediaPlayback', args); @@ -3297,8 +3407,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.setAllMediaPlaybackSuspended](https://developer.apple.com/documentation/webkit/wkwebview/3752242-setallmediaplaybacksuspended)). + ///- MacOS ([Official API - WKWebView.setAllMediaPlaybackSuspended](https://developer.apple.com/documentation/webkit/wkwebview/3752242-setallmediaplaybacksuspended)). Future setAllMediaPlaybackSuspended({required bool suspended}) async { Map args = {}; args.putIfAbsent("suspended", () => suspended); @@ -3309,8 +3422,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 14.5+. /// + ///**NOTE for MacOS**: available on MacOS 11.3+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.closeAllMediaPresentations](https://developer.apple.com/documentation/webkit/wkwebview/3752235-closeallmediapresentations)). + ///- MacOS ([Official API - WKWebView.closeAllMediaPresentations](https://developer.apple.com/documentation/webkit/wkwebview/3752235-closeallmediapresentations)). Future closeAllMediaPresentations() async { Map args = {}; return await _channel.invokeMethod('closeAllMediaPresentations', args); @@ -3322,8 +3438,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.requestMediaPlaybackState](https://developer.apple.com/documentation/webkit/wkwebview/3752241-requestmediaplaybackstate)). + ///- MacOS ([Official API - WKWebView.requestMediaPlaybackState](https://developer.apple.com/documentation/webkit/wkwebview/3752241-requestmediaplaybackstate)). Future requestMediaPlaybackState() async { Map args = {}; return MediaPlaybackState.fromNativeValue( @@ -3335,6 +3454,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS Future isInFullscreen() async { Map args = {}; return await _channel.invokeMethod('isInFullscreen', args); @@ -3344,8 +3464,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.cameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763093-cameracapturestate)). + ///- MacOS ([Official API - WKWebView.cameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763093-cameracapturestate)). Future getCameraCaptureState() async { Map args = {}; return MediaCaptureState.fromNativeValue( @@ -3356,8 +3479,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.setCameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763097-setcameracapturestate)). + ///- MacOS ([Official API - WKWebView.setCameraCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763097-setcameracapturestate)). Future setCameraCaptureState({required MediaCaptureState state}) async { Map args = {}; args.putIfAbsent('state', () => state.toNativeValue()); @@ -3368,8 +3494,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.microphoneCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763096-microphonecapturestate)). + ///- MacOS ([Official API - WKWebView.microphoneCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763096-microphonecapturestate)). Future getMicrophoneCaptureState() async { Map args = {}; return MediaCaptureState.fromNativeValue( @@ -3380,8 +3509,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.setMicrophoneCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763098-setmicrophonecapturestate)). + ///- MacOS ([Official API - WKWebView.setMicrophoneCaptureState](https://developer.apple.com/documentation/webkit/wkwebview/3763098-setmicrophonecapturestate)). Future setMicrophoneCaptureState( {required MediaCaptureState state}) async { Map args = {}; @@ -3409,8 +3541,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available on iOS 15.0+. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.loadSimulatedRequest(_:response:responseData:)](https://developer.apple.com/documentation/webkit/wkwebview/3763094-loadsimulatedrequest) and [Official API - WKWebView.loadSimulatedRequest(_:responseHTML:)](https://developer.apple.com/documentation/webkit/wkwebview/3763095-loadsimulatedrequest)). + ///- MacOS ([Official API - WKWebView.loadSimulatedRequest(_:response:responseData:)](https://developer.apple.com/documentation/webkit/wkwebview/3763094-loadsimulatedrequest) and [Official API - WKWebView.loadSimulatedRequest(_:responseHTML:)](https://developer.apple.com/documentation/webkit/wkwebview/3763095-loadsimulatedrequest)). Future loadSimulatedRequest( {required URLRequest urlRequest, required Uint8List data, @@ -3436,6 +3571,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - WebSettings.getDefaultUserAgent](https://developer.android.com/reference/android/webkit/WebSettings#getDefaultUserAgent(android.content.Context))) ///- iOS + ///- MacOS static Future getDefaultUserAgent() async { Map args = {}; return await _staticChannel.invokeMethod('getDefaultUserAgent', args); @@ -3545,8 +3681,11 @@ class InAppWebViewController { /// ///**NOTE for iOS**: available only on iOS 11.0+. /// + ///**NOTE for MacOS**: available only on MacOS 10.13+. + /// ///**Supported Platforms/Implementations**: ///- iOS ([Official API - WKWebView.handlesURLScheme](https://developer.apple.com/documentation/webkit/wkwebview/2875370-handlesurlscheme)) + ///- MacOS ([Official API - WKWebView.handlesURLScheme](https://developer.apple.com/documentation/webkit/wkwebview/2875370-handlesurlscheme)) static Future handlesURLScheme(String urlScheme) async { Map args = {}; args.putIfAbsent('urlScheme', () => urlScheme); @@ -3558,6 +3697,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS static Future get tRexRunnerHtml async => await rootBundle.loadString( 'packages/flutter_inappwebview/assets/t_rex_runner/t-rex.html'); @@ -3566,6 +3706,7 @@ class InAppWebViewController { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS static Future get tRexRunnerCss async => await rootBundle.loadString( 'packages/flutter_inappwebview/assets/t_rex_runner/t-rex.css'); diff --git a/lib/src/in_app_webview/in_app_webview_settings.dart b/lib/src/in_app_webview/in_app_webview_settings.dart index 58e99250..c398fc6b 100755 --- a/lib/src/in_app_webview/in_app_webview_settings.dart +++ b/lib/src/in_app_webview/in_app_webview_settings.dart @@ -1,6 +1,25 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/src/types/user_preferred_content_mode.dart'; +import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart'; +import '../types/action_mode_menu_item.dart'; +import '../types/cache_mode.dart'; +import '../types/data_detector_types.dart'; +import '../types/force_dark.dart'; +import '../types/force_dark_strategy.dart'; +import '../types/layout_algorithm.dart'; +import '../types/mixed_content_mode.dart'; +import '../types/over_scroll_mode.dart'; +import '../types/referrer_policy.dart'; +import '../types/renderer_priority_policy.dart'; +import '../types/requested_with_header_mode.dart'; +import '../types/sandbox.dart'; +import '../types/scrollbar_style.dart'; +import '../types/scrollview_content_inset_adjustment_behavior.dart'; +import '../types/scrollview_deceleration_rate.dart'; +import '../types/selection_granularity.dart'; +import '../types/vertical_scrollbar_position.dart'; import 'android/in_app_webview_options.dart'; import 'apple/in_app_webview_options.dart'; import '../content_blocker.dart'; @@ -12,35 +31,54 @@ import '../android/webview_feature.dart'; import '../in_app_webview/in_app_webview_controller.dart'; import '../context_menu.dart'; +part 'in_app_webview_settings.g.dart'; + +List _deserializeContentBlockers(List? contentBlockersMapList) { + List contentBlockers = []; + if (contentBlockersMapList != null) { + contentBlockersMapList.forEach((contentBlocker) { + contentBlockers.add(ContentBlocker.fromMap( + Map>.from( + Map.from(contentBlocker)))); + }); + } + return contentBlockers; +} + ///This class represents all the WebView settings available. -class InAppWebViewSettings { +@ExchangeableObject(copyMethod: true) +class InAppWebViewSettings_ { ///Set to `true` to be able to listen at the [WebView.shouldOverrideUrlLoading] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool useShouldOverrideUrlLoading; + ///- MacOS + bool? useShouldOverrideUrlLoading; ///Set to `true` to be able to listen at the [WebView.onLoadResource] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool useOnLoadResource; + ///- MacOS + bool? useOnLoadResource; ///Set to `true` to be able to listen at the [WebView.onDownloadStartRequest] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool useOnDownloadStart; + ///- MacOS + bool? useOnDownloadStart; ///Set to `true` to have all the browser's cache cleared before the new WebView is opened. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool clearCache; + ///- MacOS + bool? clearCache; ///Sets the user-agent for the WebView. /// @@ -49,7 +87,8 @@ class InAppWebViewSettings { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - String userAgent; + ///- MacOS + String? userAgent; ///Append to the existing user-agent. Setting userAgent will override this. /// @@ -58,7 +97,8 @@ class InAppWebViewSettings { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - String applicationNameForUserAgent; + ///- MacOS + String? applicationNameForUserAgent; ///Set to `true` to enable JavaScript. The default value is `true`. /// @@ -66,7 +106,8 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool javaScriptEnabled; + ///- MacOS + bool? javaScriptEnabled; ///Set to `true` to allow JavaScript open windows without user interaction. The default value is `false`. /// @@ -76,22 +117,27 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool javaScriptCanOpenWindowsAutomatically; + ///- MacOS + bool? javaScriptCanOpenWindowsAutomatically; ///Set to `true` to prevent HTML5 audio or video from autoplaying. The default value is `true`. /// - ///**NOTE**: available on iOS 10.0+. + ///**NOTE for iOS**: available on iOS 10.0+. + /// + ///**NOTE for MacOS**: available on MacOS 10.12+. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool mediaPlaybackRequiresUserGesture; + ///- MacOS + bool? mediaPlaybackRequiresUserGesture; ///Sets the minimum font size. The default value is `8` for Android, `0` for iOS. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS + ///- MacOS int? minimumFontSize; ///Define whether the vertical scrollbar should be drawn or not. The default value is `true`. @@ -103,7 +149,7 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool verticalScrollBarEnabled; + bool? verticalScrollBarEnabled; ///Define whether the horizontal scrollbar should be drawn or not. The default value is `true`. /// @@ -114,75 +160,93 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool horizontalScrollBarEnabled; + bool? horizontalScrollBarEnabled; ///List of custom schemes that the WebView must handle. Use the [WebView.onLoadResourceWithCustomScheme] event to intercept resource requests with custom scheme. /// - ///**NOTE**: available on iOS 11.0+. + ///**NOTE for iOS**: available on iOS 11.0+. + /// + ///**NOTE for MacOS**: available on MacOS 10.13+. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - List resourceCustomSchemes; + ///- MacOS + List? resourceCustomSchemes; ///List of [ContentBlocker] that are a set of rules used to block content in the browser window. /// - ///**NOTE**: available on iOS 11.0+. + ///**NOTE for iOS**: available on iOS 11.0+. + /// + ///**NOTE for MacOS**: available on MacOS 10.13+. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - List contentBlockers; + ///- MacOS + @ExchangeableObjectProperty(deserializer: _deserializeContentBlockers) + List? contentBlockers; ///Sets the content mode that the WebView needs to use when loading and rendering a webpage. The default value is [UserPreferredContentMode.RECOMMENDED]. /// - ///**NOTE**: available on iOS 13.0+. + ///**NOTE for iOS**: available on iOS 13.0+. + /// + ///**NOTE for MacOS**: available on MacOS 10.15+. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - UserPreferredContentMode? preferredContentMode; + ///- MacOS + UserPreferredContentMode_? preferredContentMode; ///Set to `true` to be able to listen at the [WebView.shouldInterceptAjaxRequest] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool useShouldInterceptAjaxRequest; + ///- MacOS + bool? useShouldInterceptAjaxRequest; ///Set to `true` to be able to listen at the [WebView.shouldInterceptFetchRequest] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool useShouldInterceptFetchRequest; + ///- MacOS + bool? useShouldInterceptFetchRequest; ///Set to `true` to open a browser window with incognito mode. The default value is `false`. /// - ///**NOTE**: available on iOS 9.0+. - ///On Android, by setting this option to `true`, it will clear all the cookies of all WebView instances, + ///**NOTE for iOS**: available on iOS 9.0+. + /// + ///**NOTE for Android**: setting this to `true`, it will clear all the cookies of all WebView instances, ///because there isn't any way to make the website data store non-persistent for the specific WebView instance such as on iOS. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool incognito; + ///- MacOS + bool? incognito; ///Sets whether WebView should use browser caching. The default value is `true`. /// - ///**NOTE**: available on iOS 9.0+. + ///**NOTE for iOS**: available on iOS 9.0+. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool cacheEnabled; + ///- MacOS + bool? cacheEnabled; ///Set to `true` to make the background of the WebView transparent. If your app has a dark theme, this can prevent a white flash on initialization. The default value is `false`. /// + ///**NOTE for MacOS**: available on MacOS 12.0+. + /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool transparentBackground; + ///- MacOS + bool? transparentBackground; ///Set to `true` to disable vertical scroll. The default value is `false`. /// @@ -192,7 +256,7 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool disableVerticalScroll; + bool? disableVerticalScroll; ///Set to `true` to disable horizontal scroll. The default value is `false`. /// @@ -202,7 +266,7 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool disableHorizontalScroll; + bool? disableHorizontalScroll; ///Set to `true` to disable context menu. The default value is `false`. /// @@ -212,14 +276,15 @@ class InAppWebViewSettings { ///- Android native WebView ///- iOS ///- Web - bool disableContextMenu; + bool? disableContextMenu; ///Set to `false` if the WebView should not support zooming using its on-screen zoom controls and gestures. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool supportZoom; + ///- MacOS + bool? supportZoom; ///Sets whether cross-origin requests in the context of a file scheme URL should be allowed to access content from other file scheme URLs. ///Note that some accesses such as image HTML elements don't follow same-origin rules and aren't affected by this setting. @@ -234,7 +299,8 @@ class InAppWebViewSettings { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool allowFileAccessFromFileURLs; + ///- MacOS + bool? allowFileAccessFromFileURLs; ///Sets whether cross-origin requests in the context of a file scheme URL should be allowed to access content from any origin. ///This includes access to content from other file scheme URLs or web contexts. @@ -249,43 +315,44 @@ class InAppWebViewSettings { ///**Supported Platforms/Implementations**: ///- Android native WebView ///- iOS - bool allowUniversalAccessFromFileURLs; + ///- MacOS + bool? allowUniversalAccessFromFileURLs; ///Sets the text zoom of the page in percent. The default value is `100`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - int textZoom; + int? textZoom; ///Set to `true` to have the session cookie cache cleared before the new window is opened. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool clearSessionCache; + bool? clearSessionCache; ///Set to `true` if the WebView should use its built-in zoom mechanisms. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool builtInZoomControls; + bool? builtInZoomControls; ///Set to `true` if the WebView should display on-screen zoom controls when using the built-in zoom mechanisms. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool displayZoomControls; + bool? displayZoomControls; ///Set to `true` if you want the database storage API is enabled. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool databaseEnabled; + bool? databaseEnabled; ///Set to `true` if you want the DOM storage API is enabled. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool domStorageEnabled; + bool? domStorageEnabled; ///Set to `true` if the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport. ///When the value of the setting is false, the layout width is always set to the width of the WebView control in device-independent (CSS) pixels. @@ -294,7 +361,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool useWideViewPort; + bool? useWideViewPort; ///Sets whether Safe Browsing is enabled. Safe Browsing allows WebView to protect against malware and phishing attacks by verifying the links. ///Safe Browsing is enabled by default for devices which support it. @@ -303,7 +370,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool safeBrowsingEnabled; + bool? safeBrowsingEnabled; ///Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. /// @@ -311,20 +378,20 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - MixedContentMode? mixedContentMode; + MixedContentMode_? mixedContentMode; ///Enables or disables content URL access within WebView. Content URL access allows WebView to load content from a content provider installed in the system. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool allowContentAccess; + bool? allowContentAccess; ///Enables or disables file access within WebView. Note that this enables or disables file system access only. ///Assets and resources are still accessible using `file:///android_asset` and `file:///android_res`. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool allowFileAccess; + bool? allowFileAccess; ///Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this option must be set a path to which the application can write. ///This option is used one time: repeated calls are ignored. @@ -337,44 +404,44 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool blockNetworkImage; + bool? blockNetworkImage; ///Sets whether the WebView should not load resources from the network. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool blockNetworkLoads; + bool? blockNetworkLoads; ///Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. ///When navigating back, content is not revalidated, instead the content is just retrieved from the cache. The default value is [CacheMode.LOAD_DEFAULT]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - CacheMode? cacheMode; + CacheMode_? cacheMode; ///Sets the cursive font family name. The default value is `"cursive"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String cursiveFontFamily; + String? cursiveFontFamily; ///Sets the default fixed font size. The default value is `16`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - int defaultFixedFontSize; + int? defaultFixedFontSize; ///Sets the default font size. The default value is `16`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - int defaultFontSize; + int? defaultFontSize; ///Sets the default text encoding name to use when decoding html pages. The default value is `"UTF-8"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String defaultTextEncodingName; + String? defaultTextEncodingName; ///Disables the action mode menu items according to menuItems flag. /// @@ -382,19 +449,19 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - ActionModeMenuItem? disabledActionModeMenuItems; + ActionModeMenuItem_? disabledActionModeMenuItems; ///Sets the fantasy font family name. The default value is `"fantasy"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String fantasyFontFamily; + String? fantasyFontFamily; ///Sets the fixed font family name. The default value is `"monospace"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String fixedFontFamily; + String? fixedFontFamily; ///Set the force dark mode for this WebView. The default value is [ForceDark.OFF]. /// @@ -402,7 +469,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - ForceDark? forceDark; + ForceDark_? forceDark; ///Set how WebView content should be darkened. ///The default value is [ForceDarkStrategy.PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING]. @@ -411,19 +478,19 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - ForceDarkStrategy? forceDarkStrategy; + ForceDarkStrategy_? forceDarkStrategy; ///Sets whether Geolocation API is enabled. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool geolocationEnabled; + bool? geolocationEnabled; ///Sets the underlying layout algorithm. This will cause a re-layout of the WebView. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - LayoutAlgorithm? layoutAlgorithm; + LayoutAlgorithm_? layoutAlgorithm; ///Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width. ///This setting is taken into account when the content width is greater than the width of the WebView control, for example, when [useWideViewPort] is enabled. @@ -431,7 +498,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool loadWithOverviewMode; + bool? loadWithOverviewMode; ///Sets whether the WebView should load image resources. Note that this method controls loading of all images, including those embedded using the data URI scheme. ///Note that if the value of this setting is changed from false to true, all images resources referenced by content currently displayed by the WebView are loaded automatically. @@ -439,13 +506,13 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool loadsImagesAutomatically; + bool? loadsImagesAutomatically; ///Sets the minimum logical font size. The default is `8`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - int minimumLogicalFontSize; + int? minimumLogicalFontSize; ///Sets the initial scale for this WebView. 0 means default. The behavior for the default scale depends on the state of [useWideViewPort] and [loadWithOverviewMode]. ///If the content fits into the WebView control by width, then the zoom is set to 100%. For wide content, the behavior depends on the state of [loadWithOverviewMode]. @@ -456,13 +523,13 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - int initialScale; + int? initialScale; ///Tells the WebView whether it needs to set a node. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool needInitialFocus; + bool? needInitialFocus; ///Sets whether this WebView should raster tiles when it is offscreen but attached to a window. ///Turning this on can avoid rendering artifacts when animating an offscreen WebView on-screen. @@ -472,25 +539,25 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool offscreenPreRaster; + bool? offscreenPreRaster; ///Sets the sans-serif font family name. The default value is `"sans-serif"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String sansSerifFontFamily; + String? sansSerifFontFamily; ///Sets the serif font family name. The default value is `"sans-serif"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String serifFontFamily; + String? serifFontFamily; ///Sets the standard font family name. The default value is `"sans-serif"`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - String standardFontFamily; + String? standardFontFamily; ///Sets whether the WebView should save form data. In Android O, the platform has implemented a fully functional Autofill feature to store form data. ///Therefore, the Webview form data save feature is disabled. Note that the feature will continue to be supported on older versions of Android as before. @@ -498,7 +565,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool saveFormData; + bool? saveFormData; ///Boolean value to enable third party cookies in the WebView. ///Used on Android Lollipop and above only as third party cookies are enabled by default on Android Kitkat and below and on iOS. @@ -508,21 +575,21 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool thirdPartyCookiesEnabled; + bool? thirdPartyCookiesEnabled; ///Boolean value to enable Hardware Acceleration in the WebView. ///The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool hardwareAcceleration; + bool? hardwareAcceleration; ///Sets whether the WebView supports multiple windows. ///If set to `true`, [WebView.onCreateWindow] event must be implemented by the host application. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool supportMultipleWindows; + bool? supportMultipleWindows; ///Regular expression used by [WebView.shouldOverrideUrlLoading] event to cancel navigation requests for frames that are not the main frame. ///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled. @@ -539,19 +606,19 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool useHybridComposition; + bool? useHybridComposition; ///Set to `true` to be able to listen at the [WebView.shouldInterceptRequest] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool useShouldInterceptRequest; + bool? useShouldInterceptRequest; ///Set to `true` to be able to listen at the [WebView.onRenderProcessGone] event. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool useOnRenderProcessGone; + bool? useOnRenderProcessGone; ///Sets the WebView's over-scroll mode. ///Setting the over-scroll mode of a WebView will have an effect only if the WebView is capable of scrolling. @@ -559,7 +626,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - OverScrollMode? overScrollMode; + OverScrollMode_? overScrollMode; ///Informs WebView of the network state. ///This is used to set the JavaScript property `window.navigator.isOnline` and generates the online/offline event as specified in HTML5, sec. 5.7.7. @@ -577,14 +644,14 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - ScrollBarStyle? scrollBarStyle; + ScrollBarStyle_? scrollBarStyle; ///Sets the position of the vertical scroll bar. ///The default value is [VerticalScrollbarPosition.SCROLLBAR_POSITION_DEFAULT]. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - VerticalScrollbarPosition? verticalScrollbarPosition; + VerticalScrollbarPosition_? verticalScrollbarPosition; ///Defines the delay in milliseconds that a scrollbar waits before fade out. /// @@ -597,7 +664,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool scrollbarFadingEnabled; + bool? scrollbarFadingEnabled; ///Defines the scrollbar fade duration in milliseconds. /// @@ -609,14 +676,14 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - RendererPriorityPolicy? rendererPriorityPolicy; + RendererPriorityPolicy_? rendererPriorityPolicy; ///Sets whether the default Android error page should be disabled. ///The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool disableDefaultErrorPage; + bool? disableDefaultErrorPage; ///Sets the vertical scrollbar thumb color. /// @@ -657,7 +724,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool willSuppressErrorPage; + bool? willSuppressErrorPage; ///Control whether algorithmic darkening is allowed. /// @@ -677,7 +744,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool algorithmicDarkeningAllowed; + bool? algorithmicDarkeningAllowed; ///Sets how the WebView will set the `X-Requested-With` header on requests. ///If you are calling this method, you may also want to call [ServiceWorkerWebSettingsCompat.setRequestedWithHeaderMode] @@ -688,7 +755,7 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - RequestedWithHeaderMode? requestedWithHeaderMode; + RequestedWithHeaderMode_? requestedWithHeaderMode; ///Sets whether EnterpriseAuthenticationAppLinkPolicy if set by admin is allowed to have any ///effect on WebView. @@ -703,37 +770,41 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- Android native WebView - bool enterpriseAuthenticationAppLinkPolicyEnabled; + bool? enterpriseAuthenticationAppLinkPolicyEnabled; ///Set to `true` to disable the bouncing of the WebView when the scrolling has reached an edge of the content. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool disallowOverScroll; + bool? disallowOverScroll; ///Set to `true` to allow a viewport meta tag to either disable or restrict the range of user scaling. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool enableViewportScale; + ///- MacOS + bool? enableViewportScale; ///Set to `true` if you want the WebView suppresses content rendering until it is fully loaded into memory. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool suppressesIncrementalRendering; + ///- MacOS + bool? suppressesIncrementalRendering; ///Set to `true` to allow AirPlay. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool allowsAirPlayForMediaPlayback; + ///- MacOS + bool? allowsAirPlayForMediaPlayback; ///Set to `true` to allow the horizontal swipe gestures trigger back-forward list navigations. The default value is `true`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool allowsBackForwardNavigationGestures; + ///- MacOS + bool? allowsBackForwardNavigationGestures; ///Set to `true` to allow that pressing on a link displays a preview of the destination for the link. The default value is `true`. /// @@ -741,21 +812,22 @@ class InAppWebViewSettings { /// ///**Supported Platforms/Implementations**: ///- iOS - bool allowsLinkPreview; + ///- MacOS + bool? allowsLinkPreview; ///Set to `true` if you want that the WebView should always allow scaling of the webpage, regardless of the author's intent. ///The ignoresViewportScaleLimits property overrides the `user-scalable` HTML property in a webpage. The default value is `false`. /// ///**Supported Platforms/Implementations**: ///- iOS - bool ignoresViewportScaleLimits; + bool? ignoresViewportScaleLimits; ///Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. ///For this to work, add the `webkit-playsinline` attribute to any `