diff --git a/CHANGELOG.md b/CHANGELOG.md index dbbeea73..7b2b34b8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Removed `PrintJobInfo.printerId` - All `InAppWebViewSettings`, `InAppBrowserSettings` properties are optionals +- `InAppBrowser.webViewController` can be null ## 6.0.0-beta.2 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/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_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/integration_test/in_app_webview/take_screenshot.dart b/example/integration_test/in_app_webview/take_screenshot.dart index 47f28e9b..d2f57c88 100644 --- a/example/integration_test/in_app_webview/take_screenshot.dart +++ b/example/integration_test/in_app_webview/take_screenshot.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -21,27 +20,23 @@ void takeScreenshot() { 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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, ); + headlessWebView.onLoadStop = (controller, url) async { + pageLoaded.complete(); + }; + + await headlessWebView.run(); + expect(headlessWebView.isRunning(), true); final InAppWebViewController controller = await controllerCompleter.future; await pageLoaded.future; await Future.delayed(Duration(seconds: 1)); - await tester.pump(); var screenshotConfiguration = ScreenshotConfiguration( compressFormat: CompressFormat.JPEG, diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index fb7828d5..a4ac3aa0 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -33,13 +33,13 @@ void main() { FindInteractionController.debugLoggingSettings.usePrint = true; FindInteractionController.debugLoggingSettings.maxLogMessageLength = 7000; - in_app_webview_tests.main(); - find_interaction_controller_tests.main(); + // in_app_webview_tests.main(); + // find_interaction_controller_tests.main(); service_worker_controller_tests.main(); proxy_controller_tests.main(); headless_in_app_webview_tests.main(); cookie_manager_tests.main(); in_app_browser_tests.main(); - chrome_safari_browser_tests.main(); + // chrome_safari_browser_tests.main(); in_app_localhost_server_tests.main(); } diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index 9e98dd5e..fae63896 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -3,12 +3,11 @@ export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/2.10.4" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" -export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/example/lib/in_app_browser_example.screen.dart b/example/lib/in_app_browser_example.screen.dart index e9aa7d42..cc626d76 100755 --- a/example/lib/in_app_browser_example.screen.dart +++ b/example/lib/in_app_browser_example.screen.dart @@ -76,11 +76,11 @@ class _InAppBrowserExampleScreenState extends State { ), onRefresh: () async { if (Platform.isAndroid) { - widget.browser.webViewController.reload(); + widget.browser.webViewController?.reload(); } else if (Platform.isIOS) { - widget.browser.webViewController.loadUrl( + widget.browser.webViewController?.loadUrl( urlRequest: URLRequest( - url: await widget.browser.webViewController.getUrl())); + url: await widget.browser.webViewController?.getUrl())); } }, ); diff --git a/lib/src/in_app_browser/in_app_browser.dart b/lib/src/in_app_browser/in_app_browser.dart index a02ac2ed..c52f0a28 100755 --- a/lib/src/in_app_browser/in_app_browser.dart +++ b/lib/src/in_app_browser/in_app_browser.dart @@ -73,8 +73,12 @@ 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; + 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 _webViewController; +} ///The window id of a [CreateWindowAction.windowId]. final int? windowId; @@ -99,7 +103,7 @@ class InAppBrowser { } }); _isOpened = false; - webViewController = new InAppWebViewController.fromInAppBrowser( + _webViewController = new InAppWebViewController.fromInAppBrowser( this._channel, this, this.initialUserScripts); } @@ -139,10 +143,11 @@ class InAppBrowser { case "onExit": _debugLog(call.method, call.arguments); this._isOpened = false; + this._webViewController = null; onExit(); break; default: - return webViewController.handleMethod(call); + return _webViewController?.handleMethod(call); } } diff --git a/macos/Classes/ISettings.swift b/macos/Classes/ISettings.swift index 3c536486..1e21d4e8 100755 --- a/macos/Classes/ISettings.swift +++ b/macos/Classes/ISettings.swift @@ -29,17 +29,12 @@ public class ISettings: NSObject { func toMap() -> [String: Any?] { var settings: [String: Any?] = [:] - var counts = UInt32() - let properties = class_copyPropertyList(object_getClass(self), &counts) - for i in 0.. { realSettings["isFraudulentWebsiteWarningEnabled"] = configuration.preferences.isFraudulentWebsiteWarningEnabled realSettings["preferredContentMode"] = configuration.defaultWebpagePreferences.preferredContentMode.rawValue } - realSettings["allowUniversalAccessFromFileURLs"] = configuration.value(forKey: "allowUniversalAccessFromFileURLs") - realSettings["allowFileAccessFromFileURLs"] = configuration.preferences.value(forKey: "allowFileAccessFromFileURLs") + realSettings["allowUniversalAccessFromFileURLs"] = configuration.value(forKey: "allowUniversalAccessFromFileURLs") as? Bool + realSettings["allowFileAccessFromFileURLs"] = configuration.preferences.value(forKey: "allowFileAccessFromFileURLs") as? Bool realSettings["javaScriptEnabled"] = configuration.preferences.javaScriptEnabled if #available(macOS 11.0, *) { realSettings["mediaType"] = webView.mediaType diff --git a/macos/Classes/Types/NSColor.swift b/macos/Classes/Types/NSColor.swift index 263a5c24..4f33b18f 100644 --- a/macos/Classes/Types/NSColor.swift +++ b/macos/Classes/Types/NSColor.swift @@ -27,30 +27,29 @@ extension NSColor { } var hexString: String? { - var red: CGFloat = 0 - var green: CGFloat = 0 - var blue: CGFloat = 0 - var alpha: CGFloat = 0 - - let multiplier = CGFloat(255.999999) - - self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + guard let rgbColor = usingColorSpace(.sRGB) else { + return "#FFFFFF" + } + var red: CGFloat = rgbColor.redComponent + var green: CGFloat = rgbColor.greenComponent + var blue: CGFloat = rgbColor.blueComponent + var alpha: CGFloat = rgbColor.alphaComponent if alpha == 1.0 { return String( format: "#%02lX%02lX%02lX", - Int(red * multiplier), - Int(green * multiplier), - Int(blue * multiplier) + Int(red * 0xFF), + Int(green * 0xFF), + Int(blue * 0xFF) ) } else { return String( format: "#%02lX%02lX%02lX%02lX", - Int(red * multiplier), - Int(green * multiplier), - Int(blue * multiplier), - Int(alpha * multiplier) + Int(red * 0xFF), + Int(green * 0xFF), + Int(blue * 0xFF), + Int(alpha * 0xFF) ) } }